diff --git a/dll/win32/setupapi/dialog.c b/dll/win32/setupapi/dialog.c index 17d468f0932..7899e66e55f 100644 --- a/dll/win32/setupapi/dialog.c +++ b/dll/win32/setupapi/dialog.c @@ -228,6 +228,33 @@ UINT WINAPI SetupPromptForDiskW(HWND hwndParent, PCWSTR DialogTitle, PCWSTR Disk SetLastError(ERROR_INVALID_PARAMETER); return DPROMPT_CANCEL; } + + if (PathToSource && (DiskPromptStyle & IDF_CHECKFIRST)) + { + WCHAR filepath[MAX_PATH]; + + if (lstrlenW(PathToSource) + 1 + lstrlenW(FileSought) < ARRAY_SIZE(filepath)) + { + swprintf(filepath, ARRAY_SIZE(filepath), L"%s\\%s", PathToSource, FileSought); + if (GetFileAttributesW(filepath) != INVALID_FILE_ATTRIBUTES) + { + if (PathRequiredSize) + *PathRequiredSize = lstrlenW(PathToSource) + 1; + + if (!PathBuffer) + return DPROMPT_SUCCESS; + + if (PathBufferSize >= lstrlenW(PathToSource) + 1) + { + lstrcpyW(PathBuffer, PathToSource); + return DPROMPT_SUCCESS; + } + else + return DPROMPT_BUFFERTOOSMALL; + } + } + } + params.DialogTitle = DialogTitle; params.DiskName = DiskName; params.PathToSource = PathToSource; diff --git a/dll/win32/setupapi/parser.c b/dll/win32/setupapi/parser.c index 02297be7f44..4917cf2eeeb 100644 --- a/dll/win32/setupapi/parser.c +++ b/dll/win32/setupapi/parser.c @@ -1966,6 +1966,15 @@ BOOL WINAPI SetupGetIntField( PINFCONTEXT context, DWORD index, PINT result ) } +static int xdigit_to_int(WCHAR c) +{ + if ('0' <= c && c <= '9') return c - '0'; + if ('a' <= c && c <= 'f') return c - 'a' + 10; + if ('A' <= c && c <= 'F') return c - 'A' + 10; + return -1; +} + + /*********************************************************************** * SetupGetBinaryField (SETUPAPI.@) */ @@ -2000,15 +2009,15 @@ BOOL WINAPI SetupGetBinaryField( PINFCONTEXT context, DWORD index, BYTE *buffer, { const WCHAR *p; DWORD value = 0; - for (p = field->text; *p && iswxdigit(*p); p++) + int d; + for (p = field->text; *p && (d = xdigit_to_int(*p)) != -1; p++) { if ((value <<= 4) > 255) { SetLastError( ERROR_INVALID_DATA ); return FALSE; } - if (*p <= '9') value |= (*p - '0'); - else value |= (towlower(*p) - 'a' + 10); + value |= d; } buffer[i - index] = value; } diff --git a/dll/win32/setupapi/queue.c b/dll/win32/setupapi/queue.c index 437116cf58f..fb8ba130770 100644 --- a/dll/win32/setupapi/queue.c +++ b/dll/win32/setupapi/queue.c @@ -1300,9 +1300,6 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style, VersionSizeTarget = GetFileVersionInfoSizeW(target,&zero); } - TRACE("SizeTarget %i ... SizeSource %i\n",VersionSizeTarget, - VersionSizeSource); - if (VersionSizeSource && VersionSizeTarget) { LPVOID VersionSource; @@ -1396,7 +1393,7 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style, #else rc = CopyFileW(source,target,FALSE); #endif - TRACE("Did copy... rc was %i\n",rc); + if (!rc) WARN( "failed to copy, err %u\n", GetLastError() ); } else SetLastError(ERROR_SUCCESS); @@ -1725,11 +1722,32 @@ BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBAC break; #endif } + paths.Win32Error = GetLastError(); + if (paths.Win32Error == ERROR_PATH_NOT_FOUND || + paths.Win32Error == ERROR_FILE_NOT_FOUND) #if defined(__REACTOS__) // TEMP HACK! - ERR( "** Could not find source install media! ** copy error %d %s -> %s\n", - paths.Win32Error, debugstr_w(paths.Source), debugstr_w(paths.Target) ); - break; + { + ERR( "** Could not find source install media! ** copy error %d %s -> %s\n", + paths.Win32Error, debugstr_w(paths.Source), debugstr_w(paths.Target) ); + break; + } +#else + continue; #endif + + newpath[0] = 0; + op_result = handler( context, SPFILENOTIFY_COPYERROR, (UINT_PTR)&paths, (UINT_PTR)newpath ); + if (op_result == FILEOP_ABORT) + goto done; + else if (op_result == FILEOP_SKIP) + break; + else if (op_result == FILEOP_NEWPATH) + { + lstrcpyW(op->media->root, newpath); + build_filepathsW(op, &paths); + } + else if (op_result != FILEOP_DOIT) + FIXME("Unhandled return value %#x.\n", op_result); } } else diff --git a/modules/rostests/winetests/setupapi/CMakeLists.txt b/modules/rostests/winetests/setupapi/CMakeLists.txt index cf2ce4b449c..380f0cc365a 100644 --- a/modules/rostests/winetests/setupapi/CMakeLists.txt +++ b/modules/rostests/winetests/setupapi/CMakeLists.txt @@ -15,6 +15,7 @@ add_importlibs(setupapi_coinst msvcrt kernel32) list(APPEND SOURCE devinst.c + dialog.c diskspace.c install.c misc.c diff --git a/modules/rostests/winetests/setupapi/devinst.c b/modules/rostests/winetests/setupapi/devinst.c index d13113fcc10..8af42a2070e 100644 --- a/modules/rostests/winetests/setupapi/devinst.c +++ b/modules/rostests/winetests/setupapi/devinst.c @@ -31,6 +31,7 @@ #include "devpkey.h" #include "setupapi.h" #include "cfgmgr32.h" +#include "cguid.h" #include "wine/heap.h" #include "wine/test.h" @@ -1450,7 +1451,7 @@ static void test_register_device_iface(void) 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', 'E','n','u','m','\\','R','o','o','t','\\', 'L','E','G','A','C','Y','_','B','O','G','U','S',0}; - SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}, ret_iface = {sizeof(ret_iface)}; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; SP_DEVINFO_DATA device = {sizeof(device)}; HDEVINFO set, set2; BOOL ret; @@ -2014,6 +2015,7 @@ static void test_device_interface_key(void) ok(!ret, "key should exist: %u\n", ret); ret = RegSetValueA(key, NULL, REG_SZ, "test", 5); + ok(!ret, "RegSetValue failed: %u\n", ret); sz = sizeof(buffer); ret = RegQueryValueA(dikey, NULL, buffer, &sz); ok(!ret, "RegQueryValue failed: %u\n", ret); @@ -2034,6 +2036,64 @@ static void test_device_interface_key(void) SetupDiDestroyDeviceInfoList(set); } +static void test_open_device_interface_key(void) +{ + SP_DEVICE_INTERFACE_DATA iface; + SP_DEVINFO_DATA device; + CHAR buffer[5]; + HDEVINFO set; + LSTATUS lr; + LONG size; + HKEY key; + BOOL ret; + + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x\n", GetLastError()); + + device.cbSize = sizeof(device); + ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + iface.cbSize = sizeof(iface); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + + /* Test open before creation */ + key = SetupDiOpenDeviceInterfaceRegKey(set, &iface, 0, KEY_ALL_ACCESS); + ok(key == INVALID_HANDLE_VALUE, "Expect open interface registry key failure\n"); + + /* Test opened key is from SetupDiCreateDeviceInterfaceRegKey */ + key = SetupDiCreateDeviceInterfaceRegKeyW(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL); + ok(key != INVALID_HANDLE_VALUE, "Failed to create interface registry key, error %#x\n", GetLastError()); + + lr = RegSetValueA(key, NULL, REG_SZ, "test", 5); + ok(!lr, "RegSetValue failed, error %#x\n", lr); + + RegCloseKey(key); + + key = SetupDiOpenDeviceInterfaceRegKey(set, &iface, 0, KEY_ALL_ACCESS); + ok(key != INVALID_HANDLE_VALUE, "Failed to open interface registry key, error %#x\n", GetLastError()); + + size = sizeof(buffer); + lr = RegQueryValueA(key, NULL, buffer, &size); + ok(!lr, "RegQueryValue failed, error %#x\n", lr); + ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer); + + RegCloseKey(key); + + /* Test open after removal */ + ret = SetupDiRemoveDeviceInterface(set, &iface); + ok(ret, "Failed to remove device interface, error %#x.\n", GetLastError()); + + key = SetupDiOpenDeviceInterfaceRegKey(set, &iface, 0, KEY_ALL_ACCESS); + ok(key == INVALID_HANDLE_VALUE, "Expect open interface registry key failure\n"); + + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + ret = SetupDiDestroyDeviceInfoList(set); + ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError()); +} + static void test_device_install_params(void) { SP_DEVINFO_DATA device = {sizeof(device)}; @@ -3145,6 +3205,7 @@ START_TEST(devinst) test_get_inf_class(); test_devnode(); test_device_interface_key(); + test_open_device_interface_key(); test_device_install_params(); test_driver_list(); test_call_class_installer(); diff --git a/modules/rostests/winetests/setupapi/dialog.c b/modules/rostests/winetests/setupapi/dialog.c new file mode 100644 index 00000000000..b6191afa41d --- /dev/null +++ b/modules/rostests/winetests/setupapi/dialog.c @@ -0,0 +1,107 @@ +/* + * Unit tests for SetupPromptForDisk + * + * Copyright 2014 Michael Müller + * + * 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 + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winreg.h" +#include "guiddef.h" +#include "setupapi.h" + +#include "wine/test.h" + +static void test_SetupPromptForDiskA(void) +{ + char path[MAX_PATH]; + char buffer[MAX_PATH]; + UINT ret; + DWORD length; + + GetSystemDirectoryA(path, MAX_PATH); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskA(0, "Test", "Testdisk", path, "kernel32.dll", NULL, IDF_CHECKFIRST, buffer, sizeof(buffer) - 1, &length); + ok(ret == DPROMPT_SUCCESS, "Expected DPROMPT_SUCCESS, got %u\n", ret); + ok(length == strlen(path) + 1, "Expect length %u, got %u\n", lstrlenA(path) + 1, length); + ok(!strcmp(path, buffer), "Expected path %s, got %s\n", debugstr_a(path), debugstr_a(buffer)); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskA(0, "Test", "Testdisk", path, "kernel32.dll", NULL, IDF_CHECKFIRST, NULL, 0, &length); + ok(ret == DPROMPT_SUCCESS, "Expected DPROMPT_SUCCESS, got %d\n", ret); + ok(length == strlen(path) + 1, "Expect length %u, got %u\n", lstrlenA(path) + 1, length); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskA(0, "Test", "Testdisk", path, "kernel32.dll", NULL, IDF_CHECKFIRST, buffer, 1, &length); + ok(ret == DPROMPT_BUFFERTOOSMALL, "Expected DPROMPT_BUFFERTOOSMALL, got %u\n", ret); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskA(0, "Test", "Testdisk", path, "kernel32.dll", NULL, IDF_CHECKFIRST, buffer, strlen(path), &length); + ok(ret == DPROMPT_BUFFERTOOSMALL, "Expected DPROMPT_BUFFERTOOSMALL, got %u\n", ret); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskA(0, "Test", "Testdisk", path, "kernel32.dll", NULL, IDF_CHECKFIRST, buffer, strlen(path) + 1, &length); + ok(ret == DPROMPT_SUCCESS, "Expected DPROMPT_SUCCESS, got %u\n", ret); + ok(length == strlen(path) + 1, "Expect length %u, got %u\n", lstrlenA(path) + 1, length); + ok(!strcmp(path, buffer), "Expected path %s, got %s\n", debugstr_a(path), debugstr_a(buffer)); +} + +static void test_SetupPromptForDiskW(void) +{ + WCHAR path[MAX_PATH]; + WCHAR buffer[MAX_PATH]; + UINT ret; + DWORD length; + + GetSystemDirectoryW(path, MAX_PATH); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskW(0, L"Test", L"Testdisk", path, L"kernel32.dll", NULL, IDF_CHECKFIRST, buffer, ARRAY_SIZE(buffer) - 1, &length); + ok(ret == DPROMPT_SUCCESS, "Expected DPROMPT_SUCCESS, got %u\n", ret); + ok(length == lstrlenW(path) + 1, "Expect length %u, got %u\n", lstrlenW(path) + 1, length); + ok(!lstrcmpW(path, buffer), "Expected path %s, got %s\n", debugstr_w(path), debugstr_w(buffer)); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskW(0, L"Test", L"Testdisk", path, L"kernel32.dll", NULL, IDF_CHECKFIRST, NULL, 0, &length); + ok(ret == DPROMPT_SUCCESS, "Expected DPROMPT_SUCCESS, got %d\n", ret); + ok(length == lstrlenW(path) + 1, "Expect length %u, got %u\n", lstrlenW(path) + 1, length); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskW(0, L"Test", L"Testdisk", path, L"kernel32.dll", NULL, IDF_CHECKFIRST, buffer, 1, &length); + ok(ret == DPROMPT_BUFFERTOOSMALL, "Expected DPROMPT_BUFFERTOOSMALL, got %u\n", ret); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskW(0, L"Test", L"Testdisk", path, L"kernel32.dll", NULL, IDF_CHECKFIRST, buffer, lstrlenW(path), &length); + ok(ret == DPROMPT_BUFFERTOOSMALL, "Expected DPROMPT_BUFFERTOOSMALL, got %u\n", ret); + + memset(buffer, 0, sizeof(buffer)); + ret = SetupPromptForDiskW(0, L"Test", L"Testdisk", path, L"kernel32.dll", NULL, IDF_CHECKFIRST, buffer, lstrlenW(path) + 1, &length); + ok(ret == DPROMPT_SUCCESS, "Expected DPROMPT_SUCCESS, got %u\n", ret); + ok(length == lstrlenW(path) + 1, "Expect length %u, got %u\n", lstrlenW(path) + 1, length); + ok(!lstrcmpW(path, buffer), "Expected path %s, got %s\n", debugstr_w(path), debugstr_w(buffer)); +} + +START_TEST(dialog) +{ + test_SetupPromptForDiskA(); + test_SetupPromptForDiskW(); +} diff --git a/modules/rostests/winetests/setupapi/testlist.c b/modules/rostests/winetests/setupapi/testlist.c index ccf33787079..895715aa95c 100644 --- a/modules/rostests/winetests/setupapi/testlist.c +++ b/modules/rostests/winetests/setupapi/testlist.c @@ -4,6 +4,7 @@ #include extern void func_devinst(void); +extern void func_dialog(void); extern void func_diskspace(void); extern void func_install(void); extern void func_misc(void); @@ -15,6 +16,7 @@ extern void func_stringtable(void); const struct test winetest_testlist[] = { { "devinst", func_devinst }, + { "dialog", func_dialog }, { "diskspace", func_diskspace }, { "install", func_install }, { "misc", func_misc }, diff --git a/sdk/tools/winesync/setupapi.cfg b/sdk/tools/winesync/setupapi.cfg index 88b28a5172f..109ac92b7a2 100644 --- a/sdk/tools/winesync/setupapi.cfg +++ b/sdk/tools/winesync/setupapi.cfg @@ -10,4 +10,4 @@ files: dlls/setupapi/setupcab.c: dll/win32/setupapi/setupcab.c dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable_wine.c tags: - wine: f1b94dc16c35a5c477b6df8aa94c6d3537642c77 + wine: d580d2c2fdad7f6f00dd12923e475298c019b660