summaryrefslogtreecommitdiff
path: root/plugins/PluginUpdater/pu_stub/pu_stub.cpp
blob: 2a42d51c4cc4ee434af138f19cdcd14249dd2808 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#define _CRT_SECURE_NO_WARNINGS

#define WIN32_LEAN_AND_MEAN 
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <varargs.h>
#include <stdio.h>

// Global Variables:
HINSTANCE hInst;								// current instance

void log(const wchar_t *tszFormat, ...)
{
	#if defined(_DEBUG)
	FILE *out = fopen("c:\\temp\\pu.log", "a");
	if (out) {
		va_list params;
		va_start(params, tszFormat);
		vfwprintf(out, tszFormat, params);
		va_end(params);
		fputc('\n', out);
		fclose(out);
	}
	#endif
}

int CreateDirectoryTreeW(const WCHAR* szDir)
{
	wchar_t szTestDir[MAX_PATH];
	lstrcpynW(szTestDir, szDir, MAX_PATH);

	DWORD dwAttributes = GetFileAttributesW(szTestDir);
	if (dwAttributes != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
		return 0;

	WCHAR *pszLastBackslash = wcsrchr(szTestDir, '\\');
	if (pszLastBackslash == nullptr)
		return 0;

	*pszLastBackslash = '\0';
	CreateDirectoryTreeW(szTestDir);
	*pszLastBackslash = '\\';
	return (CreateDirectoryW(szTestDir, nullptr) == 0) ? GetLastError() : 0;
}

void CreatePathToFileW(WCHAR* wszFilePath)
{
	WCHAR* pszLastBackslash = wcsrchr(wszFilePath, '\\');
	if (pszLastBackslash == nullptr)
		return;

	*pszLastBackslash = '\0';
	CreateDirectoryTreeW(wszFilePath);
	*pszLastBackslash = '\\';
}

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int)
{
	DWORD dwError;
	hInst = hInstance;

	wchar_t tszPipeName[MAX_PATH];
	#if _MSC_VER < 1400
	swprintf(tszPipeName, L"\\\\.\\pipe\\Miranda_Pu_%s", lpCmdLine);
	#else
	swprintf_s(tszPipeName, L"\\\\.\\pipe\\Miranda_Pu_%s", lpCmdLine);
	#endif
	log(L"Opening pipe %s...", tszPipeName);
	HANDLE hPipe = CreateFile(tszPipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
	if (hPipe == INVALID_HANDLE_VALUE) {
		dwError = GetLastError();
		log(L"Failed to open a pipe: error %d", dwError);
		return dwError;
	}

	log(L"Entering the reading cycle...");

	BYTE szReadBuffer[1024] = { 0 };
	DWORD dwBytes;
	while (ReadFile(hPipe, szReadBuffer, sizeof(szReadBuffer), &dwBytes, nullptr)) {
		DWORD dwAction = *(DWORD*)szReadBuffer;
		wchar_t *ptszFile1 = (wchar_t*)(szReadBuffer + sizeof(DWORD));
		wchar_t *ptszFile2 = ptszFile1 + wcslen(ptszFile1) + 1;
		log(L"Received command: %d <%s> <%s>", dwAction, ptszFile1, ptszFile2);
		switch (dwAction) {
		case 1:  // copy
			dwError = CopyFile(ptszFile1, ptszFile2, FALSE);
			break;

		case 2: // move
			DeleteFile(ptszFile2);
			if (MoveFile(ptszFile1, ptszFile2) == 0) // use copy on error
				dwError = CopyFile(ptszFile1, ptszFile2, FALSE);
			else
				dwError = 0;
			DeleteFile(ptszFile1);
			break;

		case 3: // erase
			dwError = DeleteFile(ptszFile1);
			break;

		case 4: // create dir														  
			dwError = CreateDirectoryTreeW(ptszFile1);
			break;

		case 5: // create path to file
			CreatePathToFileW(ptszFile1);
			dwError = 0;
			break;

		default:
			dwError = ERROR_UNKNOWN_FEATURE;
		}

		WriteFile(hPipe, &dwError, sizeof(DWORD), &dwBytes, nullptr);
	}

	dwError = GetLastError();
	log(L"Pipe is closed (%d), exiting", dwError);
	CloseHandle(hPipe);
	return 0;
}