From a5633b1971be3f5dc47e2f38a383abbfa8748576 Mon Sep 17 00:00:00 2001 From: crs Date: Mon, 17 Mar 2003 22:32:10 +0000 Subject: [PATCH] Added options and advanced options dialogs which should've been part of an earlier checkin. Also now saving and restoring options that aren't in the configuration file to/from the registry. --- cmd/launcher/CAdvancedOptions.cpp | 46 +++++++++ cmd/launcher/CAdvancedOptions.h | 2 + cmd/launcher/LaunchUtil.cpp | 12 +++ cmd/launcher/LaunchUtil.h | 2 + cmd/launcher/launcher.cpp | 67 +++++++++++-- cmd/launcher/launcher.rc | 85 +++++++++++++--- cmd/launcher/resource.h | 5 +- lib/arch/CArchDaemonWindows.cpp | 160 ++++++------------------------ lib/arch/CArchDaemonWindows.h | 8 -- lib/arch/CArchMiscWindows.cpp | 143 ++++++++++++++++++++++++-- lib/arch/CArchMiscWindows.h | 35 +++++++ 11 files changed, 396 insertions(+), 169 deletions(-) diff --git a/cmd/launcher/CAdvancedOptions.cpp b/cmd/launcher/CAdvancedOptions.cpp index a6742ea1..6ffb37c4 100644 --- a/cmd/launcher/CAdvancedOptions.cpp +++ b/cmd/launcher/CAdvancedOptions.cpp @@ -16,6 +16,7 @@ #include "ProtocolTypes.h" #include "CStringUtil.h" #include "CArch.h" +#include "CArchMiscWindows.h" #include "CAdvancedOptions.h" #include "LaunchUtil.h" #include "resource.h" @@ -96,6 +97,28 @@ CAdvancedOptions::getCommandLine(bool isClient, const CString& serverName) const void CAdvancedOptions::init(HWND hwnd) { + // get values from registry + HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath()); + if (key != NULL) { + DWORD newPort = CArchMiscWindows::readValueInt(key, "port"); + CString newName = CArchMiscWindows::readValueString(key, "name"); + if (newPort != 0) { + m_port = static_cast(newPort); + } + if (!newName.empty()) { + m_screenName = newName; + } + CArchMiscWindows::closeKey(key); + } + + // now set GUI + doInit(hwnd); +} + +void +CAdvancedOptions::doInit(HWND hwnd) +{ + // set values in GUI HWND child; char buffer[20]; sprintf(buffer, "%d", m_port); @@ -144,9 +167,28 @@ CAdvancedOptions::save(HWND hwnd) m_screenName = name; m_port = port; + // save values to registry + HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath()); + if (key != NULL) { + CArchMiscWindows::setValue(key, "port", m_port); + CArchMiscWindows::setValue(key, "name", m_screenName); + CArchMiscWindows::closeKey(key); + } + return true; } +void +CAdvancedOptions::setDefaults(HWND hwnd) +{ + // restore defaults + m_screenName = ARCH->getHostName(); + m_port = kDefaultPort; + + // update GUI + doInit(hwnd); +} + BOOL CAdvancedOptions::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM) { @@ -166,6 +208,10 @@ CAdvancedOptions::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM) case IDCANCEL: EndDialog(hwnd, 0); return TRUE; + + case IDC_ADVANCED_DEFAULTS: + setDefaults(hwnd); + return TRUE; } break; diff --git a/cmd/launcher/CAdvancedOptions.h b/cmd/launcher/CAdvancedOptions.h index f073f821..e4106f44 100644 --- a/cmd/launcher/CAdvancedOptions.h +++ b/cmd/launcher/CAdvancedOptions.h @@ -55,7 +55,9 @@ public: private: void init(HWND hwnd); + void doInit(HWND hwnd); bool save(HWND hwnd); + void setDefaults(HWND hwnd); // message handling BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM); diff --git a/cmd/launcher/LaunchUtil.cpp b/cmd/launcher/LaunchUtil.cpp index 6a41f0c5..46c8ef97 100644 --- a/cmd/launcher/LaunchUtil.cpp +++ b/cmd/launcher/LaunchUtil.cpp @@ -214,3 +214,15 @@ saveConfig(const CConfig& config, bool sysOnly) return false; } + +const TCHAR* const* +getSettingsPath() +{ + static const TCHAR* s_keyNames[] = { + TEXT("Software"), + TEXT("Synergy"), + TEXT("Synergy"), + NULL + }; + return s_keyNames; +} diff --git a/cmd/launcher/LaunchUtil.h b/cmd/launcher/LaunchUtil.h index a7638a10..48889264 100644 --- a/cmd/launcher/LaunchUtil.h +++ b/cmd/launcher/LaunchUtil.h @@ -50,4 +50,6 @@ CString getAppPath(const CString& appName); bool loadConfig(CConfig& config); bool saveConfig(const CConfig& config, bool sysOnly); +const TCHAR* const* getSettingsPath(); + #endif diff --git a/cmd/launcher/launcher.cpp b/cmd/launcher/launcher.cpp index fe13e452..587a3b84 100644 --- a/cmd/launcher/launcher.cpp +++ b/cmd/launcher/launcher.cpp @@ -19,6 +19,7 @@ #include "CLog.h" #include "CStringUtil.h" #include "CArch.h" +#include "CArchMiscWindows.h" #include "Version.h" #include "stdvector.h" #include "resource.h" @@ -703,12 +704,39 @@ initMainWindow(HWND hwnd) ARG->m_oldConfig = ARG->m_config; enableSaveControls(hwnd); + // get settings from registry + bool isServer = configLoaded; + int debugLevel = s_defaultDebug; + CString server; + HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath()); + if (key != NULL) { + if (isServer && CArchMiscWindows::hasValue(key, "isServer")) { + isServer = (CArchMiscWindows::readValueInt(key, "isServer") != 0); + } + if (CArchMiscWindows::hasValue(key, "debug")) { + debugLevel = static_cast( + CArchMiscWindows::readValueInt(key, "debug")); + if (debugLevel < 0) { + debugLevel = 0; + } + else if (debugLevel > CLog::kDEBUG2) { + debugLevel = CLog::kDEBUG2; + } + } + server = CArchMiscWindows::readValueString(key, "server"); + CArchMiscWindows::closeKey(key); + } + // choose client/server radio buttons HWND child; child = getItem(hwnd, IDC_MAIN_CLIENT_RADIO); - setItemChecked(child, !configLoaded); + setItemChecked(child, !isServer); child = getItem(hwnd, IDC_MAIN_SERVER_RADIO); - setItemChecked(child, configLoaded); + setItemChecked(child, isServer); + + // set server name + child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT); + setWindowText(child, server); // if config is loaded then initialize server controls if (configLoaded) { @@ -728,13 +756,31 @@ initMainWindow(HWND hwnd) sizeof(s_debugName[0]); ++i) { SendMessage(child, CB_ADDSTRING, 0, (LPARAM)s_debugName[i][0]); } - SendMessage(child, CB_SETCURSEL, s_defaultDebug, 0); + SendMessage(child, CB_SETCURSEL, debugLevel, 0); // update neighbor combo boxes enableMainWindowControls(hwnd); updateNeighbors(hwnd); } +static +void +saveMainWindow(HWND hwnd) +{ + HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath()); + if (key != NULL) { + HWND child; + child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT); + CArchMiscWindows::setValue(key, "server", getWindowText(child)); + child = getItem(hwnd, IDC_MAIN_DEBUG); + CArchMiscWindows::setValue(key, "debug", + SendMessage(child, CB_GETCURSEL, 0, 0)); + CArchMiscWindows::setValue(key, "isServer", + isClientChecked(hwnd) ? 0 : 1); + CArchMiscWindows::closeKey(key); + } +} + static BOOL CALLBACK addDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -1128,16 +1174,16 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int nCmdShow) RegisterClassEx(&classInfo); // create main window - HWND m_mainWindow = CreateDialog(s_instance, + HWND mainWindow = CreateDialog(s_instance, MAKEINTRESOURCE(IDD_MAIN), 0, NULL); // prep windows - initMainWindow(m_mainWindow); - s_globalOptions = new CGlobalOptions(m_mainWindow, &ARG->m_config); - s_advancedOptions = new CAdvancedOptions(m_mainWindow, &ARG->m_config); + initMainWindow(mainWindow); + s_globalOptions = new CGlobalOptions(mainWindow, &ARG->m_config); + s_advancedOptions = new CAdvancedOptions(mainWindow, &ARG->m_config); // show window - ShowWindow(m_mainWindow, nCmdShow); + ShowWindow(mainWindow, nCmdShow); // main loop MSG msg; @@ -1154,7 +1200,7 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int nCmdShow) break; default: - if (!IsDialogMessage(m_mainWindow, &msg)) { + if (!IsDialogMessage(mainWindow, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } @@ -1162,5 +1208,8 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int nCmdShow) } } while (!done); + // save values to registry + saveMainWindow(mainWindow); + return msg.wParam; } diff --git a/cmd/launcher/launcher.rc b/cmd/launcher/launcher.rc index b9840a49..4bc02fad 100644 --- a/cmd/launcher/launcher.rc +++ b/cmd/launcher/launcher.rc @@ -62,7 +62,7 @@ BEGIN IDC_STATIC,7,7,286,19 GROUPBOX "",IDC_STATIC,7,29,286,31 GROUPBOX "",IDC_STATIC,7,67,286,103 - GROUPBOX "Advanced Options",IDC_STATIC,7,177,286,56 + GROUPBOX "Options",IDC_STATIC,7,177,286,56 CONTROL "&Client",IDC_MAIN_CLIENT_RADIO,"Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,11,29,33,10 CONTROL "Server",IDC_MAIN_SERVER_RADIO,"Button", @@ -79,26 +79,23 @@ BEGIN PUSHBUTTON "&Remove",IDC_MAIN_SERVER_REMOVE_BUTTON,12,150,50,14 LTEXT "&Layout:",IDC_MAIN_SERVER_LAYOUT_LABEL,138,79,24,8 LTEXT "Left:",IDC_MAIN_SERVER_LEFT_LABEL,144,93,15,8 - COMBOBOX IDC_MAIN_SERVER_LEFT_COMBO,175,91,118,46, + COMBOBOX IDC_MAIN_SERVER_LEFT_COMBO,175,91,111,46, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP LTEXT "Right:",IDC_MAIN_SERVER_RIGHT_LABEL,144,109,20,8 - COMBOBOX IDC_MAIN_SERVER_RIGHT_COMBO,175,107,118,46, + COMBOBOX IDC_MAIN_SERVER_RIGHT_COMBO,175,107,112,46, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP LTEXT "Above:",IDC_MAIN_SERVER_TOP_LABEL,144,125,24,8 - COMBOBOX IDC_MAIN_SERVER_TOP_COMBO,175,123,118,46, + COMBOBOX IDC_MAIN_SERVER_TOP_COMBO,175,123,112,46, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP LTEXT "Below:",IDC_MAIN_SERVER_BOTTOM_LABEL,144,141,22,8 - COMBOBOX IDC_MAIN_SERVER_BOTTOM_COMBO,175,139,118,46, + COMBOBOX IDC_MAIN_SERVER_BOTTOM_COMBO,175,139,112,46, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Screen &Name:",IDC_STATIC,12,192,46,8 - EDITTEXT IDC_MAIN_ADVANCED_NAME_EDIT,64,190,106,12,ES_AUTOHSCROLL - LTEXT "&Port:",IDC_STATIC,194,192,16,8 - EDITTEXT IDC_MAIN_ADVANCED_PORT_EDIT,216,190,40,12,ES_AUTOHSCROLL | - ES_NUMBER - LTEXT "Automatic Startup:",IDC_STATIC,12,212,59,8 - PUSHBUTTON "Con&figure...",IDC_MAIN_AUTOSTART,78,210,50,14 - LTEXT "Test &Debug Level:",IDC_STATIC,151,212,60,8 - COMBOBOX IDC_MAIN_DEBUG,216,210,61,60,CBS_DROPDOWNLIST | + PUSHBUTTON "&Options...",IDC_MAIN_OPTIONS,12,191,50,14 + PUSHBUTTON "Adva&nced...",IDC_MAIN_ADVANCED,68,191,50,14 + LTEXT "Automatic Startup:",IDC_STATIC,138,193,59,8 + PUSHBUTTON "Con&figure...",IDC_MAIN_AUTOSTART,202,191,50,14 + LTEXT "Test &Debug Level:",IDC_STATIC,12,216,60,8 + COMBOBOX IDC_MAIN_DEBUG,78,213,61,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Sa&ve",IDC_MAIN_SAVE,75,241,50,14 DEFPUSHBUTTON "&Test",IDC_MAIN_TEST,131,241,50,14 @@ -157,6 +154,50 @@ BEGIN IDC_STATIC,7,43,181,17 END +IDD_GLOBAL_OPTIONS DIALOG DISCARDABLE 0, 0, 207, 148 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Options" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "It's easy to unintentionally switch screens when the pointer is near a screen's edge. Synergy can prevent switching until certain conditions are met to reduce unintentional switching.", + IDC_STATIC,7,7,191,26 + LTEXT "Synergy can wait to switch until the cursor has been at a screen's edge for some amount of time.", + IDC_STATIC,7,37,193,16 + CONTROL "Switch after waiting",IDC_GLOBAL_DELAY_CHECK,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,59,77,10 + EDITTEXT IDC_GLOBAL_DELAY_TIME,112,58,45,12,ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "ms",IDC_STATIC,159,60,10,8 + LTEXT "Synergy can switch only when the cursor hits a screen edge twice within some amount of time.", + IDC_STATIC,7,77,193,16 + CONTROL "Switch on double tap within",IDC_GLOBAL_TWO_TAP_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,99,103,10 + EDITTEXT IDC_GLOBAL_TWO_TAP_TIME,112,98,45,12,ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "ms",IDC_STATIC,159,100,10,8 + DEFPUSHBUTTON "OK",IDOK,94,127,50,14 + PUSHBUTTON "Cancel",IDCANCEL,150,127,50,14 +END + +IDD_ADVANCED_OPTIONS DIALOG DISCARDABLE 0, 0, 230, 133 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Advanced Options" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Synergy normally uses this computer's name as its screen name. Enter another name here if you want to use a different screen name.", + IDC_STATIC,7,7,216,19 + LTEXT "Screen &Name:",IDC_STATIC,7,34,46,8 + EDITTEXT IDC_ADVANCED_NAME_EDIT,63,32,106,12,ES_AUTOHSCROLL + LTEXT "Synergy normally uses a particular network port number. Enter an alternative port here. (The server and all clients must use the same port number.)", + IDC_STATIC,7,56,216,26 + LTEXT "&Port:",IDC_STATIC,7,90,16,8 + EDITTEXT IDC_ADVANCED_PORT_EDIT,63,88,40,12,ES_AUTOHSCROLL | + ES_NUMBER + PUSHBUTTON "&Defaults",IDC_ADVANCED_DEFAULTS,7,112,50,14 + DEFPUSHBUTTON "OK",IDOK,118,112,50,14 + PUSHBUTTON "Cancel",IDCANCEL,173,112,50,14 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -197,6 +238,22 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 182 END + + IDD_GLOBAL_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 200 + TOPMARGIN, 7 + BOTTOMMARGIN, 141 + END + + IDD_ADVANCED_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 223 + TOPMARGIN, 7 + BOTTOMMARGIN, 126 + END END #endif // APSTUDIO_INVOKED diff --git a/cmd/launcher/resource.h b/cmd/launcher/resource.h index 6e1c1aba..c141e686 100644 --- a/cmd/launcher/resource.h +++ b/cmd/launcher/resource.h @@ -95,15 +95,16 @@ #define IDC_ADD_MOD_ALT 1045 #define IDC_ADD_MOD_META 1046 #define IDC_ADD_MOD_SUPER 1047 +#define IDC_ADVANCED_DEFAULTS 1049 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_RESOURCE_VALUE 110 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1044 +#define _APS_NEXT_CONTROL_VALUE 1050 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/lib/arch/CArchDaemonWindows.cpp b/lib/arch/CArchDaemonWindows.cpp index 6f4f14e3..54dc5b40 100644 --- a/lib/arch/CArchDaemonWindows.cpp +++ b/lib/arch/CArchDaemonWindows.cpp @@ -93,10 +93,10 @@ CArchDaemonWindows::installDaemon(const char* name, value += commandLine; // install entry - setValue(key, name, value); + CArchMiscWindows::setValue(key, name, value); // clean up - closeKey(key); + CArchMiscWindows::closeKey(key); } // windows NT family services @@ -137,7 +137,7 @@ CArchDaemonWindows::installDaemon(const char* name, // open the registry key for this service HKEY key = openNTServicesKey(); - key = openKey(key, name); + key = CArchMiscWindows::openKey(key, name); if (key == NULL) { // can't open key DWORD err = GetLastError(); @@ -151,14 +151,14 @@ CArchDaemonWindows::installDaemon(const char* name, } // set the description - setValue(key, _T("Description"), description); + CArchMiscWindows::setValue(key, _T("Description"), description); // set command line - key = openKey(key, _T("Parameters")); + key = CArchMiscWindows::openKey(key, _T("Parameters")); if (key == NULL) { // can't open key DWORD err = GetLastError(); - closeKey(key); + CArchMiscWindows::closeKey(key); try { uninstallDaemon(name, allUsers); } @@ -167,10 +167,10 @@ CArchDaemonWindows::installDaemon(const char* name, } throw XArchDaemonInstallFailed(new XArchEvalWindows(err)); } - setValue(key, _T("CommandLine"), commandLine); + CArchMiscWindows::setValue(key, _T("CommandLine"), commandLine); // done with registry - closeKey(key); + CArchMiscWindows::closeKey(key); } } @@ -189,20 +189,20 @@ CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers) } // remove entry - deleteValue(key, name); + CArchMiscWindows::deleteValue(key, name); // clean up - closeKey(key); + CArchMiscWindows::closeKey(key); } // windows NT family services else { // remove parameters for this service. ignore failures. HKEY key = openNTServicesKey(); - key = openKey(key, name); + key = CArchMiscWindows::openKey(key, name); if (key != NULL) { - deleteKey(key, _T("Parameters")); - closeKey(key); + CArchMiscWindows::deleteKey(key, _T("Parameters")); + CArchMiscWindows::closeKey(key); } // open service manager @@ -314,7 +314,7 @@ CArchDaemonWindows::canInstallDaemon(const char* name, bool allUsers) // check if we can open the registry key HKEY key = CArchMiscWindows::isWindows95Family() ? open95ServicesKey() : openUserStartupKey(); - closeKey(key); + CArchMiscWindows::closeKey(key); return (key != NULL); } @@ -329,9 +329,9 @@ CArchDaemonWindows::canInstallDaemon(const char* name, bool allUsers) // check if we can open the registry key for this service HKEY key = openNTServicesKey(); - key = openKey(key, name); - key = openKey(key, _T("Parameters")); - closeKey(key); + key = CArchMiscWindows::openKey(key, name); + key = CArchMiscWindows::openKey(key, _T("Parameters")); + CArchMiscWindows::closeKey(key); return (key != NULL); } @@ -351,10 +351,11 @@ CArchDaemonWindows::isDaemonInstalled(const char* name, bool allUsers) } // check for entry - const bool installed = !readValueString(key, name).empty(); + const bool installed = !CArchMiscWindows::readValueString(key, + name).empty(); // clean up - closeKey(key); + CArchMiscWindows::closeKey(key); return installed; } @@ -363,12 +364,12 @@ CArchDaemonWindows::isDaemonInstalled(const char* name, bool allUsers) else { // check parameters for this service HKEY key = openNTServicesKey(); - key = openKey(key, name); - key = openKey(key, _T("Parameters")); + key = CArchMiscWindows::openKey(key, name); + key = CArchMiscWindows::openKey(key, _T("Parameters")); if (key != NULL) { - const bool installed = !readValueString(key, + const bool installed = !CArchMiscWindows::readValueString(key, _T("CommandLine")).empty(); - closeKey(key); + CArchMiscWindows::closeKey(key); if (!installed) { return false; } @@ -393,106 +394,6 @@ CArchDaemonWindows::isDaemonInstalled(const char* name, bool allUsers) } } -HKEY -CArchDaemonWindows::openKey(HKEY key, const TCHAR* keyName) -{ - // ignore if parent is NULL - if (key == NULL) { - return NULL; - } - - // open next key - HKEY newKey; - LONG result = RegOpenKeyEx(key, keyName, 0, - KEY_WRITE | KEY_QUERY_VALUE, &newKey); - if (result != ERROR_SUCCESS) { - DWORD disp; - result = RegCreateKeyEx(key, keyName, 0, _T(""), - 0, KEY_WRITE | KEY_QUERY_VALUE, - NULL, &newKey, &disp); - } - if (result != ERROR_SUCCESS) { - RegCloseKey(key); - return NULL; - } - - // switch to new key - RegCloseKey(key); - return newKey; -} - -HKEY -CArchDaemonWindows::openKey(HKEY key, const TCHAR** keyNames) -{ - for (size_t i = 0; key != NULL && keyNames[i] != NULL; ++i) { - // open next key - key = openKey(key, keyNames[i]); - } - return key; -} - -void -CArchDaemonWindows::closeKey(HKEY key) -{ - assert(key != NULL); - RegCloseKey(key); -} - -void -CArchDaemonWindows::deleteKey(HKEY key, const TCHAR* name) -{ - assert(key != NULL); - assert(name != NULL); - RegDeleteKey(key, name); -} - -void -CArchDaemonWindows::deleteValue(HKEY key, const TCHAR* name) -{ - assert(key != NULL); - assert(name != NULL); - RegDeleteValue(key, name); -} - -void -CArchDaemonWindows::setValue(HKEY key, - const TCHAR* name, const std::string& value) -{ - assert(key != NULL); - assert(name != NULL); - RegSetValueEx(key, name, 0, REG_SZ, - reinterpret_cast(value.c_str()), - value.size() + 1); -} - -std::string -CArchDaemonWindows::readValueString(HKEY key, const TCHAR* name) -{ - // get the size of the string - DWORD type; - DWORD size = 0; - LONG result = RegQueryValueEx(key, name, 0, &type, NULL, &size); - if (result != ERROR_SUCCESS || type != REG_SZ) { - return std::string(); - } - - // allocate space - char* buffer = new char[size]; - - // read it - result = RegQueryValueEx(key, name, 0, &type, - reinterpret_cast(buffer), &size); - if (result != ERROR_SUCCESS || type != REG_SZ) { - delete[] buffer; - return std::string(); - } - - // clean up and return value - std::string value(buffer); - delete[] buffer; - return value; -} - HKEY CArchDaemonWindows::openNTServicesKey() { @@ -503,7 +404,7 @@ CArchDaemonWindows::openNTServicesKey() NULL }; - return openKey(HKEY_LOCAL_MACHINE, s_keyNames); + return CArchMiscWindows::openKey(HKEY_LOCAL_MACHINE, s_keyNames); } HKEY @@ -518,7 +419,7 @@ CArchDaemonWindows::open95ServicesKey() NULL }; - return openKey(HKEY_LOCAL_MACHINE, s_keyNames); + return CArchMiscWindows::openKey(HKEY_LOCAL_MACHINE, s_keyNames); } HKEY @@ -533,7 +434,7 @@ CArchDaemonWindows::openUserStartupKey() NULL }; - return openKey(HKEY_CURRENT_USER, s_keyNames); + return CArchMiscWindows::openKey(HKEY_CURRENT_USER, s_keyNames); } int @@ -730,10 +631,11 @@ CArchDaemonWindows::serviceMain(DWORD argc, LPTSTR* argvIn) // read command line std::string commandLine; HKEY key = openNTServicesKey(); - key = openKey(key, argvIn[0]); - key = openKey(key, _T("Parameters")); + key = CArchMiscWindows::openKey(key, argvIn[0]); + key = CArchMiscWindows::openKey(key, _T("Parameters")); if (key != NULL) { - commandLine = readValueString(key, _T("CommandLine")); + commandLine = CArchMiscWindows::readValueString(key, + _T("CommandLine")); } // if the command line isn't empty then parse and use it diff --git a/lib/arch/CArchDaemonWindows.h b/lib/arch/CArchDaemonWindows.h index 9c291c9e..57fe74fe 100644 --- a/lib/arch/CArchDaemonWindows.h +++ b/lib/arch/CArchDaemonWindows.h @@ -75,14 +75,6 @@ public: virtual bool isDaemonInstalled(const char* name, bool allUsers); private: - static HKEY openKey(HKEY parent, const TCHAR*); - static HKEY openKey(HKEY parent, const TCHAR**); - static void closeKey(HKEY); - static void deleteKey(HKEY, const TCHAR* name); - static void deleteValue(HKEY, const TCHAR* name); - static void setValue(HKEY, const TCHAR* name, - const std::string& value); - static std::string readValueString(HKEY, const TCHAR* name); static HKEY openNTServicesKey(); static HKEY open95ServicesKey(); static HKEY openUserStartupKey(); diff --git a/lib/arch/CArchMiscWindows.cpp b/lib/arch/CArchMiscWindows.cpp index 40edd53e..cc91d025 100644 --- a/lib/arch/CArchMiscWindows.cpp +++ b/lib/arch/CArchMiscWindows.cpp @@ -12,11 +12,7 @@ * GNU General Public License for more details. */ -#define WIN32_LEAN_AND_MEAN - #include "CArchMiscWindows.h" -#include "CArchDaemonWindows.h" -#include // // CArchMiscWindows @@ -37,17 +33,150 @@ CArchMiscWindows::isWindows95Family() int CArchMiscWindows::runDaemon(RunFunc runFunc) { - return CArchDaemonWindows::runDaemon(runFunc); + return CArchMiscWindows::runDaemon(runFunc); } void CArchMiscWindows::daemonRunning(bool running) { - CArchDaemonWindows::daemonRunning(running); + CArchMiscWindows::daemonRunning(running); } void CArchMiscWindows::daemonFailed(int result) { - CArchDaemonWindows::daemonFailed(result); + CArchMiscWindows::daemonFailed(result); +} + +HKEY +CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName) +{ + // ignore if parent is NULL + if (key == NULL) { + return NULL; + } + + // open next key + HKEY newKey; + LONG result = RegOpenKeyEx(key, keyName, 0, + KEY_WRITE | KEY_QUERY_VALUE, &newKey); + if (result != ERROR_SUCCESS) { + DWORD disp; + result = RegCreateKeyEx(key, keyName, 0, TEXT(""), + 0, KEY_WRITE | KEY_QUERY_VALUE, + NULL, &newKey, &disp); + } + if (result != ERROR_SUCCESS) { + RegCloseKey(key); + return NULL; + } + + // switch to new key + RegCloseKey(key); + return newKey; +} + +HKEY +CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames) +{ + for (size_t i = 0; key != NULL && keyNames[i] != NULL; ++i) { + // open next key + key = openKey(key, keyNames[i]); + } + return key; +} + +void +CArchMiscWindows::closeKey(HKEY key) +{ + assert(key != NULL); + RegCloseKey(key); +} + +void +CArchMiscWindows::deleteKey(HKEY key, const TCHAR* name) +{ + assert(key != NULL); + assert(name != NULL); + RegDeleteKey(key, name); +} + +void +CArchMiscWindows::deleteValue(HKEY key, const TCHAR* name) +{ + assert(key != NULL); + assert(name != NULL); + RegDeleteValue(key, name); +} + +bool +CArchMiscWindows::hasValue(HKEY key, const TCHAR* name) +{ + DWORD type; + LONG result = RegQueryValueEx(key, name, 0, &type, NULL, NULL); + return (result == ERROR_SUCCESS && + (type == REG_DWORD || type == REG_SZ)); +} + +void +CArchMiscWindows::setValue(HKEY key, + const TCHAR* name, const std::string& value) +{ + assert(key != NULL); + assert(name != NULL); + RegSetValueEx(key, name, 0, REG_SZ, + reinterpret_cast(value.c_str()), + value.size() + 1); +} + +void +CArchMiscWindows::setValue(HKEY key, const TCHAR* name, DWORD value) +{ + assert(key != NULL); + assert(name != NULL); + RegSetValueEx(key, name, 0, REG_DWORD, + reinterpret_cast(&value), + sizeof(DWORD)); +} + +std::string +CArchMiscWindows::readValueString(HKEY key, const TCHAR* name) +{ + // get the size of the string + DWORD type; + DWORD size = 0; + LONG result = RegQueryValueEx(key, name, 0, &type, NULL, &size); + if (result != ERROR_SUCCESS || type != REG_SZ) { + return std::string(); + } + + // allocate space + char* buffer = new char[size]; + + // read it + result = RegQueryValueEx(key, name, 0, &type, + reinterpret_cast(buffer), &size); + if (result != ERROR_SUCCESS || type != REG_SZ) { + delete[] buffer; + return std::string(); + } + + // clean up and return value + std::string value(buffer); + delete[] buffer; + return value; +} + +DWORD +CArchMiscWindows::readValueInt(HKEY key, const TCHAR* name) +{ + DWORD type; + DWORD value; + DWORD size = sizeof(value); + LONG result = RegQueryValueEx(key, name, 0, &type, + reinterpret_cast(&value), &size); + if (result != ERROR_SUCCESS || type != REG_DWORD) { + return 0; + } + return value; } diff --git a/lib/arch/CArchMiscWindows.h b/lib/arch/CArchMiscWindows.h index 51433ba4..dc993362 100644 --- a/lib/arch/CArchMiscWindows.h +++ b/lib/arch/CArchMiscWindows.h @@ -15,7 +15,11 @@ #ifndef CARCHMISCWINDOWS_H #define CARCHMISCWINDOWS_H +#define WIN32_LEAN_AND_MEAN + #include "common.h" +#include "stdstring.h" +#include //! Miscellaneous win32 functions. class CArchMiscWindows { @@ -45,6 +49,37 @@ public: Delegates to CArchDaemonWindows. */ static void daemonFailed(int result); + + //! Open and return a registry key, closing the parent key + static HKEY openKey(HKEY parent, const TCHAR* child); + + //! Open and return a registry key, closing the parent key + static HKEY openKey(HKEY parent, const TCHAR* const* keyPath); + + //! Close a key + static void closeKey(HKEY); + + //! Delete a key (which should have no subkeys) + static void deleteKey(HKEY parent, const TCHAR* name); + + //! Delete a value + static void deleteValue(HKEY parent, const TCHAR* name); + + //! Test if a value exists + static bool hasValue(HKEY key, const TCHAR* name); + + //! Set a string value in the registry + static void setValue(HKEY key, const TCHAR* name, + const std::string& value); + + //! Set a DWORD value in the registry + static void setValue(HKEY key, const TCHAR* name, DWORD value); + + //! Read a string value from the registry + static std::string readValueString(HKEY, const TCHAR* name); + + //! Read a DWORD value from the registry + static DWORD readValueInt(HKEY, const TCHAR* name); }; #endif