pidgin/win32/winpidgin.c

changeset 43085
b349c302413c
parent 43077
54cb1cfca9ae
equal deleted inserted replaced
43084:80bdedb243d7 43085:b349c302413c
48 # define PIDGIN_WIN32_UNUSED __attribute__((unused)) 48 # define PIDGIN_WIN32_UNUSED __attribute__((unused))
49 #else 49 #else
50 # define PIDGIN_WIN32_UNUSED 50 # define PIDGIN_WIN32_UNUSED
51 #endif 51 #endif
52 52
53 typedef int (__cdecl* LPFNPIDGINMAIN)(HINSTANCE, int, char**); 53 typedef int (__cdecl* LPFNPIDGINMAIN)(int, char**);
54 typedef BOOL (WINAPI* LPFNSETDLLDIRECTORY)(LPCWSTR); 54 typedef BOOL (WINAPI* LPFNSETDLLDIRECTORY)(LPCWSTR);
55 typedef BOOL (WINAPI* LPFNATTACHCONSOLE)(DWORD); 55 typedef BOOL (WINAPI* LPFNATTACHCONSOLE)(DWORD);
56 typedef BOOL (WINAPI* LPFNSETPROCESSDEPPOLICY)(DWORD); 56 typedef BOOL (WINAPI* LPFNSETPROCESSDEPPOLICY)(DWORD);
57 57
58 /* 58 /*
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 */
222 } 135 }
223 } 136 }
224 } 137 }
225 138
226 cmdLine = GetCommandLineW(); 139 cmdLine = GetCommandLineW();
227
228 /* If this is a protocol handler invocation, deal with it accordingly */
229 if ((wtmp = wcsstr(cmdLine, PROTO_HANDLER_SWITCH)) != NULL) {
230 handle_protocol(wtmp);
231 return 0;
232 }
233 140
234 /* Load exception handler if we have it */ 141 /* Load exception handler if we have it */
235 if (GetModuleFileNameW(NULL, pidgin_dir, MAX_PATH) != 0) { 142 if (GetModuleFileNameW(NULL, pidgin_dir, MAX_PATH) != 0) {
236 143
237 /* primitive dirname() */ 144 /* primitive dirname() */
387 if (!success) 294 if (!success)
388 pidgin_argc--; 295 pidgin_argc--;
389 } 296 }
390 LocalFree(szArglist); 297 LocalFree(szArglist);
391 298
392 299 return pidgin_main(pidgin_argc, pidgin_argv);
393 return pidgin_main(hInstance, pidgin_argc, pidgin_argv);
394 } 300 }

mercurial