| 70 (LPWSTR) &err_msg, sizeof(err_msg) / sizeof(wchar_t), NULL); |
70 (LPWSTR) &err_msg, sizeof(err_msg) / sizeof(wchar_t), NULL); |
| 71 |
71 |
| 72 return err_msg; |
72 return err_msg; |
| 73 } |
73 } |
| 74 |
74 |
| 75 #define PIDGIN_WM_PROTOCOL_HANDLE (WM_APP + 14) |
|
| 76 |
|
| 77 #define PROTO_HANDLER_SWITCH L"--protocolhandler=" |
|
| 78 |
|
| 79 static void handle_protocol(wchar_t *cmd) { |
|
| 80 char *remote_msg, *utf8msg; |
|
| 81 wchar_t *tmp1, *tmp2; |
|
| 82 int len, wlen; |
|
| 83 SIZE_T len_written; |
|
| 84 HWND msg_win; |
|
| 85 DWORD pid; |
|
| 86 HANDLE process; |
|
| 87 |
|
| 88 /* The start of the message */ |
|
| 89 tmp1 = cmd + wcslen(PROTO_HANDLER_SWITCH); |
|
| 90 |
|
| 91 /* The end of the message */ |
|
| 92 if ((tmp2 = wcschr(tmp1, L' '))) |
|
| 93 wlen = (tmp2 - tmp1); |
|
| 94 else |
|
| 95 wlen = wcslen(tmp1); |
|
| 96 |
|
| 97 if (wlen == 0) { |
|
| 98 wprintf(L"No protocol message specified.\n"); |
|
| 99 return; |
|
| 100 } |
|
| 101 |
|
| 102 if (!(msg_win = FindWindowExW(NULL, NULL, L"WinpidginMsgWinCls", NULL))) { |
|
| 103 wprintf(L"Unable to find an instance of Pidgin to handle protocol message.\n"); |
|
| 104 return; |
|
| 105 } |
|
| 106 |
|
| 107 len = WideCharToMultiByte(CP_UTF8, 0, tmp1, |
|
| 108 wlen, NULL, 0, NULL, NULL); |
|
| 109 if (len) { |
|
| 110 utf8msg = malloc(len); |
|
| 111 len = WideCharToMultiByte(CP_UTF8, 0, tmp1, |
|
| 112 wlen, utf8msg, len, NULL, NULL); |
|
| 113 } |
|
| 114 |
|
| 115 if (len == 0) { |
|
| 116 wprintf(L"No protocol message specified.\n"); |
|
| 117 return; |
|
| 118 } |
|
| 119 |
|
| 120 GetWindowThreadProcessId(msg_win, &pid); |
|
| 121 if (!(process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid))) { |
|
| 122 DWORD dw = GetLastError(); |
|
| 123 const wchar_t *err_msg = get_win32_error_message(dw); |
|
| 124 wprintf(L"Unable to open Pidgin process. (%u) %ls\n", |
|
| 125 (UINT)dw, err_msg); |
|
| 126 return; |
|
| 127 } |
|
| 128 |
|
| 129 wprintf(L"Trying to handle protocol message:\n'%.*ls'\n", wlen, tmp1); |
|
| 130 |
|
| 131 /* MEM_COMMIT initializes the memory to zero |
|
| 132 * so we don't need to worry that our section of utf8msg isn't nul-terminated */ |
|
| 133 if ((remote_msg = (char*) VirtualAllocEx(process, NULL, len + 1, MEM_COMMIT, PAGE_READWRITE))) { |
|
| 134 if (WriteProcessMemory(process, remote_msg, utf8msg, len, &len_written)) { |
|
| 135 if (!SendMessageA(msg_win, PIDGIN_WM_PROTOCOL_HANDLE, len_written, (LPARAM) remote_msg)) |
|
| 136 printf("Unable to send protocol message to Pidgin instance.\n"); |
|
| 137 } else { |
|
| 138 DWORD dw = GetLastError(); |
|
| 139 const wchar_t *err_msg = get_win32_error_message(dw); |
|
| 140 wprintf(L"Unable to write to remote memory. (%u) %ls\n", |
|
| 141 (UINT)dw, err_msg); |
|
| 142 } |
|
| 143 |
|
| 144 VirtualFreeEx(process, remote_msg, 0, MEM_RELEASE); |
|
| 145 } else { |
|
| 146 DWORD dw = GetLastError(); |
|
| 147 const wchar_t *err_msg = get_win32_error_message(dw); |
|
| 148 wprintf(L"Unable to allocate remote memory. (%u) %ls\n", |
|
| 149 (UINT)dw, err_msg); |
|
| 150 } |
|
| 151 |
|
| 152 CloseHandle(process); |
|
| 153 free(utf8msg); |
|
| 154 } |
|
| 155 |
|
| 156 |
|
| 157 int __stdcall |
75 int __stdcall |
| 158 WinMain(struct HINSTANCE__ *hInstance, |
76 WinMain(PIDGIN_WIN32_UNUSED struct HINSTANCE__ *hInstance, |
| 159 PIDGIN_WIN32_UNUSED struct HINSTANCE__ *hPrevInstance, |
77 PIDGIN_WIN32_UNUSED struct HINSTANCE__ *hPrevInstance, |
| 160 PIDGIN_WIN32_UNUSED char *lpszCmdLine, |
78 PIDGIN_WIN32_UNUSED char *lpszCmdLine, |
| 161 PIDGIN_WIN32_UNUSED int nCmdShow) |
79 PIDGIN_WIN32_UNUSED int nCmdShow) |
| 162 { |
80 { |
| 163 wchar_t errbuf[512]; |
81 wchar_t errbuf[512]; |
| 164 wchar_t pidgin_dir[MAX_PATH]; |
82 wchar_t pidgin_dir[MAX_PATH]; |
| 165 wchar_t *pidgin_dir_start = NULL; |
83 wchar_t *pidgin_dir_start = NULL; |
| 166 wchar_t exe_name[MAX_PATH]; |
84 wchar_t exe_name[MAX_PATH]; |
| 167 HMODULE hmod; |
85 HMODULE hmod; |
| 168 wchar_t *wtmp; |
|
| 169 int pidgin_argc; |
86 int pidgin_argc; |
| 170 char **pidgin_argv; /* This is in utf-8 */ |
87 char **pidgin_argv; /* This is in utf-8 */ |
| 171 int i, j, k; |
88 int i, j, k; |
| 172 BOOL debug = FALSE, help = FALSE, version = FALSE, multiple = FALSE, success; |
89 BOOL debug = FALSE, help = FALSE, version = FALSE, success; |
| 173 LPWSTR *szArglist; |
90 LPWSTR *szArglist; |
| 174 LPWSTR cmdLine; |
91 LPWSTR cmdLine; |
| 175 |
92 |
| 176 /* If debug or help or version flag used, create console for output */ |
93 /* If debug or help or version flag used, create console for output */ |
| 177 for (i = 1; i < __argc; i++) { |
94 for (i = 1; i < __argc; i++) { |
| 182 debug = TRUE; |
99 debug = TRUE; |
| 183 else if (strstr(__argv[i], "--help") == __argv[i]) |
100 else if (strstr(__argv[i], "--help") == __argv[i]) |
| 184 help = TRUE; |
101 help = TRUE; |
| 185 else if (strstr(__argv[i], "--version") == __argv[i]) |
102 else if (strstr(__argv[i], "--version") == __argv[i]) |
| 186 version = TRUE; |
103 version = TRUE; |
| 187 else if (strstr(__argv[i], "--multiple") == __argv[i]) |
|
| 188 multiple = TRUE; |
|
| 189 } else { |
104 } else { |
| 190 if (strchr(__argv[i], 'd')) |
105 if (strchr(__argv[i], 'd')) |
| 191 debug = TRUE; |
106 debug = TRUE; |
| 192 if (strchr(__argv[i], 'h')) |
107 if (strchr(__argv[i], 'h')) |
| 193 help = TRUE; |
108 help = TRUE; |
| 194 if (strchr(__argv[i], 'v')) |
109 if (strchr(__argv[i], 'v')) |
| 195 version = TRUE; |
110 version = TRUE; |
| 196 if (strchr(__argv[i], 'm')) |
|
| 197 multiple = TRUE; |
|
| 198 } |
111 } |
| 199 } |
112 } |
| 200 } |
113 } |
| 201 |
114 |
| 202 /* Permanently enable DEP if the OS supports it */ |
115 /* Permanently enable DEP if the OS supports it */ |