summaryrefslogtreecommitdiff
path: root/mapi/instmapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'mapi/instmapi.c')
-rw-r--r--mapi/instmapi.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/mapi/instmapi.c b/mapi/instmapi.c
new file mode 100644
index 00000000..ab79f2f4
--- /dev/null
+++ b/mapi/instmapi.c
@@ -0,0 +1,406 @@
+
+/*
+ * ========================================================================
+ * Copyright 2006 University of Washington
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * ========================================================================
+ */
+
+/* installmapi.c : installs the Alpine version of mapi32.dll
+ * into the directory from which this program is run. The PC-Pine
+ * version is pmapi32.dll, and must be in the same directory as the
+ * program being run. Note that we will run into trouble if we want
+ * to name our dll mapi32.dll, unless we're putting it in the system
+ * directory
+ */
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <io.h>
+#include <string.h>
+#include <direct.h>
+
+#define FIXREG 1
+
+/* this program consists of two parts:
+ * (1) Updating the registry,
+ * most particulary the string of DLLPath in the key
+ * HKLM\Software\Clients\PC-Pine.
+ * (2) Deciding whether or not to copy pmapi32.dll into the system
+ * directory. Starting with Windows 2000, Internet Explorer 5.0
+ * or Outlook 2000, mapi32.dll started to be a stub library, loading
+ * whichever mapi32.dll was defined in the registry (see (1)). We
+ * don't want to overwrite mapi32.dll if it is the stub library, but
+ * if the stub library isn't installed, then we want to install our
+ * own version of mapi32.dll. Since the method for detecting the
+ * stub library isn't very well documented (as of Feb 17, 2000), we
+ * should use a liberal policy of whether or not to copy our mapi
+ * into the system directory. Here are the criteria that determine
+ * that the stub library is correctly installed:
+ * i) Existence of mapistub.dll in the system directory
+ * ii) Existence of the exported function FixMAPI() in mapi32.dll
+ * If either of these two conditions fail, then we'll copy into the
+ * system directory (provided we have correct permissions for it).
+ *
+ * Jeff Franklin
+ * University of Washington
+ */
+
+int check_defaults(int, int);
+int check_url_commands(int);
+
+#define CD_MAILER 1
+#define CD_NEWS 2
+
+#define CUC_MAILTO 1
+#define CUC_NEWS 2
+#define CUC_NNTP 3
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ char dir[1000], filename[1024], mapifile[1024],
+ buffer[3*1024], buffer2[3*1024];
+ unsigned long bufflen = 3*1024;
+ DWORD dtype;
+ int copy = 0, success = 0, silent = 0;
+ FARPROC proc;
+ HKEY hKey;
+ HINSTANCE hDll;
+ LPSTR p, pp;
+
+ for(pp = p = lpCmdLine; *(p-1); p++){
+ if(*p == ' ' || *p == '\t' || *p == '\0'){
+ if(strncmp("-silent", pp, strlen("-silent")) == 0)
+ silent = 1;
+ if(!*p)
+ break;
+ pp = p + 1;
+ }
+ }
+
+
+ /* This is the first part of writing the registry with our values */
+ _getcwd(dir, 1000);
+ sprintf(filename, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
+ "pmapi32.dll": "\\pmapi32.dll");
+ if(_access(filename, 00) == -1){
+ sprintf(buffer,
+ "pmapi32.dll for PC-Pine not found in %s. Install not completed.",
+ dir);
+ MessageBox(NULL, buffer, "instmapi.exe",
+ MB_OK|MB_ICONERROR);
+ return 0;
+ }
+
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail",
+ 0, KEY_READ, &hKey) == ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail",
+ 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS){
+ MessageBox(NULL,
+ "Cannot install pmapi32.dll. Please make sure that you have permissions to update your registry.",
+ "instmapi.exe",
+ MB_OK|MB_ICONERROR);
+ return 0;
+ }
+ }
+ else {
+ MessageBox(NULL,
+ "Cannot install pmapi32.dll. Mailer information not found in registry.",
+ "instmapi.exe",
+ MB_OK|MB_ICONERROR);
+ return 0;
+ }
+
+#ifdef FIXREG
+ /*
+ * I want to take this out next release because it is only intended to fix
+ * problems that pine (<=4.43) set in the registry.
+ */
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto",
+ 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
+ RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, "", 1);
+ RegCloseKey(hKey);
+ }
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news",
+ 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
+ RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, "", 1);
+ RegCloseKey(hKey);
+ }
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp",
+ 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
+ RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, "", 1);
+ RegCloseKey(hKey);
+ }
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\News\\PC-Pine\\shell\\open\\command",
+ 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
+ char *tp;
+
+ buffer[0] = '\0';
+ bufflen = 1024*3;
+ RegQueryValueEx(hKey, "", 0, &dtype, buffer, &bufflen);
+ tp = buffer + strlen(buffer) - strlen(" -url news:%1");
+ if((tp - buffer > 0) && (tp - buffer < (int)bufflen)
+ && (strcmp(tp, " -url news:%1") == 0)){
+ *tp = '\0';
+ RegSetValueEx(hKey, "", 0, dtype, buffer, strlen(buffer));
+ }
+ RegCloseKey(hKey);
+ }
+#endif
+
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Clients\\Mail\\PC-Pine",
+ 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
+ if(RegSetValueEx(hKey, "DLLPath", 0, REG_SZ,
+ filename, strlen(filename) + 1) != ERROR_SUCCESS){
+ MessageBox(NULL,
+ "Could not update registry. Install not completed.",
+ "instmapi.exe",
+ MB_OK|MB_ICONERROR);
+ RegCloseKey(hKey);
+ return 0;
+ }
+ else
+ RegCloseKey(hKey);
+ }
+ else{
+ MessageBox(NULL,
+ "No entry found for PC-Pine. Try running PC-Pine, and then run this program",
+ "instmapi.exe",
+ MB_OK|MB_ICONERROR);
+ return 0;
+ }
+ if(check_defaults(CD_MAILER, silent))
+ MessageBox(NULL,
+ "Default mailer could not be set",
+ "instmapi.exe",
+ MB_OK|MB_ICONERROR);
+ if(check_defaults(CD_NEWS, silent))
+ MessageBox(NULL,
+ "Default newsreader could not be set",
+ "instmapi.exe",
+ MB_OK|MB_ICONERROR);
+
+ /* This next part determines whether or not we should write our mapi
+ * into the system directory
+ */
+ if(GetSystemDirectory(dir, 1000)){
+ sprintf(mapifile, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
+ "mapi32.dll" : "\\mapi32.dll");
+
+ hDll = LoadLibrary(mapifile);
+ if(hDll){
+ if(proc = GetProcAddress(hDll,"GetPCPineVersion")){
+ sprintf(buffer2, "pmapi32.dll exists in %s as mapi32.dll",
+ dir);
+ MessageBox(NULL, buffer2,
+ "instmapi.exe",
+ MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
+ success = 1;
+ }
+ if(!success){
+ sprintf(buffer, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
+ "mapistub.dll" : "\\mapistub.dll");
+ if(_access(buffer, 00) != 0)
+ copy = 1;
+ if(!copy){
+ proc = GetProcAddress(hDll, "FixMAPI");
+ if(!proc){
+ copy = 1;
+ }
+ else
+ success = 1;
+ }
+ }
+ FreeLibrary(hDll);
+ }
+ else
+ copy = 1;
+ if(copy){
+ sprintf(buffer2, "%s%s", dir, dir[strlen(dir)-1] == '\\' ?
+ "mapi32x.dll" : "\\mapi32x.dll");
+ CopyFile(mapifile, buffer2, 0);
+ if(CopyFile(filename, mapifile, 0)){
+ sprintf(buffer2, "pmapi32.dll has been copied to %s",
+ mapifile);
+ MessageBox(NULL, buffer2, "instmapi.exe",
+ MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
+ success = 1;
+ }
+ else{
+ sprintf(buffer2, "pmapi32.dll could not be copied to %s",
+ mapifile);
+ MessageBox(NULL, buffer2, "instmapi.exe",
+ MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
+ }
+ }
+ }
+
+ if(success && !silent){
+ sprintf(buffer2,
+ "Installation of pmapi32.dll was successfully completed",
+ buffer);
+ MessageBox(NULL, buffer2, "instmapi.exe",
+ MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
+ }
+ else if(!success){
+ sprintf(buffer2,
+ "Installation of pmapi32.dll may not have successfully completed",
+ buffer);
+ MessageBox(NULL, buffer2, "instmapi.exe",
+ MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
+ }
+ return 0;
+}
+
+int
+check_defaults(wdef, silent)
+ int wdef, silent;
+{
+ HKEY hKey;
+ DWORD dtype;
+ char buffer[1024*3];
+ unsigned long bufflen = 1024*3;
+ int ret;
+
+ if(wdef != CD_MAILER && wdef != CD_NEWS)
+ return(1);
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CD_MAILER
+ ? "SOFTWARE\\Clients\\Mail" : "SOFTWARE\\Clients\\News",
+ 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
+ return(1);
+ bufflen = 1024*3;
+ RegQueryValueEx(hKey, "", 0, &dtype, buffer, &bufflen);
+ if(strcmp(buffer, "PC-Pine") == 0){
+ RegCloseKey(hKey);
+ return(0);
+ }
+ ret = silent ? IDYES
+ : MessageBox (NULL, wdef == CD_MAILER
+ ? "Do you want to make PC-Pine your default mailer?"
+ : "Do you want to make PC-Pine your default newsreader?",
+ "instmapi.exe",
+ MB_APPLMODAL | MB_ICONQUESTION | MB_YESNO);
+ if(ret == IDYES){
+ strcpy(buffer, "PC-Pine");
+ bufflen = strlen(buffer)+1;
+ if(RegSetValueEx(hKey, "", 0,
+ REG_SZ, buffer, bufflen) != ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ return(1);
+ }
+ RegCloseKey(hKey);
+ if(wdef == CD_MAILER){
+ if(check_url_commands(CUC_MAILTO))
+ return(1);
+ }
+ else if(wdef == CD_NEWS){
+ if(check_url_commands(CUC_NEWS)
+ || check_url_commands(CUC_NNTP))
+ return(1);
+ }
+ }
+ return(0);
+}
+
+int
+check_url_commands(wdef)
+ int wdef;
+{
+ HKEY hKey, hKeyCP;
+ DWORD dtype;
+ char buffer[1024*3];
+ unsigned long bufflen = 1024*3;
+
+ if(wdef != CUC_MAILTO && wdef != CUC_NEWS && wdef != CUC_NNTP)
+ return(1);
+ if(RegOpenKeyEx(HKEY_CLASSES_ROOT, wdef == CUC_MAILTO
+ ? "mailto\\shell\\open\\command"
+ : (wdef == CUC_NEWS ? "news\\shell\\open\\command"
+ : "nntp\\shell\\open\\command"),
+ 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
+ return(1);
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CUC_MAILTO
+ ? "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto\\shell\\open\\command"
+ : (wdef == CUC_NEWS ? "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news\\shell\\open\\command"
+ : "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp\\shell\\open\\command"),
+ 0, KEY_ALL_ACCESS, &hKeyCP) != ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ return(1);
+ }
+ buffer[0] = '\0';
+ bufflen = 1024*3;
+ if(RegQueryValueEx(hKeyCP, "", 0, &dtype,
+ buffer, &bufflen) != ERROR_SUCCESS
+ || RegSetValueEx(hKey, "", 0, REG_SZ, buffer,
+ bufflen) != ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ RegCloseKey(hKeyCP);
+ return(1);
+ }
+ RegCloseKey(hKey);
+ RegCloseKey(hKeyCP);
+ if(RegOpenKeyEx(HKEY_CLASSES_ROOT, wdef == CUC_MAILTO
+ ? "mailto\\DefaultIcon"
+ : (wdef == CUC_NEWS ? "news\\DefaultIcon"
+ : "nntp\\DefaultIcon"),
+ 0, KEY_ALL_ACCESS,
+ &hKey) != ERROR_SUCCESS)
+ return(1);
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CUC_MAILTO
+ ? "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto\\DefaultIcon"
+ : (wdef == CUC_NEWS ? "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news\\DefaultIcon"
+ : "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp\\DefaultIcon"),
+ 0, KEY_ALL_ACCESS, &hKeyCP) != ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ return(1);
+ }
+ buffer[0] = '\0';
+ bufflen = 1024*3;
+ if(RegQueryValueEx(hKeyCP, "", 0, &dtype, buffer, &bufflen) != ERROR_SUCCESS
+ || RegSetValueEx(hKey, "", 0, REG_SZ, buffer, bufflen) != ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ RegCloseKey(hKeyCP);
+ return(1);
+ }
+ RegCloseKey(hKey);
+ RegCloseKey(hKeyCP);
+
+ if(RegOpenKeyEx(HKEY_CLASSES_ROOT, wdef == CUC_MAILTO
+ ? "mailto"
+ : (wdef == CUC_NEWS ? "news"
+ : "nntp"),
+ 0, KEY_ALL_ACCESS,
+ &hKey) != ERROR_SUCCESS)
+ return(1);
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, wdef == CUC_MAILTO
+ ? "SOFTWARE\\Clients\\Mail\\PC-Pine\\Protocols\\Mailto"
+ : (wdef == CUC_NEWS ? "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\news"
+ : "SOFTWARE\\Clients\\News\\PC-Pine\\Protocols\\nntp"),
+ 0, KEY_ALL_ACCESS, &hKeyCP) != ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ return(1);
+ }
+ buffer[0] = '\0';
+ bufflen = 1024*3;
+ if(RegQueryValueEx(hKeyCP, "URL Protocol", 0, &dtype, buffer, &bufflen) != ERROR_SUCCESS
+ || RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, buffer, bufflen) != ERROR_SUCCESS){
+ RegCloseKey(hKey);
+ RegCloseKey(hKeyCP);
+ return(1);
+ }
+ RegCloseKey(hKey);
+ RegCloseKey(hKeyCP);
+
+ return(0);
+}