--- trunk/init/GPGOEInit.c 2006/03/24 13:36:54 1 +++ trunk/init/GPGOEInit.c 2006/04/13 07:41:30 18 @@ -18,34 +18,188 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#ifdef HAVE_CONFIG_H +#include +#endif #include +#include +#include +#include #include "resource.h" -/*-- GPGOE DLL calls --*/ -int gpgoe_initialize (void); -int gpgoe_remove (void); +/* Supported plug-in modes. */ +enum gpgoe_mode_t { + GPGOE_MODE_NORMAL = 0, + GPGOE_MODE_PLAINREPLY = 1 +}; + +/* DLL imports. */ +int gpgoe_initialize (void); +int gpgoe_remove (void); +void gpgoe_set_active_modes (int mode); +int gpgoe_get_active_modes (void); + + +/* Global module handle. */ static HINSTANCE glob_hinst = NULL; +/* String array of programs which are known to cause trouble + with GPGoe. */ +static const char *conflict_apps[] = { + "DUMMY", /* dummy entry. */ + "SPYXX.EXE", + NULL +}; + + +/* Enumerate all processes and figure out if a program + is running which could be a conflict for gpgoe. */ +static int +check_for_conflict_apps (void) +{ + PROCESSENTRY32 pe; + HANDLE hd; + BOOL next; + int fnd = 0; + + hd = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); + if (hd == (HANDLE)-1) + return 0; + + memset (&pe, 0, sizeof (pe)); + pe.dwSize = sizeof (pe); + next = Process32First (hd, &pe); + while (next) { + size_t i; + + for (i=0; i < strlen (pe.szExeFile); i++) + pe.szExeFile[i] = (char)toupper ((int)pe.szExeFile[i]); + for (i=0; conflict_apps[i] != NULL; i++) { + if (strstr (pe.szExeFile, conflict_apps[i])) { + fnd = i; + break; + } + } + next = Process32Next (hd, &pe); + if (!next) + break; + } + CloseHandle (hd); + return fnd; +} + + +/* Return -1 if there was a running instance of OE detected. */ +static int +outlook_is_running (void) +{ + if (!FindWindowEx (NULL, NULL, "Outlook Express Browser Class", NULL)) + return 0; + return -1; +} + + +/* Set the menu item @muid to the state @state. */ +void +set_menu_state (HMENU menu, UINT muid, UINT state) +{ + MENUITEMINFO mii; + + memset (&mii, 0, sizeof (mii)); + mii.cbSize = sizeof (mii); + mii.fMask = MIIM_STATE; + mii.fState = state; + SetMenuItemInfo (menu, muid, FALSE, &mii); +} + + +/* Get an option with the name @name from the registry. */ +int +get_gpgoe_option (const char *name) +{ + HKEY hkey; + LONG err; + char val[32]; + DWORD type = 0, vallen = sizeof (val); + + err = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\GNU\\GPGoe", 0, + KEY_READ, &hkey); + if (err != ERROR_SUCCESS) + return 0; + err = RegQueryValueEx (hkey, name, NULL, &type, (BYTE*)val, &vallen); + RegCloseKey (hkey); + if (err != ERROR_SUCCESS) + return 0; + return atoi (val); +} + + +/* Put an option with the name @name and the value @val in th registry. */ +int +put_gpgoe_option (const char *name, int val) +{ + HKEY hkey; + char buf[32]; + LONG err; + + sprintf (buf, "%d", val); + err = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\GNU\\GPGoe", 0, + KEY_WRITE, &hkey); + if (err != ERROR_SUCCESS) + return -1; + err = RegSetValueEx (hkey, name, 0, REG_SZ, (BYTE *)buf, strlen (buf)); + RegCloseKey (hkey); + return err != ERROR_SUCCESS? -1 : 0; +} + + +/* Create the GPGoe registry if needed. */ +static int +create_registry_key (void) +{ + HKEY hkey; + LONG err; + err = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\GNU\\GPGoe", + 0, KEY_READ, &hkey); + if (err == ERROR_SUCCESS) { + RegCloseKey (hkey); + return 0; + } + err = RegCreateKey (HKEY_CURRENT_USER, "Software\\GNU\\GPGoe", &hkey); + if (err != ERROR_SUCCESS) + return -1; + RegCloseKey (hkey); + return 0; +} + + +/* Main window procedure for the taskbar program. */ LRESULT CALLBACK gpgoe_main_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + static int decrypt_replies = 0; NOTIFYICONDATA NID; + POINT p; + HMENU hm, popup; int id; - switch (msg) - { + switch (msg) { case WM_CREATE: - NID.cbSize = sizeof(NID); - NID.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + NID.cbSize = sizeof (NID); + NID.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; NID.uCallbackMessage = WM_USER; NID.hWnd = hwnd; - NID.hIcon = LoadIcon(glob_hinst, MAKEINTRESOURCE(IDI_GPGOE)); + NID.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (IDI_GPGOE)); strcpy(NID.szTip, "GPG for Outlook Express"); Shell_NotifyIcon (NIM_ADD, &NID); - DestroyIcon (NID.hIcon); + DestroyIcon (NID.hIcon); + + decrypt_replies = get_gpgoe_option ("PlaintextReply"); + if (decrypt_replies) + gpgoe_set_active_modes (GPGOE_MODE_PLAINREPLY); if (gpgoe_initialize ()) { MessageBox (hwnd, "Couldn't register GPG OE hook", "Error", MB_ICONERROR|MB_OK); ExitProcess (0); @@ -54,16 +208,39 @@ case WM_DESTROY: case WM_ENDSESSION: + put_gpgoe_option ("PlaintextReply", decrypt_replies); gpgoe_remove (); - Shell_NotifyIcon(NIM_DELETE, &NID); + Shell_NotifyIcon (NIM_DELETE, &NID); PostQuitMessage (0); ExitProcess (0); return 0; + case WM_COMMAND: + switch (LOWORD (wparam)) { + case ID_INIT_SUPP_PLAINREPLY: + decrypt_replies ^= 1; + if (!decrypt_replies) { + int modes = gpgoe_get_active_modes (); + gpgoe_set_active_modes (modes & (~GPGOE_MODE_PLAINREPLY)); + } + else { + gpgoe_set_active_modes (GPGOE_MODE_PLAINREPLY); + if (outlook_is_running ()) + MessageBox (NULL, "You need to restart Outlook Express.", + "GPGOE Information", MB_ICONINFORMATION|MB_OK); + } + break; + + case ID_INIT_QUIT: + SendMessage (hwnd, WM_DESTROY, 0, 0); + break; + } + break; + case WM_USER: switch (lparam) { case WM_LBUTTONDBLCLK: - SetForegroundWindow(hwnd); + SetForegroundWindow (hwnd); id = MessageBox (NULL, "Remove the GPG OE plug-in from the system?", "Are you sure?", MB_YESNO|MB_ICONINFORMATION); if (id == IDYES) @@ -71,48 +248,61 @@ break; case WM_RBUTTONUP: - { - POINT p; - HMENU hm, popup; - - GetCursorPos (&p); - hm = LoadMenu (glob_hinst, MAKEINTRESOURCE (IDR_INIT)); - popup = GetSubMenu (hm, 0); - TrackPopupMenu (popup, TPM_RIGHTALIGN, p.x, p.y, 0, hwnd, NULL); - DestroyMenu (popup); - DestroyMenu (hm); - } + SetForegroundWindow (hwnd); + GetCursorPos (&p); + hm = LoadMenu (glob_hinst, MAKEINTRESOURCE (IDR_INIT)); + popup = GetSubMenu (hm, 0); + set_menu_state (popup, ID_INIT_SUPP_PLAINREPLY, + decrypt_replies? MFS_CHECKED : MFS_UNCHECKED); + TrackPopupMenu (popup, TPM_RIGHTALIGN, p.x, p.y, 0, hwnd, NULL); + PostMessage (hwnd, WM_USER, 0, 0); + DestroyMenu (popup); + DestroyMenu (hm); break; } break; - - case WM_COMMAND: - if (LOWORD (wparam) == ID_INIT_QUIT) - SendMessage(hwnd, WM_DESTROY, 0, 0); - break; } - return DefWindowProc(hwnd, msg, wparam, lparam); + + return DefWindowProc (hwnd, msg, wparam, lparam); } +/* Main entry function. */ int WINAPI WinMain (HINSTANCE hinst, HINSTANCE prev, LPSTR cmdline, int cmd_show) { WNDCLASS wc; HWND hwnd; MSG msg; + int idx; + + idx = check_for_conflict_apps (); + if (idx > 0) { + char buf[256]; + _snprintf (buf, sizeof (buf)-1, + "GPGoe found an instance of a program which\n" + "might be effect the functionality of the plugin.\n" + "\n" + "Name of the process: %s\n" + "\n" + "Continue to load the plug-in?", conflict_apps[idx]); + idx = MessageBox (NULL, buf, "GPGOE Warning", MB_ICONWARNING|MB_YESNO); + if (idx == IDNO) + return 0; + } + create_registry_key (); glob_hinst = hinst; CreateMutex (NULL, 1, "GPGOE"); if (GetLastError () == ERROR_ALREADY_EXISTS) return 0; - memset(&wc, 0, sizeof(wc)); + memset (&wc, 0, sizeof(wc)); wc.hInstance = hinst; wc.lpszClassName = "GPGOE"; wc.lpfnWndProc = (WNDPROC)gpgoe_main_proc; - if (!RegisterClass(&wc)) { - MessageBox(NULL, "Couldn't register the window class", "Error", + if (!RegisterClass (&wc)) { + MessageBox (NULL, "Couldn't register the window class", "Error", MB_ICONERROR|MB_OK); return 1; }