ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
February 2019
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
23 participants
208 discussions
Start a n
N
ew thread
[reactos] 01/01: [SHDOCVW_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=138051c0bec144f8114c7…
commit 138051c0bec144f8114c7516127bfc165b7d4145 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:16:27 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:16:27 2019 +0100 [SHDOCVW_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/shdocvw/shdocvw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/rostests/winetests/shdocvw/shdocvw.c b/modules/rostests/winetests/shdocvw/shdocvw.c index cdf1814f6d..167fcf1a92 100644 --- a/modules/rostests/winetests/shdocvw/shdocvw.c +++ b/modules/rostests/winetests/shdocvw/shdocvw.c @@ -207,7 +207,7 @@ static void test_ParseURLFromOutsideSourceA(void) return; } - for(i = 0; i < sizeof(ParseURL_table)/sizeof(ParseURL_table[0]); i++) { + for(i = 0; i < ARRAY_SIZE(ParseURL_table); i++) { memset(buffer, '#', sizeof(buffer)-1); buffer[sizeof(buffer)-1] = '\0'; len = sizeof(buffer); @@ -306,7 +306,7 @@ static void test_ParseURLFromOutsideSourceW(void) MultiByteToWideChar(CP_ACP, 0, bufferA, -1, bufferW, INTERNET_MAX_URL_LENGTH); /* len is in characters */ - len = sizeof(bufferW)/sizeof(bufferW[0]); + len = ARRAY_SIZE(bufferW); dummy = 0; /* on success, 1 is returned for unicode version */ res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
5 years, 10 months
1
0
0
0
[reactos] 01/01: [SHDOCVW] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=876fef085a9929ad8306c…
commit 876fef085a9929ad8306cd7d2dc7eac53e060735 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:16:02 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:16:02 2019 +0100 [SHDOCVW] Sync with Wine Staging 4.0. CORE-15682 --- dll/win32/shdocvw/shdocvw_main.c | 6 +++--- dll/win32/shdocvw/shlinstobj.c | 4 ++-- media/doc/README.WINE | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dll/win32/shdocvw/shdocvw_main.c b/dll/win32/shdocvw/shdocvw_main.c index ef9e3a7dfb..e699b4c2c9 100644 --- a/dll/win32/shdocvw/shdocvw_main.c +++ b/dll/win32/shdocvw/shdocvw_main.c @@ -385,7 +385,7 @@ DWORD WINAPI ParseURLFromOutsideSourceW(LPCWSTR url, LPWSTR out, LPDWORD plen, L plen ? *plen : 0, unknown ? *unknown : 0); if (!PathIsURLW(ptr)) { - len = sizeof(buffer_in) / sizeof(buffer_in[0]); + len = ARRAY_SIZE(buffer_in); buffer_in[0] = 0; hr = UrlApplySchemeW(ptr, buffer_in, &len, URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT); TRACE("got 0x%x with %s\n", hr, debugstr_w(buffer_in)); @@ -399,7 +399,7 @@ DWORD WINAPI ParseURLFromOutsideSourceW(LPCWSTR url, LPWSTR out, LPDWORD plen, L } } - len = sizeof(buffer_out) / sizeof(buffer_out[0]); + len = ARRAY_SIZE(buffer_out); buffer_out[0] = '\0'; hr = UrlCanonicalizeW(ptr, buffer_out, &len, URL_ESCAPE_SPACES_ONLY); needed = lstrlenW(buffer_out)+1; @@ -443,7 +443,7 @@ DWORD WINAPI ParseURLFromOutsideSourceA(LPCSTR url, LPSTR out, LPDWORD plen, LPD MultiByteToWideChar(CP_ACP, 0, url, -1, urlW, len); } - len = sizeof(buffer) / sizeof(buffer[0]); + len = ARRAY_SIZE(buffer); ParseURLFromOutsideSourceW(urlW, buffer, &len, unknown); HeapFree(GetProcessHeap(), 0, urlW); diff --git a/dll/win32/shdocvw/shlinstobj.c b/dll/win32/shdocvw/shlinstobj.c index 9c3232c65e..6f6786bdb5 100644 --- a/dll/win32/shdocvw/shlinstobj.c +++ b/dll/win32/shdocvw/shlinstobj.c @@ -361,8 +361,8 @@ HRESULT SHDOCVW_GetShellInstanceObjectClassObject(REFCLSID rclsid, REFIID riid, WCHAR wszInstanceKey[] = { 'C','L','S','I','D','\\','{','0','0','0','0','0','0','0','0','-', '0','0','0','0','-','0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0', '0','0','0','0','}','\\','I','n','s','t','a','n','c','e', 0 }; - const WCHAR wszCLSID[] = { 'C','L','S','I','D',0 }; - const WCHAR wszInitPropertyBag[] = + static const WCHAR wszCLSID[] = { 'C','L','S','I','D',0 }; + static const WCHAR wszInitPropertyBag[] = { 'I','n','i','t','P','r','o','p','e','r','t','y','B','a','g',0 }; WCHAR wszCLSIDInstance[CHARS_IN_GUID]; CLSID clsidInstance; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 6f654787d8..859ae5a226 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -171,7 +171,7 @@ reactos/dll/win32/security # Forked (different .spec) reactos/dll/win32/sensapi # Synced to WineStaging-3.3 reactos/dll/win32/setupapi # Forked at Wine-20050524 reactos/dll/win32/shdoclc # Synced to WineStaging-3.3 -reactos/dll/win32/shdocvw # Synced to WineStaging-3.3 +reactos/dll/win32/shdocvw # Synced to WineStaging-4.0 reactos/dll/win32/shell32 # Forked at Wine-20071011 reactos/dll/win32/shfolder # Synced to WineStaging-3.3 reactos/dll/win32/shlwapi # Synced to WineStaging-3.3
5 years, 10 months
1
0
0
0
[reactos] 01/01: [SETUPAPI_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6828353ace28e8526f7d3…
commit 6828353ace28e8526f7d34d2f376da250013e6b5 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:15:35 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:15:35 2019 +0100 [SETUPAPI_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/setupapi/CMakeLists.txt | 1 + modules/rostests/winetests/setupapi/devinst.c | 1854 ++++++++++---------- modules/rostests/winetests/setupapi/install.c | 40 + modules/rostests/winetests/setupapi/misc.c | 4 +- modules/rostests/winetests/setupapi/parser.c | 16 +- modules/rostests/winetests/setupapi/setupcab.c | 20 +- 6 files changed, 979 insertions(+), 956 deletions(-) diff --git a/modules/rostests/winetests/setupapi/CMakeLists.txt b/modules/rostests/winetests/setupapi/CMakeLists.txt index 341ffe85fa..4f301cc08c 100644 --- a/modules/rostests/winetests/setupapi/CMakeLists.txt +++ b/modules/rostests/winetests/setupapi/CMakeLists.txt @@ -13,5 +13,6 @@ list(APPEND SOURCE add_executable(setupapi_winetest ${SOURCE} setupapi.rc) set_module_type(setupapi_winetest win32cui) +target_link_libraries(setupapi_winetest uuid) add_importlibs(setupapi_winetest advapi32 setupapi user32 shell32 msvcrt kernel32 ntdll) add_rostests_file(TARGET setupapi_winetest) diff --git a/modules/rostests/winetests/setupapi/devinst.c b/modules/rostests/winetests/setupapi/devinst.c index bdf664aadf..ba0481744b 100644 --- a/modules/rostests/winetests/setupapi/devinst.c +++ b/modules/rostests/winetests/setupapi/devinst.c @@ -28,76 +28,18 @@ #include "winreg.h" #include "guiddef.h" #include "setupapi.h" +#include "cfgmgr32.h" +#include "wine/heap.h" #include "wine/test.h" -static BOOL is_wow64; - -/* function pointers */ -static HDEVINFO (WINAPI *pSetupDiCreateDeviceInfoList)(GUID*,HWND); -static HDEVINFO (WINAPI *pSetupDiCreateDeviceInfoListExW)(GUID*,HWND,PCWSTR,PVOID); -static BOOL (WINAPI *pSetupDiCreateDeviceInterfaceA)(HDEVINFO, PSP_DEVINFO_DATA, const GUID *, PCSTR, DWORD, PSP_DEVICE_INTERFACE_DATA); -static BOOL (WINAPI *pSetupDiCallClassInstaller)(DI_FUNCTION, HDEVINFO, PSP_DEVINFO_DATA); -static BOOL (WINAPI *pSetupDiDestroyDeviceInfoList)(HDEVINFO); -static BOOL (WINAPI *pSetupDiEnumDeviceInfo)(HDEVINFO, DWORD, PSP_DEVINFO_DATA); -static BOOL (WINAPI *pSetupDiEnumDeviceInterfaces)(HDEVINFO, PSP_DEVINFO_DATA, const GUID *, DWORD, PSP_DEVICE_INTERFACE_DATA); -static BOOL (WINAPI *pSetupDiGetINFClassA)(PCSTR, LPGUID, PSTR, DWORD, PDWORD); -static BOOL (WINAPI *pSetupDiInstallClassA)(HWND, PCSTR, DWORD, HSPFILEQ); -static HKEY (WINAPI *pSetupDiOpenClassRegKeyExA)(GUID*,REGSAM,DWORD,PCSTR,PVOID); -static HKEY (WINAPI *pSetupDiOpenDevRegKey)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM); -static HKEY (WINAPI *pSetupDiCreateDevRegKeyW)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, HINF, PCWSTR); -static BOOL (WINAPI *pSetupDiCreateDeviceInfoA)(HDEVINFO, PCSTR, GUID *, PCSTR, HWND, DWORD, PSP_DEVINFO_DATA); -static BOOL (WINAPI *pSetupDiCreateDeviceInfoW)(HDEVINFO, PCWSTR, GUID *, PCWSTR, HWND, DWORD, PSP_DEVINFO_DATA); -static BOOL (WINAPI *pSetupDiGetDeviceInstanceIdA)(HDEVINFO, PSP_DEVINFO_DATA, PSTR, DWORD, PDWORD); -static BOOL (WINAPI *pSetupDiGetDeviceInterfaceDetailA)(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA); -static BOOL (WINAPI *pSetupDiGetDeviceInterfaceDetailW)(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA_W, DWORD, PDWORD, PSP_DEVINFO_DATA); -static BOOL (WINAPI *pSetupDiRegisterDeviceInfo)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PSP_DETSIG_CMPPROC, PVOID, PSP_DEVINFO_DATA); -static HDEVINFO (WINAPI *pSetupDiGetClassDevsA)(const GUID *, LPCSTR, HWND, DWORD); -static HDEVINFO (WINAPI *pSetupDiGetClassDevsW)(const GUID *, LPCWSTR, HWND, DWORD); -static BOOL (WINAPI *pSetupDiSetDeviceRegistryPropertyA)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const BYTE *, DWORD); -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); +#ifdef __REACTOS__ +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); +#endif /* This is a unique guid for testing purposes */ static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}}; - -static void init_function_pointers(void) -{ - HMODULE hSetupAPI = GetModuleHandleA("setupapi.dll"); - HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); - - pSetupDiCreateDeviceInfoA = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoA"); - pSetupDiCreateDeviceInfoW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoW"); - pSetupDiCreateDeviceInfoList = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoList"); - pSetupDiCreateDeviceInfoListExW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoListExW"); - pSetupDiCreateDeviceInterfaceA = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInterfaceA"); - pSetupDiDestroyDeviceInfoList = (void *)GetProcAddress(hSetupAPI, "SetupDiDestroyDeviceInfoList"); - pSetupDiCallClassInstaller = (void *)GetProcAddress(hSetupAPI, "SetupDiCallClassInstaller"); - pSetupDiEnumDeviceInfo = (void *)GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInfo"); - pSetupDiEnumDeviceInterfaces = (void *)GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInterfaces"); - pSetupDiGetDeviceInstanceIdA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceInstanceIdA"); - pSetupDiGetDeviceInterfaceDetailA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceInterfaceDetailA"); - pSetupDiGetDeviceInterfaceDetailW = (void *)GetProcAddress(hSetupAPI, "SetupDiGetDeviceInterfaceDetailW"); - pSetupDiInstallClassA = (void *)GetProcAddress(hSetupAPI, "SetupDiInstallClassA"); - pSetupDiOpenClassRegKeyExA = (void *)GetProcAddress(hSetupAPI, "SetupDiOpenClassRegKeyExA"); - pSetupDiOpenDevRegKey = (void *)GetProcAddress(hSetupAPI, "SetupDiOpenDevRegKey"); - pSetupDiCreateDevRegKeyW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDevRegKeyW"); - pSetupDiRegisterDeviceInfo = (void *)GetProcAddress(hSetupAPI, "SetupDiRegisterDeviceInfo"); - pSetupDiGetClassDevsA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetClassDevsA"); - pSetupDiGetClassDevsW = (void *)GetProcAddress(hSetupAPI, "SetupDiGetClassDevsW"); - pSetupDiGetINFClassA = (void *)GetProcAddress(hSetupAPI, "SetupDiGetINFClassA"); - pSetupDiSetDeviceRegistryPropertyA = (void *)GetProcAddress(hSetupAPI, "SetupDiSetDeviceRegistryPropertyA"); - 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 GUID guid2 = {0x6a55b5a5, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}}; static LSTATUS devinst_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) { @@ -121,7 +63,7 @@ static LSTATUS devinst_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) dwMaxSubkeyLen++; dwMaxValueLen++; dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); - if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR)) + if (dwMaxLen > ARRAY_SIZE(szNameBuf)) { /* Name too big: alloc a buffer for it */ if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR)))) @@ -165,95 +107,66 @@ cleanup: return ret; } -static void test_SetupDiCreateDeviceInfoListEx(void) +static void test_create_device_list_ex(void) { - HDEVINFO devlist; - BOOL ret; - DWORD error; - static CHAR notnull[] = "NotNull"; static const WCHAR machine[] = { 'd','u','m','m','y',0 }; static const WCHAR empty[] = { 0 }; + static char notnull[] = "NotNull"; + HDEVINFO set; + BOOL ret; SetLastError(0xdeadbeef); - /* create empty DeviceInfoList, but set Reserved to a value, which is not NULL */ - devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, notnull); - - error = GetLastError(); - if (error == ERROR_CALL_NOT_IMPLEMENTED) - { - win_skip("SetupDiCreateDeviceInfoListExW is not implemented\n"); - return; - } - ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE); - ok(error == ERROR_INVALID_PARAMETER, "GetLastError returned wrong value : %d, (expected %d)\n", error, ERROR_INVALID_PARAMETER); + set = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, notnull); + ok(set == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); SetLastError(0xdeadbeef); - /* create empty DeviceInfoList, but set MachineName to something */ - devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, machine, NULL); + set = SetupDiCreateDeviceInfoListExW(NULL, NULL, machine, NULL); + ok(set == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_MACHINENAME + || GetLastError() == ERROR_MACHINE_UNAVAILABLE + || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, + "Got unexpected error %#x.\n", GetLastError()); - error = GetLastError(); - if (error == ERROR_CALL_NOT_IMPLEMENTED) - { - /* win10 reports ERROR_CALL_NOT_IMPLEMENTED at first here */ - win_skip("SetupDiCreateDeviceInfoListExW is not implemented\n"); - return; - } - ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE); - ok(error == ERROR_INVALID_MACHINENAME || error == ERROR_MACHINE_UNAVAILABLE, "GetLastError returned wrong value : %d, (expected %d or %d)\n", error, ERROR_INVALID_MACHINENAME, ERROR_MACHINE_UNAVAILABLE); - - /* create empty DeviceInfoList */ - devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); - ok(devlist && devlist != INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected != %p)\n", devlist, error, INVALID_HANDLE_VALUE); + set = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.", GetLastError()); - /* destroy DeviceInfoList */ - ret = pSetupDiDestroyDeviceInfoList(devlist); - ok(ret, "SetupDiDestroyDeviceInfoList failed : %d\n", error); + ret = SetupDiDestroyDeviceInfoList(set); + ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError()); - /* create empty DeviceInfoList with empty machine name */ - devlist = pSetupDiCreateDeviceInfoListExW(NULL, NULL, empty, NULL); - ok(devlist && devlist != INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %d (expected != %p)\n", devlist, error, INVALID_HANDLE_VALUE); + set = SetupDiCreateDeviceInfoListExW(NULL, NULL, empty, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.", GetLastError()); - /* destroy DeviceInfoList */ - ret = pSetupDiDestroyDeviceInfoList(devlist); - ok(ret, "SetupDiDestroyDeviceInfoList failed : %d\n", error); + ret = SetupDiDestroyDeviceInfoList(set); + ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError()); } -static void test_SetupDiOpenClassRegKeyExA(void) +static void test_open_class_key(void) { - static const CHAR guidString[] = "{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; - HKEY hkey; + static const char guidstr[] = "{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; + HKEY root_key, class_key; + LONG res; - /* Check return value for nonexistent key */ - hkey = pSetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS, - DIOCR_INSTALLER, NULL, NULL); - ok(hkey == INVALID_HANDLE_VALUE, - "returned %p (expected INVALID_HANDLE_VALUE)\n", hkey); + SetLastError(0xdeadbeef); + class_key = SetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS, DIOCR_INSTALLER, NULL, NULL); + ok(class_key == INVALID_HANDLE_VALUE, "Expected failure.\n"); +todo_wine + ok(GetLastError() == ERROR_INVALID_CLASS, "Got unexpected error %#x.\n", GetLastError()); - /* Test it for a key that exists */ - hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS); - if (hkey != INVALID_HANDLE_VALUE) - { - HKEY classKey; - if (RegCreateKeyA(hkey, guidString, &classKey) == ERROR_SUCCESS) - { - RegCloseKey(classKey); - SetLastError(0xdeadbeef); - classKey = pSetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS, - DIOCR_INSTALLER, NULL, NULL); - ok(classKey != INVALID_HANDLE_VALUE, - "opening class registry key failed with error %d\n", - GetLastError()); - if (classKey != INVALID_HANDLE_VALUE) - RegCloseKey(classKey); - RegDeleteKeyA(hkey, guidString); - } - else - trace("failed to create registry key for test\n"); + root_key = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS); + ok(root_key != INVALID_HANDLE_VALUE, "Failed to open root key, error %#x.\n", GetLastError()); - RegCloseKey(hkey); - } - else - trace("failed to open classes key %u\n", GetLastError()); + res = RegCreateKeyA(root_key, guidstr, &class_key); + ok(!res, "Failed to create class key, error %#x.\n", GetLastError()); + RegCloseKey(class_key); + + SetLastError(0xdeadbeef); + class_key = SetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS, DIOCR_INSTALLER, NULL, NULL); + ok(class_key != INVALID_HANDLE_VALUE, "Failed to open class key, error %#x.\n", GetLastError()); + RegCloseKey(class_key); + + RegDeleteKeyA(root_key, guidstr); + RegCloseKey(root_key); } static void create_inf_file(LPCSTR filename) @@ -290,7 +203,7 @@ static void get_temp_filename(LPSTR path) lstrcpyA(path, ptr + 1); } -static void testInstallClass(void) +static void test_install_class(void) { 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','\\', @@ -306,568 +219,555 @@ static void testInstallClass(void) get_temp_filename(tmpfile + 2); create_inf_file(tmpfile + 2); - ret = pSetupDiInstallClassA(NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - ret = pSetupDiInstallClassA(NULL, NULL, DI_NOVCP, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - ret = pSetupDiInstallClassA(NULL, tmpfile + 2, DI_NOVCP, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - ret = pSetupDiInstallClassA(NULL, tmpfile + 2, 0, NULL); - ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError()); + ret = SetupDiInstallClassA(NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiInstallClassA(NULL, NULL, DI_NOVCP, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiInstallClassA(NULL, tmpfile + 2, DI_NOVCP, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiInstallClassA(NULL, tmpfile + 2, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got unexpected error %#x.\n", GetLastError()); + /* The next call will succeed. Information is put into the registry but the * location(s) is/are depending on the Windows version. */ - ret = pSetupDiInstallClassA(NULL, tmpfile, 0, NULL); - ok(ret, "SetupDiInstallClassA failed: %08x\n", GetLastError()); - - ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, classKey), - "Couldn't delete classkey\n"); + ret = SetupDiInstallClassA(NULL, tmpfile, 0, NULL); + ok(ret, "Failed to install class, error %#x.\n", GetLastError()); + ok(!RegDeleteKeyW(HKEY_LOCAL_MACHINE, classKey), "Failed to delete class key, error %u.\n", GetLastError()); DeleteFileA(tmpfile); } -static void testCreateDeviceInfo(void) +static void check_device_info_(int line, HDEVINFO set, int index, const GUID *class, const char *expect_id) { + SP_DEVINFO_DATA device = {sizeof(device)}; + char id[50]; BOOL ret; - HDEVINFO set; - - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoA(NULL, NULL, NULL, NULL, NULL, 0, NULL); - ok(!ret, "Expected failure\n"); - ok(GetLastError() == ERROR_INVALID_DEVINST_NAME || - GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, - "Unexpected last error, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoA(NULL, "Root\\LEGACY_BOGUS\\0000", NULL, - NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLEHANDLE, got %08x\n", GetLastError()); - set = pSetupDiCreateDeviceInfoList(&guid, NULL); - ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %08x\n", - GetLastError()); - if (set) + ret = SetupDiEnumDeviceInfo(set, index, &device); + if (expect_id) { - SP_DEVINFO_DATA devInfo = { 0 }; - DWORD i; - static GUID deadbeef = - {0xdeadbeef, 0xdead, 0xbeef, {0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}}; - - /* No GUID given */ - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", NULL, - NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - - /* 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()); - - /* Finally, with all three required parameters, this succeeds: */ - ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, - NULL, NULL, 0, NULL); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - /* This fails because the device ID already exists.. */ - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, - NULL, NULL, 0, &devInfo); - ok(!ret && GetLastError() == ERROR_DEVINST_ALREADY_EXISTS, - "Expected ERROR_DEVINST_ALREADY_EXISTS, got %08x\n", GetLastError()); - /* whereas this "fails" because cbSize is wrong.. */ - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, - DICD_GENERATE_ID, &devInfo); - ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, - "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError()); - /* and this finally succeeds. */ - devInfo.cbSize = sizeof(devInfo); - ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, - DICD_GENERATE_ID, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - /* There were three devices added, however - the second failure just - * resulted in the SP_DEVINFO_DATA not getting copied. - */ - SetLastError(0xdeadbeef); - i = 0; - while (pSetupDiEnumDeviceInfo(set, i, &devInfo)) - i++; - 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); + ok_(__FILE__, line)(ret, "Got unexpected error %#x.\n", GetLastError()); + ok_(__FILE__, line)(IsEqualGUID(&device.ClassGuid, class), + "Got unexpected class %s.\n", wine_dbgstr_guid(&device.ClassGuid)); + ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL); + ok_(__FILE__, line)(ret, "Got unexpected error %#x.\n", GetLastError()); + ok_(__FILE__, line)(!strcasecmp(id, expect_id), "Got unexpected id %s.\n", id); + } + else + { + ok_(__FILE__, line)(!ret, "Expected failure.\n"); + ok_(__FILE__, line)(GetLastError() == ERROR_NO_MORE_ITEMS, + "Got unexpected error %#x.\n", GetLastError()); } } +#define check_device_info(a,b,c,d) check_device_info_(__LINE__,a,b,c,d) -static void testGetDeviceInstanceId(void) +static void test_device_info(void) { - BOOL ret; + static const GUID deadbeef = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}}; + SP_DEVINFO_DATA device = {0}, ret_device = {sizeof(ret_device)}; + char id[MAX_DEVICE_ID_LEN + 2]; HDEVINFO set; - SP_DEVINFO_DATA devInfo = { 0 }; + BOOL ret; SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInstanceIdA(NULL, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); + ret = SetupDiCreateDeviceInfoA(NULL, NULL, NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DEVINST_NAME, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInstanceIdA(NULL, &devInfo, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); - set = pSetupDiCreateDeviceInfoList(&guid, NULL); - ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %08x\n", - GetLastError()); - if (set) - { - char instanceID[MAX_PATH]; - DWORD size; + ret = SetupDiCreateDeviceInfoA(NULL, "Root\\LEGACY_BOGUS\\0000", NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInstanceIdA(set, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - devInfo.cbSize = sizeof(devInfo); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); - ret = pSetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, - NULL, NULL, 0, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError()); - ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, instanceID, - sizeof(instanceID), NULL); - ok(ret, "SetupDiGetDeviceInstanceIdA failed: %08x\n", GetLastError()); - ok(!lstrcmpA(instanceID, "ROOT\\LEGACY_BOGUS\\0000"), - "Unexpected instance ID %s\n", instanceID); - ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, - NULL, NULL, DICD_GENERATE_ID, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - ret = pSetupDiGetDeviceInstanceIdA(set, &devInfo, instanceID, - sizeof(instanceID), NULL); - ok(ret, "SetupDiGetDeviceInstanceIdA failed: %08x\n", GetLastError()); - /* 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); - } + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device info, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &deadbeef, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_CLASS_MISMATCH, "Got unexpected error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &GUID_NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_CLASS_MISMATCH, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, NULL); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0000"); + check_device_info(set, 1, &guid, NULL); + + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_DEVINST_ALREADY_EXISTS, "Got unexpected error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &device); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0000"); + check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\0001"); + check_device_info(set, 2, &guid, NULL); + + device.cbSize = sizeof(device); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0002", &guid, NULL, NULL, 0, &device); + ok(ret, "Got unexpected error %#x.\n", GetLastError()); + ok(IsEqualGUID(&device.ClassGuid, &guid), "Got unexpected class %s.\n", + wine_dbgstr_guid(&device.ClassGuid)); + ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL); + ok(ret, "Got unexpected error %#x.\n", GetLastError()); + ok(!strcmp(id, "ROOT\\LEGACY_BOGUS\\0002"), "Got unexpected id %s.\n", id); + + check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0000"); + check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\0001"); + check_device_info(set, 2, &guid, "ROOT\\LEGACY_BOGUS\\0002"); + check_device_info(set, 3, &guid, NULL); + + ret = SetupDiEnumDeviceInfo(set, 0, &ret_device); + ok(ret, "Failed to enumerate devices, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInfo(set, &ret_device); + ok(ret, "Failed to delete device, error %#x.\n", GetLastError()); + + check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0001"); + check_device_info(set, 1, &guid, "ROOT\\LEGACY_BOGUS\\0002"); + check_device_info(set, 2, &guid, NULL); + + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Got unexpected error %#x.\n", GetLastError()); + + check_device_info(set, 0, &guid, "ROOT\\LEGACY_BOGUS\\0001"); + + ret = SetupDiEnumDeviceInfo(set, 1, &ret_device); + ok(ret, "Got unexpected error %#x.\n", GetLastError()); + ok(IsEqualGUID(&ret_device.ClassGuid, &guid), "Got unexpected class %s.\n", + wine_dbgstr_guid(&ret_device.ClassGuid)); + ret = SetupDiGetDeviceInstanceIdA(set, &ret_device, id, sizeof(id), NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_NO_SUCH_DEVINST, "Got unexpected error %#x.\n", GetLastError()); + ok(ret_device.DevInst == device.DevInst, "Expected device node %#x, got %#x.\n", + device.DevInst, ret_device.DevInst); + + check_device_info(set, 2, &guid, NULL); + + SetupDiDestroyDeviceInfoList(set); + + set = SetupDiCreateDeviceInfoList(NULL, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device info, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\deadbeef", &deadbeef, NULL, NULL, 0, NULL); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\null", &GUID_NULL, NULL, NULL, 0, NULL); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\testguid", &guid, NULL, NULL, 0, NULL); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + check_device_info(set, 0, &deadbeef, "ROOT\\LEGACY_BOGUS\\deadbeef"); + check_device_info(set, 1, &GUID_NULL, "ROOT\\LEGACY_BOGUS\\null"); + check_device_info(set, 2, &guid, "ROOT\\LEGACY_BOGUS\\testguid"); + check_device_info(set, 3, NULL, NULL); + + memset(id, 'x', sizeof(id)); + memcpy(id, "Root\\LEGACY_BOGUS\\", strlen("Root\\LEGACY_BOGUS\\")); + id[MAX_DEVICE_ID_LEN + 1] = 0; + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, id, &guid, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DEVINST_NAME, "Got unexpected error %#x.\n", GetLastError()); + + id[MAX_DEVICE_ID_LEN] = 0; + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInfoA(set, id, &guid, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DEVINST_NAME, "Got unexpected error %#x.\n", GetLastError()); + + id[MAX_DEVICE_ID_LEN - 1] = 0; + ret = SetupDiCreateDeviceInfoA(set, id, &guid, NULL, NULL, 0, NULL); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + SetupDiDestroyDeviceInfoList(set); } -static void testRegisterDeviceInfo(void) +static void test_get_device_instance_id(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; + SP_DEVINFO_DATA device = {0}; + char id[200]; + DWORD size; SetLastError(0xdeadbeef); - ret = pSetupDiRegisterDeviceInfo(NULL, NULL, 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); - set = pSetupDiCreateDeviceInfoList(&guid, NULL); - ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError()); - if (set) - { - SP_DEVINFO_DATA devInfo = { 0 }; + ret = SetupDiGetDeviceInstanceIdA(NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiRegisterDeviceInfo(set, NULL, 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - devInfo.cbSize = sizeof(devInfo); - SetLastError(0xdeadbeef); - ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInstanceIdA(NULL, &device, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); - ret = pSetupDiCreateDeviceInfoA(set, "USB\\BOGUS\\0000", &guid, - NULL, NULL, 0, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); - ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); - ok(ret, "SetupDiRegisterDeviceInfo failed: %d\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInstanceIdA(set, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); - ret = pSetupDiRemoveDevice(set, &devInfo); - todo_wine ok(ret, "got %u\n", GetLastError()); - pSetupDiDestroyDeviceInfoList(set); + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); - /* remove once Wine is fixed */ - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); - } + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + device.cbSize = sizeof(device); + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInstanceIdA(set, &device, NULL, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL); + ok(ret, "Failed to get device id, error %#x.\n", GetLastError()); + ok(!strcmp(id, "ROOT\\LEGACY_BOGUS\\0000"), "Got unexpected id %s.\n", id); + + ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device); + ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); + + ret = SetupDiGetDeviceInstanceIdA(set, &device, id, sizeof(id), NULL); + ok(ret, "Failed to get device id, error %#x.\n", GetLastError()); + ok(!strcmp(id, "ROOT\\LEGACY_BOGUS\\0001"), "Got unexpected id %s.\n", id); + + SetupDiDestroyDeviceInfoList(set); } -static void testCreateDeviceInterface(void) +static void test_register_device_info(void) { + SP_DEVINFO_DATA device = {0}; BOOL ret; HDEVINFO set; + int i = 0; - if (!pSetupDiCreateDeviceInterfaceA || !pSetupDiEnumDeviceInterfaces) - { - win_skip("SetupDiCreateDeviceInterfaceA and/or SetupDiEnumDeviceInterfaces are not available\n"); - return; - } SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInterfaceA(NULL, NULL, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); + ret = SetupDiRegisterDeviceInfo(NULL, NULL, 0, NULL, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiRegisterDeviceInfo(set, NULL, 0, NULL, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInterfaceA(NULL, NULL, &guid, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); - set = pSetupDiCreateDeviceInfoList(&guid, NULL); - ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError()); - if (set) + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + device.cbSize = sizeof(device); + SetLastError(0xdeadbeef); + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(ret, "Failed to register device, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(ret, "Failed to register device, error %#x.\n", GetLastError()); + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0002", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(ret, "Failed to register device, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInfo(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0003", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + SetupDiDestroyDeviceInfoList(set); + + set = SetupDiGetClassDevsA(&guid, NULL, NULL, 0); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); + + check_device_info(set, 0, &guid, "Root\\LEGACY_BOGUS\\0000"); + check_device_info(set, 1, &guid, "Root\\LEGACY_BOGUS\\0002"); + check_device_info(set, 2, &guid, NULL); + + while (SetupDiEnumDeviceInfo(set, i++, &device)) { - SP_DEVINFO_DATA devInfo = { 0 }; - SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData), - { 0 } }; - DWORD i; + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + } - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInterfaceA(set, NULL, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, NULL, NULL, 0, - NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - devInfo.cbSize = sizeof(devInfo); - ret = pSetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, - NULL, NULL, 0, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, NULL, NULL, 0, - NULL); - ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, - "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError()); - ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0, - NULL); - ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError()); - /* Creating the same interface a second time succeeds */ - ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0, - NULL); - ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError()); - ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, "Oogah", 0, - NULL); - ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError()); - ret = pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, 0, - &interfaceData); - ok(ret, "SetupDiEnumDeviceInterfaces failed: %d\n", GetLastError()); - i = 0; - while (pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, i, - &interfaceData)) - i++; - 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()); + SetupDiDestroyDeviceInfoList(set); +} - ret = pSetupDiRemoveDeviceInterface(set, &interfaceData); - todo_wine ok(ret, "SetupDiRemoveDeviceInterface failed: %08x\n", GetLastError()); - } +static void check_device_iface_(int line, HDEVINFO set, SP_DEVINFO_DATA *device, + const GUID *class, int index, DWORD flags, const char *path) +{ + char buffer[200]; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)buffer; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + BOOL ret; - ret = pSetupDiRemoveDevice(set, &devInfo); - todo_wine ok(ret, "got %u\n", GetLastError()); + detail->cbSize = sizeof(*detail); - ret = pSetupDiDestroyDeviceInfoList(set); - ok(ret, "SetupDiDestroyDeviceInfoList failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = SetupDiEnumDeviceInterfaces(set, device, class, index, &iface); + if (path) + { + ok_(__FILE__, line)(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ok_(__FILE__, line)(IsEqualGUID(&iface.InterfaceClassGuid, class), + "Got unexpected class %s.\n", wine_dbgstr_guid(&iface.InterfaceClassGuid)); + ok_(__FILE__, line)(iface.Flags == flags, "Got unexpected flags %#x.\n", iface.Flags); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, sizeof(buffer), NULL, NULL); + ok_(__FILE__, line)(ret, "Failed to get interface detail, error %#x.\n", GetLastError()); + ok_(__FILE__, line)(!strcasecmp(detail->DevicePath, path), "Got unexpected path %s.\n", detail->DevicePath); + } + else + { + ok_(__FILE__, line)(!ret, "Expected failure.\n"); + ok_(__FILE__, line)(GetLastError() == ERROR_NO_MORE_ITEMS, + "Got unexpected error %#x.\n", GetLastError()); } } +#define check_device_iface(a,b,c,d,e,f) check_device_iface_(__LINE__,a,b,c,d,e,f) -static void testGetDeviceInterfaceDetail(void) +static void test_device_iface(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','\\','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}; + char buffer[200]; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)buffer; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + SP_DEVINFO_DATA device = {0}; BOOL ret; HDEVINFO set; - if (!pSetupDiCreateDeviceInterfaceA || !pSetupDiGetDeviceInterfaceDetailA) - { - win_skip("SetupDiCreateDeviceInterfaceA and/or SetupDiGetDeviceInterfaceDetailA are not available\n"); - return; - } + detail->cbSize = sizeof(*detail); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(NULL, NULL, NULL, 0, NULL, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); - set = pSetupDiCreateDeviceInfoList(&guid, NULL); - ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError()); - if (set) - { - SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } }; - SP_DEVICE_INTERFACE_DATA interfaceData = { sizeof(interfaceData), - { 0 } }; - DWORD size = 0; + ret = SetupDiCreateDeviceInterfaceA(NULL, NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, NULL, NULL, 0, NULL, - NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - ret = pSetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, - NULL, NULL, 0, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0, - &interfaceData); - ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL, - 0, NULL, NULL); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL, - 100, NULL, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, - "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL, - 0, &size, NULL); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %d\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_w2k[] = - "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\"; - SP_DEVINFO_DATA devinfo; - LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size); - SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail = - (SP_DEVICE_INTERFACE_DETAIL_DATA_A *)buf; - DWORD expectedsize = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) + sizeof(WCHAR)*(1 + strlen(path)); - - detail->cbSize = 0; - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail, - size, &size, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, - "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError()); - detail->cbSize = size; - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail, - size, &size, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER, - "Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError()); - detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail, - size, &size, NULL); - ok(ret, "SetupDiGetDeviceInterfaceDetailA failed: %d\n", - GetLastError()); - ok(!lstrcmpiA(path, detail->DevicePath) || - !lstrcmpiA(path_w2k, detail->DevicePath), "Unexpected path %s\n", - detail->DevicePath); - /* Check SetupDiGetDeviceInterfaceDetailW */ - memset(&devinfo, 0, sizeof(devinfo)); - devinfo.cbSize = sizeof(devinfo); - ret = pSetupDiGetDeviceInterfaceDetailW(set, &interfaceData, NULL, 0, &size, &devinfo); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got error code: %d\n", GetLastError()); - ok(devinfo.DevInst, "Expected DevInst to be set\n"); - ok(expectedsize == size || - (expectedsize + sizeof(WCHAR)) == size /* W2K adds a backslash */, - "SetupDiGetDeviceInterfaceDetailW returned wrong reqsize, got %d\n", - size); - - HeapFree(GetProcessHeap(), 0, buf); - } + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInterfaceA(NULL, NULL, &guid, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInterfaceA(set, NULL, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); - ret = pSetupDiEnumDeviceInterfaces(set, &devInfo, &guid, 0, &interfaceData); - ok(ret, "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInterfaceA(set, &device, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); - ret = pSetupDiRemoveDeviceInterface(set, &interfaceData); - todo_wine ok(ret, "SetupDiRemoveDeviceInterface failed: %08x\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()); - ret = pSetupDiRemoveDevice(set, &devInfo); - todo_wine ok(ret, "got %u\n", GetLastError()); - pSetupDiDestroyDeviceInfoList(set); + check_device_iface(set, &device, &guid, 0, 0, NULL); - /* remove once Wine is fixed */ - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, devclass); - } + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInterfaceA(set, &device, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, NULL); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + + check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}"); + check_device_iface(set, &device, &guid, 1, 0, NULL); + + /* Creating the same interface a second time succeeds */ + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, NULL); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + + check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}"); + check_device_iface(set, &device, &guid, 1, 0, NULL); + + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "Oogah", 0, NULL); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + + check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}"); + check_device_iface(set, &device, &guid, 1, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\Oogah"); + check_device_iface(set, &device, &guid, 2, 0, NULL); + + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "test", 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + ok(IsEqualGUID(&iface.InterfaceClassGuid, &guid), "Got unexpected class %s.\n", + wine_dbgstr_guid(&iface.InterfaceClassGuid)); + ok(iface.Flags == 0, "Got unexpected flags %#x.\n", iface.Flags); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, sizeof(buffer), NULL, NULL); + ok(ret, "Failed to get interface detail, error %#x.\n", GetLastError()); + ok(!strcasecmp(detail->DevicePath, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\test"), + "Got unexpected path %s.\n", detail->DevicePath); + + check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}"); + check_device_iface(set, &device, &guid, 1, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\Oogah"); + check_device_iface(set, &device, &guid, 2, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\test"); + check_device_iface(set, &device, &guid, 3, 0, NULL); + + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid2, NULL, 0, NULL); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + + check_device_iface(set, &device, &guid2, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A5-3F65-11DB-B704-0011955C2BDB}"); + check_device_iface(set, &device, &guid2, 1, 0, NULL); + + ret = SetupDiEnumDeviceInterfaces(set, &device, &guid2, 0, &iface); + ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ret = SetupDiRemoveDeviceInterface(set, &iface); + ok(ret, "Failed to remove interface, error %#x.\n", GetLastError()); + + check_device_iface(set, &device, &guid2, 0, SPINT_REMOVED, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A5-3F65-11DB-B704-0011955C2BDB}"); + check_device_iface(set, &device, &guid2, 1, 0, NULL); + + ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 0, &iface); + ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInterfaceData(set, &iface); + ok(ret, "Failed to delete interface, error %#x.\n", GetLastError()); + + check_device_iface(set, &device, &guid, 0, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\Oogah"); + check_device_iface(set, &device, &guid, 1, 0, "\\\\?\\ROOT#LEGACY_BOGUS#0000#{6A55B5A4-3F65-11DB-B704-0011955C2BDB}\\test"); + check_device_iface(set, &device, &guid, 2, 0, NULL); + + ret = SetupDiDestroyDeviceInfoList(set); + ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError()); } -static void testDevRegKey(void) +static void test_device_iface_detail(void) { - 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}; - BOOL ret; + static const char path[] = "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; + SP_DEVICE_INTERFACE_DETAIL_DATA_A *detail; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + SP_DEVINFO_DATA device = {sizeof(device)}; + DWORD size = 0, expectedsize; HDEVINFO set; - HKEY key = NULL; + BOOL ret; SetLastError(0xdeadbeef); - key = pSetupDiCreateDevRegKeyW(NULL, NULL, 0, 0, 0, NULL, NULL); - ok(key == INVALID_HANDLE_VALUE, - "Expected INVALID_HANDLE_VALUE, got %p\n", key); - ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); + ret = SetupDiGetDeviceInterfaceDetailA(NULL, NULL, NULL, 0, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); - set = pSetupDiCreateDeviceInfoList(&guid, NULL); - ok(set != NULL, "SetupDiCreateDeviceInfoList failed: %d\n", GetLastError()); - if (set) - { - SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } }; - LONG res; + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); - /* The device info key shouldn't be there */ - res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key); - ok(res != ERROR_SUCCESS, "Expected key to not exist\n"); - RegCloseKey(key); - /* Create the device information */ - ret = pSetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, - NULL, NULL, 0, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - /* The device info key should have been created */ - ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key), - "Expected registry key to exist\n"); - RegCloseKey(key); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(NULL, NULL, 0, 0, 0, 0); - ok(!key || key == INVALID_HANDLE_VALUE, - "Expected INVALID_HANDLE_VALUE or a NULL key (NT4)\n"); - ok(GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, NULL, 0, 0, 0, 0); - ok(key == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, &devInfo, 0, 0, 0, 0); - ok(key == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_INVALID_FLAGS, - "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, 0, 0); - ok(key == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_INVALID_FLAGS, - "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, - DIREG_BOTH, 0); - ok(key == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_INVALID_FLAGS, - "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError()); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, - DIREG_DRV, 0); - ok(key == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_DEVINFO_NOT_REGISTERED, - "Expected ERROR_DEVINFO_NOT_REGISTERED, got %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); - ok(ret, "SetupDiRegisterDeviceInfo failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, - DIREG_DRV, 0); - /* The software key isn't created by default */ - ok(key == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_KEY_DOES_NOT_EXIST, - "Expected ERROR_KEY_DOES_NOT_EXIST, got %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, - DIREG_DEV, 0); - todo_wine - ok(key == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_KEY_DOES_NOT_EXIST, - "Expected ERROR_KEY_DOES_NOT_EXIST, got %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - /* The class key shouldn't be there */ - res = RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key); - todo_wine - ok(res != ERROR_SUCCESS, "Expected key to not exist\n"); - RegCloseKey(key); - /* Create the device reg key */ - key = pSetupDiCreateDevRegKeyW(set, &devInfo, DICS_FLAG_GLOBAL, 0, - DIREG_DRV, NULL, NULL); - /* Vista and higher don't actually create the key */ - ok(key != INVALID_HANDLE_VALUE || GetLastError() == ERROR_KEY_DOES_NOT_EXIST, - "SetupDiCreateDevRegKey failed: %08x\n", GetLastError()); - if (key != INVALID_HANDLE_VALUE) - { - RegCloseKey(key); - /* The class key should have been created */ - ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key), - "Expected registry key to exist\n"); - RegCloseKey(key); - SetLastError(0xdeadbeef); - key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, - DIREG_DRV, 0); - todo_wine - ok(key == INVALID_HANDLE_VALUE && - (GetLastError() == ERROR_INVALID_DATA || - GetLastError() == ERROR_ACCESS_DENIED), /* win2k3 */ - "Expected ERROR_INVALID_DATA or ERROR_ACCESS_DENIED, got %08x\n", GetLastError()); - key = pSetupDiOpenDevRegKey(set, &devInfo, DICS_FLAG_GLOBAL, 0, - DIREG_DRV, KEY_READ); - ok(key != INVALID_HANDLE_VALUE, "SetupDiOpenDevRegKey failed: %08x\n", - GetLastError()); - RegCloseKey(key); - } + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInterfaceDetailA(set, NULL, NULL, 0, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); - ret = pSetupDiRemoveDevice(set, &devInfo); - todo_wine ok(ret, "got %u\n", GetLastError()); - pSetupDiDestroyDeviceInfoList(set); + ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); - /* remove once Wine is fixed */ - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, classKey); - } + SetLastError(0xdeadbeef); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, NULL, 0, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, NULL, 100, NULL, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, NULL, 0, &size, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + detail = heap_alloc(size); + expectedsize = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath[strlen(path) + 1]); + + detail->cbSize = 0; + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, size, &size, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + detail->cbSize = size; + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, size, &size, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + + detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, size, &size, NULL); + ok(ret, "Failed to get interface detail, error %#x.\n", GetLastError()); + ok(!strcasecmp(path, detail->DevicePath), "Got unexpected path %s.\n", detail->DevicePath); + + ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, NULL, 0, &size, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(size == expectedsize, "Got unexpected size %d.\n", size); + + memset(&device, 0, sizeof(device)); + device.cbSize = sizeof(device); + ret = SetupDiGetDeviceInterfaceDetailW(set, &iface, NULL, 0, &size, &device); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(IsEqualGUID(&device.ClassGuid, &guid), "Got unexpected class %s.\n", wine_dbgstr_guid(&device.ClassGuid)); + + heap_free(detail); + SetupDiDestroyDeviceInfoList(set); } -static void testRegisterAndGetDetail(void) +static void test_device_key(void) { 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','\\', @@ -879,211 +779,264 @@ static void testRegisterAndGetDetail(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}; - HDEVINFO set, set2; + SP_DEVINFO_DATA device = {sizeof(device)}; 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; + HDEVINFO set; + HKEY key = NULL; LONG res; - if (!pSetupDiCreateDeviceInterfaceA || !pSetupDiEnumDeviceInterfaces || - !pSetupDiGetDeviceInterfaceDetailA) - { - win_skip("Needed functions are not available\n"); - return; - } - SetLastError(0xdeadbeef); - set = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_ALLCLASSES); - ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", - GetLastError()); + key = SetupDiCreateDevRegKeyW(NULL, NULL, 0, 0, 0, NULL, NULL); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key); - ok(res != ERROR_SUCCESS, "Expected key to not exist\n"); + ok(res != ERROR_SUCCESS, "Key should not exist.\n"); + RegCloseKey(key); + + ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key), "Key should exist.\n"); RegCloseKey(key); SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, 0, - DICD_GENERATE_ID, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); + key = SetupDiOpenDevRegKey(NULL, NULL, 0, 0, 0, 0); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + key = SetupDiOpenDevRegKey(set, NULL, 0, 0, 0, 0); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + key = SetupDiOpenDevRegKey(set, &device, 0, 0, 0, 0); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_FLAGS, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInterfaceA(set, &devInfo, &guid, NULL, 0, &interfaceData); - ok(ret, "SetupDiCreateDeviceInterfaceA failed: %08x\n", GetLastError()); + key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, 0, 0); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_FLAGS, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiRegisterDeviceInfo(set, &devInfo, 0, NULL, NULL, NULL); - ok(ret, "SetupDiRegisterDeviceInfo failed: %08x\n", GetLastError()); + key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_BOTH, 0); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_FLAGS, "Got unexpected error %#x.\n", GetLastError()); SetLastError(0xdeadbeef); - set2 = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); - ok(set2 != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", - GetLastError()); + key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_DEVINFO_NOT_REGISTERED, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(ret, "Failed to register device, error %#x.\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pSetupDiEnumDeviceInterfaces(set2, NULL, &guid, 0, &interfaceData2); - ok(ret, "SetupDiEnumDeviceInterfaces failed: %08x\n", GetLastError()); + key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0); + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_KEY_DOES_NOT_EXIST, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - 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) + res = RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key); +todo_wine + ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n"); + RegCloseKey(key); + + key = SetupDiCreateDevRegKeyW(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); + ok(key != INVALID_HANDLE_VALUE || GetLastError() == ERROR_KEY_DOES_NOT_EXIST, /* Vista+ */ + "Failed to create device key, error %#x.\n", GetLastError()); + if (key != INVALID_HANDLE_VALUE) { - static const char path[] = - "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; - 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}\\"; - PSP_DEVICE_INTERFACE_DETAIL_DATA_A detail = NULL; - - detail = HeapAlloc(GetProcessHeap(), 0, dwSize); - if (detail) - { - detail->cbSize = sizeof(*detail); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceInterfaceDetailA(set2, &interfaceData2, - detail, dwSize, &dwSize, NULL); - ok(ret, "SetupDiGetDeviceInterfaceDetailA failed: %08x\n", GetLastError()); - 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); - } - } + RegCloseKey(key); - ret = pSetupDiRemoveDeviceInterface(set, &interfaceData); - todo_wine ok(ret, "SetupDiRemoveDeviceInterface failed: %08x\n", GetLastError()); + ok(!RegOpenKeyW(HKEY_LOCAL_MACHINE, classKey, &key), "Key should exist.\n"); + RegCloseKey(key); - ret = pSetupDiRemoveDevice(set, &devInfo); - todo_wine ok(ret, "got %u\n", GetLastError()); + SetLastError(0xdeadbeef); + key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, 0); +todo_wine { + ok(key == INVALID_HANDLE_VALUE, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_ACCESS_DENIED, /* win2k3 */ + "Got unexpected error %#x.\n", GetLastError()); +} - pSetupDiDestroyDeviceInfoList(set); - pSetupDiDestroyDeviceInfoList(set2); + key = SetupDiOpenDevRegKey(set, &device, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ); + ok(key != INVALID_HANDLE_VALUE, "Failed to open device key, error %#x.\n", GetLastError()); + RegCloseKey(key); + } + + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + SetupDiDestroyDeviceInfoList(set); /* remove once Wine is fixed */ - devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, bogus); devinst_RegDeleteTreeW(HKEY_LOCAL_MACHINE, classKey); } -static void testDeviceRegistryPropertyA(void) +static void test_register_device_iface(void) { - HDEVINFO set; - SP_DEVINFO_DATA devInfo = { sizeof(SP_DEVINFO_DATA), { 0 } }; - CHAR devName[] = "LEGACY_BOGUS"; - CHAR friendlyName[] = "Bogus"; + 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}; + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}, ret_iface = {sizeof(ret_iface)}; + SP_DEVINFO_DATA device = {sizeof(device)}; + HDEVINFO set, set2; + BOOL ret; + HKEY key; + LONG res; + + set = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_ALLCLASSES); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); + + res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key); + ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n"); + + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "removed", 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, "deleted", 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + ret = SetupDiRegisterDeviceInfo(set, &device, 0, NULL, NULL, NULL); + ok(ret, "Failed to register device, error %#x.\n", GetLastError()); + + ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 1, &iface); + ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ret = SetupDiRemoveDeviceInterface(set, &iface); + ok(ret, "Failed to delete interface, error %#x.\n", GetLastError()); + ret = SetupDiEnumDeviceInterfaces(set, &device, &guid, 2, &iface); + ok(ret, "Failed to enumerate interfaces, error %#x.\n", GetLastError()); + ret = SetupDiDeleteDeviceInterfaceData(set, &iface); + ok(ret, "Failed to delete interface, error %#x.\n", GetLastError()); + + set2 = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); + ok(set2 != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); + + check_device_iface(set2, NULL, &guid, 0, 0, "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"); + check_device_iface(set2, NULL, &guid, 1, 0, "\\\\?\\root#legacy_bogus#0000#{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\deleted"); + check_device_iface(set2, NULL, &guid, 2, 0, NULL); + + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + + SetupDiDestroyDeviceInfoList(set); + SetupDiDestroyDeviceInfoList(set2); +} + +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] = ""; - DWORD buflen = 6; - DWORD size; - DWORD regType; + DWORD size, type; + HDEVINFO set; BOOL ret; LONG res; HKEY key; - static const CHAR bogus[] = - "System\\CurrentControlSet\\Enum\\Root\\LEGACY_BOGUS"; + + set = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "Failed to get device list, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); SetLastError(0xdeadbeef); - set = pSetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); - ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", - GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoA(set, devName, &guid, NULL, NULL, - DICD_GENERATE_ID, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoA failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, 0); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); + ret = SetupDiSetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, 0); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyA(set, NULL, -1, NULL, 0); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + ret = SetupDiSetDeviceRegistryPropertyA(set, NULL, -1, NULL, 0); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, -1, NULL, 0); + ret = SetupDiSetDeviceRegistryPropertyA(set, &device, -1, NULL, 0); + ok(!ret, "Expected failure.\n"); +todo_wine + ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, 0); todo_wine - ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY, - "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError()); + ok(!ret, "Expected failure.\n"); /* GetLastError() returns nonsense in win2k3 */ - ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, 0); - todo_wine - ok(!ret, "Expected failure, got %d\n", ret); + SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, - (PBYTE)friendlyName, buflen); - ok(ret, "SetupDiSetDeviceRegistryPropertyA failed: %08x\n", GetLastError()); + ret = SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, (BYTE *)"Bogus", sizeof("Bogus")); + ok(ret, "Failed to set property, error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); + ret = SetupDiGetDeviceRegistryPropertyA(NULL, NULL, -1, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyA(set, NULL, -1, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + ret = SetupDiGetDeviceRegistryPropertyA(set, NULL, -1, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, -1, NULL, NULL, 0, NULL); - todo_wine - ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY, - "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError()); - /* GetLastError() returns nonsense in win2k3 */ - ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, NULL, buflen, NULL); + ret = SetupDiGetDeviceRegistryPropertyA(set, &device, -1, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); +todo_wine + ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, sizeof("Bogus"), NULL); ok(!ret, "Expected failure, got %d\n", ret); + /* GetLastError() returns nonsense in win2k3 */ + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError()); - ok(buflen == size, "Unexpected size: %d\n", size); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, (PBYTE)buf, buflen, NULL); - ok(ret, "SetupDiGetDeviceRegistryPropertyA failed: %08x\n", GetLastError()); - ok(!lstrcmpiA(friendlyName, buf), "Unexpected property\n"); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, - ®Type, (PBYTE)buf, buflen, NULL); - ok(ret, "SetupDiGetDeviceRegistryPropertyA failed: %08x\n", GetLastError()); - ok(!lstrcmpiA(friendlyName, buf), "Unexpected value of property\n"); - ok(regType == REG_SZ, "Unexpected type of property: %d\n", regType); - SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyA(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, 0); - ok(ret, "SetupDiSetDeviceRegistryPropertyA failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - 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); + ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(size == sizeof("Bogus"), "Got unexpected size %d.\n", size); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), NULL); + ok(ret, "Failed to get property, error %#x.\n", GetLastError()); + ok(!strcmp(buf, "Bogus"), "Got unexpected property %s.\n", buf); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, &type, (BYTE *)buf, sizeof(buf), NULL); + ok(ret, "Failed to get property, error %#x.\n", GetLastError()); + ok(!strcmp(buf, "Bogus"), "Got unexpected property %s.\n", buf); + ok(type == REG_SZ, "Got unexpected type %d.\n", type); + + SetLastError(0xdeadbeef); + ret = SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, 0); + ok(ret, "Failed to set property, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), &size); +todo_wine { + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError()); +} + + ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_HARDWAREID, NULL, NULL, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError()); + + SetupDiDestroyDeviceInfoList(set); res = RegOpenKeyA(HKEY_LOCAL_MACHINE, bogus, &key); - if(!is_wow64) - todo_wine ok(res == ERROR_FILE_NOT_FOUND, "Expected key to not exist\n"); - /* FIXME: Remove when Wine is fixed */ - if (res == ERROR_SUCCESS) - { - /* Wine doesn't delete the information currently */ - RegDeleteKeyA(HKEY_LOCAL_MACHINE, bogus); - } + ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n"); } -static void testDeviceRegistryPropertyW(void) +static void test_registry_property_w(void) { - HDEVINFO set; - SP_DEVINFO_DATA devInfo = { sizeof(SP_DEVINFO_DATA), { 0 } }; - WCHAR devName[] = {'L','E','G','A','C','Y','_','B','O','G','U','S',0}; - WCHAR friendlyName[] = {'B','o','g','u','s',0}; + WCHAR friendly_name[] = {'B','o','g','u','s',0}; + SP_DEVINFO_DATA device = {sizeof(device)}; WCHAR buf[6] = {0}; - DWORD buflen = 6 * sizeof(WCHAR); - DWORD size; - DWORD regType; + DWORD size, type; + HDEVINFO set; BOOL ret; LONG res; HKEY key; @@ -1092,98 +1045,96 @@ static void testDeviceRegistryPropertyW(void) 'E','n','u','m','\\','R','o','o','t','\\', 'L','E','G','A','C','Y','_','B','O','G','U','S',0}; + set = SetupDiGetClassDevsA(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "Failed to get device list, error %#x.\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "LEGACY_BOGUS", &guid, NULL, NULL, DICD_GENERATE_ID, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - set = pSetupDiGetClassDevsW(&guid, NULL, 0, DIGCF_DEVICEINTERFACE); - ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsW failed: %08x\n", - GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiCreateDeviceInfoW(set, devName, &guid, NULL, NULL, - DICD_GENERATE_ID, &devInfo); - ok(ret, "SetupDiCreateDeviceInfoW failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, 0); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); + ret = SetupDiSetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, 0); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyW(set, NULL, -1, NULL, 0); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + ret = SetupDiSetDeviceRegistryPropertyW(set, NULL, -1, NULL, 0); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, -1, NULL, 0); + ret = SetupDiSetDeviceRegistryPropertyW(set, &device, -1, NULL, 0); + ok(!ret, "Expected failure.\n"); +todo_wine + ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiSetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, 0); todo_wine - ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY, - "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError()); + ok(!ret, "Expected failure.\n"); /* GetLastError() returns nonsense in win2k3 */ - ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, 0); - todo_wine - ok(!ret, "Expected failure, got %d\n", ret); + SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, - (PBYTE)friendlyName, buflen); - ok(ret, "SetupDiSetDeviceRegistryPropertyW failed: %08x\n", GetLastError()); + ret = SetupDiSetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, (BYTE *)friendly_name, sizeof(friendly_name)); + ok(ret, "Failed to set property, error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, - "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError()); + ret = SetupDiGetDeviceRegistryPropertyW(NULL, NULL, -1, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyW(set, NULL, -1, NULL, NULL, 0, NULL); - ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError()); + ret = SetupDiGetDeviceRegistryPropertyW(set, NULL, -1, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected error %#x.\n", GetLastError()); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, -1, NULL, NULL, 0, NULL); - todo_wine - ok(!ret && GetLastError() == ERROR_INVALID_REG_PROPERTY, - "Expected ERROR_INVALID_REG_PROPERTY, got %08x\n", GetLastError()); + ret = SetupDiGetDeviceRegistryPropertyW(set, &device, -1, NULL, NULL, 0, NULL); + ok(!ret, "Expected failure.\n"); +todo_wine + ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, sizeof(buf), NULL); + ok(!ret, "Expected failure.\n"); /* GetLastError() returns nonsense in win2k3 */ - ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, NULL, buflen, NULL); - ok(!ret, "Expected failure, got %d\n", ret); + SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, NULL, 0, &size); - ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %08x\n", GetLastError()); - ok(buflen == size, "Unexpected size: %d\n", size); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, (PBYTE)buf, buflen, NULL); - ok(ret, "SetupDiGetDeviceRegistryPropertyW failed: %08x\n", GetLastError()); - ok(!lstrcmpiW(friendlyName, buf), "Unexpected property\n"); - SetLastError(0xdeadbeef); - ret = pSetupDiGetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, - ®Type, (PBYTE)buf, buflen, NULL); - ok(ret, "SetupDiGetDeviceRegistryPropertyW failed: %08x\n", GetLastError()); - ok(!lstrcmpiW(friendlyName, buf), "Unexpected value of property\n"); - ok(regType == REG_SZ, "Unexpected type of property: %d\n", regType); - SetLastError(0xdeadbeef); - ret = pSetupDiSetDeviceRegistryPropertyW(set, &devInfo, SPDRP_FRIENDLYNAME, - NULL, 0); - ok(ret, "SetupDiSetDeviceRegistryPropertyW failed: %08x\n", GetLastError()); - SetLastError(0xdeadbeef); - 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); + ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(size == sizeof(friendly_name), "Got unexpected size %d.\n", size); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), NULL); + ok(ret, "Failed to get property, error %#x.\n", GetLastError()); + ok(!lstrcmpW(buf, friendly_name), "Got unexpected property %s.\n", wine_dbgstr_w(buf)); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, &type, (BYTE *)buf, sizeof(buf), NULL); + ok(ret, "Failed to get property, error %#x.\n", GetLastError()); + ok(!lstrcmpW(buf, friendly_name), "Got unexpected property %s.\n", wine_dbgstr_w(buf)); + ok(type == REG_SZ, "Got unexpected type %d.\n", type); + + SetLastError(0xdeadbeef); + ret = SetupDiSetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, 0); + ok(ret, "Failed to set property, error %#x.\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, (BYTE *)buf, sizeof(buf), &size); +todo_wine { + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError()); +} + + ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_HARDWAREID, NULL, NULL, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_DATA, "Got unexpected error %#x.\n", GetLastError()); + + SetupDiDestroyDeviceInfoList(set); res = RegOpenKeyW(HKEY_LOCAL_MACHINE, bogus, &key); - if(!is_wow64) - todo_wine ok(res == ERROR_FILE_NOT_FOUND, "Expected key to not exist\n"); - /* FIXME: Remove when Wine is fixed */ - if (res == ERROR_SUCCESS) - { - /* Wine doesn't delete the information currently */ - RegDeleteKeyW(HKEY_LOCAL_MACHINE, bogus); - } + ok(res == ERROR_FILE_NOT_FOUND, "Key should not exist.\n"); } -static void testSetupDiGetINFClassA(void) +static void test_get_inf_class(void) { static const char inffile[] = "winetest.inf"; static const char content[] = "[Version]\r\n\r\n"; @@ -1197,19 +1148,7 @@ static void testSetupDiGetINFClassA(void) HANDLE h; int i; - if(!pSetupDiGetINFClassA) - { - win_skip("SetupDiGetINFClassA not present\n"); - return; - } - - count = GetTempPathA(MAX_PATH, filename); - if(!count) - { - win_skip("GetTempPathA failed\n"); - return; - } - + GetTempPathA(MAX_PATH, filename); strcat(filename, inffile); DeleteFileA(filename); @@ -1217,11 +1156,6 @@ static void testSetupDiGetINFClassA(void) SetLastError(0xdeadbeef); retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count); ok(!retval, "expected SetupDiGetINFClassA to fail!\n"); - if (ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) - { - skip("SetupDiGetINFClassA is not implemented\n"); - return; - } ok(ERROR_FILE_NOT_FOUND == GetLastError(), "expected error ERROR_FILE_NOT_FOUND, got %u\n", GetLastError()); @@ -1253,28 +1187,20 @@ static void testSetupDiGetINFClassA(void) /* test file content */ h = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if(h == INVALID_HANDLE_VALUE) - { - win_skip("failed to create file %s (error %u)\n", filename, GetLastError()); - return; - } - CloseHandle( h); + ok(h != INVALID_HANDLE_VALUE, "Failed to create file, error %#x.\n", GetLastError()); + CloseHandle(h); retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count); ok(!retval, "expected SetupDiGetINFClassA to fail!\n"); - for(i=0; i < sizeof(signatures)/sizeof(char*); i++) + for(i=0; i < ARRAY_SIZE(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) - { - win_skip("failed to create file %s (error %u)\n", filename, GetLastError()); - return; - } - WriteFile( h, content, sizeof(content), &count, NULL); - CloseHandle( h); + ok(h != INVALID_HANDLE_VALUE, "Failed to create file, error %#x.\n", GetLastError()); + WriteFile(h, content, sizeof(content), &count, NULL); + CloseHandle(h); retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count); ok(!retval, "expected SetupDiGetINFClassA to fail!\n"); @@ -1326,10 +1252,8 @@ static void testSetupDiGetINFClassA(void) SetLastError(0xdeadbeef); retval = SetupDiGetINFClassA(filename, &guid, cn, 0, &count); ok(!retval, "expected SetupDiGetINFClassA to fail!\n"); - ok(ERROR_INSUFFICIENT_BUFFER == GetLastError() || - ERROR_INVALID_PARAMETER == GetLastError(), - "expected error ERROR_INSUFFICIENT_BUFFER or ERROR_INVALID_PARAMETER, " - "got %u\n", GetLastError()); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER || GetLastError() == ERROR_INVALID_PARAMETER /* 2k3+ */, + "Got unexpected error %#x.\n", GetLastError()); DeleteFileA(filename); @@ -1339,10 +1263,8 @@ static void testSetupDiGetINFClassA(void) SetLastError(0xdeadbeef); retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count); ok(!retval, "expected SetupDiGetINFClassA to fail!\n"); - ok(RPC_S_INVALID_STRING_UUID == GetLastError() || - ERROR_INVALID_PARAMETER == GetLastError(), - "expected error RPC_S_INVALID_STRING_UUID or ERROR_INVALID_PARAMETER, " - "got %u\n", GetLastError()); + ok(GetLastError() == RPC_S_INVALID_STRING_UUID || GetLastError() == ERROR_INVALID_PARAMETER /* 7+ */, + "Got unexpected error %#x.\n", GetLastError()); /* network adapter guid */ WritePrivateProfileStringA("Version", "ClassGUID", @@ -1359,6 +1281,80 @@ static void testSetupDiGetINFClassA(void) } } +static void test_devnode(void) +{ + HDEVINFO set; + SP_DEVINFO_DATA device = { sizeof(SP_DEVINFO_DATA) }; + char buffer[50]; + DWORD ret; + + set = SetupDiGetClassDevsA(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE); + ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError()); + ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, + NULL, 0, &device); + ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError()); + + ret = CM_Get_Device_IDA(device.DevInst, buffer, sizeof(buffer), 0); + ok(!ret, "got %#x\n", ret); + ok(!strcmp(buffer, "ROOT\\LEGACY_BOGUS\\0000"), "got %s\n", buffer); + + SetupDiDestroyDeviceInfoList(set); +} + +static void test_device_interface_key(void) +{ + const char keypath[] = "System\\CurrentControlSet\\Control\\DeviceClasses\\" + "{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\" + "##?#ROOT#LEGACY_BOGUS#0001#{6a55b5a4-3f65-11db-b704-0011955c2bdb}"; + SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) }; + SP_DEVINFO_DATA devinfo = { sizeof(devinfo) }; + HKEY parent, key, dikey; + char buffer[5]; + HDEVINFO set; + LONG sz, ret; + + set = SetupDiGetClassDevsA(NULL, NULL, 0, DIGCF_ALLCLASSES); + ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &devinfo); + ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError()); + + ret = SetupDiCreateDeviceInterfaceA(set, &devinfo, &guid, NULL, 0, &iface); + ok(ret, "SetupDiCreateDeviceInterface failed: %#x\n", GetLastError()); + + ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &parent); + ok(!ret, "failed to open device parent key: %u\n", ret); + + ret = RegOpenKeyA(parent, "#\\Device Parameters", &key); + ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n"); + + dikey = SetupDiCreateDeviceInterfaceRegKeyA(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL); + ok(dikey != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + + ret = RegOpenKeyA(parent, "#\\Device Parameters", &key); + ok(!ret, "key should exist: %u\n", ret); + + ret = RegSetValueA(key, NULL, REG_SZ, "test", 5); + sz = sizeof(buffer); + ret = RegQueryValueA(dikey, NULL, buffer, &sz); + ok(!ret, "RegQueryValue failed: %u\n", ret); + ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer); + + RegCloseKey(dikey); + RegCloseKey(key); + + ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0); + ok(ret, "got error %u\n", GetLastError()); + + ret = RegOpenKeyA(parent, "#\\Device Parameters", &key); + ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n"); + + RegCloseKey(parent); + SetupDiRemoveDeviceInterface(set, &iface); + SetupDiRemoveDevice(set, &devinfo); + SetupDiDestroyDeviceInfoList(set); +} + static void testSetupDiGetClassDevsA(void) { static GUID displayguid = {0x4d36e968, 0xe325, 0x11ce, {0xbf,0xc1,0x08,0x00,0x2b,0xe1,0x03,0x18}}; @@ -1371,22 +1367,20 @@ static void testSetupDiGetClassDevsA(void) ok(EnumDisplayDevicesA(NULL, 0, &disp, 0), "EnumDisplayDevices failed: %08x\n", GetLastError()); SetLastError(0xdeadbeef); - set = pSetupDiGetClassDevsA(&displayguid, disp.DeviceID, 0, 0); + set = SetupDiGetClassDevsA(&displayguid, disp.DeviceID, 0, 0); ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevsA failed: %08x\n", GetLastError()); devinfo.cbSize = sizeof(devinfo); ret = SetupDiEnumDeviceInfo(set, 0, &devinfo); ok(ret, "SetupDiEnumDeviceInfo failed: %08x\n", GetLastError()); - pSetupDiDestroyDeviceInfoList(set); + SetupDiDestroyDeviceInfoList(set); } START_TEST(devinst) { HKEY hkey; - init_function_pointers(); - if ((hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS)) == INVALID_HANDLE_VALUE) { skip("needs admin rights\n"); @@ -1394,36 +1388,20 @@ START_TEST(devinst) } RegCloseKey(hkey); - if (pIsWow64Process) - pIsWow64Process(GetCurrentProcess(), &is_wow64); - - if (pSetupDiCreateDeviceInfoListExW) - test_SetupDiCreateDeviceInfoListEx(); - else - win_skip("SetupDiCreateDeviceInfoListExW is not available\n"); - - if (pSetupDiOpenClassRegKeyExA) - test_SetupDiOpenClassRegKeyExA(); - else - win_skip("SetupDiOpenClassRegKeyExA is not available\n"); - - testInstallClass(); - testCreateDeviceInfo(); - testGetDeviceInstanceId(); - testRegisterDeviceInfo(); - testCreateDeviceInterface(); - testGetDeviceInterfaceDetail(); - testDevRegKey(); - testRegisterAndGetDetail(); - testDeviceRegistryPropertyA(); - testDeviceRegistryPropertyW(); - if (!winetest_interactive) - { - win_skip("testSetupDiGetINFClassA(), ROSTESTS-66.\n"); - } - else - { - testSetupDiGetINFClassA(); - } + test_create_device_list_ex(); + test_open_class_key(); + test_install_class(); + test_device_info(); + test_get_device_instance_id(); + test_register_device_info(); + test_device_iface(); + test_device_iface_detail(); + test_device_key(); + test_register_device_iface(); + test_registry_property_a(); + test_registry_property_w(); + test_get_inf_class(); testSetupDiGetClassDevsA(); + test_devnode(); + test_device_interface_key(); } diff --git a/modules/rostests/winetests/setupapi/install.c b/modules/rostests/winetests/setupapi/install.c index 72d16a1020..a3b562ecc8 100644 --- a/modules/rostests/winetests/setupapi/install.c +++ b/modules/rostests/winetests/setupapi/install.c @@ -174,6 +174,45 @@ static void test_registry(void) ok(ret, "Expected source inf to exist, last error was %d\n", GetLastError()); } +static void test_install_from(void) +{ + char path[MAX_PATH]; + HINF infhandle; + HKEY key; + LONG res; + BOOL ret; + + /* First create a registry structure we would like to be deleted */ + ok(!RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest", &key), + "Expected RegCreateKeyA to succeed\n"); + + /* Doublecheck if the registry key is present */ + ok(!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest", &key), + "Expected registry key to exist\n"); + + create_inf_file(inffile, cmdline_inf_reg); + sprintf(path, "%s\\%s", CURR_DIR, inffile); + infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); + SetLastError(0xdeadbeef); + ret = SetupInstallFromInfSectionA(NULL, infhandle, "DefaultInstall", SPINST_REGISTRY, key, + "A:\\", 0, NULL, NULL, NULL, NULL); + ok(ret, "Unexpected failure\n"); + ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08x\n", GetLastError()); + + /* Check if the registry key is recursively deleted */ + res = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest", &key); + ok(res == ERROR_FILE_NOT_FOUND, "Didn't expect the registry key to exist\n"); + /* Just in case */ + if (res == ERROR_SUCCESS) + { + RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest"); + RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest"); + } + + SetupCloseInfFile(infhandle); + DeleteFileA(inffile); +} + static void test_install_svc_from(void) { char inf[2048]; @@ -742,6 +781,7 @@ START_TEST(install) test_cmdline(); test_registry(); + test_install_from(); test_install_svc_from(); test_driver_install(); test_dirid(); diff --git a/modules/rostests/winetests/setupapi/misc.c b/modules/rostests/winetests/setupapi/misc.c index dbe684bb29..9143cd4bd3 100644 --- a/modules/rostests/winetests/setupapi/misc.c +++ b/modules/rostests/winetests/setupapi/misc.c @@ -594,7 +594,7 @@ static void test_SetupDecompressOrCopyFile(void) create_source_file(source, uncompressed, sizeof(uncompressed)); - for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++) + for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++) { type = FILE_COMPRESSION_NONE; ret = SetupDecompressOrCopyFileA(invalid_parameters[i].source, @@ -697,7 +697,7 @@ static void test_SetupDecompressOrCopyFile(void) p = strrchr(target, '\\'); - for (i = 0; i < sizeof(zip_multi_tests)/sizeof(zip_multi_tests[0]); i++) + for (i = 0; i < ARRAY_SIZE(zip_multi_tests); i++) { lstrcpyA(p + 1, zip_multi_tests[i].filename); diff --git a/modules/rostests/winetests/setupapi/parser.c b/modules/rostests/winetests/setupapi/parser.c index 67c9887a61..07dcaafd55 100644 --- a/modules/rostests/winetests/setupapi/parser.c +++ b/modules/rostests/winetests/setupapi/parser.c @@ -59,7 +59,8 @@ static const char tmpfilename[] = ".\\tmp.inf"; "aaaaaaaaaaaaaaaa" A256 #define A1200 A400 A400 A400 #define A511 A255 A256 -#define A4097 "a" A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 +#define A4096 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 A256 +#define A4097 "a" A4096 #define STD_HEADER "[Version]\r\nSignature=\"$CHICAGO$\"\r\n" @@ -154,7 +155,7 @@ static void test_invalid_files(void) HINF hinf; DWORD err; - for (i = 0; i < sizeof(invalid_files)/sizeof(invalid_files[0]); i++) + for (i = 0; i < ARRAY_SIZE(invalid_files); i++) { SetLastError( 0xdeadbeef ); err_line = 0xdeadbeef; @@ -229,7 +230,7 @@ static void test_section_names(void) DWORD err; LONG ret; - for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); i++) + for (i = 0; i < ARRAY_SIZE(section_names); i++) { SetLastError( 0xdeadbeef ); hinf = test_file_contents( section_names[i].data, &err_line ); @@ -418,7 +419,7 @@ static void test_key_names(void) BOOL ret; INFCONTEXT context; - for (i = 0; i < sizeof(key_names)/sizeof(key_names[0]); i++) + for (i = 0; i < ARRAY_SIZE(key_names); i++) { strcpy( buffer, STD_HEADER "[Test]\n" ); strcat( buffer, key_names[i].data ); @@ -452,6 +453,11 @@ static void test_key_names(void) !strcmp( field, A1200), /* Vista, W2K8 */ "line %u: bad field %s/%s\n", i, field, key_names[i].fields[index] ); + else if (i == 52) + ok( !strcmp( field, key_names[i].fields[index] ) || + !strcmp( field, A4096), /* Win10 >= 1709 */ + "line %u: bad field %s/%s\n", + i, field, key_names[i].fields[index] ); else /* don't compare drive letter of paths */ if (field[0] && field[1] == ':' && field[2] == '\\') ok( !strcmp( field + 1, key_names[i].fields[index] + 1 ), @@ -622,7 +628,7 @@ static void test_SetupGetIntField(void) }; unsigned int i; - for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) + for (i = 0; i < ARRAY_SIZE(keys); i++) { HINF hinf; char buffer[MAX_INF_STRING_LENGTH]; diff --git a/modules/rostests/winetests/setupapi/setupcab.c b/modules/rostests/winetests/setupapi/setupcab.c index f2528865aa..2e776e6687 100644 --- a/modules/rostests/winetests/setupapi/setupcab.c +++ b/modules/rostests/winetests/setupapi/setupcab.c @@ -109,7 +109,7 @@ static void test_invalid_parametersA(void) create_source_fileA(source, NULL, 0); - for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++) + for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++) { SetLastError(0xdeadbeef); ret = SetupIterateCabinetA(invalid_parameters[i].CabinetFile, 0, @@ -170,12 +170,12 @@ static void test_invalid_parametersW(void) return; } - GetTempPathW(sizeof(temp)/sizeof(WCHAR), temp); + GetTempPathW(ARRAY_SIZE(temp), temp); GetTempFileNameW(temp, docW, 0, source); create_source_fileW(source, NULL, 0); - for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++) + for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++) { SetLastError(0xdeadbeef); ret = SetupIterateCabinetW(invalid_parameters[i].CabinetFile, 0, @@ -275,7 +275,7 @@ static void test_invalid_callbackW(void) return; } - GetTempPathW(sizeof(temp)/sizeof(WCHAR), temp); + GetTempPathW(ARRAY_SIZE(temp), temp); GetTempFileNameW(temp, docW, 0, source); create_source_fileW(source, comp_cab_zip_multi, sizeof(comp_cab_zip_multi)); @@ -331,7 +331,7 @@ static UINT CALLBACK simple_callbackA(PVOID Context, UINT Notification, ctx->count++; - if (index < sizeof(expected_files)/sizeof(char *)) + if (index < ARRAY_SIZE(expected_files)) { ok(!strcmp(expected_files[index], info->NameInCabinet), "[%d] Expected file \"%s\", got \"%s\"\n", @@ -389,8 +389,7 @@ static void test_simple_enumerationA(void) ctx.target = target; ret = SetupIterateCabinetA(source, 0, simple_callbackA, &ctx); ok(ret == 1, "Expected SetupIterateCabinetA to return 1, got %d\n", ret); - ok(ctx.count == sizeof(expected_files)/sizeof(char *), - "Unexpectedly enumerated %d files\n", ctx.count); + ok(ctx.count == ARRAY_SIZE(expected_files), "Unexpectedly enumerated %d files\n", ctx.count); DeleteFileA(source); DeleteFileA(target); @@ -434,7 +433,7 @@ static UINT CALLBACK simple_callbackW(PVOID Context, UINT Notification, ctx->count++; - if (index < sizeof(expected_filesW)/sizeof(WCHAR *)) + if (index < ARRAY_SIZE(expected_filesW)) { ok(!lstrcmpW(expected_filesW[index], info->NameInCabinet), "[%d] Expected file %s, got %s\n", @@ -488,7 +487,7 @@ static void test_simple_enumerationW(void) return; } - GetTempPathW(sizeof(temp)/sizeof(WCHAR), temp); + GetTempPathW(ARRAY_SIZE(temp), temp); GetTempFileNameW(temp, docW, 0, source); GetTempFileNameW(temp, docW, 0, target); @@ -499,8 +498,7 @@ static void test_simple_enumerationW(void) ctx.target = target; ret = SetupIterateCabinetW(source, 0, simple_callbackW, &ctx); ok(ret == 1, "Expected SetupIterateCabinetW to return 1, got %d\n", ret); - ok(ctx.count == sizeof(expected_files)/sizeof(WCHAR *), - "Unexpectedly enumerated %d files\n", ctx.count); + ok(ctx.count == ARRAY_SIZE(expected_files), "Unexpectedly enumerated %d files\n", ctx.count); DeleteFileW(source); DeleteFileW(target);
5 years, 10 months
1
0
0
0
[reactos] 01/01: [SERVICES_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aee77bdeee409d6e985d0…
commit aee77bdeee409d6e985d05e8ed66ec0eb9314e38 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:14:59 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:14:59 2019 +0100 [SERVICES_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/services/service.c | 50 ++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/modules/rostests/winetests/services/service.c b/modules/rostests/winetests/services/service.c index 728d515f85..5e9265d587 100644 --- a/modules/rostests/winetests/services/service.c +++ b/modules/rostests/winetests/services/service.c @@ -35,6 +35,8 @@ static SERVICE_STATUS_HANDLE service_handle; /* Service process global variables */ static HANDLE service_stop_event; +static int monitor_count; + static void send_msg(const char *type, const char *msg) { DWORD written = 0; @@ -127,6 +129,51 @@ static void test_create_window(void) service_ok(r, "DestroyWindow failed: %08x\n", GetLastError()); } +static BOOL CALLBACK monitor_enum_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam) +{ + BOOL r; + MONITORINFOEXA mi; + + service_ok(hmon != NULL, "Unexpected hmon=%#x\n", hmon); + + monitor_count++; + + mi.cbSize = sizeof(mi); + + SetLastError(0xdeadbeef); + r = GetMonitorInfoA(NULL, (MONITORINFO*)&mi); + service_ok(GetLastError() == ERROR_INVALID_MONITOR_HANDLE, "Unexpected GetLastError: %#x.\n", GetLastError()); + service_ok(!r, "GetMonitorInfo with NULL HMONITOR succeeded.\n"); + + r = GetMonitorInfoA(hmon, (MONITORINFO*)&mi); + service_ok(r, "GetMonitorInfo failed.\n"); + + service_ok(mi.rcMonitor.left == 0 && mi.rcMonitor.top == 0 && mi.rcMonitor.right >= 640 && mi.rcMonitor.bottom >= 480, + "Unexpected monitor rcMonitor values: {%d,%d,%d,%d}\n", + mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom); + + service_ok(mi.rcWork.left == 0 && mi.rcWork.top == 0 && mi.rcWork.right >= 640 && mi.rcWork.bottom >= 480, + "Unexpected monitor rcWork values: {%d,%d,%d,%d}\n", + mi.rcWork.left, mi.rcWork.top, mi.rcWork.right, mi.rcWork.bottom); + + service_ok(!strcmp(mi.szDevice, "WinDisc") || !strcmp(mi.szDevice, "\\\\.\\DISPLAY1"), + "Unexpected szDevice received: %s\n", mi.szDevice); + + service_ok(mi.dwFlags == MONITORINFOF_PRIMARY, "Unexpected secondary monitor info.\n"); + + return TRUE; +} + +/* query monitor information, even in non-interactive services */ +static void test_monitors(void) +{ + BOOL r; + + r = EnumDisplayMonitors(0, 0, monitor_enum_proc, 0); + service_ok(r, "EnumDisplayMonitors failed.\n"); + service_ok(monitor_count == 1, "Callback got called less or more than once. %d\n", monitor_count); +} + static DWORD WINAPI service_handler(DWORD ctrl, DWORD event_type, void *event_data, void *context) { SERVICE_STATUS status; @@ -151,6 +198,7 @@ static DWORD WINAPI service_handler(DWORD ctrl, DWORD event_type, void *event_da case 128: test_winstation(); test_create_window(); + test_monitors(); service_event("CUSTOM"); return 0xdeadbeef; default: @@ -541,7 +589,7 @@ static void test_runner(void (*p_run_test)(void)) sprintf(named_pipe_name, "\\\\.\\pipe\\%s_pipe", service_name); pipe_handle = CreateNamedPipeA(named_pipe_name, PIPE_ACCESS_INBOUND, - PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, 10, 2048, 2048, 10000, NULL); + PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, 10, 2048, 2048, 10000, NULL); ok(pipe_handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError()); if(pipe_handle == INVALID_HANDLE_VALUE) return;
5 years, 10 months
1
0
0
0
[reactos] 01/01: [SERIALUI_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=96eddc22d217aafd68abc…
commit 96eddc22d217aafd68abc2eb3854197b36ea4bc9 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:14:08 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:14:08 2019 +0100 [SERIALUI_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/serialui/confdlg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/rostests/winetests/serialui/confdlg.c b/modules/rostests/winetests/serialui/confdlg.c index 4606a75b60..bd541cda2b 100644 --- a/modules/rostests/winetests/serialui/confdlg.c +++ b/modules/rostests/winetests/serialui/confdlg.c @@ -165,7 +165,7 @@ static void test_drvCommConfigDialogW(void) /* test ports "com1" - "com4" */ for (i = 1; i < 5 ; i++) { sprintf(bufferA, fmt_comA, i); - MultiByteToWideChar( CP_ACP, 0, bufferA, -1, bufferW, sizeof(bufferW)/sizeof(WCHAR) ); + MultiByteToWideChar(CP_ACP, 0, bufferA, -1, bufferW, ARRAY_SIZE(bufferW)); len = sizeof(pCC); ZeroMemory(pCC, sizeof(pCC)); SetLastError(0xdeadbeef); @@ -346,7 +346,7 @@ static void test_drvGetDefaultCommConfigW(void) /* test ports "com0" - "com10" */ for (i = 0; i < 11 ; i++) { sprintf(bufferA, fmt_comA, i); - MultiByteToWideChar( CP_ACP, 0, bufferA, -1, bufferW, sizeof(bufferW)/sizeof(WCHAR) ); + MultiByteToWideChar(CP_ACP, 0, bufferA, -1, bufferW, ARRAY_SIZE(bufferW)); len = sizeof(pCC); ZeroMemory(pCC, sizeof(pCC)); SetLastError(0xdeadbeef);
5 years, 10 months
1
0
0
0
[reactos] 01/01: [SECUR32_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=739fc06f27cbd1b382012…
commit 739fc06f27cbd1b3820120383c77a65dbd92ab4c Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:13:33 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:13:33 2019 +0100 [SECUR32_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/secur32/ntlm.c | 6 +++--- modules/rostests/winetests/secur32/schannel.c | 22 +++++++++++----------- modules/rostests/winetests/secur32/secur32.c | 10 +++++----- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/modules/rostests/winetests/secur32/ntlm.c b/modules/rostests/winetests/secur32/ntlm.c index b9fdf6f237..6b1249d201 100644 --- a/modules/rostests/winetests/secur32/ntlm.c +++ b/modules/rostests/winetests/secur32/ntlm.c @@ -1165,7 +1165,7 @@ static void testSignSeal(void) trace("Testing with more than one buffer.\n"); - crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]); + crypt.cBuffers = ARRAY_SIZE(complex_data); crypt.pBuffers = complex_data; complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM; @@ -1436,7 +1436,7 @@ static void test_cred_multiple_use(void) getSecError(ret)); buffer_desc.ulVersion = SECBUFFER_VERSION; - buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]); + buffer_desc.cBuffers = ARRAY_SIZE(buffers); buffer_desc.pBuffers = buffers; ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION, @@ -1487,7 +1487,7 @@ static void test_null_auth_data(void) buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer); buffer_desc.ulVersion = SECBUFFER_VERSION; - buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]); + buffer_desc.cBuffers = ARRAY_SIZE(buffers); buffer_desc.pBuffers = buffers; size = sizeof(user); diff --git a/modules/rostests/winetests/secur32/schannel.c b/modules/rostests/winetests/secur32/schannel.c index 1a37c5226a..ebdfcb61a1 100644 --- a/modules/rostests/winetests/secur32/schannel.c +++ b/modules/rostests/winetests/secur32/schannel.c @@ -202,6 +202,7 @@ static void test_supported_protocols(CredHandle *handle, unsigned exprots) X(SP_PROT_TLS1_0_CLIENT, "TLS 1.0 client"); X(SP_PROT_TLS1_1_CLIENT, "TLS 1.1 client"); X(SP_PROT_TLS1_2_CLIENT, "TLS 1.2 client"); + X(SP_PROT_TLS1_3_CLIENT, "TLS 1.3 client"); #undef X if(protocols.grbitProtocol) @@ -560,11 +561,11 @@ static void test_remote_cert(PCCERT_CONTEXT remote_cert) cert_cnt++; } - ok(cert_cnt == 2 || cert_cnt == 3, "cert_cnt = %u\n", cert_cnt); + ok(cert_cnt == 4, "cert_cnt = %u\n", cert_cnt); ok(incl_remote, "context does not contain cert itself\n"); } -static const char http_request[] = "HEAD /test.html HTTP/1.1\r\nHost:
www.winehq.org\r\nConnection
: close\r\n\r\n"; +static const char http_request[] = "HEAD /test.html HTTP/1.1\r\nHost: test.winehq.org\r\nConnection: close\r\n\r\n"; static void init_buffers(SecBufferDesc *desc, unsigned count, unsigned size) { @@ -690,7 +691,7 @@ static void test_communication(void) SecBufferDesc buffers[2]; SecBuffer *buf; - unsigned buf_size = 4000; + unsigned buf_size = 8192; unsigned char *data; unsigned data_size; @@ -700,7 +701,7 @@ static void test_communication(void) return; } - /* Create a socket and connect to
www.winehq.org
*/ + /* Create a socket and connect to
test.winehq.org
*/ ret = WSAStartup(0x0202, &wsa_data); if (ret) { @@ -708,10 +709,10 @@ static void test_communication(void) return; } - host = gethostbyname("
www.winehq.org
"); + host = gethostbyname("
test.winehq.org
"); if (!host) { - skip("Can't resolve
www.winehq.org\n
"); + skip("Can't resolve test.winehq.org\n"); return; } @@ -728,7 +729,7 @@ static void test_communication(void) ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr)); if (ret == SOCKET_ERROR) { - skip("Can't connect to
www.winehq.org\n
"); + skip("Can't connect to test.winehq.org\n"); return; } @@ -806,7 +807,7 @@ todo_wine ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n"); ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n"); - buffers[1].cBuffers = 4; + buffers[1].cBuffers = 1; buffers[1].pBuffers[0].cbBuffer = 0; status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", @@ -865,10 +866,9 @@ todo_wine } ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n"); - ok(status == SEC_E_OK || broken(status == SEC_E_INVALID_TOKEN) /* WinNT */, - "InitializeSecurityContext failed: %08x\n", status); + ok(status == SEC_E_OK, "InitializeSecurityContext failed: %08x\n", status); if(status != SEC_E_OK) { - win_skip("Handshake failed\n"); + skip("Handshake failed\n"); return; } diff --git a/modules/rostests/winetests/secur32/secur32.c b/modules/rostests/winetests/secur32/secur32.c index 40c272ada3..2d2c2a6925 100644 --- a/modules/rostests/winetests/secur32/secur32.c +++ b/modules/rostests/winetests/secur32/secur32.c @@ -67,7 +67,7 @@ static void testGetComputerObjectNameA(void) BOOLEAN rc; UINT i; - for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { + for (i = 0; i < ARRAY_SIZE(formats); i++) { size = 0; SetLastError(0xdeadbeef); rc = pGetComputerObjectNameA(formats[i], NULL, &size); @@ -112,7 +112,7 @@ static void testGetComputerObjectNameW(void) BOOLEAN rc; UINT i; - for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { + for (i = 0; i < ARRAY_SIZE(formats); i++) { size = 0; SetLastError(0xdeadbeef); rc = pGetComputerObjectNameW(formats[i], NULL, &size); @@ -134,7 +134,7 @@ static void testGetComputerObjectNameW(void) if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) continue; - size = sizeof(nameW)/sizeof(nameW[0]); + size = ARRAY_SIZE(nameW); SetLastError(0xdeadbeef); rc = pGetComputerObjectNameW(formats[i], nameW, &size); switch (formats[i]) @@ -158,7 +158,7 @@ static void testGetUserNameExA(void) BOOLEAN rc; UINT i; - for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { + for (i = 0; i < ARRAY_SIZE(formats); i++) { size = sizeof(name); ZeroMemory(name, sizeof(name)); rc = pGetUserNameExA(formats[i], name, &size); @@ -205,7 +205,7 @@ static void testGetUserNameExW(void) BOOLEAN rc; UINT i; - for (i = 0; i < (sizeof(formats) / sizeof(formats[0])); i++) { + for (i = 0; i < ARRAY_SIZE(formats); i++) { size = sizeof(nameW); ZeroMemory(nameW, sizeof(nameW)); rc = pGetUserNameExW(formats[i], nameW, &size);
5 years, 10 months
1
0
0
0
[reactos] 01/01: [PSDK] Update schannel.h. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1f7c95d621e2f9fa8f6e9…
commit 1f7c95d621e2f9fa8f6e98ea73b2ddce39cb8397 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:13:03 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:13:03 2019 +0100 [PSDK] Update schannel.h. CORE-15682 --- sdk/include/psdk/schannel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/include/psdk/schannel.h b/sdk/include/psdk/schannel.h index fcdde0d4f0..a6ce4debd7 100644 --- a/sdk/include/psdk/schannel.h +++ b/sdk/include/psdk/schannel.h @@ -32,6 +32,7 @@ extern "C" { #define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT #define SP_PROT_TLS1_1_CLIENT 512 #define SP_PROT_TLS1_2_CLIENT 2048 +#define SP_PROT_TLS1_3_CLIENT 8192 #define SP_PROT_SSL2_SERVER 4 #define SP_PROT_SSL3_SERVER 16
5 years, 10 months
1
0
0
0
[reactos] 01/01: [SCRRUN_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c3b5406849e38c27fcd3c…
commit c3b5406849e38c27fcd3c08b44430c04a7540bd9 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:12:33 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:12:33 2019 +0100 [SCRRUN_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/scrrun/dictionary.c | 15 +++++++++------ modules/rostests/winetests/scrrun/filesystem.c | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/modules/rostests/winetests/scrrun/dictionary.c b/modules/rostests/winetests/scrrun/dictionary.c index a6fecd15ba..a058f40c0f 100644 --- a/modules/rostests/winetests/scrrun/dictionary.c +++ b/modules/rostests/winetests/scrrun/dictionary.c @@ -18,6 +18,9 @@ */ #define COBJMACROS +#ifdef __REACTOS__ +#define CONST_VTABLE +#endif #include <stdio.h> #include "windows.h" @@ -251,13 +254,13 @@ static ULONG WINAPI test_unk_Release(IUnknown *iface) return 1; } -static /* const */ IUnknownVtbl test_unk_vtbl = { +static const IUnknownVtbl test_unk_vtbl = { test_unk_QI, test_unk_AddRef, test_unk_Release }; -static /* const */ IUnknownVtbl test_unk_no_vtbl = { +static const IUnknownVtbl test_unk_no_vtbl = { test_unk_no_QI, test_unk_AddRef, test_unk_Release @@ -312,7 +315,7 @@ static HRESULT WINAPI test_disp_Invoke(IDispatch *iface, DISPID dispid, REFIID r return E_NOTIMPL; } -static /* const */ IDispatchVtbl test_disp_vtbl = { +static const IDispatchVtbl test_disp_vtbl = { test_disp_QI, test_disp_AddRef, test_disp_Release, @@ -368,7 +371,7 @@ static void test_hash_value(void) ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); ok(V_I4(&hash) == 0, "got %d\n", V_I4(&hash)); - for (i = 0; i < sizeof(str_hash_tests)/sizeof(str_hash_tests[0]); i++) { + for (i = 0; i < ARRAY_SIZE(str_hash_tests); i++) { expected = get_str_hash(str_hash_tests[i], BinaryCompare); hr = IDictionary_put_CompareMode(dict, BinaryCompare); @@ -461,7 +464,7 @@ static void test_hash_value(void) ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash)); - for (i = 0; i < sizeof(int_hash_tests)/sizeof(int_hash_tests[0]); i++) { + for (i = 0; i < ARRAY_SIZE(int_hash_tests); i++) { SHORT i2; BYTE ui1; LONG i4; @@ -597,7 +600,7 @@ static void test_hash_value(void) ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash)); ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash)); - for (i = 0; i < sizeof(float_hash_tests)/sizeof(float_hash_tests[0]); i++) { + for (i = 0; i < ARRAY_SIZE(float_hash_tests); i++) { double dbl; FLOAT flt; DATE date; diff --git a/modules/rostests/winetests/scrrun/filesystem.c b/modules/rostests/winetests/scrrun/filesystem.c index d0c448c085..29ee73f243 100644 --- a/modules/rostests/winetests/scrrun/filesystem.c +++ b/modules/rostests/winetests/scrrun/filesystem.c @@ -375,7 +375,7 @@ static void test_GetFileVersion(void) BSTR path, version; HRESULT hr; - GetSystemDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + GetSystemDirectoryW(pathW, ARRAY_SIZE(pathW)); lstrcpyW(filenameW, pathW); lstrcatW(filenameW, k32W); @@ -438,7 +438,7 @@ static void test_GetParentFolderName(void) hr = IFileSystem3_GetParentFolderName(fs3, NULL, NULL); ok(hr == E_POINTER, "GetParentFolderName returned %x, expected E_POINTER\n", hr); - for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) { + for(i=0; i < ARRAY_SIZE(tests); i++) { result = (BSTR)0xdeadbeef; path = tests[i].path ? SysAllocString(tests[i].path) : NULL; hr = IFileSystem3_GetParentFolderName(fs3, path, &result); @@ -481,7 +481,7 @@ static void test_GetFileName(void) hr = IFileSystem3_GetFileName(fs3, NULL, NULL); ok(hr == E_POINTER, "GetFileName returned %x, expected E_POINTER\n", hr); - for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) { + for(i=0; i < ARRAY_SIZE(tests); i++) { result = (BSTR)0xdeadbeef; path = tests[i].path ? SysAllocString(tests[i].path) : NULL; hr = IFileSystem3_GetFileName(fs3, path, &result); @@ -527,7 +527,7 @@ static void test_GetBaseName(void) hr = IFileSystem3_GetBaseName(fs3, NULL, NULL); ok(hr == E_POINTER, "GetBaseName returned %x, expected E_POINTER\n", hr); - for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) { + for(i=0; i < ARRAY_SIZE(tests); i++) { result = (BSTR)0xdeadbeef; path = tests[i].path ? SysAllocString(tests[i].path) : NULL; hr = IFileSystem3_GetBaseName(fs3, path, &result); @@ -1521,7 +1521,7 @@ static void test_CreateTextFile(void) /* File was created in Unicode mode, it contains 0xfffe BOM. Opening it in non-Unicode mode treats BOM like a valuable data with appropriate CP_ACP -> WCHAR conversion. */ buffW[0] = 0; - MultiByteToWideChar(CP_ACP, 0, utf16bom, -1, buffW, sizeof(buffW)/sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, utf16bom, -1, buffW, ARRAY_SIZE(buffW)); hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -1569,7 +1569,7 @@ static void test_WriteLine(void) ret = ReadFile(file, buffA, sizeof(buffA), &r, NULL); ok(ret && r, "read %d, got %d, %d\n", r, ret, GetLastError()); - len = MultiByteToWideChar(CP_ACP, 0, buffA, r, buffW, sizeof(buffW)/sizeof(WCHAR)); + len = MultiByteToWideChar(CP_ACP, 0, buffA, r, buffW, ARRAY_SIZE(buffW)); buffW[len] = 0; lstrcpyW(buff2W, nameW); lstrcatW(buff2W, crlfW); @@ -1655,7 +1655,7 @@ static void test_ReadAll(void) hr = ITextStream_ReadAll(stream, &str); ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr); buffW[0] = 0; - MultiByteToWideChar(CP_ACP, 0, utf16bom, -1, buffW, sizeof(buffW)/sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, utf16bom, -1, buffW, ARRAY_SIZE(buffW)); ok(str[0] == buffW[0] && str[1] == buffW[1], "got %s, %d\n", wine_dbgstr_w(str), SysStringLen(str)); SysFreeString(str); ITextStream_Release(stream); @@ -1801,7 +1801,7 @@ static void test_Read(void) ok(hr == S_OK, "got 0x%08x\n", hr); buffW[0] = 0; - MultiByteToWideChar(CP_ACP, 0, utf16bom, -1, buffW, sizeof(buffW)/sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, utf16bom, -1, buffW, ARRAY_SIZE(buffW)); ok(!lstrcmpW(str, buffW), "got %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(buffW)); ok(SysStringLen(str) == 2, "got %d\n", SysStringLen(str)); @@ -2151,7 +2151,7 @@ static void test_GetExtensionName(void) HRESULT hr; int i; - for (i = 0; i < sizeof(extension_tests)/sizeof(extension_tests[0]); i++) { + for (i = 0; i < ARRAY_SIZE(extension_tests); i++) { path = SysAllocString(extension_tests[i].path); ext = NULL; @@ -2190,7 +2190,7 @@ static void test_GetSpecialFolder(void) ok(hr == S_OK, "got 0x%08x\n", hr); hr = IFolder_get_Path(folder, &path); ok(hr == S_OK, "got 0x%08x\n", hr); - GetWindowsDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + GetWindowsDirectoryW(pathW, ARRAY_SIZE(pathW)); ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW)); SysFreeString(path); IFolder_Release(folder); @@ -2199,7 +2199,7 @@ static void test_GetSpecialFolder(void) ok(hr == S_OK, "got 0x%08x\n", hr); hr = IFolder_get_Path(folder, &path); ok(hr == S_OK, "got 0x%08x\n", hr); - GetSystemDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR)); + GetSystemDirectoryW(pathW, ARRAY_SIZE(pathW)); ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW)); SysFreeString(path); IFolder_Release(folder); @@ -2208,7 +2208,7 @@ static void test_GetSpecialFolder(void) ok(hr == S_OK, "got 0x%08x\n", hr); hr = IFolder_get_Path(folder, &path); ok(hr == S_OK, "got 0x%08x\n", hr); - ret = GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW); + ret = GetTempPathW(ARRAY_SIZE(pathW), pathW); if (ret && pathW[ret-1] == '\\') pathW[ret-1] = 0;
5 years, 10 months
1
0
0
0
[reactos] 01/01: [RSAENH_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d4f1f05a33cc88020a71…
commit 9d4f1f05a33cc88020a7111a49a24ed2710d7581 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:12:04 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:12:04 2019 +0100 [RSAENH_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/rsaenh/rsaenh.c | 67 +++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/modules/rostests/winetests/rsaenh/rsaenh.c b/modules/rostests/winetests/rsaenh/rsaenh.c index bc8e798cdd..3e782be279 100644 --- a/modules/rostests/winetests/rsaenh/rsaenh.c +++ b/modules/rostests/winetests/rsaenh/rsaenh.c @@ -1815,7 +1815,7 @@ static void test_hmac(void) { 0xcf, 0x10, 0x6b, 0xb6, 0x7d, 0x0f, 0x13, 0x32 }; int i; - for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i; + for (i=0; i < ARRAY_SIZE(abData); i++) abData[i] = (BYTE)i; if (!derive_key(CALG_RC2, &hKey, 56)) return; @@ -1829,7 +1829,7 @@ static void test_hmac(void) { result = CryptHashData(hHash, abData, sizeof(abData), 0); ok(result, "%08x\n", GetLastError()); - dwLen = sizeof(abData)/sizeof(BYTE); + dwLen = ARRAY_SIZE(abData); result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0); ok(result, "%08x\n", GetLastError()); @@ -1855,8 +1855,8 @@ static void test_mac(void) { static const BYTE mac_40[8] = { 0xb7, 0xa2, 0x46, 0xe9, 0x11, 0x31, 0xe0, 0xad}; int i; - for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abData[i] = (BYTE)i; - for (i=0; i<sizeof(abData)/sizeof(BYTE); i++) abEnc[i] = (BYTE)i; + for (i=0; i < ARRAY_SIZE(abData); i++) abData[i] = (BYTE)i; + for (i=0; i < ARRAY_SIZE(abData); i++) abEnc[i] = (BYTE)i; if (!derive_key(CALG_RC2, &hKey, 40)) return; @@ -1871,7 +1871,7 @@ static void test_mac(void) { result = CryptHashData(hHash, abData, sizeof(abData), 0); ok(result, "%08x\n", GetLastError()); - dwLen = sizeof(abData)/sizeof(BYTE); + dwLen = ARRAY_SIZE(abData); result = CryptGetHashParam(hHash, HP_HASHVAL, abData, &dwLen, 0); ok(result && dwLen == 8, "%08x, dwLen: %d\n", GetLastError(), dwLen); @@ -2282,6 +2282,7 @@ static void test_rsa_encrypt(void) BYTE abData[2048] = "Wine rocks!"; BOOL result; DWORD dwVal, dwLen; + DWORD err; /* It is allowed to use the key exchange key for encryption/decryption */ result = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hRSAKey); @@ -2297,6 +2298,7 @@ static void test_rsa_encrypt(void) } ok(result, "CryptEncrypt failed: %08x\n", GetLastError()); ok(dwLen == 128, "Unexpected length %d\n", dwLen); + /* PKCS1 V1.5 */ dwLen = 12; result = CryptEncrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen, (DWORD)sizeof(abData)); ok (result, "%08x\n", GetLastError()); @@ -2304,7 +2306,52 @@ static void test_rsa_encrypt(void) result = CryptDecrypt(hRSAKey, 0, TRUE, 0, abData, &dwLen); ok (result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError()); - + + /* OAEP, RFC 8017 PKCS #1 V2.2 */ + /* Test minimal buffer length requirement */ + dwLen = 1; + SetLastError(0xdeadbeef); + result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, 20 * 2 + 2); + err = GetLastError(); + ok(!result && err == ERROR_MORE_DATA, "%08x\n", err); + + /* Test data length limit */ + dwLen = sizeof(abData) - (20 * 2 + 2) + 1; + result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData)); + err = GetLastError(); + ok(!result && err == NTE_BAD_LEN, "%08x\n", err); + + /* Test malformed data */ + dwLen = 12; + SetLastError(0xdeadbeef); + memcpy(abData, "Wine rocks!", dwLen); + result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen); + err = GetLastError(); + /* NTE_DOUBLE_ENCRYPT on xp or 2003 */ + ok(!result && (err == NTE_BAD_DATA || broken(err == NTE_DOUBLE_ENCRYPT)), "%08x\n", err); + + /* Test decrypt with insufficient buffer */ + dwLen = 12; + SetLastError(0xdeadbeef); + memcpy(abData, "Wine rocks!", 12); + result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData)); + ok(result, "%08x\n", GetLastError()); + dwLen = 11; + SetLastError(0xdeadbeef); + result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen); + err = GetLastError(); + /* broken on xp or 2003 */ + ok((!result && dwLen == 11 && err == NTE_BAD_DATA) || broken(result == TRUE && dwLen == 12 && err == ERROR_NO_TOKEN), + "%08x %d %08x\n", result, dwLen, err); + + /* Test normal encryption and decryption */ + dwLen = 12; + memcpy(abData, "Wine rocks!", dwLen); + result = CryptEncrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen, (DWORD)sizeof(abData)); + ok(result, "%08x\n", GetLastError()); + result = CryptDecrypt(hRSAKey, 0, TRUE, CRYPT_OAEP, abData, &dwLen); + ok(result && dwLen == 12 && !memcmp(abData, "Wine rocks!", 12), "%08x\n", GetLastError()); + dwVal = 0xdeadbeef; dwLen = sizeof(DWORD); result = CryptGetKeyParam(hRSAKey, KP_PERMISSIONS, (BYTE*)&dwVal, &dwLen, 0); @@ -2725,7 +2772,7 @@ static void test_import_hmac(void) }; DWORD i; - for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) + for (i = 0; i < ARRAY_SIZE(cases); i++) { const struct rfc2202_test_case *test_case = &cases[i]; DWORD size = sizeof(BLOBHEADER) + sizeof(DWORD) + test_case->key_len; @@ -3822,13 +3869,13 @@ static void test_key_derivation(const char *prov) }, }; /* Due to differences between encryption from <= 2000 and >= XP some tests need to be skipped */ - int old_broken[sizeof(tests)/sizeof(tests[0])]; + int old_broken[ARRAY_SIZE(tests)]; memset(old_broken, 0, sizeof(old_broken)); old_broken[3] = old_broken[4] = old_broken[15] = old_broken[16] = 1; old_broken[27] = old_broken[28] = old_broken[39] = old_broken[40] = 1; uniquecontainer(NULL); - for (i=0; i<sizeof(tests)/sizeof(tests[0]); i++) + for (i=0; i < ARRAY_SIZE(tests); i++) { if (win2k && old_broken[i]) continue; @@ -3886,7 +3933,7 @@ err: START_TEST(rsaenh) { - for (iProv = 0; iProv < sizeof(szProviders) / sizeof(szProviders[0]); iProv++) + for (iProv = 0; iProv < ARRAY_SIZE(szProviders); iProv++) { if (!init_base_environment(szProviders[iProv], 0)) continue;
5 years, 10 months
1
0
0
0
[reactos] 01/01: [RPCRT4_WINETEST] Sync with Wine Staging 4.0. CORE-15682
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f2f9161a02d974b75c36d…
commit f2f9161a02d974b75c36dc494bd8c0bb3e218fbd Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sat Feb 2 14:11:36 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sat Feb 2 14:11:36 2019 +0100 [RPCRT4_WINETEST] Sync with Wine Staging 4.0. CORE-15682 --- modules/rostests/winetests/rpcrt4/CMakeLists.txt | 6 +- modules/rostests/winetests/rpcrt4/cstub.c | 248 ++++++++- modules/rostests/winetests/rpcrt4/cstub.idl | 37 ++ modules/rostests/winetests/rpcrt4/ndr_marshall.c | 664 ++++++++++++++++++++--- modules/rostests/winetests/rpcrt4/rpc.c | 29 +- modules/rostests/winetests/rpcrt4/rpc_async.c | 23 +- modules/rostests/winetests/rpcrt4/server.c | 179 +++++- modules/rostests/winetests/rpcrt4/server.idl | 3 + 8 files changed, 1059 insertions(+), 130 deletions(-) diff --git a/modules/rostests/winetests/rpcrt4/CMakeLists.txt b/modules/rostests/winetests/rpcrt4/CMakeLists.txt index ea8c329a3d..dbb7cf7fc1 100644 --- a/modules/rostests/winetests/rpcrt4/CMakeLists.txt +++ b/modules/rostests/winetests/rpcrt4/CMakeLists.txt @@ -3,13 +3,15 @@ remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502) add_definitions( -DUSE_WINE_TODOS - -DWINETEST_USE_DBGSTR_LONGLONG) + -DWINETEST_USE_DBGSTR_LONGLONG + -DPROXY_DELEGATION) include_directories(${CMAKE_CURRENT_BINARY_DIR}) set(IDL_FLAGS ${IDL_FLAGS} --prefix-server=s_) add_rpc_files(client server.idl) add_rpc_files(server server.idl) unset(IDL_FLAGS) +add_rpcproxy_files(cstub.idl) list(APPEND SOURCE cstub.c @@ -19,6 +21,8 @@ list(APPEND SOURCE rpc_async.c server.c testlist.c + ${CMAKE_CURRENT_BINARY_DIR}/cstub_p.c + ${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c ${CMAKE_CURRENT_BINARY_DIR}/server_c.c ${CMAKE_CURRENT_BINARY_DIR}/server_s.c) diff --git a/modules/rostests/winetests/rpcrt4/cstub.c b/modules/rostests/winetests/rpcrt4/cstub.c index 606107fcfd..a182b3ba27 100644 --- a/modules/rostests/winetests/rpcrt4/cstub.c +++ b/modules/rostests/winetests/rpcrt4/cstub.c @@ -19,11 +19,13 @@ */ #include <stdarg.h> +#include <stdio.h> -#define PROXY_DELEGATION #define COBJMACROS +#ifdef __REACTOS__ +#define CONST_VTABLE +#endif -#include "wine/test.h" #include <windef.h> #include <winbase.h> #include <winnt.h> @@ -35,10 +37,22 @@ #include "rpcdce.h" #include "rpcproxy.h" +#include "wine/heap.h" +#include "wine/test.h" + +#include "cstub_p.h" + static CStdPSFactoryBuffer PSFactoryBuffer; -CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer) -CSTDSTUBBUFFER2RELEASE(&PSFactoryBuffer) +static ULONG WINAPI test_CStdStubBuffer_Release(IRpcStubBuffer *This) +{ + return NdrCStdStubBuffer_Release(This, (IPSFactoryBuffer *)&PSFactoryBuffer); +} + +static ULONG WINAPI test_CStdStubBuffer2_Release(IRpcStubBuffer *This) +{ + return NdrCStdStubBuffer2_Release(This, (IPSFactoryBuffer *)&PSFactoryBuffer); +} static GUID IID_if1 = {0x12345678, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}}; static GUID IID_if2 = {0x12345679, 1234, 5678, {12,34,56,78,90,0xab,0xcd,0xef}}; @@ -186,7 +200,18 @@ static CInterfaceStubVtbl if1_stub_vtbl = 5, &if1_table[-3] }, - { CStdStubBuffer_METHODS } + { + CStdStubBuffer_QueryInterface, + CStdStubBuffer_AddRef, + test_CStdStubBuffer_Release, + CStdStubBuffer_Connect, + CStdStubBuffer_Disconnect, + CStdStubBuffer_Invoke, + CStdStubBuffer_IsIIDSupported, + CStdStubBuffer_CountRefs, + CStdStubBuffer_DebugServerQueryInterface, + CStdStubBuffer_DebugServerRelease + } }; static CINTERFACE_PROXY_VTABLE(13) if2_proxy_vtbl = @@ -257,7 +282,7 @@ static CInterfaceStubVtbl if2_stub_vtbl = 13, &if2_table[-3] }, - { CStdStubBuffer_DELEGATING_METHODS } + { 0, 0, test_CStdStubBuffer2_Release, 0, 0, 0, 0, 0, 0, 0 } }; static CINTERFACE_PROXY_VTABLE(5) if3_proxy_vtbl = @@ -596,7 +621,7 @@ static IPSFactoryBuffer *test_NdrDllGetClassObject(void) #undef VTBL_PROXY_TEST #undef VTBL_PROXY_TEST_NOT_ZERO - for (i = 0; i < sizeof(interfaces)/sizeof(interfaces[0]); i++) + for (i = 0; i < ARRAY_SIZE(interfaces); i++) ok( proxy_vtbl[i]->header.piid == interfaces[i], "wrong proxy %u iid %p/%p\n", i, proxy_vtbl[i]->header.piid, interfaces[i] ); @@ -1194,9 +1219,217 @@ static void test_NdrDllRegisterProxy( void ) } } +static HANDLE create_process(const char *arg) +{ + PROCESS_INFORMATION pi; + STARTUPINFOA si = {0}; + char cmdline[200]; + char **argv; + BOOL ret; + + si.cb = sizeof(si); + winetest_get_mainargs(&argv); + sprintf(cmdline, "\"%s\" %s %s", argv[0], argv[1], arg); + ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret, "CreateProcess failed: %u\n", GetLastError()); + CloseHandle(pi.hThread); + return pi.hProcess; +} + +DEFINE_GUID(CLSID_test1,0xdeadf00d,0x0001,0x44c7,0x85,0x0f,0x2a,0x0f,0x46,0x5c,0x0c,0x6c); + +static HRESULT WINAPI test1_QueryInterface(ITest1 *iface, REFIID iid, void **out) +{ + if (winetest_debug > 1) trace("%s\n", wine_dbgstr_guid(iid)); + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_ITest1)) + { + *out = iface; + return S_OK; + } + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test1_AddRef(ITest1 *iface) +{ + return 2; +} + +static ULONG WINAPI test1_Release(ITest1 *iface) +{ + return 1; +} + +static HRESULT WINAPI test1_GetClassID(ITest1 *iface, CLSID *clsid) +{ + *clsid = CLSID_test1; + return S_OK; +} + +static int WINAPI test1_square(ITest1 *iface, int x) +{ + return x * x; +} + +static const ITest1Vtbl test1_vtbl = +{ + test1_QueryInterface, + test1_AddRef, + test1_Release, + test1_GetClassID, + test1_square, +}; + +static HRESULT WINAPI test_cf_QueryInterface(IClassFactory *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory)) + { + *out = iface; + return S_OK; + } + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_cf_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI test_cf_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI test_cf_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out) +{ + ITest1 *obj = heap_alloc(sizeof(*obj)); + + obj->lpVtbl = &test1_vtbl; + + return ITest1_QueryInterface(obj, iid, out); +} + +static HRESULT WINAPI test_cf_LockServer(IClassFactory *iface, BOOL lock) +{ + return S_OK; +} + +static const IClassFactoryVtbl test_cf_vtbl = +{ + test_cf_QueryInterface, + test_cf_AddRef, + test_cf_Release, + test_cf_CreateInstance, + test_cf_LockServer, +}; + +static IClassFactory test_cf = { &test_cf_vtbl }; + +extern CStdPSFactoryBuffer gPFactory; +extern const ProxyFileInfo * aProxyFileList; + +static void local_server_proc(void) +{ + DWORD obj_cookie, ps_cookie, index; + HANDLE stop_event, ready_event; + IPSFactoryBuffer *ps; + HRESULT hr; + + stop_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "wine_cstub_test_server_stop"); + ready_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "wine_cstub_test_server_ready"); + + CoInitialize(NULL); + + hr = CoRegisterClassObject(&CLSID_test1, (IUnknown *)&test_cf, + CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &obj_cookie); + ok(hr == S_OK, "got %#x\n", hr); + + hr = NdrDllGetClassObject(&CLSID_test_ps, &IID_IPSFactoryBuffer, (void **)&ps, + &aProxyFileList, &CLSID_test_ps, &gPFactory); + ok(hr == S_OK, "got %#x\n", hr); + + hr = CoRegisterClassObject(&CLSID_test_ps, (IUnknown *)ps, + CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &ps_cookie); + ok(hr == S_OK, "got %#x\n", hr); + + hr = CoRegisterPSClsid(&IID_ITest1, &CLSID_test_ps); + ok(hr == S_OK, "got %#x\n", hr); + + SetEvent(ready_event); + + hr = CoWaitForMultipleHandles(0, 1000, 1, &stop_event, &index); + ok(hr == S_OK, "got %#x\n", hr); + ok(!index, "got %u\n", index); + + hr = CoRevokeClassObject(ps_cookie); + ok(hr == S_OK, "got %#x\n", hr); + + hr = CoRevokeClassObject(obj_cookie); + ok(hr == S_OK, "got %#x\n", hr); + + CoUninitialize(); + ExitProcess(0); +} + +static void test_delegated_methods(void) +{ + HANDLE process, stop_event, ready_event; + IPSFactoryBuffer *ps; + ITest1 *test_obj; + DWORD ps_cookie; + CLSID clsid; + HRESULT hr; + int ret; + + stop_event = CreateEventA(NULL, TRUE, FALSE, "wine_cstub_test_server_stop"); + ready_event = CreateEventA(NULL, TRUE, FALSE, "wine_cstub_test_server_ready"); + + process = create_process("server"); + ok(!WaitForSingleObject(ready_event, 1000), "wait failed\n"); + + hr = NdrDllGetClassObject(&CLSID_test_ps, &IID_IPSFactoryBuffer, (void **)&ps, + &aProxyFileList, &CLSID_test_ps, &gPFactory); + ok(hr == S_OK, "got %#x\n", hr); + + hr = CoRegisterClassObject(&CLSID_test_ps, (IUnknown *)ps, + CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &ps_cookie); + ok(hr == S_OK, "got %#x\n", hr); + + hr = CoRegisterPSClsid(&IID_ITest1, &CLSID_test_ps); + ok(hr == S_OK, "got %#x\n", hr); + + hr = CoCreateInstance(&CLSID_test1, NULL, CLSCTX_LOCAL_SERVER, &IID_ITest1, (void **)&test_obj); + ok(hr == S_OK, "got %#x\n", hr); + + ret = ITest1_square(test_obj, 3); + ok(ret == 9, "got %d\n", ret); + + hr = ITest1_GetClassID(test_obj, &clsid); + ok(hr == S_OK, "got %#x\n", hr); + ok(IsEqualGUID(&clsid, &CLSID_test1), "got %s\n", wine_dbgstr_guid(&clsid)); + + ITest1_Release(test_obj); + + SetEvent(stop_event); + ok(!WaitForSingleObject(process, 1000), "wait failed\n"); + + hr = CoRevokeClassObject(ps_cookie); + ok(hr == S_OK, "got %#x\n", hr); +} + START_TEST( cstub ) { IPSFactoryBuffer *ppsf; + int argc; + char **argv; + + argc = winetest_get_mainargs( &argv ); + if (argc > 2 && !strcmp(argv[2], "server")) + { + local_server_proc(); + return; + } OleInitialize(NULL); @@ -1209,6 +1442,7 @@ START_TEST( cstub ) test_Release(ppsf); test_delegating_Invoke(ppsf); test_NdrDllRegisterProxy(); + test_delegated_methods(); OleUninitialize(); } diff --git a/modules/rostests/winetests/rpcrt4/cstub.idl b/modules/rostests/winetests/rpcrt4/cstub.idl new file mode 100644 index 0000000000..461bd87b30 --- /dev/null +++ b/modules/rostests/winetests/rpcrt4/cstub.idl @@ -0,0 +1,37 @@ +/* + * IDL to test COM object proxy/stub functions + * + * Copyright 2018 Zebediah Figura + * + * 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 + */ + +#pragma makedep proxy + +import "oleidl.idl"; + +[ + uuid(deadbeef-0001-44c7-850f-2a0f465c0c6c), + object +] +interface ITest1 : IPersist +{ + int square(int x); +} + +[ + uuid(deadbeef-ffff-44c7-850f-2a0f465c0c6c) +] +coclass test_ps { interface IPSFactoryBuffer; } diff --git a/modules/rostests/winetests/rpcrt4/ndr_marshall.c b/modules/rostests/winetests/rpcrt4/ndr_marshall.c index 21baba74ac..e4a4c6a727 100644 --- a/modules/rostests/winetests/rpcrt4/ndr_marshall.c +++ b/modules/rostests/winetests/rpcrt4/ndr_marshall.c @@ -21,10 +21,10 @@ #define _WIN32_WINNT 0x0500 #define NTDDI_WIN2K 0x05000000 #define NTDDI_VERSION NTDDI_WIN2K /* for some MIDL_STUB_MESSAGE fields */ +#define COBJMACROS #include <stdarg.h> -#include "wine/test.h" #include <windef.h> #include <winbase.h> #include <winnt.h> @@ -35,6 +35,10 @@ #include "rpcdce.h" #include "rpcproxy.h" #include "midles.h" +#include "ndrtypes.h" + +#include "wine/heap.h" +#include "wine/test.h" static int my_alloc_called; static int my_free_called; @@ -154,17 +158,17 @@ static void test_ndr_simple_type(void) StubMsg.BufferLength = 16; StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength); l = 0xcafebabe; - NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, 8 /* FC_LONG */); + NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, FC_LONG); ok(StubMsg.Buffer == StubMsg.BufferStart + 4, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart); ok(*(LONG*)StubMsg.BufferStart == l, "%d\n", *(LONG*)StubMsg.BufferStart); StubMsg.Buffer = StubMsg.BufferStart + 1; - NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, 8 /* FC_LONG */); + NdrSimpleTypeMarshall(&StubMsg, (unsigned char*)&l, FC_LONG); ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart); ok(*(LONG*)(StubMsg.BufferStart + 4) == l, "%d\n", *(LONG*)StubMsg.BufferStart); StubMsg.Buffer = StubMsg.BufferStart + 1; - NdrSimpleTypeUnmarshall(&StubMsg, (unsigned char*)&l2, 8 /* FC_LONG */); + NdrSimpleTypeUnmarshall(&StubMsg, (unsigned char*)&l2, FC_LONG); ok(StubMsg.Buffer == StubMsg.BufferStart + 8, "%p %p\n", StubMsg.Buffer, StubMsg.BufferStart); ok(l2 == l, "%d\n", l2); @@ -186,7 +190,6 @@ static void test_pointer_marshal(const unsigned char *formattypes, void *ptr; unsigned char *mem, *mem_orig; - my_alloc_called = my_free_called = 0; if(!cmp) cmp = memcmp; @@ -230,7 +233,7 @@ static void test_pointer_marshal(const unsigned char *formattypes, size = NdrPointerMemorySize( &StubMsg, formattypes ); ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size); ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); - if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */) + if (formattypes[1] & FC_POINTER_DEREF) ok(size == srcsize + sizeof(void *), "%s: mem size %u\n", msgpfx, size); else ok(size == srcsize, "%s: mem size %u\n", msgpfx, size); @@ -240,7 +243,7 @@ static void test_pointer_marshal(const unsigned char *formattypes, size = NdrPointerMemorySize( &StubMsg, formattypes ); ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size); ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); - if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */) + if (formattypes[1] & FC_POINTER_DEREF) ok(size == srcsize + sizeof(void *) + 16, "%s: mem size %u\n", msgpfx, size); else ok(size == srcsize + 16, "%s: mem size %u\n", msgpfx, size); @@ -250,19 +253,21 @@ static void test_pointer_marshal(const unsigned char *formattypes, size = NdrPointerMemorySize( &StubMsg, formattypes ); ok(size == StubMsg.MemorySize, "%s: mem size %u size %u\n", msgpfx, StubMsg.MemorySize, size); ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); - if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */) + if (formattypes[1] & FC_POINTER_DEREF) ok(size == srcsize + sizeof(void *) + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size); else ok(size == srcsize + (srcsize == 8 ? 8 : sizeof(void *)), "%s: mem size %u\n", msgpfx, size); size = srcsize; - if(formattypes[1] & 0x10) size += 4; + if (formattypes[1] & FC_POINTER_DEREF) size += 4; StubMsg.Buffer = StubMsg.BufferStart; StubMsg.MemorySize = 0; - mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); - - if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */) + /* Using my_alloc() here is necessary to prevent a crash in Windows 7+. */ + mem_orig = mem = my_alloc(size); + memset(mem, 0, size); + my_alloc_called = my_free_called = 0; + if (formattypes[1] & FC_POINTER_DEREF) *(void**)mem = NULL; ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 ); ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); @@ -270,31 +275,51 @@ static void test_pointer_marshal(const unsigned char *formattypes, ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize); - ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); - my_alloc_called = 0; + ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + /* On Windows 7+ unmarshalling may involve calls to NdrFree, for unclear reasons. */ + my_free_called = 0; + + NdrPointerFree(&StubMsg, mem, formattypes); + if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + { + /* In this case the top-level pointer is not freed. */ + ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); + HeapFree(GetProcessHeap(), 0, mem); + } + else + ok(my_free_called == 1 + num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); /* reset the buffer and call with must alloc */ + my_alloc_called = my_free_called = 0; StubMsg.Buffer = StubMsg.BufferStart; - if(formattypes[1] & 0x10 /* FC_POINTER_DEREF */) + mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (formattypes[1] & FC_POINTER_DEREF) *(void**)mem = NULL; ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 ); ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); /* doesn't allocate mem in this case */ -todo_wine { ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig); - } ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize); - -todo_wine { ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); -} - my_alloc_called = 0; - if(formattypes[0] != 0x11 /* FC_RP */) + ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + NdrPointerFree(&StubMsg, mem, formattypes); + if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + { + /* In this case the top-level pointer is not freed. */ + ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); + HeapFree(GetProcessHeap(), 0, mem); + } + else + ok(my_free_called == 1 + num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + if (formattypes[0] != FC_RP) { /* now pass the address of a NULL ptr */ mem = NULL; + my_alloc_called = my_free_called = 0; StubMsg.Buffer = StubMsg.BufferStart; ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 ); ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); @@ -314,20 +339,161 @@ todo_wine { StubMsg.IsClient = 0; ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 ); ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); - if (formattypes[2] == 0xd /* FC_ENUM16 */) + if (formattypes[2] == FC_ENUM16) ok(mem != StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem points to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart); else ok(mem == StubMsg.BufferStart + wiredatalen - srcsize, "%s: mem doesn't point to buffer %p %p\n", msgpfx, mem, StubMsg.BufferStart); ok(!cmp(mem, memsrc, size), "%s: incorrectly unmarshaled\n", msgpfx); ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize); - if (formattypes[2] != 0xd /* FC_ENUM16 */) { + if (formattypes[2] != FC_ENUM16) + { ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); my_alloc_called = 0; } } } - HeapFree(GetProcessHeap(), 0, mem_orig); + + /* Server */ + StubMsg.IsClient = 0; + + /* For most basetypes (but not enum16), memory will not be allocated but + * instead point directly to the buffer. */ + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + mem = NULL; + ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 ); + ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); + ok(!!mem, "%s: mem was not allocated\n", msgpfx); + ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); + ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); + ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize); + if (formattypes[2] == FC_ENUM16) + ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + else + ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + NdrPointerFree(&StubMsg, mem, formattypes); + if (formattypes[2] == FC_ENUM16) + ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called); + else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + { + /* In theory this should be freed to correspond with the allocation, but + * FC_ALLOCED_ON_STACK is set, and NdrPointerFree() has no way of + * knowing that the memory allocated by NdrPointerUnmarshall() isn't + * stack memory. In practice it always *is* stack memory if ON_STACK is + * set, so this leak isn't a concern. */ + ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called); + HeapFree(GetProcessHeap(), 0, mem); + } + else + ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + /* reset the buffer and call with must alloc */ + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + mem = NULL; + ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 ); + ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); + ok(!!mem, "%s: mem was not allocated\n", msgpfx); + ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); + ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); + ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize); + if (formattypes[2] == FC_ENUM16) + ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + else + ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + NdrPointerFree(&StubMsg, mem, formattypes); + if (formattypes[2] == FC_ENUM16) + ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called); + else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + { + ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called); + HeapFree(GetProcessHeap(), 0, mem); + } + else + ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + /* Τest with an existing pointer. Unless it's a stack pointer (and deref'd) + * a new pointer will be allocated anyway (in fact, an invalid pointer works + * in every such case). */ + + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (formattypes[1] & FC_POINTER_DEREF) + *(void**)mem = NULL; + ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 0 ); + ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); + if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig); + else + { + ok(mem != mem_orig, "%s: mem has not changed\n", msgpfx); + HeapFree(GetProcessHeap(), 0, mem_orig); + } + ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); + ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); + ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize); + if (formattypes[2] == FC_ENUM16) + ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + ok(my_alloc_called == 0, "%s: my_alloc got called %d times\n", msgpfx, my_free_called); + else + ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + NdrPointerFree(&StubMsg, mem, formattypes); + if (formattypes[2] == FC_ENUM16) + ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called); + else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + { + ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called); + HeapFree(GetProcessHeap(), 0, mem); + } + else + ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + /* reset the buffer and call with must alloc */ + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + mem_orig = mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + if (formattypes[1] & FC_POINTER_DEREF) + *(void**)mem = NULL; + ptr = NdrPointerUnmarshall( &StubMsg, &mem, formattypes, 1 ); + ok(ptr == NULL, "%s: ret %p\n", msgpfx, ptr); + if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + ok(mem == mem_orig, "%s: mem has changed %p %p\n", msgpfx, mem, mem_orig); + else + { + ok(mem != mem_orig, "%s: mem has not changed\n", msgpfx); + HeapFree(GetProcessHeap(), 0, mem_orig); + } + ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); + ok(StubMsg.Buffer - StubMsg.BufferStart == wiredatalen, "%s: Buffer %p Start %p len %d\n", msgpfx, StubMsg.Buffer, StubMsg.BufferStart, wiredatalen); + ok(StubMsg.MemorySize == 0, "%s: memorysize %d\n", msgpfx, StubMsg.MemorySize); + if (formattypes[2] == FC_ENUM16) + ok(my_alloc_called == 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + ok(my_alloc_called == 0, "%s: my_alloc got called %d times\n", msgpfx, my_free_called); + else + ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); + ok(!my_free_called, "%s: my_free got called %d times\n", msgpfx, my_free_called); + + NdrPointerFree(&StubMsg, mem, formattypes); + if (formattypes[2] == FC_ENUM16) + ok(my_free_called == 1, "%s: my_free got called %d times\n", msgpfx, my_free_called); + else if ((formattypes[1] & FC_ALLOCED_ON_STACK) && (formattypes[1] & FC_POINTER_DEREF)) + { + ok(my_free_called == 0, "%s: my_free got called %d times\n", msgpfx, my_free_called); + HeapFree(GetProcessHeap(), 0, mem); + } + else + ok(my_free_called == num_additional_allocs, "%s: my_free got called %d times\n", msgpfx, my_free_called); + HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart); } @@ -379,15 +545,15 @@ static void test_simple_types(void) 0x2, /* FC_CHAR */ 0x5c, /* FC_PAD */ }; - static const unsigned char fmtstr_rpup_char[] = + static const unsigned char fmtstr_rpup_char_onstack_deref[] = { - 0x11, 0x14, /* FC_RP [alloced_on_stack] */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */ NdrFcShort( 0x2 ), /* Offset= 2 (4) */ 0x12, 0x8, /* FC_UP [simple_pointer] */ 0x2, /* FC_CHAR */ 0x5c, /* FC_PAD */ }; - static const unsigned char fmtstr_rpup_char2[] = + static const unsigned char fmtstr_rpup_char_onstack[] = { 0x11, 0x04, /* FC_RP [alloced_on_stack] */ NdrFcShort( 0x2 ), /* Offset= 2 (4) */ @@ -395,6 +561,14 @@ static void test_simple_types(void) 0x2, /* FC_CHAR */ 0x5c, /* FC_PAD */ }; + static const unsigned char fmtstr_rpup_char_deref[] = + { + 0x11, 0x10, /* FC_RP [pointer_deref] */ + NdrFcShort( 0x2 ), /* Offset= 2 (4) */ + 0x12, 0x8, /* FC_UP [simple_pointer] */ + 0x2, /* FC_CHAR */ + 0x5c, /* FC_PAD */ + }; static const unsigned char fmtstr_up_wchar[] = { @@ -479,8 +653,9 @@ static void test_simple_types(void) test_pointer_marshal(fmtstr_rp_char, ch_ptr, 1, &ch, 1, NULL, 0, "rp_char"); - test_pointer_marshal(fmtstr_rpup_char, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char"); - test_pointer_marshal(fmtstr_rpup_char2, ch_ptr, 1, wiredata, 5, NULL, 0, "rpup_char2"); + test_pointer_marshal(fmtstr_rpup_char_onstack_deref, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char_onstack_deref"); + test_pointer_marshal(fmtstr_rpup_char_onstack, ch_ptr, 1, wiredata, 5, NULL, 0, "rpup_char_onstack"); + test_pointer_marshal(fmtstr_rpup_char_deref, &ch_ptr, 1, wiredata, 5, deref_cmp, 1, "rpup_char_deref"); s = 0xa597; if (use_pointer_ids) @@ -611,10 +786,8 @@ static void test_nontrivial_pointer_types(void) my_alloc_called = 0; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1); - todo_wine { - ok(mem == mem_orig, "mem alloced\n"); - ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); - } + ok(mem == mem_orig, "mem alloced\n"); + ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); my_free_called = 0; StubMsg.Buffer = StubMsg.BufferStart; @@ -639,43 +812,43 @@ static void test_nontrivial_pointer_types(void) /* Server */ my_alloc_called = 0; + my_free_called = 0; StubMsg.IsClient = 0; mem = NULL; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0); ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n"); - todo_wine ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called); NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] ); + ok(my_free_called == 0, "free called %d\n", my_free_called); + my_free(mem); my_alloc_called = 0; + my_free_called = 0; mem = NULL; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1); ok(mem != StubMsg.BufferStart, "mem pointing at buffer\n"); - todo_wine ok(my_alloc_called == 1, "alloc called %d\n", my_alloc_called); NdrPointerFree( &StubMsg, mem, &fmtstr_ref_unique_out[4] ); + ok(my_free_called == 0, "free called %d\n", my_free_called); + my_free(mem); my_alloc_called = 0; mem = mem_orig; *(void **)mem = NULL; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 0); - todo_wine { - ok(mem == mem_orig, "mem alloced\n"); - ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); - } + ok(mem == mem_orig, "mem alloced\n"); + ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); my_alloc_called = 0; mem = mem_orig; *(void **)mem = NULL; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, &fmtstr_ref_unique_out[4], 1); - todo_wine { - ok(mem == mem_orig, "mem alloced\n"); - ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); - } + ok(mem == mem_orig, "mem alloced\n"); + ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); mem = my_alloc(sizeof(void *)); *(void **)mem = NULL; @@ -756,7 +929,10 @@ static void test_simple_struct_marshal(const unsigned char *formattypes, ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); my_alloc_called = 0; + my_free_called = 0; ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx); + NdrSimpleStructFree(&StubMsg, mem, formattypes ); + ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called); /* If we're a server we still use the supplied memory */ StubMsg.Buffer = StubMsg.BufferStart; @@ -767,7 +943,10 @@ static void test_simple_struct_marshal(const unsigned char *formattypes, ok(!cmp(mem, memsrc, srcsize), "%s: incorrectly unmarshaled\n", msgpfx); ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); my_alloc_called = 0; + my_free_called = 0; ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx); + NdrSimpleStructFree(&StubMsg, mem, formattypes ); + ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called); /* ...unless we pass a NULL ptr, then the buffer is used. Passing a NULL ptr while we're a client && !must_alloc @@ -785,6 +964,8 @@ static void test_simple_struct_marshal(const unsigned char *formattypes, ok(my_alloc_called == num_additional_allocs, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); my_alloc_called = 0; ok(StubMsg.MemorySize == 0, "%s: memorysize touched in unmarshal\n", msgpfx); + NdrSimpleStructFree(&StubMsg, mem, formattypes ); + ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called); } /*** now must_alloc is true ***/ @@ -800,7 +981,11 @@ static void test_simple_struct_marshal(const unsigned char *formattypes, ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n"); ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); my_alloc_called = 0; + my_free_called = 0; ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n"); + NdrSimpleStructFree(&StubMsg, mem, formattypes ); + ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called); + my_free(mem); mem = NULL; StubMsg.Buffer = StubMsg.BufferStart; @@ -809,8 +994,12 @@ static void test_simple_struct_marshal(const unsigned char *formattypes, ok(mem != mem_orig, "mem not changed %p %p\n", mem, mem_orig); ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n"); ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); - my_alloc_called = 0; + my_alloc_called = 0; + my_free_called = 0; ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n"); + NdrSimpleStructFree(&StubMsg, mem, formattypes ); + ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called); + my_free(mem); mem = mem_orig; StubMsg.Buffer = StubMsg.BufferStart; @@ -823,7 +1012,11 @@ static void test_simple_struct_marshal(const unsigned char *formattypes, ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n"); ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); my_alloc_called = 0; + my_free_called = 0; ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n"); + NdrSimpleStructFree(&StubMsg, mem, formattypes ); + ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called); + my_free(mem); mem = NULL; StubMsg.Buffer = StubMsg.BufferStart; @@ -835,7 +1028,11 @@ static void test_simple_struct_marshal(const unsigned char *formattypes, ok(!cmp(mem, memsrc, srcsize), "incorrectly unmarshaled\n"); ok(my_alloc_called == num_additional_allocs + 1, "%s: my_alloc got called %d times\n", msgpfx, my_alloc_called); my_alloc_called = 0; + my_free_called = 0; ok(StubMsg.MemorySize == 0, "memorysize touched in unmarshal\n"); + NdrSimpleStructFree(&StubMsg, mem, formattypes ); + ok(my_free_called == num_additional_allocs, "free called %d\n", my_free_called); + my_free(mem); HeapFree(GetProcessHeap(), 0, mem_orig); HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart); @@ -1015,6 +1212,341 @@ static void test_simple_struct(void) test_pointer_marshal(fmtstr_pointer_struct, &ps1, 17, wiredata, 21, ps1_cmp, 2, "pointer_struct"); } +struct aligned +{ + int a; + LONGLONG b; +}; + +static void test_struct_align(void) +{ + RPC_MESSAGE RpcMessage; + MIDL_STUB_MESSAGE StubMsg; + MIDL_STUB_DESC StubDesc; + void *ptr; + struct aligned *memsrc_orig, *memsrc, *mem; + + /* force bogus struct so that members are marshalled individually */ + static const unsigned char fmtstr[] = + { + 0x1a, /* FC_BOGUS_STRUCT */ + 0x7, /* alignment 8 */ + NdrFcShort(0x10), /* memory size 16 */ + NdrFcShort(0x0), + NdrFcShort(0x0), + 0x08, /* FC_LONG */ + 0x39, /* FC_ALIGNM8 */ + 0x0b, /* FC_HYPER */ + 0x5b, /* FC_END */ + }; + + memsrc_orig = heap_alloc_zero(sizeof(struct aligned) + 8); + /* intentionally mis-align memsrc */ + memsrc = (struct aligned *)((((ULONG_PTR)memsrc_orig + 7) & ~7) + 4); + + memsrc->a = 0xdeadbeef; + memsrc->b = ((ULONGLONG) 0xbadefeed << 32) | 0x2468ace0; + + StubDesc = Object_StubDesc; + StubDesc.pFormatTypes = fmtstr; + NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0); + + StubMsg.BufferLength = 0; + NdrComplexStructBufferSize(&StubMsg, (unsigned char *)memsrc, fmtstr); + + StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = heap_alloc(StubMsg.BufferLength); + StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength; + + ptr = NdrComplexStructMarshall(&StubMsg, (unsigned char *)memsrc, fmtstr); + ok(ptr == NULL, "ret %p\n", ptr); + + /* Server */ + StubMsg.IsClient = 0; + mem = NULL; + StubMsg.Buffer = StubMsg.BufferStart; + ptr = NdrComplexStructUnmarshall(&StubMsg, (unsigned char **)&mem, fmtstr, 0); + ok(ptr == NULL, "ret %p\n", ptr); + ok(!memcmp(mem, memsrc, sizeof(*memsrc)), "struct wasn't unmarshalled correctly\n"); + StubMsg.pfnFree(mem); + + heap_free(StubMsg.RpcMsg->Buffer); + heap_free(memsrc_orig); +} + +struct testiface +{ + IPersist IPersist_iface; + LONG ref; +}; + +static struct testiface *impl_from_IPersist(IPersist *iface) +{ + return CONTAINING_RECORD(iface, struct testiface, IPersist_iface); +} + +static HRESULT WINAPI test_persist_QueryInterface(IPersist *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPersist)) + { + *out = iface; + IPersist_AddRef(iface); + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_persist_AddRef(IPersist *iface) +{ + struct testiface *unk = impl_from_IPersist(iface); + return ++unk->ref; +} + +static ULONG WINAPI test_persist_Release(IPersist *iface) +{ + struct testiface *unk = impl_from_IPersist(iface); + return --unk->ref; +} + +static HRESULT WINAPI test_persist_GetClassId(IPersist *iface, GUID *clsid) +{ + *clsid = IID_IPersist; + return S_OK; +} + +static IPersistVtbl testiface_vtbl = { + test_persist_QueryInterface, + test_persist_AddRef, + test_persist_Release, + test_persist_GetClassId, +}; + +static void test_iface_ptr(void) +{ + struct testiface server_obj = {{&testiface_vtbl}, 1}; + struct testiface client_obj = {{&testiface_vtbl}, 1}; + + MIDL_STUB_MESSAGE StubMsg; + MIDL_STUB_DESC StubDesc; + RPC_MESSAGE RpcMessage; + IPersist *proxy; + HRESULT hr; + GUID clsid; + void *ptr; + LONG ref; + + static const unsigned char fmtstr_ip[] = + { + FC_IP, + FC_CONSTANT_IID, + NdrFcLong(0x0000010c), + NdrFcShort(0x0000), + NdrFcShort(0x0000), + 0xc0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x46, + }; + + CoInitialize(NULL); + + StubDesc = Object_StubDesc; + StubDesc.pFormatTypes = fmtstr_ip; + + NdrClientInitializeNew(&RpcMessage, &StubMsg, &StubDesc, 0); + StubMsg.BufferLength = 0; + NdrInterfacePointerBufferSize(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip); + + StubMsg.RpcMsg->Buffer = StubMsg.BufferStart = StubMsg.Buffer = HeapAlloc(GetProcessHeap(), 0, StubMsg.BufferLength); + StubMsg.BufferEnd = StubMsg.BufferStart + StubMsg.BufferLength; + + /* server -> client */ + + StubMsg.IsClient = 0; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + IPersist_AddRef(&server_obj.IPersist_iface); + ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip); + ok(!ptr, "ret %p\n", ptr); + ok(server_obj.ref > 2, "got %d references\n", server_obj.ref); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + + NdrInterfacePointerFree(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip); + ok(server_obj.ref > 1, "got %d references\n", server_obj.ref); + + StubMsg.IsClient = 1; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + proxy = NULL; + ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0); + ok(!ptr, "ret %p\n", ptr); + ok(!!proxy, "mem not alloced\n"); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + ok(server_obj.ref > 1, "got %d references\n", server_obj.ref); + + hr = IPersist_GetClassID(proxy, &clsid); + ok(hr == S_OK, "got hr %#x\n", hr); + ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid)); + + ref = IPersist_Release(proxy); + ok(ref == 1, "got %d references\n", ref); + ok(server_obj.ref == 1, "got %d references\n", server_obj.ref); + + /* An existing interface pointer is released; this is necessary so that an + * [in, out] pointer which changes does not leak references. */ + + StubMsg.IsClient = 0; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + IPersist_AddRef(&server_obj.IPersist_iface); + ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip); + ok(!ptr, "ret %p\n", ptr); + ok(server_obj.ref > 2, "got %d references\n", server_obj.ref); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + + NdrInterfacePointerFree(&StubMsg, (unsigned char *)&server_obj.IPersist_iface, fmtstr_ip); + ok(server_obj.ref > 1, "got %d references\n", server_obj.ref); + + StubMsg.IsClient = 1; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + proxy = &client_obj.IPersist_iface; + IPersist_AddRef(proxy); + ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0); + ok(!ptr, "ret %p\n", ptr); + ok(!!proxy && proxy != &client_obj.IPersist_iface, "mem not alloced\n"); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + ok(server_obj.ref > 1, "got %d references\n", server_obj.ref); + ok(client_obj.ref == 1, "got %d references\n", client_obj.ref); + + hr = IPersist_GetClassID(proxy, &clsid); + ok(hr == S_OK, "got hr %#x\n", hr); + ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid)); + + ref = IPersist_Release(proxy); + ok(ref == 1, "got %d references\n", ref); + ok(server_obj.ref == 1, "got %d references\n", server_obj.ref); + + /* client -> server */ + + StubMsg.IsClient = 1; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + IPersist_AddRef(&client_obj.IPersist_iface); + ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip); + ok(!ptr, "ret %p\n", ptr); + ok(client_obj.ref > 2, "got %d references\n", client_obj.ref); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + + StubMsg.IsClient = 0; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + proxy = NULL; + ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0); + ok(!ptr, "ret %p\n", ptr); + ok(!!proxy, "mem not alloced\n"); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + ok(client_obj.ref > 2, "got %d references\n", client_obj.ref); + + hr = IPersist_GetClassID(proxy, &clsid); + ok(hr == S_OK, "got hr %#x\n", hr); + ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid)); + + ref = IPersist_Release(proxy); + ok(client_obj.ref > 1, "got %d references\n", client_obj.ref); + ok(ref == client_obj.ref, "expected %d references, got %d\n", client_obj.ref, ref); + + NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip); + ok(client_obj.ref == 1, "got %d references\n", client_obj.ref); + + /* same, but free the interface after calling NdrInterfacePointerFree */ + + StubMsg.IsClient = 1; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + IPersist_AddRef(&client_obj.IPersist_iface); + ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip); + ok(!ptr, "ret %p\n", ptr); + ok(client_obj.ref > 2, "got %d references\n", client_obj.ref); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + + StubMsg.IsClient = 0; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + proxy = NULL; + ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0); + ok(!ptr, "ret %p\n", ptr); + ok(!!proxy, "mem not alloced\n"); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + ok(client_obj.ref > 2, "got %d references\n", client_obj.ref); + + NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip); + ok(client_obj.ref > 1, "got %d references\n", client_obj.ref); + + hr = IPersist_GetClassID(proxy, &clsid); + ok(hr == S_OK, "got hr %#x\n", hr); + ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid)); + + ref = IPersist_Release(proxy); + ok(ref == 1, "got %d references\n", ref); + ok(client_obj.ref == 1, "got %d references\n", client_obj.ref); + + /* An existing interface pointer is *not* released (in fact, it is ignored + * and may be invalid). In practice it will always be NULL anyway. */ + + StubMsg.IsClient = 1; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + IPersist_AddRef(&client_obj.IPersist_iface); + ptr = NdrInterfacePointerMarshall(&StubMsg, (unsigned char *)&client_obj.IPersist_iface, fmtstr_ip); + ok(!ptr, "ret %p\n", ptr); + ok(client_obj.ref > 2, "got %d references\n", client_obj.ref); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + + StubMsg.IsClient = 0; + my_alloc_called = my_free_called = 0; + StubMsg.Buffer = StubMsg.BufferStart; + proxy = &server_obj.IPersist_iface; + IPersist_AddRef(proxy); + ptr = NdrInterfacePointerUnmarshall(&StubMsg, (unsigned char **)&proxy, fmtstr_ip, 0); + ok(!ptr, "ret %p\n", ptr); + ok(!!proxy && proxy != &server_obj.IPersist_iface, "mem not alloced\n"); + ok(!my_alloc_called, "alloc called %d\n", my_alloc_called); + ok(!my_free_called, "free called %d\n", my_free_called); + ok(client_obj.ref > 2, "got %d references\n", client_obj.ref); + ok(server_obj.ref == 2, "got %d references\n", server_obj.ref); + IPersist_Release(&server_obj.IPersist_iface); + + hr = IPersist_GetClassID(proxy, &clsid); + ok(hr == S_OK, "got hr %#x\n", hr); + ok(IsEqualGUID(&clsid, &IID_IPersist), "wrong clsid %s\n", wine_dbgstr_guid(&clsid)); + + ref = IPersist_Release(proxy); + ok(client_obj.ref > 1, "got %d references\n", client_obj.ref); + ok(ref == client_obj.ref, "expected %d references, got %d\n", client_obj.ref, ref); + + NdrInterfacePointerFree(&StubMsg, (unsigned char *)proxy, fmtstr_ip); + ok(client_obj.ref == 1, "got %d references\n", client_obj.ref); + + HeapFree(GetProcessHeap(), 0, StubMsg.BufferStart); + + CoUninitialize(); +} + static void test_fullpointer_xlat(void) { PFULL_PTR_XLAT_TABLES pXlatTables; @@ -1373,6 +1905,8 @@ static void test_ndr_allocate(void) else win_skip("v1 mem list format\n"); } /* NdrFree isn't exported so we can't test free'ing */ + my_free(p1); + my_free(p2); } static void test_conformant_array(void) @@ -1555,10 +2089,8 @@ static void test_conformant_string(void) my_alloc_called = 0; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1); -todo_wine { ok(mem == mem_orig, "mem not alloced\n"); ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); -} /* Prevent a memory leak when running with Wine. Remove once the todo_wine block above is fixed. */ @@ -1590,11 +2122,9 @@ todo_wine { mem = NULL; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1); -todo_wine { ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */ "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 ); ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); -} my_alloc_called = 0; mem = mem_orig = HeapAlloc(GetProcessHeap(), 0, sizeof(memsrc)); @@ -1608,11 +2138,9 @@ todo_wine { mem = mem_orig; StubMsg.Buffer = StubMsg.BufferStart; NdrPointerUnmarshall( &StubMsg, &mem, fmtstr_conf_str, 1); -todo_wine { ok(mem == StubMsg.BufferStart + 12 || broken(!mem), /* win9x, nt4 */ "mem not pointing at buffer %p/%p\n", mem, StubMsg.BufferStart + 12 ); ok(my_alloc_called == 0, "alloc called %d\n", my_alloc_called); -} mem = my_alloc(10); my_free_called = 0; @@ -2002,11 +2530,6 @@ static void test_conf_complex_array(void) #endif expected_length = (4 + memsrc.dim1 * (2 + memsrc.dim2)) * 4; - if (StubMsg.BufferLength == 96) - { - win_skip("Tests crash on Win9x, WinMe and NT4\n"); - goto cleanup; - } ok(StubMsg.BufferLength >= expected_length, "length %d\n", StubMsg.BufferLength); /*NdrGetBuffer(&_StubMsg, _StubMsg.BufferLength, NULL);*/ @@ -2076,7 +2599,6 @@ static void test_conf_complex_array(void) HeapFree(GetProcessHeap(), 0, StubMsg.RpcMsg->Buffer); -cleanup: for(i = 0; i < memsrc.dim1; i++) HeapFree(GetProcessHeap(), 0, memsrc.array[i]); HeapFree(GetProcessHeap(), 0, memsrc.array); @@ -2212,14 +2734,6 @@ static void test_NdrGetUserMarshalInfo(void) unsigned char buffer[16]; void *rpc_channel_buffer = (void *)(ULONG_PTR)0xcafebabe; RPC_MESSAGE rpc_msg; - RPC_STATUS (RPC_ENTRY *pNdrGetUserMarshalInfo)(ULONG *,ULONG,NDR_USER_MARSHAL_INFO *); - - pNdrGetUserMarshalInfo = (void *)GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "NdrGetUserMarshalInfo"); - if (!pNdrGetUserMarshalInfo) - { - skip("NdrGetUserMarshalInfo not exported\n"); - return; - } /* unmarshall */ @@ -2247,7 +2761,7 @@ static void test_NdrGetUserMarshalInfo(void) memset(&umi, 0xaa, sizeof(umi)); - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status); ok( umi.InformationLevel == 1, "umi.InformationLevel was %u instead of 1\n", @@ -2281,7 +2795,7 @@ static void test_NdrGetUserMarshalInfo(void) memset(&umi, 0xaa, sizeof(umi)); - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status); ok( umi.InformationLevel == 1, "umi.InformationLevel was %u instead of 1\n", @@ -2315,7 +2829,7 @@ static void test_NdrGetUserMarshalInfo(void) memset(&umi, 0xaa, sizeof(umi)); - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status); ok( umi.InformationLevel == 1, "umi.InformationLevel was %u instead of 1\n", @@ -2349,7 +2863,7 @@ static void test_NdrGetUserMarshalInfo(void) memset(&umi, 0xaa, sizeof(umi)); - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status); ok( umi.InformationLevel == 1, "umi.InformationLevel was %u instead of 1\n", @@ -2381,7 +2895,7 @@ static void test_NdrGetUserMarshalInfo(void) umcb.CBType = USER_MARSHAL_CB_MARSHALL; - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status); ok( U1(umi).Level1.BufferSize == 0, "umi.Level1.BufferSize was %u instead of 0\n", @@ -2390,22 +2904,22 @@ static void test_NdrGetUserMarshalInfo(void) /* error conditions */ rpc_msg.BufferLength = 14; - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == ERROR_INVALID_USER_BUFFER, "NdrGetUserMarshalInfo should have failed with ERROR_INVALID_USER_BUFFER instead of %d\n", status); rpc_msg.BufferLength = 15; - status = pNdrGetUserMarshalInfo(&umcb.Flags, 9999, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 9999, &umi); ok(status == RPC_S_INVALID_ARG, "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status); umcb.CBType = 9999; - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == RPC_S_OK, "NdrGetUserMarshalInfo failed with error %d\n", status); umcb.CBType = USER_MARSHAL_CB_MARSHALL; umcb.Signature = 0; - status = pNdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); + status = NdrGetUserMarshalInfo(&umcb.Flags, 1, &umi); ok(status == RPC_S_INVALID_ARG, "NdrGetUserMarshalInfo should have failed with RPC_S_INVALID_ARG instead of %d\n", status); } @@ -2497,6 +3011,8 @@ START_TEST( ndr_marshall ) test_simple_types(); test_nontrivial_pointer_types(); test_simple_struct(); + test_struct_align(); + test_iface_ptr(); test_fullpointer_xlat(); test_client_init(); test_server_init(); diff --git a/modules/rostests/winetests/rpcrt4/rpc.c b/modules/rostests/winetests/rpcrt4/rpc.c index f026e99de2..d3a3aee6c8 100644 --- a/modules/rostests/winetests/rpcrt4/rpc.c +++ b/modules/rostests/winetests/rpcrt4/rpc.c @@ -149,10 +149,8 @@ static void TestDceErrorInqText (void) */ DWORD dwCount; - dwCount = FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, RPC_S_NOT_RPC_ERROR, 0, bufferInvalid, - sizeof(bufferInvalid)/sizeof(bufferInvalid[0]), NULL); + dwCount = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + RPC_S_NOT_RPC_ERROR, 0, bufferInvalid, ARRAY_SIZE(bufferInvalid), NULL); /* A random sample of DceErrorInqText */ /* 0 is success */ @@ -651,15 +649,15 @@ static void test_RpcStringBindingParseA(void) ok(options == NULL, "options was %p instead of NULL\n", options); } -static void test_I_RpcExceptionFilter(void) +static void test_RpcExceptionFilter(const char *func_name) { ULONG exception; int retval; - int (WINAPI *pI_RpcExceptionFilter)(ULONG) = (void *)GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "I_RpcExceptionFilter"); + int (WINAPI *pRpcExceptionFilter)(ULONG) = (void *)GetProcAddress(GetModuleHandleA("rpcrt4.dll"), func_name); - if (!pI_RpcExceptionFilter) + if (!pRpcExceptionFilter) { - win_skip("I_RpcExceptionFilter not exported\n"); + win_skip("%s not exported\n", func_name); return; } @@ -670,7 +668,7 @@ static void test_I_RpcExceptionFilter(void) if (exception == 0x40000005) exception = 0x80000000; if (exception == 0x80000005) exception = 0xc0000000; - retval = pI_RpcExceptionFilter(exception); + retval = pRpcExceptionFilter(exception); switch (exception) { case STATUS_DATATYPE_MISALIGNMENT: @@ -681,17 +679,17 @@ static void test_I_RpcExceptionFilter(void) case STATUS_INSTRUCTION_MISALIGNMENT: case STATUS_STACK_OVERFLOW: case STATUS_POSSIBLE_DEADLOCK: - ok(retval == EXCEPTION_CONTINUE_SEARCH, "I_RpcExceptionFilter(0x%x) should have returned %d instead of %d\n", - exception, EXCEPTION_CONTINUE_SEARCH, retval); + ok(retval == EXCEPTION_CONTINUE_SEARCH, "%s(0x%x) should have returned %d instead of %d\n", + func_name, exception, EXCEPTION_CONTINUE_SEARCH, retval); break; case STATUS_GUARD_PAGE_VIOLATION: case STATUS_IN_PAGE_ERROR: case STATUS_HANDLE_NOT_CLOSABLE: - trace("I_RpcExceptionFilter(0x%x) returned %d\n", exception, retval); + trace("%s(0x%x) returned %d\n", func_name, exception, retval); break; default: - ok(retval == EXCEPTION_EXECUTE_HANDLER, "I_RpcExceptionFilter(0x%x) should have returned %d instead of %d\n", - exception, EXCEPTION_EXECUTE_HANDLER, retval); + ok(retval == EXCEPTION_EXECUTE_HANDLER, "%s(0x%x) should have returned %d instead of %d\n", + func_name, exception, EXCEPTION_EXECUTE_HANDLER, retval); } } } @@ -1200,7 +1198,8 @@ START_TEST( rpc ) test_towers(); test_I_RpcMapWin32Status(); test_RpcStringBindingParseA(); - test_I_RpcExceptionFilter(); + test_RpcExceptionFilter("I_RpcExceptionFilter"); + test_RpcExceptionFilter("RpcExceptionFilter"); test_RpcStringBindingFromBinding(); test_UuidCreate(); test_UuidCreateSequential(); diff --git a/modules/rostests/winetests/rpcrt4/rpc_async.c b/modules/rostests/winetests/rpcrt4/rpc_async.c index 555c58f102..15c57fefb5 100644 --- a/modules/rostests/winetests/rpcrt4/rpc_async.c +++ b/modules/rostests/winetests/rpcrt4/rpc_async.c @@ -25,9 +25,6 @@ #include <rpc.h> #include <rpcasync.h> -static RPC_STATUS (RPC_ENTRY *pRpcAsyncInitializeHandle)(PRPC_ASYNC_STATE,unsigned int); -static RPC_STATUS (RPC_ENTRY *pRpcAsyncGetCallStatus)(PRPC_ASYNC_STATE); - static void test_RpcAsyncInitializeHandle(void) { char buffer[256]; @@ -36,15 +33,15 @@ static void test_RpcAsyncInitializeHandle(void) int i; void *unset_ptr; - status = pRpcAsyncInitializeHandle((PRPC_ASYNC_STATE)buffer, sizeof(buffer)); + status = RpcAsyncInitializeHandle((PRPC_ASYNC_STATE)buffer, sizeof(buffer)); ok(status == ERROR_INVALID_PARAMETER, "RpcAsyncInitializeHandle with large Size should have returned ERROR_INVALID_PARAMETER instead of %d\n", status); - status = pRpcAsyncInitializeHandle(&async, sizeof(async) - 1); + status = RpcAsyncInitializeHandle(&async, sizeof(async) - 1); ok(status == ERROR_INVALID_PARAMETER, "RpcAsyncInitializeHandle with small Size should have returned ERROR_INVALID_PARAMETER instead of %d\n", status); memset(&async, 0xcc, sizeof(async)); memset(&unset_ptr, 0xcc, sizeof(unset_ptr)); - status = pRpcAsyncInitializeHandle(&async, sizeof(async)); + status = RpcAsyncInitializeHandle(&async, sizeof(async)); ok(status == RPC_S_OK, "RpcAsyncInitializeHandle failed with error %d\n", status); ok(async.Size == sizeof(async), "async.Size wrong: %d\n", async.Size); @@ -65,29 +62,21 @@ static void test_RpcAsyncGetCallStatus(void) RPC_ASYNC_STATE async; RPC_STATUS status; - status = pRpcAsyncInitializeHandle(&async, sizeof(async)); + status = RpcAsyncInitializeHandle(&async, sizeof(async)); ok(status == RPC_S_OK, "RpcAsyncInitializeHandle failed with error %d\n", status); - status = pRpcAsyncGetCallStatus(&async); + status = RpcAsyncGetCallStatus(&async); todo_wine ok(status == RPC_S_INVALID_BINDING, "RpcAsyncGetCallStatus should have returned RPC_S_INVALID_BINDING instead of %d\n", status); memset(&async, 0, sizeof(async)); - status = pRpcAsyncGetCallStatus(&async); + status = RpcAsyncGetCallStatus(&async); todo_wine ok(status == RPC_S_INVALID_BINDING, "RpcAsyncGetCallStatus should have returned RPC_S_INVALID_BINDING instead of %d\n", status); } START_TEST( rpc_async ) { - HMODULE hRpcRt4 = GetModuleHandleA("rpcrt4.dll"); - pRpcAsyncInitializeHandle = (void *)GetProcAddress(hRpcRt4, "RpcAsyncInitializeHandle"); - pRpcAsyncGetCallStatus = (void *)GetProcAddress(hRpcRt4, "RpcAsyncGetCallStatus"); - if (!pRpcAsyncInitializeHandle || !pRpcAsyncGetCallStatus) - { - win_skip("asynchronous functions not available\n"); - return; - } test_RpcAsyncInitializeHandle(); test_RpcAsyncGetCallStatus(); } diff --git a/modules/rostests/winetests/rpcrt4/server.c b/modules/rostests/winetests/rpcrt4/server.c index 96cea2c3f6..2a66a38aab 100644 --- a/modules/rostests/winetests/rpcrt4/server.c +++ b/modules/rostests/winetests/rpcrt4/server.c @@ -313,7 +313,7 @@ void __cdecl s_get_number_array(int x[20], int *n) { int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; memcpy(x, c, sizeof(c)); - *n = sizeof(c)/sizeof(c[0]); + *n = ARRAY_SIZE(c); } int __cdecl s_sum_cs(cs_t *cs) @@ -861,6 +861,16 @@ void __cdecl s_ip_test(ipu_t *a) ok(hr == S_OK, "got %#x\n", hr); } +int __cdecl s_sum_ptr_array(int *a[2]) +{ + return *a[0] + *a[1]; +} + +int __cdecl s_sum_array_ptr(int (*a)[2]) +{ + return (*a)[0] + (*a)[1]; +} + static void make_cmdline(char buffer[MAX_PATH], const char *test) { @@ -1388,6 +1398,7 @@ array_tests(void) pints_t api[5]; numbers_struct_t *ns; refpint_t rpi[5]; + int i0 = 1, i1 = 2, *ptr_array[2] = {&i0, &i1}, array[2] = {3, 4}; if (!old_windows_version) { @@ -1518,6 +1529,9 @@ array_tests(void) pi[4] = -4; rpi[4] = &pi[4]; ok(sum_complex_array(5, rpi) == 1, "RPC sum_complex_array\n"); HeapFree(GetProcessHeap(), 0, pi); + + ok(sum_ptr_array(ptr_array) == 3, "RPC sum_ptr_array\n"); + ok(sum_array_ptr(&array) == 7, "RPC sum_array_ptr\n"); } void __cdecl s_authinfo_test(unsigned int protseq, int secure) @@ -1959,6 +1973,118 @@ static void test_server_listening(void) ok(status == RPC_S_OK, "RpcStringFree\n"); } +static HANDLE create_server_process(void) +{ + SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE }; + HANDLE ready_event; + char cmdline[MAX_PATH]; + PROCESS_INFORMATION info; + STARTUPINFOA startup; + DWORD ret; + + memset(&startup, 0, sizeof startup); + startup.cb = sizeof startup; + + ready_event = CreateEventW(&sec_attr, TRUE, FALSE, NULL); + ok(ready_event != NULL, "CreateEvent failed: %u\n", GetLastError()); + + sprintf(cmdline, "%s server run %lx", progname, (UINT_PTR)ready_event); + trace("running server process...\n"); + ok(CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); + ret = WaitForSingleObject(ready_event, 10000); + ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); + + ok(CloseHandle(info.hThread), "CloseHandle\n"); + ok(CloseHandle(ready_event), "CloseHandle\n"); + return info.hProcess; +} + +static void run_server(HANDLE ready_event) +{ + static unsigned char np[] = "ncacn_np"; + static unsigned char pipe[] = PIPE "term_test"; + RPC_STATUS status; + BOOL ret; + + status = RpcServerUseProtseqEpA(np, 0, pipe, NULL); + ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", status); + + status = RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL); + ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status); + + test_is_server_listening(NULL, RPC_S_NOT_LISTENING); + status = RpcServerListen(1, 20, TRUE); + ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status); + + stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError()); + + ret = SetEvent(ready_event); + ok(ret, "SetEvent failed: %u\n", GetLastError()); + + ret = WaitForSingleObject(stop_event, 1000); + ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); + + status = RpcMgmtWaitServerListen(); + ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status); + + CloseHandle(stop_event); + stop_event = NULL; +} + +static DWORD WINAPI basic_tests_thread(void *arg) +{ + basic_tests(); + return 0; +} + +static void test_reconnect(void) +{ + static unsigned char np[] = "ncacn_np"; + static unsigned char address_np[] = "\\\\."; + static unsigned char pipe[] = PIPE "term_test"; + unsigned char *binding; + HANDLE threads[32]; + HANDLE server_process; + unsigned i; + DWORD ret; + + server_process = create_server_process(); + + ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n"); + ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n"); + + for (i = 0; i < ARRAY_SIZE(threads); i++) + { + threads[i] = CreateThread(NULL, 0, basic_tests_thread, 0, 0, NULL); + ok(threads[i] != NULL, "CreateThread failed: %u\n", GetLastError()); + } + + for (i = 0; i < ARRAY_SIZE(threads); i++) + { + ret = WaitForSingleObject(threads[i], 10000); + ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); + CloseHandle(threads[i]); + } + + stop(); + + winetest_wait_child_process(server_process); + ok(CloseHandle(server_process), "CloseHandle\n"); + + /* create new server, rpcrt4 will connect to it once sending to existing connection fails + * that current connection is broken. */ + server_process = create_server_process(); + basic_tests(); + stop(); + + winetest_wait_child_process(server_process); + ok(CloseHandle(server_process), "CloseHandle\n"); + + ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); + ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n"); +} + static BOOL is_process_elevated(void) { HANDLE token; @@ -2085,16 +2211,10 @@ START_TEST(server) ULONG size = 0; int argc; char **argv; - BOOL firewall_enabled = is_firewall_enabled(); + BOOL firewall_enabled = is_firewall_enabled(), firewall_disabled = FALSE; InitFunctionPointers(); - if (firewall_enabled && !is_process_elevated()) - { - trace("no privileges, skipping tests to avoid firewall dialog\n"); - return; - } - ok(!GetUserNameExA(NameSamCompatible, NULL, &size), "GetUserNameExA\n"); domain_and_user = HeapAlloc(GetProcessHeap(), 0, size); ok(GetUserNameExA(NameSamCompatible, domain_and_user, &size), "GetUserNameExA\n"); @@ -2116,23 +2236,50 @@ START_TEST(server) } else if (argc == 4) { - test_server_listening(); + if (!strcmp(argv[3], "listen")) + { + test_server_listening(); + } + else if(!strcmp(argv[2], "run")) + { + UINT_PTR event; + sscanf(argv[3], "%lx", &event); + run_server((HANDLE)event); + } } else { if (firewall_enabled) { - HRESULT hr = set_firewall(APP_ADD); - if (hr != S_OK) + if (is_process_elevated()) { - skip("can't authorize app in firewall %08x\n", hr); - HeapFree(GetProcessHeap(), 0, domain_and_user); - return; + HRESULT hr = set_firewall(APP_ADD); + if (hr == S_OK) + { + firewall_enabled = FALSE; + firewall_disabled = TRUE; + } + else + { + skip("can't authorize app in firewall %08x\n", hr); + } + } + else + { + trace("no privileges, skipping tests to avoid firewall dialog\n"); } } - server(); + + if (!firewall_enabled) server(); + + /* Those tests cause occasional crashes on winxp and win2k3 */ + if (GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "RpcExceptionFilter")) + test_reconnect(); + else + win_skip("Skipping reconnect tests on too old Windows version\n"); + run_client("test listen"); - if (firewall_enabled) set_firewall(APP_REMOVE); + if (firewall_disabled) set_firewall(APP_REMOVE); } HeapFree(GetProcessHeap(), 0, domain_and_user); diff --git a/modules/rostests/winetests/rpcrt4/server.idl b/modules/rostests/winetests/rpcrt4/server.idl index 6aa73823f0..7d89445f72 100644 --- a/modules/rostests/winetests/rpcrt4/server.idl +++ b/modules/rostests/winetests/rpcrt4/server.idl @@ -393,4 +393,7 @@ cpp_quote("#endif") } ipu_t; void ip_test([in] ipu_t *a); + + int sum_ptr_array([in] int *a[2]); + int sum_array_ptr([in] int (*a)[2]); }
5 years, 10 months
1
0
0
0
← Newer
1
...
16
17
18
19
20
21
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Results per page:
10
25
50
100
200