[WINESYNC] setupapi: Support full path enumerator in SetupDiGetClassDevs.

Based on a patch by Michael Müller.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35345
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id d5e24897e2cd61a5af71a317c1797757acf1b794 by Zhiyi Zhang <zzhang@codeweavers.com>

[WINESYNC] setupapi/tests: A spelling fix in an ok() message.

Signed-off-by: Francois Gouget <fgouget@free.fr>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 21db058d14ac6fb769a42bdeea3dadfa4fd0e8bf by Francois Gouget <fgouget@free.fr>

[WINESYNC] setupapi/tests: Fix a crash in the need_media tests.

Signed-off-by: Sven Baars <sven.wine@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 448f4cc9a25c6f994395978df0dfd7c7487b5dbb by Sven Baars <sven.wine@gmail.com>

[WINESYNC] setupapi: Fix a path leak (Valgrind).

Signed-off-by: Sven Baars <sven.wine@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 5f0d53e20903b009ee47a238a642f2e95f27d712 by Sven Baars <sven.wine@gmail.com>

[WINESYNC] setupapi: Fix an uninitialized variable warning (Valgrind).

Signed-off-by: Sven Baars <sven.wine@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id ecbd2dd34b4239318162242caaa197ae4f0911f5 by Sven Baars <sven.wine@gmail.com>

[WINESYNC] setupapi/tests: Add some tests for SPFILENOTIFY_STARTCOPY.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id ab3cc3c11a78cbaec7173a4576fda93ecf70ae90 by Zebediah Figura <z.figura12@gmail.com>

[WINESYNC] setupapi: Fix handling of FILEOP_SKIP from the SPFILENOTIFY_STARTCOPY callback.

Fixes a regression introduced by 3e5c9798a80641e0e39e95e4467c60405b22b062.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47436
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id a431b4b54a36b49821cae363d7ea8733eefe62ef by Zebediah Figura <z.figura12@gmail.com>

[WINESYNC] setupapi/tests: Remove win_9x checks.

Signed-off-by: Vijay Kiran Kamuju <infyquest@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id c59e9d302b79527f4a99be71d1346f56737dc3f3 by Vijay Kiran Kamuju <infyquest@gmail.com>

[WINESYNC] setupapi: Define .inf section names for ARM platforms.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id b2b3975f46c203a129a946128ccd018dd7ed6e46 by Alexandre Julliard <julliard@winehq.org>

[WINESYNC] setupapi/tests: Fix timeout on win10 1809+.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 177d6d7f8981b9e036437d78023b76232dcadb3d by Zhiyi Zhang <zzhang@codeweavers.com>

[WINESYNC] setupapi/tests: Add default device registry property tests.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 4fe3d7e220225ddd57ef0acd9142ef8437cdb9ca by Zhiyi Zhang <zzhang@codeweavers.com>

[WINESYNC] setupapi: Set device SPDRP_CLASS registry property in create_device().

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 288a6625ad0177e258a0db1da166d292ff420b1e by Zhiyi Zhang <zzhang@codeweavers.com>

[WINESYNC] setupapi: Add SetupGetInfDriverStoreLocationW stub.

Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id f1b94dc16c35a5c477b6df8aa94c6d3537642c77 by Derek Lesho <dlesho@codeweavers.com>
This commit is contained in:
winesync 2023-09-14 20:11:36 +02:00 committed by Hermès Bélusca-Maïto
parent 283648f6c5
commit f554e58231
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
8 changed files with 331 additions and 105 deletions

View file

