summaryrefslogtreecommitdiff
path: root/plugins/PluginUpdater/pu_stub/pu_stub.cpp
blob: 8167c32d8323785594dd403d608eaa809761ac08 (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
128
#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 <tchar.h>
#include <varargs.h>
#include <stdio.h>

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

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

int CreateDirectoryTreeW(const WCHAR* szDir)
{
	DWORD  dwAttributes;
	WCHAR* pszLastBackslash, szTestDir[ MAX_PATH ];

	lstrcpynW(szTestDir, szDir, MAX_PATH);
	if ((dwAttributes = GetFileAttributesW(szTestDir)) != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
		return 0;

	pszLastBackslash = wcsrchr(szTestDir, '\\');
	if (pszLastBackslash == NULL)
		return 0;

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

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

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

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

	TCHAR tszPipeName[MAX_PATH];
	#if _MSC_VER < 1400
		_stprintf(tszPipeName,  L"\\\\.\\pipe\\Miranda_Pu_%s", lpCmdLine);
	#else
		_stprintf_s(tszPipeName, MAX_PATH, L"\\\\.\\pipe\\Miranda_Pu_%s", lpCmdLine);
	#endif
	log( L"Opening pipe %s...", tszPipeName);
	HANDLE hPipe = CreateFile(tszPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	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, NULL)) {
		DWORD dwAction = *(DWORD*)szReadBuffer;
		TCHAR *ptszFile1 = (TCHAR*)(szReadBuffer + sizeof(DWORD));
		TCHAR *ptszFile2 = ptszFile1 + _tcslen(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, NULL);
	}

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