From fca7431a535a413d77127c48bb6b752cde056a43 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sun, 4 Jun 2017 01:51:43 +0000 Subject: [PATCH] [SETUPAPI_WINETEST] Sync with Wine Staging 2.9. CORE-13362 svn path=/trunk/; revision=74886 --- rostests/winetests/setupapi/devinst.c | 424 +++++++------------------ rostests/winetests/setupapi/install.c | 8 + rostests/winetests/setupapi/misc.c | 7 +- rostests/winetests/setupapi/query.c | 17 +- rostests/winetests/setupapi/setupcab.c | 117 ++++++- 5 files changed, 246 insertions(+), 327 deletions(-) diff --git a/rostests/winetests/setupapi/devinst.c b/rostests/winetests/setupapi/devinst.c index 5eedded7860..91ca61319e6 100644 --- a/rostests/winetests/setupapi/devinst.c +++ b/rostests/winetests/setupapi/devinst.c @@ -58,6 +58,8 @@ static BOOL (WINAPI *pSetupDiSetDeviceRegistryPropertyA)(HDEVINFO, PSP_DEVIN static BOOL (WINAPI *pSetupDiSetDeviceRegistryPropertyW)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const BYTE *, DWORD); static BOOL (WINAPI *pSetupDiGetDeviceRegistryPropertyA)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD); static BOOL (WINAPI *pSetupDiGetDeviceRegistryPropertyW)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD); +static BOOL (WINAPI *pSetupDiRemoveDevice)(HDEVINFO, PSP_DEVINFO_DATA); +static BOOL (WINAPI *pSetupDiRemoveDeviceInterface)(HDEVINFO, PSP_DEVICE_INTERFACE_DATA); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); /* This is a unique guid for testing purposes */ @@ -92,74 +94,11 @@ static void init_function_pointers(void) pSetupDiSetDeviceRegistryPropertyW = (void *)GetProcAddress(hSetupAPI, "SetupDiSetDeviceRegistryPropertyW"); pSetupDiGetDeviceRegistryPropertyA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyA"); pSetupDiGetDeviceRegistryPropertyW = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyW"); + pSetupDiRemoveDeviceInterface = (void *)GetProcAddress(hSetupAPI, "SetupDiRemoveDeviceInterface"); + pSetupDiRemoveDevice = (void *)GetProcAddress(hSetupAPI, "SetupDiRemoveDevice"); pIsWow64Process = (void *)GetProcAddress(hKernel32, "IsWow64Process"); } -static void change_reg_permissions(const WCHAR *regkey) -{ - HKEY hkey; - SID_IDENTIFIER_AUTHORITY ident = { SECURITY_WORLD_SID_AUTHORITY }; - SECURITY_DESCRIPTOR sd; - PSID EveryoneSid; - PACL pacl = NULL; - - RegOpenKeyExW(HKEY_LOCAL_MACHINE, regkey, 0, WRITE_DAC, &hkey); - - /* Initialize the 'Everyone' sid */ - AllocateAndInitializeSid(&ident, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); - - pacl = HeapAlloc(GetProcessHeap(), 0, 256); - InitializeAcl(pacl, 256, ACL_REVISION); - - /* Add 'Full Control' for 'Everyone' */ - AddAccessAllowedAce(pacl, ACL_REVISION, KEY_ALL_ACCESS, EveryoneSid); - - InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); - - SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE); - - /* Set the new security on the registry key */ - RegSetKeySecurity(hkey, DACL_SECURITY_INFORMATION, &sd); - - RegCloseKey(hkey); - - HeapFree(GetProcessHeap(), 0, pacl); - if (EveryoneSid) - FreeSid(EveryoneSid); -} - -static BOOL remove_device(void) -{ - HDEVINFO set; - SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } }; - BOOL ret, retval; - - SetLastError(0xdeadbeef); - set = pSetupDiGetClassDevsA(&guid, NULL, 0, 0); - ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", - GetLastError()); - - SetLastError(0xdeadbeef); - ret = pSetupDiEnumDeviceInfo(set, 0, &devInfo); - ok(ret, "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError()); - - SetLastError(0xdeadbeef); - retval = pSetupDiCallClassInstaller(DIF_REMOVE, set, &devInfo); - if(is_wow64) - todo_wine ok(!retval && GetLastError() == ERROR_IN_WOW64, - "SetupDiCallClassInstaller(DIF_REMOVE...) succeeded: %08x\n", GetLastError()); - else - todo_wine ok(retval, - "SetupDiCallClassInstaller(DIF_REMOVE...) failed: %08x\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = pSetupDiDestroyDeviceInfoList(set); - ok(ret, "SetupDiDestroyDeviceInfoList failed: %08x\n", GetLastError()); - - return retval; -} - -/* RegDeleteTreeW from dlls/advapi32/registry.c */ static LSTATUS devinst_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) { LONG ret; @@ -226,35 +165,7 @@ cleanup: return ret; } -static void clean_devclass_key(void) -{ - static const WCHAR devclass[] = {'S','y','s','t','e','m','\\', - 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', - 'C','o','n','t','r','o','l','\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\', - '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-', - '1','1','d','b','-','b','7','0','4','-', - '0','0','1','1','9','5','5','c','2','b','d','b','}',0}; - HKEY key; - DWORD subkeys; - - /* Check if we have subkeys as Windows 2000 doesn't delete - * the keys under the DeviceClasses key after a SetupDiDestroyDeviceInfoList. - */ - RegOpenKeyW(HKEY_LOCAL_MACHINE, devclass, &key); - RegQueryInfoKeyW(key, NULL, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (subkeys > 0) - { - trace("We are most likely on Windows 2000\n"); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass); - } - else - { - ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, devclass), - "Couldn't delete deviceclass key\n"); - } -} - -static void test_SetupDiCreateDeviceInfoListEx(void) +static void test_SetupDiCreateDeviceInfoListEx(void) { HDEVINFO devlist; BOOL ret; @@ -342,7 +253,7 @@ static void test_SetupDiOpenClassRegKeyExA(void) RegCloseKey(hkey); } else - trace("failed to open classes key\n"); + trace("failed to open classes key %u\n", GetLastError()); } static void create_inf_file(LPCSTR filename) @@ -423,12 +334,6 @@ static void testCreateDeviceInfo(void) { BOOL ret; HDEVINFO set; - HKEY key; - LONG res; - static const WCHAR bogus[] = {'S','y','s','t','e','m','\\', - '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}; SetLastError(0xdeadbeef); ret = pSetupDiCreateDeviceInfoA(NULL, NULL, NULL, NULL, NULL, 0, NULL); @@ -451,19 +356,6 @@ static void testCreateDeviceInfo(void) DWORD i; static GUID deadbeef = {0xdeadbeef, 0xdead, 0xbeef, {0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}}; - HKEY key; - static const WCHAR bogus0000[] = {'S','y','s','t','e','m','\\', - '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','0','0','0',0}; - - /* So we know we have a clean start */ - if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus0000, &key)) - { - trace("Expected LEGACY_BOGUS\\0000 key to not exist, will be removed now\n"); - change_reg_permissions(bogus0000); - ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus0000), "Could not delete LEGACY_BOGUS\\0000 key\n"); - } /* No GUID given */ SetLastError(0xdeadbeef); @@ -471,30 +363,14 @@ static void testCreateDeviceInfo(void) NULL, NULL, 0, NULL); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - /* Even though NT4 fails it still adds some stuff to the registry that - * can't be deleted via normal setupapi functions. As the registry is written - * by a different user (SYSTEM) we have to do some magic to get rid of the key - */ - if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus0000, &key)) - { - trace("NT4 created a bogus key on failure, will be removed now\n"); - change_reg_permissions(bogus0000); - ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus0000), - "Could not delete LEGACY_BOGUS\\0000 key\n"); - } + /* We can't add device information to the set with a different GUID */ SetLastError(0xdeadbeef); ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &deadbeef, NULL, NULL, 0, NULL); ok(!ret && GetLastError() == ERROR_CLASS_MISMATCH, "Expected ERROR_CLASS_MISMATCH, got %08x\n", GetLastError()); - if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus0000, &key)) - { - trace("NT4 created a bogus key on failure, will be removed now\n"); - change_reg_permissions(bogus0000); - ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus0000), - "Could not delete LEGACY_BOGUS\\0000 key\n"); - } + /* Finally, with all three required parameters, this succeeds: */ ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, NULL); @@ -526,45 +402,11 @@ static void testCreateDeviceInfo(void) ok(i == 3, "Expected 3 devices, got %d\n", i); ok(GetLastError() == ERROR_NO_MORE_ITEMS, "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError()); + + ret = pSetupDiRemoveDevice(set, &devInfo); + todo_wine ok(ret, "got %u\n", GetLastError()); pSetupDiDestroyDeviceInfoList(set); } - - /* The bogus registry key shouldn't be there after this test. The only - * reasons this key would still be present: - * - * - We are running on Wine which has to be fixed - * - We have leftovers from old tests - */ - res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key); - todo_wine - ok(res == ERROR_FILE_NOT_FOUND, "Expected key to not exist\n"); - if (res == ERROR_SUCCESS) - { - DWORD subkeys; - - /* Check if we have subkeys */ - RegQueryInfoKeyA(key, NULL, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (subkeys > 0) - { - int i; - - /* Leftovers from old tests */ - trace("Going to remove %d devices\n", subkeys); - for (i = 0; i < subkeys; i++) - { - BOOL ret; - - ret = remove_device(); - ok(ret, "Expected a device to be removed\n"); - } - } - else - { - /* Wine doesn't delete the bogus key itself currently */ - trace("We are most likely on Wine\n"); - RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus); - } - } } static void testGetDeviceInstanceId(void) @@ -627,12 +469,18 @@ static void testGetDeviceInstanceId(void) /* NT4 returns 'Root' and W2K and above 'ROOT' */ ok(!lstrcmpiA(instanceID, "ROOT\\LEGACY_BOGUS\\0001"), "Unexpected instance ID %s\n", instanceID); + + ret = pSetupDiRemoveDevice(set, &devInfo); + todo_wine ok(ret, "got %u\n", GetLastError()); pSetupDiDestroyDeviceInfoList(set); } } static void testRegisterDeviceInfo(void) { + static const WCHAR bogus[] = {'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'E','n','u','m','\\','U','S','B','\\','B','O','G','U','S',0}; BOOL ret; HDEVINFO set; @@ -659,22 +507,20 @@ static void testRegisterDeviceInfo(void) ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + ret = pSetupDiCreateDeviceInfoA(set, "USB\\BOGUS\\0000", &guid, NULL, NULL, 0, &devInfo); - ok(ret || GetLastError() == ERROR_DEVINST_ALREADY_EXISTS, - "SetupDiCreateDeviceInfoA failed: %d\n", GetLastError()); - if (ret) - { - /* If it already existed, registering it again will fail */ - ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, - NULL); - ok(ret, "SetupDiCreateDeviceInfoA failed: %d\n", GetLastError()); - } - /* FIXME: On Win2K+ systems, this is now persisted to registry in - * HKLM\System\CCS\Enum\USB\Bogus\0000. - * FIXME: the key also becomes undeletable. How to get rid of it? - */ + ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); + + ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); + ok(ret, "SetupDiRegisterDeviceInfo failed: %d\n", GetLastError()); + + ret = pSetupDiRemoveDevice(set, &devInfo); + todo_wine ok(ret, "got %u\n", GetLastError()); pSetupDiDestroyDeviceInfoList(set); + + /* remove once Wine is fixed */ + devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); } } @@ -682,17 +528,6 @@ static void testCreateDeviceInterface(void) { BOOL ret; HDEVINFO set; - HKEY key; - static const WCHAR bogus[] = {'S','y','s','t','e','m','\\', - '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}; - static const WCHAR devclass[] = {'S','y','s','t','e','m','\\', - 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', - 'C','o','n','t','r','o','l','\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\', - '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-', - '1','1','d','b','-','b','7','0','4','-', - '0','0','1','1','9','5','5','c','2','b','d','b','}',0}; if (!pSetupDiCreateDeviceInterfaceA || !pSetupDiEnumDeviceInterfaces) { @@ -754,32 +589,26 @@ static void testCreateDeviceInterface(void) ok(i == 2, "expected 2 interfaces, got %d\n", i); ok(GetLastError() == ERROR_NO_MORE_ITEMS, "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError()); + + for (i = 0; i < 2; i++) + { + ret = pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, i, &interfaceData); + ok(ret, "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError()); + + ret = pSetupDiRemoveDeviceInterface(set, &interfaceData); + todo_wine ok(ret, "SetupDiRemoveDeviceInterface failed: %08x\n", GetLastError()); + } + + ret = pSetupDiRemoveDevice(set, &devInfo); + todo_wine ok(ret, "got %u\n", GetLastError()); + ret = pSetupDiDestroyDeviceInfoList(set); ok(ret, "SetupDiDestroyDeviceInfoList failed: %08x\n", GetLastError()); - - /* Cleanup */ - /* FIXME: On Wine we still have the bogus entry in Enum\Root and - * subkeys, as well as the deviceclass key with subkeys. - * Only clean the deviceclass key once Wine if fixed. - */ - if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key)) - { - /* Wine doesn't delete the information currently */ - trace("We are most likely on Wine\n"); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass); - } - else - { - clean_devclass_key(); - } } } static void testGetDeviceInterfaceDetail(void) { - BOOL ret; - HDEVINFO set; static const WCHAR bogus[] = {'S','y','s','t','e','m','\\', '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','\\', @@ -790,6 +619,8 @@ static void testGetDeviceInterfaceDetail(void) '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-', '1','1','d','b','-','b','7','0','4','-', '0','0','1','1','9','5','5','c','2','b','d','b','}',0}; + BOOL ret; + HDEVINFO set; if (!pSetupDiCreateDeviceInterfaceA || !pSetupDiGetDeviceInterfaceDetailA) { @@ -808,7 +639,6 @@ static void testGetDeviceInterfaceDetail(void) SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData), { 0 } }; DWORD size = 0; - HKEY key; SetLastError(0xdeadbeef); ret = pSetupDiGetDeviceInterfaceDetailA(set, NULL, NULL, 0, NULL, @@ -884,24 +714,20 @@ static void testGetDeviceInterfaceDetail(void) HeapFree(GetProcessHeap(), 0, buf); } + + ret = pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, 0, &interfaceData); + ok(ret, "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError()); + + ret = pSetupDiRemoveDeviceInterface(set, &interfaceData); + todo_wine ok(ret, "SetupDiRemoveDeviceInterface failed: %08x\n", GetLastError()); + + ret = pSetupDiRemoveDevice(set, &devInfo); + todo_wine ok(ret, "got %u\n", GetLastError()); pSetupDiDestroyDeviceInfoList(set); - /* Cleanup */ - /* FIXME: On Wine we still have the bogus entry in Enum\Root and - * subkeys, as well as the deviceclass key with subkeys. - * Only do the RegDeleteKey, once Wine is fixed. - */ - if (!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key)) - { - /* Wine doesn't delete the information currently */ - trace("We are most likely on Wine\n"); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass); - } - else - { - clean_devclass_key(); - } + /* remove once Wine is fixed */ + devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); + devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass); } } @@ -920,7 +746,6 @@ static void testDevRegKey(void) BOOL ret; HDEVINFO set; HKEY key = NULL; - BOOL classKeyCreated; SetLastError(0xdeadbeef); key = pSetupDiCreateDevRegKeyW(NULL, NULL, 0, 0, 0, NULL, NULL); @@ -1012,7 +837,6 @@ static void testDevRegKey(void) "SetupDiCreateDevRegKey failed: %08x\n", GetLastError()); if (key != INVALID_HANDLE_VALUE) { - classKeyCreated = TRUE; RegCloseKey(key); /* The class key should have been created */ ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key), @@ -1030,55 +854,39 @@ static void testDevRegKey(void) DIREG_DRV, KEY_READ); ok(key != INVALID_HANDLE_VALUE, "SetupDiOpenDevRegKey failed: %08x\n", GetLastError()); - pSetupDiDestroyDeviceInfoList(set); + RegCloseKey(key); } - else - classKeyCreated = FALSE; - /* Cleanup */ - ret = remove_device(); - if(!is_wow64) - todo_wine ok(ret, "Expected the device to be removed: %08x\n", GetLastError()); + ret = pSetupDiRemoveDevice(set, &devInfo); + todo_wine ok(ret, "got %u\n", GetLastError()); + pSetupDiDestroyDeviceInfoList(set); - /* FIXME: Only do the RegDeleteKey, once Wine is fixed */ - if (!ret) - { - /* Wine doesn't delete the information currently */ - trace("We are most likely on Wine\n"); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, classKey); - } - else if (classKeyCreated) - { - /* There should only be a class key entry, so a simple - * RegDeleteKey should work - * - * This could fail if it's the first time for this new test - * after running the old tests. - */ - ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, classKey), - "Couldn't delete classkey\n"); - } + /* remove once Wine is fixed */ + devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); + devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, classKey); } } static void testRegisterAndGetDetail(void) { - HDEVINFO set; - BOOL ret; - SP_DEVINFO_DATA devInfo = { sizeof(SP_DEVINFO_DATA), { 0 } }; - SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData), { 0 } }; - DWORD dwSize = 0; + static const WCHAR classKey[] = {'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'C','o','n','t','r','o','l','\\','C','l','a','s','s','\\', + '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-', + '1','1','d','b','-','b','7','0','4','-', + '0','0','1','1','9','5','5','c','2','b','d','b','}',0}; static const WCHAR bogus[] = {'S','y','s','t','e','m','\\', '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}; - static const WCHAR devclass[] = {'S','y','s','t','e','m','\\', - 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', - 'C','o','n','t','r','o','l','\\','D','e','v','i','c','e','C','l','a','s','s','e','s','\\', - '{','6','a','5','5','b','5','a','4','-','3','f','6','5','-', - '1','1','d','b','-','b','7','0','4','-', - '0','0','1','1','9','5','5','c','2','b','d','b','}',0}; + HDEVINFO set, set2; + BOOL ret; + SP_DEVINFO_DATA devInfo = { sizeof(SP_DEVINFO_DATA), { 0 } }; + SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData), { 0 } }; + SP_DEVICE_INTERFACE_DATA interfaceData2 = { sizeof(interfaceData2), { 0 } }; + DWORD dwSize = 0; + HKEY key; + LONG res; if (!pSetupDiCreateDeviceInterfaceA || !pSetupDiEnumDeviceInterfaces || !pSetupDiGetDeviceInterfaceDetailA) @@ -1092,6 +900,10 @@ static void testRegisterAndGetDetail(void) ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", GetLastError()); + res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key); + ok(res != ERROR_SUCCESS, "Expected key to not exist\n"); + RegCloseKey(key); + SetLastError(0xdeadbeef); ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, 0, DICD_GENERATE_ID, &devInfo); @@ -1103,25 +915,23 @@ static void testRegisterAndGetDetail(void) ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); ok(ret, "SetupDiRegisterDeviceInfo failed: %08x\n", GetLastError()); - pSetupDiDestroyDeviceInfoList(set); - SetLastError(0xdeadbeef); - set = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); - ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", + set2 = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); + ok(set2 != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pSetupDiEnumDeviceInterfaces(set, NULL, &guid, 0, &interfaceData); + ret = pSetupDiEnumDeviceInterfaces(set2, NULL, &guid, 0, &interfaceData2); ok(ret, "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL, 0, &dwSize, NULL); + ret = pSetupDiGetDeviceInterfaceDetailA(set2, &interfaceData2, NULL, 0, &dwSize, NULL); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError()); if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { static const char path[] = "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; - static const char path_wow64[] = + static const char path_w10[] = "\\\\?\\root#legacy_bogus#0001#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; static const char path_w2k[] = "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\"; @@ -1132,42 +942,29 @@ static void testRegisterAndGetDetail(void) { detail->cbSize = sizeof(*detail); SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, + ret = pSetupDiGetDeviceInterfaceDetailA(set2, &interfaceData2, detail, dwSize, &dwSize, NULL); ok(ret, "SetupDiGetDeviceInterfaceDetailA failed: %08x\n", GetLastError()); - /* FIXME: This one only worked because old data wasn't removed properly. As soon - * as all the tests are cleaned up correctly this has to be (or should be) fixed - */ - if(is_wow64) - ok(!lstrcmpiA(path_wow64, detail->DevicePath), - "Unexpected path %s\n", detail->DevicePath); - else - todo_wine ok(!lstrcmpiA(path, detail->DevicePath) || - !lstrcmpiA(path_w2k, detail->DevicePath), - "Unexpected path %s\n", detail->DevicePath); + ok(!lstrcmpiA(path, detail->DevicePath) || + !lstrcmpiA(path_w10, detail->DevicePath) || + !lstrcmpiA(path_w2k, detail->DevicePath), + "Unexpected path %s\n", detail->DevicePath); HeapFree(GetProcessHeap(), 0, detail); } } + ret = pSetupDiRemoveDeviceInterface(set, &interfaceData); + todo_wine ok(ret, "SetupDiRemoveDeviceInterface failed: %08x\n", GetLastError()); + + ret = pSetupDiRemoveDevice(set, &devInfo); + todo_wine ok(ret, "got %u\n", GetLastError()); + pSetupDiDestroyDeviceInfoList(set); + pSetupDiDestroyDeviceInfoList(set2); - /* Cleanup */ - ret = remove_device(); - if(!is_wow64) - todo_wine ok(ret, "Expected the device to be removed: %08x\n", GetLastError()); - - /* FIXME: Only do the RegDeleteKey, once Wine is fixed */ - if (!ret) - { - /* Wine doesn't delete the information currently */ - trace("We are most likely on Wine\n"); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass); - } - else - { - clean_devclass_key(); - } + /* remove once Wine is fixed */ + devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); + devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, classKey); } static void testDeviceRegistryPropertyA(void) @@ -1258,6 +1055,10 @@ static void testDeviceRegistryPropertyA(void) ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, NULL, (PBYTE)buf, buflen, &size); todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_DATA, + "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError()); + ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_HARDWAREID, + NULL, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError()); pSetupDiDestroyDeviceInfoList(set); @@ -1269,7 +1070,6 @@ static void testDeviceRegistryPropertyA(void) if (res == ERROR_SUCCESS) { /* Wine doesn't delete the information currently */ - trace("We are most likely on Wine\n"); RegDeleteKeyA(HKEY_LOCAL_MACHINE, bogus); } } @@ -1364,6 +1164,10 @@ static void testDeviceRegistryPropertyW(void) ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, NULL, (PBYTE)buf, buflen, &size); todo_wine + ok(!ret && GetLastError() == ERROR_INVALID_DATA, + "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError()); + ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_HARDWAREID, + NULL, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INVALID_DATA, "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError()); pSetupDiDestroyDeviceInfoList(set); @@ -1375,7 +1179,6 @@ static void testDeviceRegistryPropertyW(void) if (res == ERROR_SUCCESS) { /* Wine doesn't delete the information currently */ - trace("We are most likely on Wine\n"); RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus); } } @@ -1462,7 +1265,7 @@ static void testSetupDiGetINFClassA(void) for(i=0; i < sizeof(signatures)/sizeof(char*); i++) { - trace("testing signarture %s\n", signatures[i]); + trace("testing signature %s\n", signatures[i]); h = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(h == INVALID_HANDLE_VALUE) @@ -1580,8 +1383,17 @@ static void testSetupDiGetClassDevsA(void) START_TEST(devinst) { + HKEY hkey; + init_function_pointers(); + if ((hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS)) == INVALID_HANDLE_VALUE) + { + skip("needs admin rights\n"); + return; + } + RegCloseKey(hkey); + if (pIsWow64Process) pIsWow64Process(GetCurrentProcess(), &is_wow64); diff --git a/rostests/winetests/setupapi/install.c b/rostests/winetests/setupapi/install.c index 5be61c076c4..3ca7f26acf4 100644 --- a/rostests/winetests/setupapi/install.c +++ b/rostests/winetests/setupapi/install.c @@ -454,6 +454,14 @@ static void test_profile_items(void) goto cleanup; } + snprintf(path, MAX_PATH, "%s\\TestDir", commonprogs); + if (!CreateDirectoryA(path, NULL) && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("need admin rights\n"); + return; + } + RemoveDirectoryA(path); + create_inf_file(inffile, inf); sprintf(path, "%s\\%s", CURR_DIR, inffile); run_cmdline("DefaultInstall", 128, path); diff --git a/rostests/winetests/setupapi/misc.c b/rostests/winetests/setupapi/misc.c index 04b2171ff82..dbe684bb295 100644 --- a/rostests/winetests/setupapi/misc.c +++ b/rostests/winetests/setupapi/misc.c @@ -231,6 +231,11 @@ static void test_SetupCopyOEMInf(void) strcat(path, tmpfile); SetLastError(0xdeadbeef); res = pSetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, NULL, 0, NULL, NULL); + if (!res && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("SetupCopyOEMInfA() failed on insufficient permissions\n"); + return; + } ok(res == TRUE, "Expected TRUE, got %d\n", res); ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError()); ok(file_exists(path), "Expected source inf to exist\n"); @@ -792,7 +797,7 @@ static void test_SetupLogError(void) ret = SetupOpenLog(FALSE); if (!ret && GetLastError() == ERROR_ACCESS_DENIED) { - win_skip("SetupOpenLog() failed on insufficient permissions\n"); + skip("SetupOpenLog() failed on insufficient permissions\n"); return; } ok(ret, "SetupOpenLog failed, error %d\n", GetLastError()); diff --git a/rostests/winetests/setupapi/query.c b/rostests/winetests/setupapi/query.c index 17c24bfb8c7..6b6d1bd5c29 100644 --- a/rostests/winetests/setupapi/query.c +++ b/rostests/winetests/setupapi/query.c @@ -99,13 +99,16 @@ static const char inf_data6[] = "[CopyAlways.Windir.Files]\n" "WindowsCodecs.dll\n"; -static void create_inf_file(LPSTR filename, const char *data, DWORD size) +static BOOL create_inf_file(LPSTR filename, const char *data, DWORD size) { + BOOL ret; DWORD dwNumberOfBytesWritten; HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - WriteFile(hf, data, size, &dwNumberOfBytesWritten, NULL); + if (hf == INVALID_HANDLE_VALUE) return FALSE; + ret = WriteFile(hf, data, size, &dwNumberOfBytesWritten, NULL); CloseHandle(hf); + return ret; } static BOOL check_info_filename(PSP_INF_INFORMATION info, LPSTR test) @@ -258,7 +261,13 @@ static void test_SetupGetInfInformation(void) lstrcpyA(inf_two, WIN_DIR); lstrcatA(inf_two, "\\system32\\"); lstrcatA(inf_two, "test.inf"); - create_inf_file(inf_two, inf_data1, sizeof(inf_data1) - 1); + ret = create_inf_file(inf_two, inf_data1, sizeof(inf_data1) - 1); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("need admin rights\n"); + goto done; + } + ok(ret, "can't create inf file %u\n", GetLastError()); HeapFree(GetProcessHeap(), 0, info); info = alloc_inf_info("test.inf", INFINFO_DEFAULT_SEARCH, &size); @@ -291,8 +300,8 @@ static void test_SetupGetInfInformation(void) ok(ret == TRUE, "Expected SetupGetInfInformation to succeed\n"); ok(check_info_filename(info, revfile), "Expected returned filename to be equal\n"); +done: HeapFree(GetProcessHeap(), 0, info); - DeleteFileA(inf_filename); DeleteFileA(inf_one); DeleteFileA(inf_two); diff --git a/rostests/winetests/setupapi/setupcab.c b/rostests/winetests/setupapi/setupcab.c index 33daae922b6..f2528865aa8 100644 --- a/rostests/winetests/setupapi/setupcab.c +++ b/rostests/winetests/setupapi/setupcab.c @@ -299,30 +299,49 @@ static void test_invalid_callbackW(void) static const char *expected_files[] = {"tristram", "wine", "shandy"}; +struct contextA +{ + int count; + const char *cabinet; + const char *target; +}; + static UINT CALLBACK simple_callbackA(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2) { static int index; - int *file_count = Context; + struct contextA *ctx = Context; switch (Notification) { case SPFILENOTIFY_CABINETINFO: + { + CABINET_INFO_A *info = (CABINET_INFO_A *)Param1; + + ok(!strcmp(info->CabinetFile, ""), + "Expected empty CabinetFile, got \"%s\"\n", info->CabinetFile); + index = 0; return NO_ERROR; + } case SPFILENOTIFY_FILEINCABINET: { FILE_IN_CABINET_INFO_A *info = (FILE_IN_CABINET_INFO_A *)Param1; + const char *cabinet_file = (const char *)Param2; - (*file_count)++; + ctx->count++; if (index < sizeof(expected_files)/sizeof(char *)) { ok(!strcmp(expected_files[index], info->NameInCabinet), "[%d] Expected file \"%s\", got \"%s\"\n", index, expected_files[index], info->NameInCabinet); - index++; - return FILEOP_SKIP; + ok(!strcmp(ctx->cabinet, cabinet_file), + "[%d] Expected cabinet \"%s\", got \"%s\"\n", + index, ctx->cabinet, cabinet_file); + + strcpy(info->FullTargetName, ctx->target); + return FILEOP_DOIT; } else { @@ -330,6 +349,23 @@ static UINT CALLBACK simple_callbackA(PVOID Context, UINT Notification, return FILEOP_ABORT; } } + case SPFILENOTIFY_FILEEXTRACTED: + { + FILEPATHS_A *info = (FILEPATHS_A *)Param1; + + ok(!strcmp(ctx->cabinet, info->Source), + "[%d] Expected cabinet \"%s\", got \"%s\"\n", + index, ctx->cabinet, info->Source); + ok(!strcmp(ctx->target, info->Target), + "[%d] Expected target \"%s\", got \"%s\"\n", + index, ctx->target, info->Target); + ok(info->Win32Error == 0, + "[%d] Expected Win32Error 0, got %u\n", + index, info->Win32Error); + + index++; + return NO_ERROR; + } default: return NO_ERROR; } @@ -339,19 +375,25 @@ static void test_simple_enumerationA(void) { BOOL ret; char source[MAX_PATH], temp[MAX_PATH]; - int enum_count = 0; + char target[MAX_PATH]; + struct contextA ctx; GetTempPathA(sizeof(temp), temp); GetTempFileNameA(temp, "doc", 0, source); + GetTempFileNameA(temp, "doc", 0, target); create_source_fileA(source, comp_cab_zip_multi, sizeof(comp_cab_zip_multi)); - ret = SetupIterateCabinetA(source, 0, simple_callbackA, &enum_count); + ctx.count = 0; + ctx.cabinet = source; + ctx.target = target; + ret = SetupIterateCabinetA(source, 0, simple_callbackA, &ctx); ok(ret == 1, "Expected SetupIterateCabinetA to return 1, got %d\n", ret); - ok(enum_count == sizeof(expected_files)/sizeof(char *), - "Unexpectedly enumerated %d files\n", enum_count); + ok(ctx.count == sizeof(expected_files)/sizeof(char *), + "Unexpectedly enumerated %d files\n", ctx.count); DeleteFileA(source); + DeleteFileA(target); } static const WCHAR tristramW[] = {'t','r','i','s','t','r','a','m',0}; @@ -359,30 +401,50 @@ static const WCHAR wineW[] = {'w','i','n','e',0}; static const WCHAR shandyW[] = {'s','h','a','n','d','y',0}; static const WCHAR *expected_filesW[] = {tristramW, wineW, shandyW}; +struct contextW +{ + int count; + const WCHAR *cabinet; + const WCHAR *target; +}; + static UINT CALLBACK simple_callbackW(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2) { + static const WCHAR emptyW[] = {0}; static int index; - int *file_count = Context; + struct contextW *ctx = Context; switch (Notification) { case SPFILENOTIFY_CABINETINFO: + { + CABINET_INFO_W *info = (CABINET_INFO_W *)Param1; + + ok(!lstrcmpW(info->CabinetFile, emptyW), + "Expected empty CabinetFile, got %s\n", wine_dbgstr_w(info->CabinetFile)); + index = 0; return NO_ERROR; + } case SPFILENOTIFY_FILEINCABINET: { FILE_IN_CABINET_INFO_W *info = (FILE_IN_CABINET_INFO_W *)Param1; + const WCHAR *cabinet_file = (const WCHAR *)Param2; - (*file_count)++; + ctx->count++; if (index < sizeof(expected_filesW)/sizeof(WCHAR *)) { ok(!lstrcmpW(expected_filesW[index], info->NameInCabinet), "[%d] Expected file %s, got %s\n", index, wine_dbgstr_w(expected_filesW[index]), wine_dbgstr_w(info->NameInCabinet)); - index++; - return FILEOP_SKIP; + ok(!lstrcmpW(ctx->cabinet, cabinet_file), + "[%d] Expected cabinet %s, got %s\n", + index, wine_dbgstr_w(ctx->cabinet), wine_dbgstr_w(cabinet_file)); + + lstrcpyW(info->FullTargetName, ctx->target); + return FILEOP_DOIT; } else { @@ -390,6 +452,23 @@ static UINT CALLBACK simple_callbackW(PVOID Context, UINT Notification, return FILEOP_ABORT; } } + case SPFILENOTIFY_FILEEXTRACTED: + { + FILEPATHS_W *info = (FILEPATHS_W *)Param1; + + ok(!lstrcmpW(ctx->cabinet, info->Source), + "[%d] Expected cabinet %s, got %s\n", + index, wine_dbgstr_w(ctx->cabinet), wine_dbgstr_w(info->Source)); + ok(!lstrcmpW(ctx->target, info->Target), + "[%d] Expected target %s, got %s\n", + index, wine_dbgstr_w(ctx->target), wine_dbgstr_w(info->Target)); + ok(info->Win32Error == 0, + "[%d] Expected Win32Error 0, got %u\n", + index, info->Win32Error); + + index++; + return NO_ERROR; + } default: return NO_ERROR; } @@ -399,7 +478,8 @@ static void test_simple_enumerationW(void) { BOOL ret; WCHAR source[MAX_PATH], temp[MAX_PATH]; - int enum_count = 0; + WCHAR target[MAX_PATH]; + struct contextW ctx; ret = SetupIterateCabinetW(NULL, 0, NULL, NULL); if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) @@ -410,15 +490,20 @@ static void test_simple_enumerationW(void) GetTempPathW(sizeof(temp)/sizeof(WCHAR), temp); GetTempFileNameW(temp, docW, 0, source); + GetTempFileNameW(temp, docW, 0, target); create_source_fileW(source, comp_cab_zip_multi, sizeof(comp_cab_zip_multi)); - ret = SetupIterateCabinetW(source, 0, simple_callbackW, &enum_count); + ctx.count = 0; + ctx.cabinet = source; + ctx.target = target; + ret = SetupIterateCabinetW(source, 0, simple_callbackW, &ctx); ok(ret == 1, "Expected SetupIterateCabinetW to return 1, got %d\n", ret); - ok(enum_count == sizeof(expected_files)/sizeof(WCHAR *), - "Unexpectedly enumerated %d files\n", enum_count); + ok(ctx.count == sizeof(expected_files)/sizeof(WCHAR *), + "Unexpectedly enumerated %d files\n", ctx.count); DeleteFileW(source); + DeleteFileW(target); } START_TEST(setupcab)