Add support for tab-completion when selecting by rule
[alpine.git] / mapi / instmapi.c
blob6cfdc086eca884b557a272a7e4480ca42ab0439d
2 /*
3 * ========================================================================
4 * Copyright 2006 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
15 /* installmapi.c : installs the Alpine version of mapi32.dll
16 * into the directory from which this program is run. The PC-Pine
17 * version is pmapi32.dll, and must be in the same directory as the
18 * program being run. Note that we will run into trouble if we want
19 * to name our dll mapi32.dll, unless we're putting it in the system
20 * directory
23 #include <windows.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <io.h>
27 #include <string.h>
28 #include <direct.h>
30 #define FIXREG 1
32 /* this program consists of two parts:
33 * (1) Updating the registry,
34 * most particularly the string of DLLPath in the key
35 * HKLM\Software\Clients\PC-Pine.
36 * (2) Deciding whether or not to copy pmapi32.dll into the system
37 * directory. Starting with Windows 2000, Internet Explorer 5.0
38 * or Outlook 2000, mapi32.dll started to be a stub library, loading
39 * whichever mapi32.dll was defined in the registry (see (1)). We
40 * don't want to overwrite mapi32.dll if it is the stub library, but
41 * if the stub library isn't installed, then we want to install our
42 * own version of mapi32.dll. Since the method for detecting the
43 * stub library isn't very well documented (as of Feb 17, 2000), we
44 * should use a liberal policy of whether or not to copy our mapi
45 * into the system directory. Here are the criteria that determine
46 * that the stub library is correctly installed:
47 * i) Existence of mapistub.dll in the system directory
48 * ii) Existence of the exported function FixMAPI() in mapi32.dll
49 * If either of these two conditions fail, then we'll copy into the
50 * system directory (provided we have correct permissions for it).
52 * Jeff Franklin
53 * University of Washington
54 */
56 int check_defaults(int, int);
57 int check_url_commands(int);
59 #define CD_MAILER 1
60 #define CD_NEWS 2
62 #define CUC_MAILTO 1
63 #define CUC_NEWS 2
64 #define CUC_NNTP 3
66 int APIENTRY WinMain(HINSTANCE hInstance,
67 HINSTANCE hPrevInstance,
68 LPSTR lpCmdLine,
69 int nCmdShow)
71 char dir[1000], filename[1024], mapifile[1024],
72 buffer[3*1024], buffer2[3*1024];
73 unsigned long bufflen = 3*1024;
74 DWORD dtype;
75 int copy = 0, success = 0, silent = 0;
76 FARPROC proc;
77 HKEY hKey;
78 HINSTANCE hDll;
79 LPSTR p, pp;
81 for(pp = p = lpCmdLine; *(p-1); p++){
82 if(*p == ' ' || *p == '\t' || *p == '\0'){
83 if(strncmp("-silent", pp, strlen("-silent")) == 0)
84 silent = 1;
85 if(!*p)
86 break;
87 pp = p + 1;
92 /* This is the first part of writing the registry with our values */
93 _getcwd(dir, 1000);
94 sprintf(filename, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
95 "pmapi32.dll": "\\pmapi32.dll");
96 if(_access(filename, 00) == -1){
97 sprintf(buffer,
98 "pmapi32.dll for PC-Pine not found in %s. Install not completed.",
99 dir);
100 MessageBox(NULL, buffer, "instmapi.exe",
101 MB_OK|MB_ICONERROR);
102 return 0;
105 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail",
106 0, KEY_READ, &hKey) == ERROR_SUCCESS){
107 RegCloseKey(hKey);
108 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail",
109 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS){
110 MessageBox(NULL,
111 "Cannot install pmapi32.dll. Please make sure that you have permissions to update your registry.",
112 "instmapi.exe",
113 MB_OK|MB_ICONERROR);
114 return 0;
117 else {
118 MessageBox(NULL,
119 "Cannot install pmapi32.dll. Mailer information not found in registry.",
120 "instmapi.exe",
121 MB_OK|MB_ICONERROR);
122 return 0;
125 #ifdef FIXREG
127 * I want to take this out next release because it is only intended to fix
128 * problems that pine (<=4.43) set in the registry.
130 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto",
131 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
132 RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, "", 1);
133 RegCloseKey(hKey);
135 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news",
136 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
137 RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, "", 1);
138 RegCloseKey(hKey);
140 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp",
141 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
142 RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, "", 1);
143 RegCloseKey(hKey);
145 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\News\\PC-Pine\\shell\\open\\command",
146 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
147 char *tp;
149 buffer[0] = '\0';
150 bufflen = 1024*3;
151 RegQueryValueEx(hKey, "", 0, &dtype, buffer, &bufflen);
152 tp = buffer + strlen(buffer) - strlen(" -url news:%1");
153 if((tp - buffer > 0) && (tp - buffer < (int)bufflen)
154 && (strcmp(tp, " -url news:%1") == 0)){
155 *tp = '\0';
156 RegSetValueEx(hKey, "", 0, dtype, buffer, strlen(buffer));
158 RegCloseKey(hKey);
160 #endif
162 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail\\PC-Pine",
163 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
164 if(RegSetValueEx(hKey, "DLLPath", 0, REG_SZ,
165 filename, strlen(filename) + 1) != ERROR_SUCCESS){
166 MessageBox(NULL,
167 "Could not update registry. Install not completed.",
168 "instmapi.exe",
169 MB_OK|MB_ICONERROR);
170 RegCloseKey(hKey);
171 return 0;
173 else
174 RegCloseKey(hKey);
176 else{
177 MessageBox(NULL,
178 "No entry found for PC-Pine. Try running PC-Pine, and then run this program",
179 "instmapi.exe",
180 MB_OK|MB_ICONERROR);
181 return 0;
183 if(check_defaults(CD_MAILER, silent))
184 MessageBox(NULL,
185 "Default mailer could not be set",
186 "instmapi.exe",
187 MB_OK|MB_ICONERROR);
188 if(check_defaults(CD_NEWS, silent))
189 MessageBox(NULL,
190 "Default newsreader could not be set",
191 "instmapi.exe",
192 MB_OK|MB_ICONERROR);
194 /* This next part determines whether or not we should write our mapi
195 * into the system directory
197 if(GetSystemDirectory(dir, 1000)){
198 sprintf(mapifile, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
199 "mapi32.dll" : "\\mapi32.dll");
201 hDll = LoadLibrary(mapifile);
202 if(hDll){
203 if(proc = GetProcAddress(hDll,"GetPCPineVersion")){
204 sprintf(buffer2, "pmapi32.dll exists in %s as mapi32.dll",
205 dir);
206 MessageBox(NULL, buffer2,
207 "instmapi.exe",
208 MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
209 success = 1;
211 if(!success){
212 sprintf(buffer, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
213 "mapistub.dll" : "\\mapistub.dll");
214 if(_access(buffer, 00) != 0)
215 copy = 1;
216 if(!copy){
217 proc = GetProcAddress(hDll, "FixMAPI");
218 if(!proc){
219 copy = 1;
221 else
222 success = 1;
225 FreeLibrary(hDll);
227 else
228 copy = 1;
229 if(copy){
230 sprintf(buffer2, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
231 "mapi32x.dll" : "\\mapi32x.dll");
232 CopyFile(mapifile, buffer2, 0);
233 if(CopyFile(filename, mapifile, 0)){
234 sprintf(buffer2, "pmapi32.dll has been copied to %s",
235 mapifile);
236 MessageBox(NULL, buffer2, "instmapi.exe",
237 MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
238 success = 1;
240 else{
241 sprintf(buffer2, "pmapi32.dll could not be copied to %s",
242 mapifile);
243 MessageBox(NULL, buffer2, "instmapi.exe",
244 MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
249 if(success && !silent){
250 sprintf(buffer2,
251 "Installation of pmapi32.dll was successfully completed",
252 buffer);
253 MessageBox(NULL, buffer2, "instmapi.exe",
254 MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
256 else if(!success){
257 sprintf(buffer2,
258 "Installation of pmapi32.dll may not have successfully completed",
259 buffer);
260 MessageBox(NULL, buffer2, "instmapi.exe",
261 MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
263 return 0;
267 check_defaults(wdef, silent)
268 int wdef, silent;
270 HKEY hKey;
271 DWORD dtype;
272 char buffer[1024*3];
273 unsigned long bufflen = 1024*3;
274 int ret;
276 if(wdef != CD_MAILER && wdef != CD_NEWS)
277 return(1);
278 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CD_MAILER
279 ? "SOFTWARE\\Clients\\Mail" : "SOFTWARE\\Clients\\News",
280 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
281 return(1);
282 bufflen = 1024*3;
283 RegQueryValueEx(hKey, "", 0, &dtype, buffer, &bufflen);
284 if(strcmp(buffer, "PC-Pine") == 0){
285 RegCloseKey(hKey);
286 return(0);
288 ret = silent ? IDYES
289 : MessageBox (NULL, wdef == CD_MAILER
290 ? "Do you want to make PC-Pine your default mailer?"
291 : "Do you want to make PC-Pine your default newsreader?",
292 "instmapi.exe",
293 MB_APPLMODAL | MB_ICONQUESTION | MB_YESNO);
294 if(ret == IDYES){
295 strcpy(buffer, "PC-Pine");
296 bufflen = strlen(buffer)+1;
297 if(RegSetValueEx(hKey, "", 0,
298 REG_SZ, buffer, bufflen) != ERROR_SUCCESS){
299 RegCloseKey(hKey);
300 return(1);
302 RegCloseKey(hKey);
303 if(wdef == CD_MAILER){
304 if(check_url_commands(CUC_MAILTO))
305 return(1);
307 else if(wdef == CD_NEWS){
308 if(check_url_commands(CUC_NEWS)
309 || check_url_commands(CUC_NNTP))
310 return(1);
313 return(0);
317 check_url_commands(wdef)
318 int wdef;
320 HKEY hKey, hKeyCP;
321 DWORD dtype;
322 char buffer[1024*3];
323 unsigned long bufflen = 1024*3;
325 if(wdef != CUC_MAILTO && wdef != CUC_NEWS && wdef != CUC_NNTP)
326 return(1);
327 if(RegOpenKeyEx(HKEY_CLASSES_ROOT, wdef == CUC_MAILTO
328 ? "mailto\\shell\\open\\command"
329 : (wdef == CUC_NEWS ? "news\\shell\\open\\command"
330 : "nntp\\shell\\open\\command"),
331 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
332 return(1);
333 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CUC_MAILTO
334 ? "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto\\shell\\open\\command"
335 : (wdef == CUC_NEWS ? "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news\\shell\\open\\command"
336 : "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp\\shell\\open\\command"),
337 0, KEY_ALL_ACCESS, &hKeyCP) != ERROR_SUCCESS){
338 RegCloseKey(hKey);
339 return(1);
341 buffer[0] = '\0';
342 bufflen = 1024*3;
343 if(RegQueryValueEx(hKeyCP, "", 0, &dtype,
344 buffer, &bufflen) != ERROR_SUCCESS
345 || RegSetValueEx(hKey, "", 0, REG_SZ, buffer,
346 bufflen) != ERROR_SUCCESS){
347 RegCloseKey(hKey);
348 RegCloseKey(hKeyCP);
349 return(1);
351 RegCloseKey(hKey);
352 RegCloseKey(hKeyCP);
353 if(RegOpenKeyEx(HKEY_CLASSES_ROOT, wdef == CUC_MAILTO
354 ? "mailto\\DefaultIcon"
355 : (wdef == CUC_NEWS ? "news\\DefaultIcon"
356 : "nntp\\DefaultIcon"),
357 0, KEY_ALL_ACCESS,
358 &hKey) != ERROR_SUCCESS)
359 return(1);
360 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CUC_MAILTO
361 ? "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto\\DefaultIcon"
362 : (wdef == CUC_NEWS ? "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news\\DefaultIcon"
363 : "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp\\DefaultIcon"),
364 0, KEY_ALL_ACCESS, &hKeyCP) != ERROR_SUCCESS){
365 RegCloseKey(hKey);
366 return(1);
368 buffer[0] = '\0';
369 bufflen = 1024*3;
370 if(RegQueryValueEx(hKeyCP, "", 0, &dtype, buffer, &bufflen) != ERROR_SUCCESS
371 || RegSetValueEx(hKey, "", 0, REG_SZ, buffer, bufflen) != ERROR_SUCCESS){
372 RegCloseKey(hKey);
373 RegCloseKey(hKeyCP);
374 return(1);
376 RegCloseKey(hKey);
377 RegCloseKey(hKeyCP);
379 if(RegOpenKeyEx(HKEY_CLASSES_ROOT, wdef == CUC_MAILTO
380 ? "mailto"
381 : (wdef == CUC_NEWS ? "news"
382 : "nntp"),
383 0, KEY_ALL_ACCESS,
384 &hKey) != ERROR_SUCCESS)
385 return(1);
386 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CUC_MAILTO
387 ? "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto"
388 : (wdef == CUC_NEWS ? "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news"
389 : "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp"),
390 0, KEY_ALL_ACCESS, &hKeyCP) != ERROR_SUCCESS){
391 RegCloseKey(hKey);
392 return(1);
394 buffer[0] = '\0';
395 bufflen = 1024*3;
396 if(RegQueryValueEx(hKeyCP, "URL Protocol", 0, &dtype, buffer, &bufflen) != ERROR_SUCCESS
397 || RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, buffer, bufflen) != ERROR_SUCCESS){
398 RegCloseKey(hKey);
399 RegCloseKey(hKeyCP);
400 return(1);
402 RegCloseKey(hKey);
403 RegCloseKey(hKeyCP);
405 return(0);