From 005949351a4b5e3a214becfc807624bb0f8ab415 Mon Sep 17 00:00:00 2001 From: Roman Dadkov Date: Wed, 14 Sep 2011 21:44:23 +0400 Subject: [PATCH] winecfg: Tab to control the loading of key drivers (eterbug #6916). --- dlls/comctl32/propsheet.c | 5 + po/ru.po | 18 ++- programs/winecfg/En.rc | 11 + programs/winecfg/Makefile.in | 1 + programs/winecfg/Ru.rc | 11 + programs/winecfg/dnglch.h | 5 + programs/winecfg/dongleui.c | 497 ++++++++++++++++++++++++++++++++++++++++++ programs/winecfg/main.c | 10 + programs/winecfg/resource.h | 10 + programs/winecfg/winecfg.c | 56 ++++- programs/winecfg/winecfg.h | 9 + programs/winecfg/winecfg.rc | 9 + 12 files changed, 634 insertions(+), 8 deletions(-) create mode 100644 programs/winecfg/dnglch.h create mode 100644 programs/winecfg/dongleui.c diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c index e6d2d30..011bb54 100644 --- a/dlls/comctl32/propsheet.c +++ b/dlls/comctl32/propsheet.c @@ -70,6 +70,8 @@ #include "wine/debug.h" #include "wine/unicode.h" +#include "../../programs/winecfg/dnglch.h" + /****************************************************************************** * Data structures */ @@ -3132,6 +3134,9 @@ static BOOL PROPSHEET_DoCommand(HWND hwnd, WORD wID) case IDOK: case IDC_APPLY_BUTTON: { + if(FixedChange() != 0) + if (MessageBoxA(NULL, "To adoptional changes need close all Wine programs.\n\n Do it now?", "Configuration was change", MB_YESNO | MB_ICONQUESTION) == IDYES) + InitiateSystemShutdownExW(NULL, NULL, 0, TRUE, FALSE); HWND hwndApplyBtn = GetDlgItem(hwnd, IDC_APPLY_BUTTON); if (PROPSHEET_Apply(hwnd, wID == IDOK ? 1: 0) == FALSE) diff --git a/po/ru.po b/po/ru.po index a7e257a..2dfe458 100644 --- a/po/ru.po +++ b/po/ru.po @@ -8636,7 +8636,7 @@ msgstr "" msgid "%s %s %s Open resources: %lu\n" msgstr "%s %s %s Открытых ресурсов: %lu\n" -#: net.rc:44 +#: net.rc:44 winecfg.rc:90 msgid "OK" msgstr "" @@ -11459,3 +11459,19 @@ msgstr "" "[/D | /D:m-d-y] Копирует только новые файлы или те, которые были изменены\n" "после указанной даты. Если дата не указана, копирует только\n" "те файлы, которые новее в исходной папке.\n" + +#: winecfg.rc:33 +msgid "Dongles" +msgstr "Ключи защиты" + +#: winecfg.rc:88 +msgid "Load" +msgstr "Загружать" + +#: winecfg.rc:89 +msgid "Do not load" +msgstr "Не загружать" + +#: winecfg.rc:91 +msgid "Dongle not found" +msgstr "Ключ не найден" \ No newline at end of file diff --git a/programs/winecfg/En.rc b/programs/winecfg/En.rc index bd51345..9f5a1d0 100644 --- a/programs/winecfg/En.rc +++ b/programs/winecfg/En.rc @@ -230,3 +230,14 @@ BEGIN EDITTEXT IDC_EDIT_SFPATH,65,195,125,13,ES_AUTOHSCROLL|WS_TABSTOP|WS_DISABLED PUSHBUTTON "B&rowse...",IDC_BROWSE_SFPATH,195,195,50,13,WS_DISABLED END + +IDD_DONGLECFG DIALOG DISCARDABLE 0, 0, 260, 250 +STYLE WS_CHILD | WS_DISABLED +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX " Loading dongles drivers ",IDC_STATIC,8,4,244,240 + CONTROL "Listview",IDC_LIST_DONGLES,"SysListView32",LVS_REPORT | LVS_AUTOARRANGE | LVS_ALIGNLEFT | + LVS_SINGLESEL | WS_BORDER | WS_TABSTOP | LVS_NOCOLUMNHEADER , 15,18,232,150 + PUSHBUTTON "Load",IDC_BUTTON_LOAD,91,172,75,14 + PUSHBUTTON "Do not load",IDC_BUTTON_UNLOAD,171,172,75,14 +END \ No newline at end of file diff --git a/programs/winecfg/Makefile.in b/programs/winecfg/Makefile.in index 5d4e499..cb9a664 100644 --- a/programs/winecfg/Makefile.in +++ b/programs/winecfg/Makefile.in @@ -7,6 +7,7 @@ C_SRCS = \ appdefaults.c \ audio.c \ drive.c \ + dongleui.c \ drivedetect.c \ driveui.c \ libraries.c \ diff --git a/programs/winecfg/Ru.rc b/programs/winecfg/Ru.rc index f337897..969c06b 100644 --- a/programs/winecfg/Ru.rc +++ b/programs/winecfg/Ru.rc @@ -205,3 +205,14 @@ BEGIN EDITTEXT IDC_EDIT_SFPATH,65,195,145,13,ES_AUTOHSCROLL|WS_TABSTOP|WS_DISABLED PUSHBUTTON "Обзор",IDC_BROWSE_SFPATH,215,195,30,13,WS_DISABLED END + +IDD_DONGLECFG DIALOG DISCARDABLE 0, 0, 260, 250 +STYLE WS_CHILD | WS_DISABLED +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX " Загрузка драйверов ключей ",IDC_STATIC,8,4,244,240 + CONTROL "",IDC_LIST_DONGLES,"SysListView32",LVS_REPORT | LVS_AUTOARRANGE | LVS_ALIGNLEFT | + LVS_SINGLESEL | WS_BORDER | WS_TABSTOP | LVS_NOCOLUMNHEADER , 15,18,232,150 + PUSHBUTTON "Загружать",IDC_BUTTON_LOAD,91,172,75,14 + PUSHBUTTON "Не загружать",IDC_BUTTON_UNLOAD,171,172,75,14 +END \ No newline at end of file diff --git a/programs/winecfg/dnglch.h b/programs/winecfg/dnglch.h new file mode 100644 index 0000000..a30ac15 --- /dev/null +++ b/programs/winecfg/dnglch.h @@ -0,0 +1,5 @@ +static int FixedChange() +{ + static int a; + return ++a; +} \ No newline at end of file diff --git a/programs/winecfg/dongleui.c b/programs/winecfg/dongleui.c new file mode 100644 index 0000000..fb1991e --- /dev/null +++ b/programs/winecfg/dongleui.c @@ -0,0 +1,497 @@ +/* + * Dongle management UI code + * + * Copyright 2009 Alexander Morozov + * Copyright 2009 Ilya Shpigor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" +#include + +#define WIN32_LEAN_AND_MEAN +#define COBJMACROS + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dnglch.h" +#include "winecfg.h" +#include "resource.h" + +#define LOADSTRING_SIZE 64 +static int Flag; +WINE_DEFAULT_DEBUG_CHANNEL(winecfg); + +static WCHAR status[2][LOADSTRING_SIZE]; +static WCHAR device[2][LOADSTRING_SIZE]; + +static const char* dongles[] = {"Guardant", + "HASP HL", + "LPT Katran", + "USB Katran", + "Senselock", + "Sentinel", + "SmartKey 3"}; + +static const int count = 7; + +static const WCHAR grdkeyW[] = {'G','r','d','K','e','y',0}; +static const WCHAR grdusbW[] = {'G','r','d','U','s','b',0}; +static const WCHAR hardlockW[] = {'H','a','r','d','l','o','c','k',0}; +static const WCHAR akshaspW[] = {'a','k','s','h','a','s','p',0}; +static const WCHAR aksusbW[] = {'a','k','s','u','s','b',0}; +static const WCHAR pkeyW[] = {'P','K','e','y',0}; +static const WCHAR nkeyW[] = {'N','K','e','y',0}; +static const WCHAR upkeyW[] = {'U','P','K','e','y',0}; +static const WCHAR sense4v2W[] = {'s','e','n','s','e','4','v','2',0}; +static const WCHAR sentinelW[] = {'S','e','n','t','i','n','e','l',0}; +static const WCHAR sntnlusbW[] = {'S','N','T','N','L','U','S','B',0}; +static const WCHAR eusk3usbW[] = {'e','u','s','k','3','u','s','b',0}; +static const WCHAR servicesW[] = {'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','S','e','r','v','i','c','e','s','\\',0}; +static const WCHAR startW[] = {'S','t','a','r','t',0}; + +enum dongle_t +{ + guardant, + hasp, + katran_lpt, + katran_usb, + senselock, + sentinel, + smartkey3 +}; + +static const WCHAR PropSheetInfoStr[] = + {'P','r','o','p','e','r','t','y','S','h','e','e','t','I','n','f','o',0 }; + +typedef struct tagPropPageInfo +{ + HPROPSHEETPAGE hpage; /* to keep track of pages not passed to PropertySheet */ + HWND hwndPage; + BOOL isDirty; + LPCWSTR pszText; + BOOL hasHelp; + BOOL useCallback; + BOOL hasIcon; +} PropPageInfo; + +typedef struct tagPropSheetInfo +{ + HWND hwnd; + PROPSHEETHEADERW ppshheader; + BOOL unicode; + LPWSTR strPropertiesFor; + int nPages; + int active_page; + BOOL isModeless; + BOOL hasHelp; + BOOL hasApply; + BOOL hasFinish; + BOOL usePropPage; + BOOL useCallback; + BOOL activeValid; + PropPageInfo* proppage; + HFONT hFont; + HFONT hFontBold; + int width; + int height; + HIMAGELIST hImageList; + BOOL ended; + INT result; +} PropSheetInfo; + +static int file_exists(LPCWSTR filename) +{ + HANDLE file; + + WINE_TRACE("%s\n", wine_dbgstr_w(filename)); + file = CreateFileW(filename, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) return 0; + CloseHandle(file); + return 1; +} + +static int interface_exists(const GUID *guid) +{ + SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail; + SP_DEVICE_INTERFACE_DATA intf_data; + HDEVINFO set; + DWORD size, i = 0; + int ret = 0; + + set = SetupDiGetClassDevsW(guid, NULL, NULL, DIGCF_DEVICEINTERFACE); + if (set == INVALID_HANDLE_VALUE) return 0; + intf_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + while (!ret && SetupDiEnumDeviceInterfaces(set, NULL, guid, i++, &intf_data)) + { + SetupDiGetDeviceInterfaceDetailW(set, &intf_data, NULL, 0, &size, NULL); + detail = HeapAlloc(GetProcessHeap(), 0, size); + if (detail == NULL) break; + detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); + if (SetupDiGetDeviceInterfaceDetailW(set, &intf_data, detail, size, NULL, NULL) && + file_exists(detail->DevicePath)) + ret = 1; + HeapFree(GetProcessHeap(), 0, detail); + } + SetupDiDestroyDeviceInfoList(set); + return ret; +} + +static int is_loaded(enum dongle_t dongle) +{ + static const WCHAR nvkeyntW[] = {'\\','\\','.','\\','n','v','k','e','y','n','t',0}; + static const WCHAR fentedevW[] = {'\\','\\','.','\\','f','e','n','t','e','d','e','v',0}; + static const WCHAR pkey0W[] = {'\\','\\','.','\\','p','k','e','y','0',0}; + static const WCHAR nkey0W[] = {'\\','\\','.','\\','n','k','e','y','0',0}; + static const WCHAR upkey0W[] = {'\\','\\','.','\\','u','p','k','e','y','0',0}; + static const WCHAR rnbodrv0W[] = {'\\','\\','.','\\','r','n','b','o','d','r','v','0',0}; + static const WCHAR skeysusbW[] = {'\\','\\','.','\\','s','k','e','y','s','u','s','b',0}; + static const WCHAR sntnlusbW[] = {'\\','\\','.','\\','s','n','t','n','l','u','s','b',0}; + static const WCHAR skeyW[] = {'\\','\\','.','\\','s','k','e','y','-','-','-','-',0}; + static const WCHAR skey000W[] = {'\\','\\','.','\\','s','k','e','y','-','0','0','0',0}; + static const GUID hasp_intf = {0x7ab02247, 0x3798, 0x44cd, {0x84,0x72,0x24,0x35,0x64,0x97,0x5f,0x04}}; + static const GUID grd_intf = {0x46b89760, 0xc784, 0x11d4, {0x81,0xa8,0x00,0x80,0xad,0x87,0xaf,0x5c}}; + static const GUID sens_intf = {0x171638f7, 0x1ead, 0x4873, {0xba,0x98,0xc9,0x66,0xab,0xcf,0x01,0x42}}; + + switch (dongle) + { + case guardant: + if (file_exists(nvkeyntW) && interface_exists(&grd_intf)) + return 1; + break; + case hasp: + if (file_exists(fentedevW) && interface_exists(&hasp_intf)) + return 1; + break; + case katran_lpt: + if (file_exists(pkey0W)) + return 1; + break; + case katran_usb: + if (file_exists(nkey0W) && file_exists(upkey0W)) + return 1; + break; + case senselock: + if (interface_exists(&sens_intf)) + return 1; + break; + case sentinel: + if (file_exists(rnbodrv0W) && file_exists(skeysusbW) && + file_exists(sntnlusbW)) + return 1; + break; + case smartkey3: + if (file_exists(skeyW) && file_exists(skey000W)) + return 1; + break; + }; + return 0; +} + +static void set_service_start(LPCWSTR service_name, DWORD start) +{ + WCHAR *wpath = HeapAlloc(GetProcessHeap(), 0, sizeof(servicesW) + + lstrlenW(service_name) * sizeof(WCHAR)); + + if (wpath == NULL) return; + lstrcpyW(wpath, servicesW); + lstrcatW(wpath, service_name); + set_reg_key_dwordW(HKEY_LOCAL_MACHINE, wpath, startW, start); + HeapFree(GetProcessHeap(), 0, wpath); +} + +static DWORD get_service_start(LPCWSTR service_name) +{ + DWORD start; + WCHAR *wpath = HeapAlloc(GetProcessHeap(), 0, sizeof(servicesW) + + lstrlenW(service_name) * sizeof(WCHAR)); + + if (wpath == NULL) return 0; + lstrcpyW(wpath, servicesW); + lstrcatW(wpath, service_name); + start = get_reg_key_dwordW(HKEY_LOCAL_MACHINE, wpath, startW, 0); + HeapFree(GetProcessHeap(), 0, wpath); + return start; +} + +static void set_start(enum dongle_t dongle, int start) +{ + switch (dongle) + { + case guardant: + set_service_start(grdkeyW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + set_service_start(grdusbW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + break; + case hasp: + set_service_start(hardlockW, start ? SERVICE_AUTO_START : SERVICE_DISABLED); + set_service_start(akshaspW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + set_service_start(aksusbW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + break; + case katran_lpt: + set_service_start(pkeyW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + break; + case katran_usb: + set_service_start(nkeyW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + set_service_start(upkeyW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + break; + case senselock: + set_service_start(sense4v2W, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + break; + case sentinel: + set_service_start(sentinelW, start ? SERVICE_AUTO_START : SERVICE_DISABLED); + set_service_start(sntnlusbW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + break; + case smartkey3: + set_service_start(eusk3usbW, start ? SERVICE_DEMAND_START : SERVICE_DISABLED); + break; + }; +} + +static int get_start(enum dongle_t dongle) +{ + switch (dongle) + { + case guardant: + if (get_service_start(grdkeyW) == SERVICE_DEMAND_START && + get_service_start(grdusbW) == SERVICE_DEMAND_START) + return 1; + break; + case hasp: + if (get_service_start(hardlockW) == SERVICE_AUTO_START && + get_service_start(akshaspW) == SERVICE_DEMAND_START && + get_service_start(aksusbW) == SERVICE_DEMAND_START) + return 1; + break; + case katran_lpt: + if (get_service_start(pkeyW) == SERVICE_DEMAND_START) + return 1; + break; + case katran_usb: + if (get_service_start(nkeyW) == SERVICE_DEMAND_START && + get_service_start(upkeyW) == SERVICE_DEMAND_START) + return 1; + break; + case senselock: + if (get_service_start(sense4v2W) == SERVICE_DEMAND_START) + return 1; + break; + case sentinel: + if (get_service_start(sentinelW) == SERVICE_AUTO_START && + get_service_start(sntnlusbW) == SERVICE_DEMAND_START) + return 1; + break; + case smartkey3: + if (get_service_start(eusk3usbW) == SERVICE_DEMAND_START) + return 1; + break; + }; + return 0; +} + +static void init_listview_columns(HWND dialog) +{ + LVCOLUMNW listColumn; + RECT viewRect; + int width; + WCHAR* empty = {'\0'}; + + GetClientRect(GetDlgItem(dialog, IDC_LIST_DONGLES), &viewRect); + width = (viewRect.right - viewRect.left)/3; + + listColumn.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + listColumn.cx = (viewRect.right - viewRect.left)/3; + listColumn.pszText = empty; + SendDlgItemMessageW (dialog, IDC_LIST_DONGLES, LVM_INSERTCOLUMNW, 0, (LPARAM) &listColumn); + + width += (viewRect.right - viewRect.left)/3; + listColumn.cx = (viewRect.right - viewRect.left)/3; + listColumn.pszText = empty; + SendDlgItemMessageW (dialog, IDC_LIST_DONGLES, LVM_INSERTCOLUMNW, 1, (LPARAM) &listColumn); + + listColumn.cx = (viewRect.right - viewRect.left) - width; + listColumn.pszText = empty; + SendDlgItemMessageW (dialog, IDC_LIST_DONGLES, LVM_INSERTCOLUMNW, 1, (LPARAM) &listColumn); +} + +static void lv_insert_item(HWND dialog, LVITEMW *item) +{ + SendDlgItemMessageW(dialog, IDC_LIST_DONGLES, LVM_INSERTITEMW, 0, (LPARAM) item); +} + +static void lv_set_item(HWND dialog, LVITEMW *item) +{ + SendDlgItemMessageW(dialog, IDC_LIST_DONGLES, LVM_SETITEMW, 0, (LPARAM) item); +} + +static void lv_set_item_text(HWND dialog, int item, int subItem, WCHAR *text) +{ + LVITEMW lvItem; + if (item < 0 || subItem < 0) return; + lvItem.mask = LVIF_TEXT; + lvItem.iItem = item; + lvItem.iSubItem = subItem; + lvItem.pszText = text; + lvItem.cchTextMax = lstrlenW(lvItem.pszText); + lv_set_item(dialog, &lvItem); +} + +static int fill_dongles_list(HWND dialog) +{ + LVITEMW item; + int i; + + SendDlgItemMessage(dialog, IDC_LIST_DONGLES, LVM_DELETEALLITEMS, 0, 0); + + LoadStringW (GetModuleHandle (NULL), IDC_DONGLE_UNLOAD, status[0], + LOADSTRING_SIZE); + LoadStringW (GetModuleHandle (NULL), IDC_DONGLE_LOAD, status[1], + LOADSTRING_SIZE); + + LoadStringW (GetModuleHandle (NULL), IDC_DONGLE_NOTFOUND, device[0], + LOADSTRING_SIZE); + LoadStringW (GetModuleHandle (NULL), IDC_DONGLE_OK, device[1], + LOADSTRING_SIZE); + + for(i = 0; i < count; i++) + { + item.mask = LVIF_TEXT | LVIF_PARAM; + item.iItem = i; + item.iSubItem = 0; + item.pszText = strdupU2W(dongles[i]); + item.cchTextMax = lstrlenW(item.pszText); + + lv_insert_item(dialog, &item); + HeapFree(GetProcessHeap(), 0, item.pszText); + + if (get_start(i)) + lv_set_item_text(dialog, i, 1, status[1]); + else + lv_set_item_text(dialog, i, 1, status[0]); + + if (is_loaded(i)) + lv_set_item_text(dialog, i, 2, device[1]); + else + lv_set_item_text(dialog, i, 2, device[0]); + } + + return i; +} + +static int get_list_selection (HWND dialog) +{ + return ListView_GetSelectionMark(GetDlgItem(dialog, IDC_LIST_DONGLES)); +} + +static void on_load_click (HWND dialog, int num) +{ + set_start(num, 1); + lv_set_item_text(dialog, num, 1, status[1]); + SendMessage(GetParent(dialog), PSM_CHANGED, 0, 0); +} + +static void on_unload_click (HWND dialog, int num) +{ + set_start(num, 0); + lv_set_item_text(dialog, num, 1, status[0]); + SendMessage(GetParent(dialog), PSM_CHANGED, 0, 0); +} + +static void set_restart_param (HWND dialog) +{ + PropSheetInfo* psInfo = GetPropW(GetParent(dialog), PropSheetInfoStr); + + if (!psInfo) return; + psInfo->result = ID_PSREBOOTSYSTEM; +} + +INT_PTR CALLBACK +DongleDlgProc (HWND dialog, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int num; + char fff[1]; + switch (msg) + { + case WM_INITDIALOG: + init_listview_columns(dialog); + fill_dongles_list(dialog); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + + case IDC_BUTTON_LOAD: + num = get_list_selection(dialog); + + if (HIWORD(wParam) != BN_CLICKED) break; + if (!get_start(num)) + { + set_restart_param(dialog); + on_load_click(dialog, num); + FixedChange(); + } + break; + case IDC_BUTTON_UNLOAD: + num = get_list_selection(dialog); + + if (HIWORD(wParam) != BN_CLICKED) break; + if (get_start(num)) + { + set_restart_param(dialog); + on_unload_click(dialog, num); + FixedChange(); + } + break; + } + break; + case WM_NOTIFY: + switch (LOWORD(wParam)) + { + case IDC_LIST_DONGLES: + { + NMHDR* nhdr; + + nhdr = (NMHDR*)lParam; + if (nhdr->code != LVN_ITEMACTIVATE) + break; + + num = ListView_GetSelectionMark(GetDlgItem(dialog, IDC_LIST_DONGLES)); + if (get_start(num)) + on_unload_click(dialog, num); + else + on_load_click(dialog, num); + } + break; + } + break; + } + return FALSE; +} \ No newline at end of file diff --git a/programs/winecfg/main.c b/programs/winecfg/main.c index b7f9331..129dc09 100644 --- a/programs/winecfg/main.c +++ b/programs/winecfg/main.c @@ -134,6 +134,16 @@ doPropertySheet (HINSTANCE hInstance, HWND hOwner) psp[pg].dwSize = sizeof (PROPSHEETPAGEW); psp[pg].dwFlags = PSP_USETITLE; psp[pg].hInstance = hInstance; + psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_DONGLECFG); + psp[pg].u2.pszIcon = NULL; + psp[pg].pfnDlgProc = DongleDlgProc; + psp[pg].pszTitle = load_string (IDS_TAB_DONGLES); + psp[pg].lParam = 0; + pg++; + + psp[pg].dwSize = sizeof (PROPSHEETPAGEW); + psp[pg].dwFlags = PSP_USETITLE; + psp[pg].hInstance = hInstance; psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_AUDIOCFG); psp[pg].u2.pszIcon = NULL; psp[pg].pfnDlgProc = AudioDlgProc; diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h index 24eaec4..369036a 100644 --- a/programs/winecfg/resource.h +++ b/programs/winecfg/resource.h @@ -242,3 +242,13 @@ #define IDC_WINVER_LAUNCH 8439 +/* Dongles tab */ +#define IDS_TAB_DONGLES 9435 +#define IDD_DONGLECFG 9436 +#define IDC_LIST_DONGLES 9437 +#define IDC_DONGLE_LOAD 9438 +#define IDC_DONGLE_UNLOAD 9439 +#define IDC_BUTTON_LOAD 9440 +#define IDC_BUTTON_UNLOAD 9441 +#define IDC_DONGLE_OK 9442 +#define IDC_DONGLE_NOTFOUND 9443 \ No newline at end of file diff --git a/programs/winecfg/winecfg.c b/programs/winecfg/winecfg.c index cdf3a84..4af3242 100644 --- a/programs/winecfg/winecfg.c +++ b/programs/winecfg/winecfg.c @@ -103,15 +103,15 @@ WCHAR* load_string (UINT id) * not. Caller is responsible for releasing the result. * */ -static WCHAR *get_config_key (HKEY root, const WCHAR *subkey, const WCHAR *name, const WCHAR *def) +static void *get_config_key (HKEY root, const WCHAR *subkey, const WCHAR *name, const void *def, DWORD type) { LPWSTR buffer = NULL; DWORD len; HKEY hSubKey = NULL; DWORD res; - WINE_TRACE("subkey=%s, name=%s, def=%s\n", wine_dbgstr_w(subkey), - wine_dbgstr_w(name), wine_dbgstr_w(def)); + WINE_TRACE("subkey=%s, name=%s, def=%p, type=%d\n", wine_dbgstr_w(subkey), + wine_dbgstr_w(name), def, type); res = RegOpenKeyExW(root, subkey, 0, MAXIMUM_ALLOWED, &hSubKey); if (res != ERROR_SUCCESS) @@ -119,7 +119,10 @@ static WCHAR *get_config_key (HKEY root, const WCHAR *subkey, const WCHAR *name, if (res == ERROR_FILE_NOT_FOUND) { WINE_TRACE("Section key not present - using default\n"); - return def ? strdupW(def) : NULL; + if (!def) return NULL; + if (type == REG_SZ) return strdupW(def); + if (type == REG_DWORD) return memdup(def, sizeof(DWORD)); + return NULL; } else { @@ -132,8 +135,12 @@ static WCHAR *get_config_key (HKEY root, const WCHAR *subkey, const WCHAR *name, if (res == ERROR_FILE_NOT_FOUND) { WINE_TRACE("Value not present - using default\n"); - buffer = def ? strdupW(def) : NULL; - goto end; + if (def) + { + if (type == REG_SZ) buffer = strdupW(def); + else if (type == REG_DWORD) buffer = memdup(def, sizeof(DWORD)); + } + goto end; } else if (res != ERROR_SUCCESS) { WINE_ERR("Couldn't query value's length (res=%d)\n", res); @@ -274,7 +281,7 @@ WCHAR *get_reg_keyW(HKEY root, const WCHAR *path, const WCHAR *name, const WCHAR } /* no, so get from the registry */ - val = get_config_key(root, path, name, def); + val = get_config_key(root, path, name, def, REG_SZ); WINE_TRACE("returning %s\n", wine_dbgstr_w(val)); @@ -318,6 +325,41 @@ char *get_reg_key(HKEY root, const char *path, const char *name, const char *def return szRet; } +DWORD get_reg_key_dwordW(HKEY root, const WCHAR *path, const WCHAR *name, DWORD def) +{ + struct list *cursor; + struct setting *s; + DWORD *val, ret = 0; + + WINE_TRACE("path=%s, name=%s, def=%d\n", wine_dbgstr_w(path), + wine_dbgstr_w(name), def); + + /* check if it's in the list */ + LIST_FOR_EACH( cursor, settings ) + { + s = LIST_ENTRY(cursor, struct setting, entry); + + if (root != s->root) continue; + if (lstrcmpiW(path, s->path) != 0) continue; + if (!s->name) continue; + if (lstrcmpiW(name, s->name) != 0) continue; + + if (s->value) ret = *(DWORD *)s->value; + WINE_TRACE("found %s:%s in settings list, returning %d\n", + wine_dbgstr_w(path), wine_dbgstr_w(name), ret); + return ret; + } + + /* no, so get from the registry */ + val = get_config_key(root, path, name, &def, REG_DWORD); + ret = *val; + HeapFree(GetProcessHeap(), 0, val); + + WINE_TRACE("returning %d\n", ret); + + return ret; +} + /** * Used to set a registry key. * diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h index 1959409..5729c5e 100644 --- a/programs/winecfg/winecfg.h +++ b/programs/winecfg/winecfg.h @@ -53,6 +53,7 @@ extern WCHAR* current_app; /* NULL means editing global settings */ void set_reg_keyW(HKEY root, const WCHAR *path, const WCHAR *name, const WCHAR *value); void set_reg_key_dwordW(HKEY root, const WCHAR *path, const WCHAR *name, DWORD value); +DWORD get_reg_key_dwordW(HKEY root, const WCHAR *path, const WCHAR *name, DWORD def); WCHAR *get_reg_keyW(HKEY root, const WCHAR *path, const WCHAR *name, const WCHAR *def); void set_reg_key(HKEY root, const char *path, const char *name, const char *value); @@ -82,6 +83,7 @@ void set_window_title(HWND dialog); /* Window procedures */ INT_PTR CALLBACK GraphDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK DongleDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -149,6 +151,13 @@ static inline WCHAR *strdupU2W(const char *unix_str) return unicode_str; } +static inline void *memdup(const void *data, size_t len) +{ + void *ptr = HeapAlloc(GetProcessHeap(), 0, len); + if (ptr) return memcpy(ptr, data, len); + return NULL; +} + static inline char *get_text(HWND dialog, WORD id) { HWND item = GetDlgItem(dialog, id); diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc index bbd7842..11371f4 100644 --- a/programs/winecfg/winecfg.rc +++ b/programs/winecfg/winecfg.rc @@ -30,6 +30,7 @@ BEGIN IDS_TAB_APPLICATIONS "Applications" IDS_TAB_DLLS "Libraries" IDS_TAB_DRIVES "Drives" + IDS_TAB_DONGLES "Dongles" IDS_CHOOSE_PATH "Select the Unix target directory, please." IDS_HIDE_ADVANCED "Hide &Advanced" IDS_SHOW_ADVANCED "Show &Advanced" @@ -82,6 +83,14 @@ BEGIN IDS_NO_DRIVE_C "You don't have a drive C. This is not so great.\n\nRemember to click 'Add' in the Drives tab to create one!\n" END +STRINGTABLE DISCARDABLE +BEGIN + IDC_DONGLE_LOAD "Load" + IDC_DONGLE_UNLOAD "Do not load" + IDC_DONGLE_OK "OK" + IDC_DONGLE_NOTFOUND "Dongle not found" +END + STRINGTABLE BEGIN IDS_ACCEL_FULL "Full" -- 1.7.6.1