@ -32,6 +32,16 @@ static const WCHAR source_disks_names_platform[] =
{'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s','.','a','m','d','6','4',0};
static const WCHAR source_disks_files_platform[] =
{'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s','.','a','m','d','6','4',0};
#elif defined(__arm__)
static const WCHAR source_disks_names_platform[] =
{'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s','.','a','r','m',0};
static const WCHAR source_disks_files_platform[] =
{'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s','.','a','r','m',0};
#elif defined(__aarch64__)
static const WCHAR source_disks_names_platform[] =
{'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s','.','a','r','m','6','4',0};
static const WCHAR source_disks_files_platform[] =
{'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s','.','a','r','m','6','4',0};
#else /* FIXME: other platforms */
static const WCHAR source_disks_names_platform[] =
{'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
@ -732,3 +742,21 @@ BOOL WINAPI SetupQueryInfOriginalFileInformationW(
return TRUE;
}
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
/***********************************************************************
* SetupGetInfDriverStoreLocationW (SETUPAPI.@)
*/
BOOL WINAPI SetupGetInfDriverStoreLocationW(
PCWSTR FileName, PSP_ALTPLATFORM_INFO AlternativePlatformInfo,
PCWSTR LocaleName, PWSTR ReturnBuffer, DWORD ReturnBufferSize,
PDWORD RequiredSize)
{
FIXME("stub: %s %p %s %p %u %p\n", debugstr_w(FileName), AlternativePlatformInfo, debugstr_w(LocaleName), ReturnBuffer, ReturnBufferSize, RequiredSize);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
#endif // (_WIN32_WINNT >= _WIN32_WINNT_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)

View file

@ -196,6 +196,7 @@ UINT CALLBACK QUEUE_callback_WtoA( void *context, UINT notification,
switch(notification)
{
case SPFILENOTIFY_COPYERROR:
buffer[0] = 0;
param2 = (UINT_PTR)buffer;
/* fall through */
case SPFILENOTIFY_STARTDELETE:
@ -1661,13 +1662,20 @@ BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBAC
* actually isn't in a subdirectory, but keep track of what it
* was, and then later strip it from the root path that we
* ultimately resolve the source disk to. */
WCHAR *src_path = op->src_path;
WCHAR src_path[MAX_PATH];
size_t path_len = 0;
op->src_path = NULL;
if (src_path)
src_path[0] = 0;
if (op->src_path)
{
lstrcpyW(src_path, op->src_path);
path_len = lstrlenW(src_path);
lstrcatW(op->media->root, backslashW);
lstrcatW(op->media->root, src_path);
lstrcatW(op->media->root, op->src_path);
heap_free(op->src_path);
op->src_path = NULL;
}
for (;;)
@ -1703,12 +1711,11 @@ BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBAC
if (queue_copy_file( paths.Source, paths.Target, op, handler, context ))
{
if (src_path && !op->media->cabinet)
if (path_len > 0 && !op->media->cabinet)
{
size_t root_len = lstrlenW(op->media->root), path_len = lstrlenW(src_path);
size_t root_len = lstrlenW(op->media->root);
if (path_len <= root_len && !wcsnicmp(op->media->root + root_len - path_len, src_path, path_len))
op->media->root[root_len - path_len - 1] = 0;
heap_free( src_path );
}
op->media->resolved = TRUE;
#ifdef __REACTOS__
@ -1732,7 +1739,7 @@ BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBAC
if (op_result == FILEOP_ABORT)
goto done;
else if (op_result == FILEOP_SKIP)
break;
continue;
else if (op_result != FILEOP_DOIT)
FIXME("Unhandled return value %#x.\n", op_result);

View file

@ -408,6 +408,7 @@
@ stdcall SetupGetFileCompressionInfoW(wstr ptr ptr ptr ptr)
@ stdcall SetupGetFileQueueCount(long long ptr)
@ stdcall SetupGetFileQueueFlags(long ptr)
@ stdcall -version=0x600+ SetupGetInfDriverStoreLocationW(wstr ptr wstr ptr long ptr)
@ stdcall SetupGetInfFileListA(str long str long ptr)
@ stdcall SetupGetInfFileListW(wstr long wstr long ptr)
@ stdcall SetupGetInfInformationA(ptr long ptr long ptr)

View file

@ -27,6 +27,7 @@
#include "winuser.h"
#include "winreg.h"
#include "initguid.h"
#include "devguid.h"
#include "devpkey.h"
#include "setupapi.h"
#include "cfgmgr32.h"
@ -1500,7 +1501,7 @@ static void test_registry_property_a(void)
{
static const CHAR bogus[] = "System\\CurrentControlSet\\Enum\\Root\\LEGACY_BOGUS";
SP_DEVINFO_DATA device = {sizeof(device)};
CHAR buf[6] = "";
CHAR buf[64] = "";
DWORD size, type;
HDEVINFO set;
BOOL ret;
@ -1594,13 +1595,69 @@ todo_wine {
res = RegOpenKeyA(HKEY_LOCAL_MACHINE, bogus, &key);
ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n");
/* Test existing registry properties right after device creation */
set = SetupDiCreateDeviceInfoList(&guid, NULL);
ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
/* Create device from a not registered class without device name */
ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device);
ok(ret, "Failed to create device, error %#x.\n", GetLastError());
/* No SPDRP_DEVICEDESC property */
SetLastError(0xdeadbeef);
ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_DEVICEDESC, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(!ret, "Expected failure.\n");
ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
/* No SPDRP_CLASS property */
SetLastError(0xdeadbeef);
ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_CLASS, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(!ret, "Expected failure.\n");
ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
/* Have SPDRP_CLASSGUID property */
memset(buf, 0, sizeof(buf));
ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_CLASSGUID, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(ret, "Failed to get property, error %#x.\n", GetLastError());
ok(!lstrcmpiA(buf, "{6a55b5a4-3f65-11db-b704-0011955c2bdb}"), "Got unexpected value %s.\n", buf);
ret = SetupDiDeleteDeviceInfo(set, &device);
ok(ret, "Failed to delete device, error %#x.\n", GetLastError());
/* Create device from a not registered class with a device name */
ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, "device_name", NULL, DICD_GENERATE_ID, &device);
ok(ret, "Failed to create device, error %#x.\n", GetLastError());
/* Have SPDRP_DEVICEDESC property */
memset(buf, 0, sizeof(buf));
ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_DEVICEDESC, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(ret, "Failed to get property, error %#x.\n", GetLastError());
ok(!lstrcmpA(buf, "device_name"), "Got unexpected value %s.\n", buf);
SetupDiDestroyDeviceInfoList(set);
/* Create device from a registered class */
set = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
ret = SetupDiCreateDeviceInfoA(set, "display", &GUID_DEVCLASS_DISPLAY, NULL, NULL, DICD_GENERATE_ID, &device);
ok(ret, "Failed to create device, error %#x.\n", GetLastError());
/* Have SPDRP_CLASS property */
memset(buf, 0, sizeof(buf));
ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_CLASS, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(ret, "Failed to get property, error %#x.\n", GetLastError());
ok(!lstrcmpA(buf, "Display"), "Got unexpected value %s.\n", buf);
SetupDiDestroyDeviceInfoList(set);
}
static void test_registry_property_w(void)
{
WCHAR friendly_name[] = {'B','o','g','u','s',0};
SP_DEVINFO_DATA device = {sizeof(device)};
WCHAR buf[6] = {0};
WCHAR buf[64] = {0};
DWORD size, type;
HDEVINFO set;
BOOL ret;
@ -1698,6 +1755,62 @@ todo_wine {
res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key);
ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n");
/* Test existing registry properties right after device creation */
set = SetupDiCreateDeviceInfoList(&guid, NULL);
ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
/* Create device from a not registered class without device name */
ret = SetupDiCreateDeviceInfoW(set, L"LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device);
ok(ret, "Failed to create device, error %#x.\n", GetLastError());
/* No SPDRP_DEVICEDESC property */
SetLastError(0xdeadbeef);
ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_DEVICEDESC, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(!ret, "Expected failure.\n");
ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
/* No SPDRP_CLASS property */
SetLastError(0xdeadbeef);
ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_CLASS, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(!ret, "Expected failure.\n");
ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError());
/* Have SPDRP_CLASSGUID property */
memset(buf, 0, sizeof(buf));
ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_CLASSGUID, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(ret, "Failed to get property, error %#x.\n", GetLastError());
ok(!lstrcmpiW(buf, L"{6a55b5a4-3f65-11db-b704-0011955c2bdb}"), "Got unexpected value %s.\n", wine_dbgstr_w(buf));
ret = SetupDiDeleteDeviceInfo(set, &device);
ok(ret, "Failed to delete device, error %#x.\n", GetLastError());
/* Create device from a not registered class with a device name */
ret = SetupDiCreateDeviceInfoW(set, L"LEGACY_BOGUS", &guid, L"device_name", NULL, DICD_GENERATE_ID, &device);
ok(ret, "Failed to create device, error %#x.\n", GetLastError());
/* Have SPDRP_DEVICEDESC property */
memset(buf, 0, sizeof(buf));
ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_DEVICEDESC, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(ret, "Failed to get property, error %#x.\n", GetLastError());
ok(!lstrcmpW(buf, L"device_name"), "Got unexpected value %s.\n", wine_dbgstr_w(buf));
SetupDiDestroyDeviceInfoList(set);
/* Create device from a registered class */
set = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
ret = SetupDiCreateDeviceInfoW(set, L"display", &GUID_DEVCLASS_DISPLAY, NULL, NULL, DICD_GENERATE_ID, &device);
ok(ret, "Failed to create device, error %#x.\n", GetLastError());
/* Have SPDRP_CLASS property */
memset(buf, 0, sizeof(buf));
ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_CLASS, NULL, (BYTE *)buf, sizeof(buf), NULL);
ok(ret, "Failed to get property, error %#x.\n", GetLastError());
ok(!lstrcmpW(buf, L"Display"), "Got unexpected value %s.\n", wine_dbgstr_w(buf));
SetupDiDestroyDeviceInfoList(set);
}
static void test_get_inf_class(void)
@ -2069,12 +2182,6 @@ static void test_get_actual_section(void)
ok(!strcasecmp(section, "section1"), "Got unexpected section %s.\n", section);
ok(size == 9, "Got size %u.\n", size);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section1", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "section1"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section2", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
@ -2105,24 +2212,6 @@ static void test_get_actual_section(void)
ok(!strcasecmp(section, "section6.NT" MYEXT), "Got unexpected section %s.\n", section);
ok(extptr == section + 8, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section7", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "section7"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section8", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "section8"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "nonexistent", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "nonexistent"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section9", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
@ -2131,7 +2220,31 @@ static void test_get_actual_section(void)
if (0)
{
/* For some reason, this call hangs on Windows 10 1809. */
/* For some reason, these calls hang on Windows 10 1809+. */
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section1", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "section1"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section7", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "section7"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section8", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "section8"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "nonexistent", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
ok(!strcasecmp(section, "nonexistent"), "Got unexpected section %s.\n", section);
ok(!extptr || !*extptr /* Windows 10 1809 */, "Got extension %s.\n", extptr);
extptr = section;
ret = SetupDiGetActualSectionToInstallA(hinf, "section10", section, ARRAY_SIZE(section), NULL, &extptr);
ok(ret, "Failed to get section, error %#x.\n", GetLastError());
@ -2827,11 +2940,9 @@ static void test_get_class_devs(void)
set = SetupDiGetClassDevsA(NULL, "ROOT\\LEGACY_BOGUS", NULL, DIGCF_ALLCLASSES);
ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
check_device_list(set, &GUID_NULL);
todo_wine {
check_device_info(set, 0, &guid2, "ROOT\\LEGACY_BOGUS\\BAR");
check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\FOO");
check_device_info(set, 2, &guid, "ROOT\\LEGACY_BOGUS\\QUX");
}
check_device_info(set, 3, NULL, NULL);
check_device_iface(set, NULL, &iface_guid, 0, 0, NULL);
ret = SetupDiDestroyDeviceInfoList(set);
@ -2840,10 +2951,8 @@ todo_wine {
set = SetupDiGetClassDevsA(&guid, "ROOT\\LEGACY_BOGUS", NULL, 0);
ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
check_device_list(set, &guid);
todo_wine {
check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\FOO");
check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\QUX");
}
check_device_info(set, 2, NULL, NULL);
check_device_iface(set, NULL, &iface_guid, 0, 0, NULL);
ret = SetupDiDestroyDeviceInfoList(set);
@ -2852,11 +2961,9 @@ todo_wine {
set = SetupDiGetClassDevsA(&guid, "ROOT\\LEGACY_BOGUS", NULL, DIGCF_ALLCLASSES);
ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
check_device_list(set, &GUID_NULL);
todo_wine {
check_device_info(set, 0, &guid2, "ROOT\\LEGACY_BOGUS\\BAR");
check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\FOO");
check_device_info(set, 2, &guid, "ROOT\\LEGACY_BOGUS\\QUX");
}
check_device_info(set, 3, NULL, NULL);
check_device_iface(set, NULL, &iface_guid, 0, 0, NULL);
ret = SetupDiDestroyDeviceInfoList(set);

View file

@ -29,8 +29,6 @@
#include "wine/test.h"
static BOOL is_win9x;
static void test_SetupCreateDiskSpaceListA(void)
{
HDSKSPC ret;
@ -152,34 +150,29 @@ static void test_SetupDuplicateDiskSpaceListA(void)
{
HDSKSPC handle, duplicate;
if (is_win9x)
win_skip("SetupDuplicateDiskSpaceListA crashes with NULL disk space handle on Win9x\n");
else
{
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, NULL, 0, 0);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", GetLastError());
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, NULL, 0, 0);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", GetLastError());
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, (void *)0xdeadbeef, 0, 0);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, (void *)0xdeadbeef, 0, 0);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, NULL, 0xdeadbeef, 0);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, NULL, 0xdeadbeef, 0);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, NULL, 0, ~0U);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
}
SetLastError(0xdeadbeef);
duplicate = SetupDuplicateDiskSpaceListA(NULL, NULL, 0, ~0U);
ok(!duplicate, "Expected SetupDuplicateDiskSpaceList to return NULL, got %p\n", duplicate);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
ok(handle != NULL,
@ -306,42 +299,37 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
HDSKSPC handle;
LONGLONG space;
if (is_win9x)
win_skip("SetupQuerySpaceRequiredOnDriveA crashes with NULL disk space handle on Win9x\n");
else
{
SetLastError(0xdeadbeef);
ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, NULL, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
GetLastError());
SetLastError(0xdeadbeef);
ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, NULL, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
GetLastError());
SetLastError(0xdeadbeef);
space = 0xdeadbeef;
ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, &space, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
GetLastError());
SetLastError(0xdeadbeef);
space = 0xdeadbeef;
ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, &space, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
GetLastError());
SetLastError(0xdeadbeef);
ret = SetupQuerySpaceRequiredOnDriveA(NULL, "", NULL, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n",
GetLastError());
SetLastError(0xdeadbeef);
ret = SetupQuerySpaceRequiredOnDriveA(NULL, "", NULL, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n",
GetLastError());
SetLastError(0xdeadbeef);
space = 0xdeadbeef;
ret = SetupQuerySpaceRequiredOnDriveA(NULL, "", &space, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n");
ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n",
GetLastError());
}
SetLastError(0xdeadbeef);
space = 0xdeadbeef;
ret = SetupQuerySpaceRequiredOnDriveA(NULL, "", &space, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n");
ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n",
GetLastError());
handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
ok(handle != NULL,
@ -474,8 +462,6 @@ static void test_SetupQuerySpaceRequiredOnDriveW(void)
START_TEST(diskspace)
{
is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) &&
GetLastError() == ERROR_CALL_NOT_IMPLEMENTED;
test_SetupCreateDiskSpaceListA();
test_SetupCreateDiskSpaceListW();
test_SetupDuplicateDiskSpaceListA();

View file

@ -1903,6 +1903,7 @@ static void test_need_media(void)
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
copy_params.LayoutInf = hinf;
copy_params.QueueHandle = queue;
/* In fact this fails with ERROR_INVALID_PARAMETER on 8+. */
if (SetupQueueCopyIndirectA(&copy_params))
{
@ -1944,6 +1945,101 @@ static void test_close_queue(void)
SetupTermDefaultQueueCallback(context);
}
static unsigned int got_start_copy, start_copy_ret;
static UINT WINAPI start_copy_cb(void *context, UINT message, UINT_PTR param1, UINT_PTR param2)
{
if (winetest_debug > 1) trace("%p, %#x, %#lx, %#lx\n", context, message, param1, param2);
if (message == SPFILENOTIFY_STARTCOPY)
{
const FILEPATHS_A *paths = (const FILEPATHS_A *)param1;
++got_start_copy;
if (strstr(paths->Source, "two.txt"))
{
SetLastError(0xdeadf00d);
return start_copy_ret;
}
}
return SetupDefaultQueueCallbackA(context, message, param1, param2);
}
static void test_start_copy(void)
{
HSPFILEQ queue;
void *context;
BOOL ret;
ret = CreateDirectoryA("src", NULL);
ok(ret, "Failed to create test directory, error %u.\n", GetLastError());
create_file("src/one.txt");
create_file("src/two.txt");
create_file("src/three.txt");
start_copy_ret = FILEOP_DOIT;
got_start_copy = 0;
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "two.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "three.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
run_queue(queue, start_copy_cb);
ok(got_start_copy == 3, "Got %u callbacks.\n", got_start_copy);
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
start_copy_ret = FILEOP_SKIP;
got_start_copy = 0;
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "two.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "three.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
run_queue(queue, start_copy_cb);
ok(got_start_copy == 3, "Got %u callbacks.\n", got_start_copy);
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
ok(!file_exists("dst/two.txt"), "Destination file should not exist.\n");
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
start_copy_ret = FILEOP_ABORT;
got_start_copy = 0;
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "two.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "three.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
context = SetupInitDefaultQueueCallbackEx(NULL, INVALID_HANDLE_VALUE, 0, 0, 0);
SetLastError(0xdeadbeef);
ret = SetupCommitFileQueueA(NULL, queue, start_copy_cb, context);
ok(!ret, "Expected failure.\n");
ok(GetLastError() == 0xdeadf00d, "Got unexpected error %u.\n", GetLastError());
SetupTermDefaultQueueCallback(context);
SetupCloseFileQueue(queue);
ok(got_start_copy == 2, "Got %u callbacks.\n", got_start_copy);
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
ok(!file_exists("dst/two.txt"), "Destination file should not exist.\n");
ok(!file_exists("dst/three.txt"), "Destination file should not exist.\n");
delete_file("src/one.txt");
delete_file("src/two.txt");
delete_file("src/three.txt");
delete_file("src/");
delete_file("dst/");
}
START_TEST(install)
{
char temp_path[MAX_PATH], prev_path[MAX_PATH];
@ -1972,6 +2068,7 @@ START_TEST(install)
test_need_media();
test_close_queue();
test_install_file();
test_start_copy();
UnhookWindowsHookEx(hhook);

View file

@ -312,7 +312,7 @@ static void test_SetupCopyOEMInf(void)
ok(res == TRUE, "Expected TRUE, got %d\n", res);
ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest);
ok(strcmp(dest, orig_dest), "Expected INF files to be copied to differnet paths.\n");
ok(strcmp(dest, orig_dest), "Expected INF files to be copied to different paths.\n");
res = SetupUninstallOEMInfA(strrchr(dest, '\\') + 1, 0, NULL);
ok(res, "Failed to uninstall '%s', error %u.\n", dest, GetLastError());

View file

@ -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: 72d6759f3a86c24e2db0b6190f4d2fae642e487f
wine: f1b94dc16c35a5c477b6df8aa94c6d3537642c77