[PATCH 0/5] MR10436: cfgmgr32: Implement CM_Get_DevNode_Registry_Property(_Ex)(A|W).
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/cfgmgr32/cfgmgr32.c | 263 +++++++++++++++++++++++++++++++++ dlls/cfgmgr32/cfgmgr32.spec | 20 +-- dlls/cfgmgr32/tests/cfgmgr32.c | 107 ++++++++++++++ dlls/setupapi/devinst.c | 169 --------------------- dlls/setupapi/setupapi.spec | 20 +-- dlls/setupapi/stubs.c | 20 --- 6 files changed, 390 insertions(+), 209 deletions(-) diff --git a/dlls/cfgmgr32/cfgmgr32.c b/dlls/cfgmgr32/cfgmgr32.c index ff179295f02..5d3ad003a8b 100644 --- a/dlls/cfgmgr32/cfgmgr32.c +++ b/dlls/cfgmgr32/cfgmgr32.c @@ -106,6 +106,13 @@ static LSTATUS query_value( HKEY hkey, const WCHAR *value, WCHAR *buffer, DWORD return RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &len ); } +static LSTATUS open_enum_key( HKEY root, const WCHAR *key, REGSAM access, BOOL open, HKEY *hkey ) +{ + WCHAR path[MAX_PATH]; + swprintf( path, ARRAY_SIZE(path), L"%s%s", enum_rootW, key ); + return open_key( root, path, access, open, hkey ); +} + static LSTATUS open_class_key( HKEY root, const WCHAR *key, REGSAM access, BOOL open, HKEY *hkey ) { WCHAR path[MAX_PATH]; @@ -528,6 +535,99 @@ static LSTATUS get_device_interface_property_keys( const struct device_interface return err; } +struct device +{ + WCHAR enumerator[MAX_PATH]; + WCHAR device[MAX_PATH]; + WCHAR instance[MAX_PATH]; +}; + +static LSTATUS init_device( struct device *dev, const WCHAR *name ) +{ + WCHAR *tmp; + + dev->enumerator[0] = dev->device[0] = dev->instance[0] = 0; + tmp = lstrcpynW( dev->enumerator, name, ARRAY_SIZE(dev->enumerator) ); + if (!(tmp = wcschr( dev->enumerator, '\\' ))) return ERROR_INVALID_DATA; + + *tmp++ = 0; + wcscpy( dev->device, tmp ); + if ((tmp = wcschr( dev->device, '\\' ))) *tmp++ = 0; + if (tmp) wcscpy( dev->instance, tmp ); + + return ERROR_SUCCESS; +} + +static LSTATUS open_device_key( HKEY root, const struct device *dev, REGSAM access, BOOL open, HKEY *hkey ) +{ + WCHAR path[MAX_PATH]; + UINT len; + + len = swprintf( path, ARRAY_SIZE(path), L"%s", dev->enumerator ); + if (*dev->device) len += swprintf( path + len, ARRAY_SIZE(path) - len, L"\\%s", dev->device ); + if (*dev->instance) len += swprintf( path + len, ARRAY_SIZE(path) - len, L"\\%s", dev->instance ); + + return open_enum_key( root, path, access, open, hkey ); +} + +static CRITICAL_SECTION devnode_cs; +static CRITICAL_SECTION_DEBUG devnode_cs_debug = { + 0, 0, &devnode_cs, + { &devnode_cs_debug.ProcessLocksList, + &devnode_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": devnode_cs") } +}; +static CRITICAL_SECTION devnode_cs = { &devnode_cs_debug, -1, 0, 0, 0, 0 }; + +/* tree of the devnodes which have been accessed */ +static struct device *devnodes; +static UINT devnodes_count, devnodes_capacity; + +/* devnode_cs must be held */ +static DEVINST devnodes_lookup( const struct device *dev ) +{ + for (DEVINST i = 0; i < devnodes_count; ++i) + { + if (wcsicmp( devnodes[i].enumerator, dev->enumerator )) continue; + if (wcsicmp( devnodes[i].device, dev->device )) continue; + if (!wcsicmp( devnodes[i].instance, dev->instance )) return i + 1; + } + + return 0; +} + +/* devnode_cs must be held */ +static LSTATUS devnodes_append( const struct device *dev, DEVINST *node ) +{ + if (devnodes_count == devnodes_capacity) + { + UINT capacity = max( 256, devnodes_capacity * 3 / 2 ); + struct device *tmp; + + if (capacity <= devnodes_capacity || !(tmp = realloc( devnodes, capacity * sizeof(*devnodes) ))) return ERROR_OUTOFMEMORY; + memset( tmp + devnodes_capacity, 0, (capacity - devnodes_capacity) * sizeof(*devnodes) ); + devnodes_capacity = capacity; + devnodes = tmp; + } + + devnodes[devnodes_count] = *dev; + *node = ++devnodes_count; /* index 0 is reserved */ + + return ERROR_SUCCESS; +} + +static LSTATUS devnode_get_device( DEVINST node, struct device *dev ) +{ + LSTATUS err = ERROR_SUCCESS; + + EnterCriticalSection( &devnode_cs ); + if (!node || node > devnodes_count) err = ERROR_NO_SUCH_DEVICE; + else *dev = devnodes[node - 1]; + LeaveCriticalSection( &devnode_cs ); + + return err; +} + static CONFIGRET map_error( LSTATUS err ) { switch (err) @@ -544,6 +644,17 @@ static CONFIGRET map_error( LSTATUS err ) } } +static CONFIGRET map_error_node( LSTATUS err ) +{ + switch (err) + { + case ERROR_INVALID_DATA: return CR_INVALID_DEVNODE; + case ERROR_NOT_FOUND: return CR_NO_SUCH_DEVNODE; + case ERROR_FILE_NOT_FOUND: return CR_NO_SUCH_DEVNODE; + default: return map_error( err ); + } +} + /*********************************************************************** * CM_MapCrToWin32Err (cfgmgr32.@) */ @@ -1080,3 +1191,155 @@ CONFIGRET WINAPI CM_Get_Device_Interface_Property_KeysW( const WCHAR *iface, DEV { return CM_Get_Device_Interface_Property_Keys_ExW( iface, keys, count, flags, NULL ); } + +/*********************************************************************** + * CM_Locate_DevNode_ExW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Locate_DevNode_ExW( DEVINST *node, DEVINSTID_W instance_id, ULONG flags, HMACHINE machine ) +{ + const WCHAR *instance = instance_id && *instance_id ? instance_id : L"HTREE\\ROOT\\0"; + struct device dev; + LSTATUS err; + HKEY hkey; + + TRACE( "node %p, instance_id %s, flags %#lx, machine %p\n", node, debugstr_w(instance_id), flags, machine ); + if (machine) FIXME( "machine %p not implemented!\n", machine ); + if (flags) FIXME( "flags %#lx not implemented!\n", flags ); + if (!node) return CR_INVALID_POINTER; + *node = 0; + + if (init_device( &dev, instance )) return CR_INVALID_DEVICE_ID; + + EnterCriticalSection( &devnode_cs ); + + if ((*node = devnodes_lookup( &dev ))) err = ERROR_SUCCESS; + else if (!(err = open_device_key( HKEY_LOCAL_MACHINE, &dev, KEY_ALL_ACCESS, TRUE, &hkey ))) + { + err = devnodes_append( &dev, node ); + RegCloseKey( hkey ); + } + + LeaveCriticalSection( &devnode_cs ); + + return map_error_node( err ); +} + +/*********************************************************************** + * CM_Locate_DevNode_ExA (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Locate_DevNode_ExA( DEVINST *node, DEVINSTID_A instance_idA, ULONG flags, HMACHINE machine ) +{ + WCHAR instance_idW[MAX_PATH]; + + TRACE( "node %p, instance_idA %s, flags %#lx, machine %p\n", node, debugstr_a(instance_idA), flags, machine ); + + if (instance_idA) MultiByteToWideChar( CP_ACP, 0, instance_idA, -1, instance_idW, ARRAY_SIZE(instance_idW) ); + return CM_Locate_DevNode_ExW( node, instance_idA ? instance_idW : NULL, flags, NULL ); +} + +/*********************************************************************** + * CM_Locate_DevNodeW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Locate_DevNodeW( DEVINST *node, DEVINSTID_W instance_id, ULONG flags ) +{ + return CM_Locate_DevNode_ExW( node, instance_id, flags, NULL ); +} + +/*********************************************************************** + * CM_Locate_DevNodeA (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Locate_DevNodeA( DEVINST *node, DEVINSTID_A instance_id, ULONG flags ) +{ + return CM_Locate_DevNode_ExA( node, instance_id, flags, NULL ); +} + +/*********************************************************************** + * CM_Get_Device_ID_Size_Ex (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex( ULONG *len, DEVINST node, ULONG flags, HMACHINE machine ) +{ + struct device dev; + + TRACE( "len %p, node %#lx, flags %#lx, machine %p\n", len, node, flags, machine ); + if (machine) FIXME( "machine %p not implemented!\n", machine ); + if (flags) FIXME( "flags %#lx not implemented!\n", flags ); + + if (!len) return CR_INVALID_POINTER; + if (devnode_get_device( node, &dev )) return CR_INVALID_DEVNODE; + + *len = wcslen( dev.enumerator ); + if (*dev.device) *len += 1 + wcslen( dev.device ); + if (*dev.instance) *len += 1 + wcslen( dev.instance ); + + return CR_SUCCESS; +} + +/*********************************************************************** + * CM_Get_Device_ID_Size (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_Size( ULONG *len, DEVINST node, ULONG flags ) +{ + return CM_Get_Device_ID_Size_Ex( len, node, flags, NULL ); +} + +/*********************************************************************** + * CM_Get_Device_ID_ExW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_ExW( DEVINST node, WCHAR *buffer, ULONG len, ULONG flags, HMACHINE machine ) +{ + WCHAR path[MAX_PATH]; + struct device dev; + ULONG path_len; + + TRACE( "node %#lx, buffer %p, len %lu, flags %#lx, machine %p\n", node, buffer, len, flags, machine ); + if (machine) FIXME( "machine %p not implemented!\n", machine ); + if (flags) FIXME( "flags %#lx not implemented!\n", flags ); + + if (!buffer) return CR_INVALID_POINTER; + if (devnode_get_device( node, &dev )) return CR_INVALID_DEVNODE; + + path_len = swprintf( path, ARRAY_SIZE(path), L"%s", dev.enumerator ); + if (*dev.device) path_len += swprintf( path + path_len, ARRAY_SIZE(path) - path_len, L"\\%s", dev.device ); + if (*dev.instance) path_len += swprintf( path + path_len, ARRAY_SIZE(path) - path_len, L"\\%s", dev.instance ); + + if (path_len > len) return CR_BUFFER_SMALL; + memcpy( buffer, path, (path_len + 1) * sizeof(WCHAR) ); + + return CR_SUCCESS; +} + +/*********************************************************************** + * CM_Get_Device_ID_ExA (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_Device_ID_ExA( DEVINST node, char *bufferA, ULONG len, ULONG flags, HMACHINE machine ) +{ + WCHAR *bufferW; + CONFIGRET ret; + + bufferW = bufferA ? malloc( len * sizeof(WCHAR) ) : NULL; + ret = CM_Get_Device_ID_ExW( node, bufferA ? bufferW : NULL, len, flags, machine ); + if (!ret && bufferA && len && !WideCharToMultiByte( CP_ACP, 0, bufferW, len, bufferA, len, 0, 0 )) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) ret = CR_BUFFER_SMALL; + else ret = CR_FAILURE; + } + free( bufferW ); + + return ret; +} + +/*********************************************************************** + * CM_Get_Device_IDW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_Device_IDW( DEVINST node, WCHAR *buffer, ULONG len, ULONG flags ) +{ + return CM_Get_Device_ID_ExW( node, buffer, len, flags, NULL ); +} + +/*********************************************************************** + * CM_Get_Device_IDA (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_Device_IDA( DEVINST node, char *buffer, ULONG len, ULONG flags ) +{ + return CM_Get_Device_ID_ExA( node, buffer, len, flags, NULL ); +} diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index 2aee10c2672..1b8a515ab8a 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -94,10 +94,10 @@ @ stdcall CM_Get_DevNode_Registry_Property_ExW(long long ptr ptr ptr long ptr) setupapi.CM_Get_DevNode_Registry_Property_ExW @ stdcall CM_Get_DevNode_Status(ptr ptr long long) setupapi.CM_Get_DevNode_Status @ stdcall CM_Get_DevNode_Status_Ex(ptr ptr long long ptr) setupapi.CM_Get_DevNode_Status_Ex -@ stdcall CM_Get_Device_IDA(ptr ptr long long) setupapi.CM_Get_Device_IDA -@ stdcall CM_Get_Device_IDW(ptr ptr long long) setupapi.CM_Get_Device_IDW -@ stdcall CM_Get_Device_ID_ExA(ptr ptr long long ptr) setupapi.CM_Get_Device_ID_ExA -@ stdcall CM_Get_Device_ID_ExW(ptr ptr long long ptr) setupapi.CM_Get_Device_ID_ExW +@ stdcall CM_Get_Device_IDA(ptr ptr long long) +@ stdcall CM_Get_Device_IDW(ptr ptr long long) +@ stdcall CM_Get_Device_ID_ExA(ptr ptr long long ptr) +@ stdcall CM_Get_Device_ID_ExW(ptr ptr long long ptr) @ stdcall CM_Get_Device_ID_ListA(str ptr long long) setupapi.CM_Get_Device_ID_ListA @ stdcall CM_Get_Device_ID_ListW(wstr ptr long long) setupapi.CM_Get_Device_ID_ListW @ stdcall CM_Get_Device_ID_List_ExA(str ptr long long ptr) setupapi.CM_Get_Device_ID_List_ExA @@ -106,8 +106,8 @@ @ stdcall CM_Get_Device_ID_List_SizeW(ptr wstr long) setupapi.CM_Get_Device_ID_List_SizeW @ stdcall CM_Get_Device_ID_List_Size_ExA(ptr str long ptr) setupapi.CM_Get_Device_ID_List_Size_ExA @ stdcall CM_Get_Device_ID_List_Size_ExW(ptr wstr long ptr) setupapi.CM_Get_Device_ID_List_Size_ExW -@ stdcall CM_Get_Device_ID_Size(ptr ptr long) setupapi.CM_Get_Device_ID_Size -@ stub CM_Get_Device_ID_Size_Ex +@ stdcall CM_Get_Device_ID_Size(ptr ptr long) +@ stdcall CM_Get_Device_ID_Size_Ex(ptr ptr long ptr) @ stdcall CM_Get_Device_Interface_AliasA(str ptr ptr ptr long) setupapi.CM_Get_Device_Interface_AliasA @ stdcall CM_Get_Device_Interface_AliasW(wstr ptr ptr ptr long) setupapi.CM_Get_Device_Interface_AliasW @ stub CM_Get_Device_Interface_Alias_ExA @@ -164,10 +164,10 @@ @ stub CM_Is_Dock_Station_Present_Ex @ stub CM_Is_Version_Available @ stub CM_Is_Version_Available_Ex -@ stdcall CM_Locate_DevNodeA(ptr str long) setupapi.CM_Locate_DevNodeA -@ stdcall CM_Locate_DevNodeW(ptr wstr long) setupapi.CM_Locate_DevNodeW -@ stdcall CM_Locate_DevNode_ExA(ptr str long long) setupapi.CM_Locate_DevNode_ExA -@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) setupapi.CM_Locate_DevNode_ExW +@ stdcall CM_Locate_DevNodeA(ptr str long) +@ stdcall CM_Locate_DevNodeW(ptr wstr long) +@ stdcall CM_Locate_DevNode_ExA(ptr str long long) +@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) @ stub CM_MapCrToSpErr @ stdcall CM_MapCrToWin32Err(long long) @ stub CM_Merge_Range_List diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index 7c6fa283f50..9cf0eb37c11 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -86,6 +86,8 @@ static const WCHAR *guid_string( const GUID *guid, WCHAR *buffer, UINT length ) return buffer; } +static DEVINST next_devinst = 1; + static void test_CM_MapCrToWin32Err(void) { unsigned int i; @@ -2889,6 +2891,110 @@ static void test_CM_Open_Device_Interface_Key(void) } } +static void test_CM_Locate_DevNode(void) +{ + WCHAR iface[4096], path[MAX_PATH], instance_id[MAX_PATH]; + DEVINST node, root = 0; + DWORD size, type, len; + CONFIGRET ret; + GUID guid; + + ret = CM_Locate_DevNodeW( NULL, (WCHAR *)L"INVALID", 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + + ret = CM_Get_Device_ID_Size( &len, 0, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + ret = CM_Get_Device_ID_Size( &len, 1, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + ret = CM_Get_Device_ID_Size( &len, 2, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, NULL, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_x4( node, ==, next_devinst ); + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, (WCHAR *)L"", 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_x4( node, ==, next_devinst ); + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, (WCHAR *)L"HTREE\\ROOT\\0", 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_x4( node, ==, next_devinst ); + if (node == next_devinst) root = next_devinst++; + + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, (WCHAR *)L"INVALID", 0 ); + ok_x4( ret, ==, CR_INVALID_DEVICE_ID ); + ok_x4( node, ==, 0 ); + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, (WCHAR *)L"WINETEST\\WINETEST\\0123456", 0 ); + ok_x4( ret, ==, CR_NO_SUCH_DEVNODE ); + ok_x4( node, ==, 0 ); + + guid = GUID_DEVINTERFACE_HID; + ret = CM_Get_Device_Interface_ListW( &guid, NULL, iface, ARRAY_SIZE(iface), CM_GET_DEVICE_INTERFACE_LIST_PRESENT ); + if (broken( !*iface )) + { + skip( "No HID device present, skipping tests\n" ); + return; + } + ok_x4( ret, ==, CR_SUCCESS ); + size = sizeof(instance_id); + ret = CM_Get_Device_Interface_PropertyW( iface, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_x4( type, ==, DEVPROP_TYPE_STRING ); + + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, instance_id, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_x4( node, ==, next_devinst ); + + wcslwr( instance_id ); + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, instance_id, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_x4( node, ==, next_devinst ); + + wcsupr( instance_id ); + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, instance_id, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_x4( node, ==, next_devinst ); + if (node == next_devinst) next_devinst++; + + + ret = CM_Get_Device_ID_Size( &len, 0, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + + len = 0xdeadbeef; + ret = CM_Get_Device_ID_Size( &len, root, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( len, ==, 12 ); + len = 0xdeadbeef; + ret = CM_Get_Device_ID_Size( &len, node, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( len, ==, wcslen( instance_id ) ); + + + ret = CM_Get_Device_IDW( 0, path, ARRAY_SIZE(path), 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + ret = CM_Get_Device_IDW( root, path, 0, 0 ); + todo_wine ok_x4( ret, ==, CR_INVALID_POINTER ); + ret = CM_Get_Device_IDW( root, NULL, ARRAY_SIZE(path), 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + + memset( path, 0xcd, sizeof(path) ); + ret = CM_Get_Device_IDW( root, path, ARRAY_SIZE(path), 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_wcs( L"HTREE\\ROOT\\0", path ); + + memset( path, 0xcd, sizeof(path) ); + ret = CM_Get_Device_IDW( node, path, ARRAY_SIZE(path), 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_wcs( instance_id, path ); +} + static void test_CM_Get_Class_Property_Keys(void) { GUID guid = GUID_DEVCLASS_HIDCLASS; @@ -2947,6 +3053,7 @@ START_TEST(cfgmgr32) pDevFindProperty = (void *)GetProcAddress(mod, "DevFindProperty"); test_CM_MapCrToWin32Err(); + test_CM_Locate_DevNode(); test_CM_Enumerate_Classes(); test_CM_Enumerate_Enumerators(); test_CM_Get_Class_Key_Name(); diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index de628d81bd2..96e47c1c084 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -243,47 +243,6 @@ static inline void copy_device_iface_data(SP_DEVICE_INTERFACE_DATA *data, data->Reserved = (ULONG_PTR)iface; } -static WCHAR **devinst_table; -static unsigned int devinst_table_size; - -static DEVINST get_devinst_for_device_id(const WCHAR *id) -{ - unsigned int i; - - for (i = 0; i < devinst_table_size; ++i) - { - if (!devinst_table[i]) - break; - if (!wcsicmp(devinst_table[i], id)) - return i; - } - return i; -} - -static DEVINST alloc_devinst_for_device_id(const WCHAR *id) -{ - DEVINST ret; - - ret = get_devinst_for_device_id(id); - if (ret == devinst_table_size) - { - if (devinst_table) - { - devinst_table = realloc(devinst_table, devinst_table_size * 2 * sizeof(*devinst_table)); - memset(devinst_table + devinst_table_size, 0, devinst_table_size * sizeof(*devinst_table)); - devinst_table_size *= 2; - } - else - { - devinst_table_size = 256; - devinst_table = calloc(devinst_table_size, sizeof(*devinst_table)); - } - } - if (!devinst_table[ret]) - devinst_table[ret] = wcsdup(id); - return ret; -} - static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr) { swprintf(guidStr, 39, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", @@ -4225,134 +4184,6 @@ BOOL WINAPI SetupDiDeleteDevRegKey(HDEVINFO devinfo, SP_DEVINFO_DATA *device_dat return !l; } -/*********************************************************************** - * CM_Get_Device_IDA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST devnode, char *buffer, ULONG len, ULONG flags) -{ - TRACE("%lu, %p, %lu, %#lx\n", devnode, buffer, len, flags); - - if (devnode >= devinst_table_size || !devinst_table[devnode]) - return CR_NO_SUCH_DEVINST; - - WideCharToMultiByte(CP_ACP, 0, devinst_table[devnode], -1, buffer, len, 0, 0); - TRACE("Returning %s\n", debugstr_a(buffer)); - return CR_SUCCESS; -} - -/*********************************************************************** - * CM_Get_Device_IDW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_IDW(DEVINST devnode, WCHAR *buffer, ULONG len, ULONG flags) -{ - TRACE("%lu, %p, %lu, %#lx\n", devnode, buffer, len, flags); - - if (devnode >= devinst_table_size || !devinst_table[devnode]) - return CR_NO_SUCH_DEVINST; - - lstrcpynW(buffer, devinst_table[devnode], len); - TRACE("Returning %s\n", debugstr_w(buffer)); - return CR_SUCCESS; -} - -/*********************************************************************** - * CM_Get_Device_ID_Size (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_Device_ID_Size(ULONG *len, DEVINST devnode, ULONG flags) -{ - TRACE("%p, %lu, %#lx\n", len, devnode, flags); - - if (devnode >= devinst_table_size || !devinst_table[devnode]) - return CR_NO_SUCH_DEVINST; - - *len = lstrlenW(devinst_table[devnode]); - return CR_SUCCESS; -} - -/*********************************************************************** - * CM_Locate_DevNodeA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNodeA(DEVINST *devinst, DEVINSTID_A device_id, ULONG flags) -{ - TRACE("%p %s %#lx.\n", devinst, debugstr_a(device_id), flags); - - return CM_Locate_DevNode_ExA(devinst, device_id, flags, NULL); -} - -/*********************************************************************** - * CM_Locate_DevNodeW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNodeW(DEVINST *devinst, DEVINSTID_W device_id, ULONG flags) -{ - TRACE("%p %s %#lx.\n", devinst, debugstr_w(device_id), flags); - - return CM_Locate_DevNode_ExW(devinst, device_id, flags, NULL); -} - -/*********************************************************************** - * CM_Locate_DevNode_ExA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNode_ExA(DEVINST *devinst, DEVINSTID_A device_id, ULONG flags, HMACHINE machine) -{ - CONFIGRET ret; - DEVINSTID_W device_idw; - unsigned int slen; - - TRACE("%p %s %#lx %p.\n", devinst, debugstr_a(device_id), flags, machine); - - if (!device_id) - { - FIXME("NULL device_id unsupported.\n"); - return CR_CALL_NOT_IMPLEMENTED; - } - - slen = strlen(device_id) + 1; - if (!(device_idw = malloc(slen * sizeof(*device_idw)))) - return CR_OUT_OF_MEMORY; - - MultiByteToWideChar(CP_ACP, 0, device_id, slen, device_idw, slen); - ret = CM_Locate_DevNode_ExW(devinst, device_idw, flags, NULL); - free(device_idw); - return ret; -} - -/*********************************************************************** - * CM_Locate_DevNode_ExW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Locate_DevNode_ExW(DEVINST *devinst, DEVINSTID_W device_id, ULONG flags, HMACHINE machine) -{ - HKEY enum_hkey, device_hkey; - LSTATUS status; - - TRACE("%p %s %#lx %p.\n", devinst, debugstr_w(device_id), flags, machine); - - if (!devinst) - return CR_INVALID_POINTER; - - *devinst = 0; - - if (machine) - FIXME("machine %p not supported.\n", machine); - if (flags) - FIXME("flags %#lx are not supported.\n", flags); - - if (!device_id) - { - FIXME("NULL device_id unsupported.\n"); - return CR_CALL_NOT_IMPLEMENTED; - } - - RegCreateKeyExW(HKEY_LOCAL_MACHINE, Enum, 0, NULL, 0, KEY_READ, NULL, &enum_hkey, NULL); - if (!(status = RegOpenKeyExW(enum_hkey, device_id, 0, KEY_READ, &device_hkey))) - RegCloseKey(device_hkey); - RegCloseKey(enum_hkey); - if (status) - return CR_NO_SUCH_DEVNODE; - - *devinst = alloc_devinst_for_device_id(device_id); - return CR_SUCCESS; -} - static CONFIGRET get_device_id_list(const WCHAR *filter, WCHAR *buffer, ULONG *len, ULONG flags) { const ULONG supported_flags = CM_GETIDLIST_FILTER_NONE | CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT; diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 6bfe922a1d7..db9fa24514e 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -75,10 +75,10 @@ @ stdcall CM_Get_DevNode_Registry_Property_ExW(long long ptr ptr ptr long ptr) @ stdcall CM_Get_DevNode_Status(ptr ptr long long) @ stdcall CM_Get_DevNode_Status_Ex(ptr ptr long long ptr) -@ stdcall CM_Get_Device_IDA(ptr ptr long long) -@ stdcall CM_Get_Device_IDW(ptr ptr long long) -@ stdcall CM_Get_Device_ID_ExA(ptr ptr long long ptr) -@ stdcall CM_Get_Device_ID_ExW(ptr ptr long long ptr) +@ stdcall CM_Get_Device_IDA(ptr ptr long long) cfgmgr32.CM_Get_Device_IDA +@ stdcall CM_Get_Device_IDW(ptr ptr long long) cfgmgr32.CM_Get_Device_IDW +@ stdcall CM_Get_Device_ID_ExA(ptr ptr long long ptr) cfgmgr32.CM_Get_Device_ID_ExA +@ stdcall CM_Get_Device_ID_ExW(ptr ptr long long ptr) cfgmgr32.CM_Get_Device_ID_ExW @ stdcall CM_Get_Device_ID_ListA(str ptr long long) @ stdcall CM_Get_Device_ID_ListW(wstr ptr long long) @ stdcall CM_Get_Device_ID_List_ExA(str ptr long long ptr) @@ -87,8 +87,8 @@ @ stdcall CM_Get_Device_ID_List_SizeW(ptr wstr long) @ stdcall CM_Get_Device_ID_List_Size_ExA(ptr str long ptr) @ stdcall CM_Get_Device_ID_List_Size_ExW(ptr wstr long ptr) -@ stdcall CM_Get_Device_ID_Size(ptr ptr long) -@ stub CM_Get_Device_ID_Size_Ex +@ stdcall CM_Get_Device_ID_Size(ptr ptr long) cfgmgr32.CM_Get_Device_ID_Size +@ stdcall CM_Get_Device_ID_Size_Ex(ptr ptr long ptr) cfgmgr32.CM_Get_Device_ID_Size_Ex @ stdcall CM_Get_Device_Interface_AliasA(str ptr ptr ptr long) @ stdcall CM_Get_Device_Interface_AliasW(wstr ptr ptr ptr long) @ stub CM_Get_Device_Interface_Alias_ExA @@ -132,10 +132,10 @@ @ stub CM_Intersect_Range_List @ stub CM_Invert_Range_List @ stub CM_Is_Dock_Station_Present -@ stdcall CM_Locate_DevNodeA(ptr str long) -@ stdcall CM_Locate_DevNodeW(ptr wstr long) -@ stdcall CM_Locate_DevNode_ExA(ptr str long long) -@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) +@ stdcall CM_Locate_DevNodeA(ptr str long) cfgmgr32.CM_Locate_DevNodeA +@ stdcall CM_Locate_DevNodeW(ptr wstr long) cfgmgr32.CM_Locate_DevNodeW +@ stdcall CM_Locate_DevNode_ExA(ptr str long long) cfgmgr32.CM_Locate_DevNode_ExA +@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long) cfgmgr32.CM_Locate_DevNode_ExW @ stub CM_Merge_Range_List @ stub CM_Modify_Res_Des @ stub CM_Modify_Res_Des_Ex diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 3b2641f9875..b14c5a958c2 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -110,26 +110,6 @@ CONFIGRET WINAPI CM_Get_Child_Ex( return CR_SUCCESS; } -/*********************************************************************** - * CM_Get_Device_ID_ExA (SETUPAPI.@) - */ -DWORD WINAPI CM_Get_Device_ID_ExA( - DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags, HMACHINE hMachine) -{ - FIXME("0x%08lx %p 0x%08lx 0x%08lx %p: stub\n", dnDevInst, Buffer, BufferLen, ulFlags, hMachine); - return CR_SUCCESS; -} - -/*********************************************************************** - * CM_Get_Device_ID_ExW (SETUPAPI.@) - */ -DWORD WINAPI CM_Get_Device_ID_ExW( - DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags, HMACHINE hMachine) -{ - FIXME("0x%08lx %p 0x%08lx 0x%08lx %p: stub\n", dnDevInst, Buffer, BufferLen, ulFlags, hMachine); - return CR_SUCCESS; -} - /*********************************************************************** * CM_Get_Parent (SETUPAPI.@) */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10436
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/cfgmgr32/cfgmgr32.c | 56 ++++++++++++++++++- dlls/cfgmgr32/cfgmgr32.spec | 4 +- dlls/cfgmgr32/tests/cfgmgr32.c | 99 +++++++++++++++++++++++++++++++++- 3 files changed, 154 insertions(+), 5 deletions(-) diff --git a/dlls/cfgmgr32/cfgmgr32.c b/dlls/cfgmgr32/cfgmgr32.c index 5d3ad003a8b..ac194614645 100644 --- a/dlls/cfgmgr32/cfgmgr32.c +++ b/dlls/cfgmgr32/cfgmgr32.c @@ -96,9 +96,14 @@ static HKEY cache_root_key( HKEY root, const WCHAR *key, const WCHAR **path ) static LSTATUS open_key( HKEY root, const WCHAR *key, REGSAM access, BOOL open, HKEY *hkey ) { + LSTATUS err; + if ((root = cache_root_key( root, key, &key )) == (HKEY)-1) return ERROR_FILE_NOT_FOUND; if (open) return RegOpenKeyExW( root, key, 0, access, hkey ); - return RegCreateKeyExW( root, key, 0, NULL, 0, access, NULL, hkey, NULL ); + + err = RegCreateKeyExW( root, key, 0, NULL, 0, access, NULL, hkey, NULL ); + if (err == ERROR_CHILD_MUST_BE_VOLATILE) err = RegCreateKeyExW( root, key, 0, NULL, REG_OPTION_VOLATILE, access, NULL, hkey, NULL ); + return err; } static LSTATUS query_value( HKEY hkey, const WCHAR *value, WCHAR *buffer, DWORD len ) @@ -1343,3 +1348,52 @@ CONFIGRET WINAPI CM_Get_Device_IDA( DEVINST node, char *buffer, ULONG len, ULONG { return CM_Get_Device_ID_ExA( node, buffer, len, flags, NULL ); } + +/*********************************************************************** + * CM_Open_DevNode_Key_Ex (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Open_DevNode_Key_Ex( DEVINST node, REGSAM access, ULONG profile, REGDISPOSITION disposition, HKEY *hkey, ULONG flags, HMACHINE machine ) +{ + BOOL open = disposition == RegDisposition_OpenExisting; + HKEY root = HKEY_LOCAL_MACHINE, dev_key; + struct device dev; + LSTATUS err; + + TRACE( "node %#lx, access %#lx, profile %lu, disposition %#lx, hkey %p, flags %#lx, machine %p\n", node, access, profile, disposition, hkey, flags, machine ); + if (machine) FIXME( "machine %p not implemented!\n", machine ); + + if (devnode_get_device( node, &dev )) return CR_NO_SUCH_DEVNODE; + if ((flags & (CM_REGISTRY_USER | CM_REGISTRY_CONFIG)) == (CM_REGISTRY_USER | CM_REGISTRY_CONFIG)) return CR_INVALID_FLAG; + + if (flags & CM_REGISTRY_CONFIG) root = HKEY_CURRENT_CONFIG; + else if (flags & CM_REGISTRY_USER) root = HKEY_CURRENT_USER; + + if (flags & CM_REGISTRY_SOFTWARE) + { + WCHAR driver[MAX_PATH]; + DWORD len = sizeof(driver); + + if ((err = open_device_key( HKEY_LOCAL_MACHINE, &dev, access, open, &dev_key ))) return map_error( err ); + if (RegQueryValueExW( dev_key, L"Driver", NULL, NULL, (BYTE *)driver, &len )) err = ERROR_NOT_FOUND; + RegCloseKey( dev_key ); + + if (!err) err = open_class_key( root, driver, access, open, hkey ); + return map_error( err ); + } + + if (root != HKEY_LOCAL_MACHINE) return map_error( open_device_key( root, &dev, access, open, hkey ) ); + + if ((err = open_device_key( root, &dev, access, open, &dev_key ))) return map_error( err ); + err = open_key( dev_key, L"Device Parameters", access, open, hkey ); + RegCloseKey( dev_key ); + + return map_error( err ); +} + +/*********************************************************************** + * CM_Open_DevNode_Key (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Open_DevNode_Key( DEVINST node, REGSAM access, ULONG profile, REGDISPOSITION disposition, HKEY *hkey, ULONG flags ) +{ + return CM_Open_DevNode_Key_Ex( node, access, profile, disposition, hkey, flags, NULL ); +} diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index 1b8a515ab8a..59e628d6165 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -180,8 +180,8 @@ @ stdcall CM_Open_Class_KeyW(ptr wstr long long ptr long) @ stdcall CM_Open_Class_Key_ExA(ptr str long long ptr long ptr) @ stdcall CM_Open_Class_Key_ExW(ptr wstr long long ptr long ptr) -@ stdcall CM_Open_DevNode_Key(long long long long ptr long) setupapi.CM_Open_DevNode_Key -@ stub CM_Open_DevNode_Key_Ex +@ stdcall CM_Open_DevNode_Key(long long long long ptr long) +@ stdcall CM_Open_DevNode_Key_Ex(long long long long ptr long ptr) @ stdcall CM_Open_Device_Interface_KeyA(str long long ptr long) @ stdcall CM_Open_Device_Interface_KeyW(wstr long long ptr long) @ stdcall CM_Open_Device_Interface_Key_ExA(str long long ptr long ptr) diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index 9cf0eb37c11..1babd6e52da 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -2253,8 +2253,8 @@ static BOOL compare_unicode_string( const UNICODE_STRING *string, const WCHAR *e !wcsnicmp( string->Buffer, expect, string->Length / sizeof(WCHAR) ); } -#define check_object_name( a, b ) _check_object_name( __LINE__, a, b ) -static void _check_object_name( unsigned line, HANDLE handle, const WCHAR *expected_name ) +#define check_object_name( a, b ) check_object_name_( __LINE__, a, b, FALSE ) +static void check_object_name_( unsigned line, HANDLE handle, const WCHAR *expected_name, BOOL todo ) { char buffer[1024]; UNICODE_STRING *str = (UNICODE_STRING *)buffer, expect; @@ -2267,6 +2267,7 @@ static void _check_object_name( unsigned line, HANDLE handle, const WCHAR *expec status = NtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len ); ok_(__FILE__, line)( status == STATUS_SUCCESS, "NtQueryObject failed %lx\n", status ); ok_(__FILE__, line)( len >= sizeof(OBJECT_NAME_INFORMATION) + str->Length, "unexpected len %lu\n", len ); + todo_wine_if(todo) ok_(__FILE__, line)( compare_unicode_string( str, expected_name ), "got %s, expected %s\n", debugstr_w(str->Buffer), debugstr_w(expected_name) ); } @@ -2995,6 +2996,99 @@ static void test_CM_Locate_DevNode(void) ok_wcs( instance_id, path ); } +static void test_CM_Open_DevNode_Key(void) +{ + WCHAR iface[4096], driver[MAX_PATH], path[MAX_PATH], instance_id[MAX_PATH]; + UNICODE_STRING user; + DWORD size, type; + CONFIGRET ret; + DEVINST node; + GUID guid; + HKEY hkey; + + RtlFormatCurrentUserKeyPath( &user ); + + guid = GUID_DEVINTERFACE_HID; + ret = CM_Get_Device_Interface_ListW( &guid, NULL, iface, ARRAY_SIZE(iface), CM_GET_DEVICE_INTERFACE_LIST_PRESENT ); + if (broken( !*iface )) + { + skip( "No HID device present, skipping tests\n" ); + return; + } + ok_x4( ret, ==, CR_SUCCESS ); + size = sizeof(instance_id); + ret = CM_Get_Device_Interface_PropertyW( iface, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_x4( type, ==, DEVPROP_TYPE_STRING ); + + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, instance_id, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_x4( node, ==, next_devinst - 1 ); + + size = ARRAY_SIZE(driver); + swprintf( path, ARRAY_SIZE(path), L"System\\CurrentControlSet\\Enum\\%s", instance_id ); + ret = RegGetValueW( HKEY_LOCAL_MACHINE, path, L"Driver", RRF_RT_ANY, NULL, (BYTE *)driver, &size ); + ok_u4( ret, ==, ERROR_SUCCESS ); + + + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkey, CM_REGISTRY_HARDWARE ); + ok_x4( ret, ==, CR_SUCCESS ); + swprintf( path, ARRAY_SIZE(path), L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Enum\\%s\\Device Parameters", instance_id ); + check_object_name( hkey, path ); + RegCloseKey( hkey ); + + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkey, CM_REGISTRY_USER ); + ok_x4( ret, ==, CR_NO_SUCH_REGISTRY_KEY ); + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenAlways, &hkey, CM_REGISTRY_USER ); + ok_x4( ret, ==, CR_SUCCESS ); + swprintf( path, ARRAY_SIZE(path), L"%s\\System\\CurrentControlSet\\Enum\\%s", user.Buffer, instance_id ); + check_object_name( hkey, path ); + RegCloseKey( hkey ); + swprintf( path, ARRAY_SIZE(path), L"System\\CurrentControlSet\\Enum\\%s", instance_id ); + RegDeleteKeyW( HKEY_CURRENT_USER, path ); + + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkey, CM_REGISTRY_CONFIG ); + ok_x4( ret, ==, CR_NO_SUCH_REGISTRY_KEY ); + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenAlways, &hkey, CM_REGISTRY_CONFIG ); + ok_x4( ret, ==, CR_SUCCESS ); + swprintf( path, ARRAY_SIZE(path), L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Hardware Profiles\\0001\\System\\CurrentControlSet\\Enum\\%s", instance_id ); + check_object_name_( __LINE__, hkey, path, TRUE ); + RegCloseKey( hkey ); + swprintf( path, ARRAY_SIZE(path), L"System\\CurrentControlSet\\Enum\\%s", instance_id ); + RegDeleteKeyW( HKEY_CURRENT_CONFIG, path ); + + + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkey, CM_REGISTRY_SOFTWARE ); + ok_x4( ret, ==, CR_SUCCESS ); + swprintf( path, ARRAY_SIZE(path), L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\%s", driver ); + check_object_name( hkey, path ); + RegCloseKey( hkey ); + + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkey, CM_REGISTRY_SOFTWARE | CM_REGISTRY_USER ); + ok_x4( ret, ==, CR_NO_SUCH_REGISTRY_KEY ); + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenAlways, &hkey, CM_REGISTRY_SOFTWARE | CM_REGISTRY_USER ); + ok_x4( ret, ==, CR_SUCCESS ); + swprintf( path, ARRAY_SIZE(path), L"%s\\System\\CurrentControlSet\\Control\\Class\\%s", user.Buffer, driver ); + check_object_name( hkey, path ); + RegCloseKey( hkey ); + swprintf( path, ARRAY_SIZE(path), L"System\\CurrentControlSet\\Control\\Class\\%s", driver ); + RegDeleteKeyW( HKEY_CURRENT_USER, path ); + + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkey, CM_REGISTRY_SOFTWARE | CM_REGISTRY_CONFIG ); + ok_x4( ret, ==, CR_NO_SUCH_REGISTRY_KEY ); + ret = CM_Open_DevNode_Key( node, KEY_QUERY_VALUE, 0, RegDisposition_OpenAlways, &hkey, CM_REGISTRY_SOFTWARE | CM_REGISTRY_CONFIG ); + ok_x4( ret, ==, CR_SUCCESS ); + swprintf( path, ARRAY_SIZE(path), L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Hardware Profiles\\0001\\System\\CurrentControlSet\\Control\\Class\\%s", driver ); + check_object_name_( __LINE__, hkey, path, TRUE ); + RegCloseKey( hkey ); + swprintf( path, ARRAY_SIZE(path), L"System\\CurrentControlSet\\Control\\Class\\%s", driver ); + RegDeleteKeyW( HKEY_CURRENT_CONFIG, path ); + + + RtlFreeUnicodeString( &user ); +} + static void test_CM_Get_Class_Property_Keys(void) { GUID guid = GUID_DEVCLASS_HIDCLASS; @@ -3069,6 +3163,7 @@ START_TEST(cfgmgr32) test_CM_Get_Device_Interface_Property_setupapi(); test_CM_Get_Device_ID_List(); test_CM_Register_Notification(); + test_CM_Open_DevNode_Key(); test_DevGetObjects(); test_DevCreateObjectQuery(); test_DevGetObjectProperties_invalid(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10436
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/setupapi/setupapi.spec | 4 ++-- dlls/setupapi/stubs.c | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index db9fa24514e..6deb5cd949b 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -146,8 +146,8 @@ @ stdcall CM_Open_Class_KeyW(ptr wstr long long ptr long) cfgmgr32.CM_Open_Class_KeyW @ stdcall CM_Open_Class_Key_ExA(ptr str long long ptr long ptr) cfgmgr32.CM_Open_Class_Key_ExA @ stdcall CM_Open_Class_Key_ExW(ptr wstr long long ptr long ptr) cfgmgr32.CM_Open_Class_Key_ExW -@ stdcall CM_Open_DevNode_Key(long long long long ptr long) -@ stub CM_Open_DevNode_Key_Ex +@ stdcall CM_Open_DevNode_Key(long long long long ptr long) cfgmgr32.CM_Open_DevNode_Key +@ stdcall CM_Open_DevNode_Key_Ex(long long long long ptr long ptr) cfgmgr32.CM_Open_DevNode_Key_Ex @ stub CM_Query_And_Remove_SubTreeA @ stub CM_Query_And_Remove_SubTreeW @ stub CM_Query_And_Remove_SubTree_ExA diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index b14c5a958c2..b1db3bb76dd 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -78,18 +78,6 @@ CONFIGRET WINAPI CM_Disconnect_Machine(HMACHINE handle) } -/*********************************************************************** - * CM_Open_DevNode_Key (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Open_DevNode_Key( - DEVINST dnDevInst, REGSAM access, ULONG ulHardwareProfile, REGDISPOSITION disposition, - PHKEY phkDevice, ULONG ulFlags) -{ - FIXME("0x%08lx 0x%08lx 0x%08lx 0x%08lx %p 0x%08lx : stub\n", dnDevInst, access, ulHardwareProfile, - disposition, phkDevice, ulFlags); - return CR_SUCCESS; -} - /*********************************************************************** * CM_Get_Child (SETUPAPI.@) */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10436
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/cfgmgr32/cfgmgr32.c | 127 ++++++++++++++++++ dlls/cfgmgr32/cfgmgr32.spec | 8 +- dlls/cfgmgr32/tests/cfgmgr32.c | 229 +++++++++++++++++++++++++++++++++ 3 files changed, 360 insertions(+), 4 deletions(-) diff --git a/dlls/cfgmgr32/cfgmgr32.c b/dlls/cfgmgr32/cfgmgr32.c index ac194614645..280f10dd4db 100644 --- a/dlls/cfgmgr32/cfgmgr32.c +++ b/dlls/cfgmgr32/cfgmgr32.c @@ -575,6 +575,79 @@ static LSTATUS open_device_key( HKEY root, const struct device *dev, REGSAM acce return open_enum_key( root, path, access, open, hkey ); } +static const struct property_desc device_properties[] = +{ + /* ansi-compatible CM_DRP properties */ + { &DEVPKEY_Device_DeviceDesc, DEVPROP_TYPE_STRING, L"DeviceDesc" }, + { &DEVPKEY_Device_HardwareIds, DEVPROP_TYPE_STRING_LIST, L"HardwareId" }, + { &DEVPKEY_Device_CompatibleIds, DEVPROP_TYPE_STRING_LIST, L"CompatibleIDs" }, + { &DEVPKEY_Device_Service, DEVPROP_TYPE_STRING, L"Service" }, + { &DEVPKEY_Device_Class, DEVPROP_TYPE_STRING, L"Class" }, + { &DEVPKEY_Device_ClassGuid, DEVPROP_TYPE_GUID, L"ClassGuid" }, + { &DEVPKEY_Device_Driver, DEVPROP_TYPE_STRING, L"Driver" }, + { &DEVPKEY_Device_ConfigFlags, DEVPROP_TYPE_UINT32, L"ConfigFlags" }, + { &DEVPKEY_Device_Manufacturer, DEVPROP_TYPE_STRING, L"Mfg" }, + { &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, L"FriendlyName" }, + { &DEVPKEY_Device_LocationInfo, DEVPROP_TYPE_STRING, L"LocationInformation" }, + { &DEVPKEY_Device_PDOName, DEVPROP_TYPE_STRING, L"PDOName" }, + { &DEVPKEY_Device_Capabilities, DEVPROP_TYPE_UINT32, L"Capabilities" }, + { &DEVPKEY_Device_UINumber, DEVPROP_TYPE_UINT32, L"UINumber" }, + { &DEVPKEY_Device_UpperFilters, DEVPROP_TYPE_STRING_LIST, L"UpperFilters" }, + { &DEVPKEY_Device_LowerFilters, DEVPROP_TYPE_STRING_LIST, L"LowerFilters" }, + { &DEVPKEY_Device_BusTypeGuid, DEVPROP_TYPE_GUID, L"BusTypeGuid" }, + { &DEVPKEY_Device_LegacyBusType, DEVPROP_TYPE_UINT32, L"LegacyBusType" }, + { &DEVPKEY_Device_BusNumber, DEVPROP_TYPE_UINT32, L"BusNumber" }, + { &DEVPKEY_Device_EnumeratorName, DEVPROP_TYPE_STRING, L"EnumeratorName" }, + { &DEVPKEY_Device_Security, DEVPROP_TYPE_SECURITY_DESCRIPTOR, L"Security" }, + { &DEVPKEY_Device_SecuritySDS, DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING, L"SecuritySDS" }, + { &DEVPKEY_Device_DevType, DEVPROP_TYPE_UINT32, L"DevType" }, + { &DEVPKEY_Device_Exclusive, DEVPROP_TYPE_BOOLEAN, L"Exclusive" }, + { &DEVPKEY_Device_Characteristics, DEVPROP_TYPE_UINT32, L"Characteristics" }, + { &DEVPKEY_Device_Address, DEVPROP_TYPE_UINT32, L"Address" }, + { &DEVPKEY_Device_UINumberDescFormat, DEVPROP_TYPE_STRING, L"UINumberDescFormat" }, + { &DEVPKEY_Device_PowerData, DEVPROP_TYPE_BINARY, L"PowerData" }, + { &DEVPKEY_Device_RemovalPolicy, DEVPROP_TYPE_UINT32, L"RemovalPolicy" }, + { &DEVPKEY_Device_RemovalPolicyDefault, DEVPROP_TYPE_UINT32, L"RemovalPolicyDefault" }, + { &DEVPKEY_Device_RemovalPolicyOverride, DEVPROP_TYPE_UINT32, L"RemovalPolicyOverride" }, + { &DEVPKEY_Device_InstallState, DEVPROP_TYPE_UINT32, L"InstallState" }, + { &DEVPKEY_Device_LocationPaths, DEVPROP_TYPE_STRING_LIST, L"LocationPaths" }, + { &DEVPKEY_Device_BaseContainerId, DEVPROP_TYPE_GUID, L"BaseContainerId" }, +}; + +static LSTATUS query_device_property( HKEY hkey, struct property *prop ) +{ + for (UINT i = 0; i < ARRAY_SIZE(device_properties); i++) + { + const struct property_desc *desc = device_properties + i; + if (memcmp( desc->key, &prop->key, sizeof(prop->key) )) continue; + if (!desc->name) return query_property( hkey, L"Properties\\", desc->type, prop ); + return query_named_property( hkey, desc->name, desc->type, prop ); + } + + if (!memcmp( &DEVPKEY_Device_DeviceDesc, &prop->key, sizeof(prop->key.fmtid) )) + { + FIXME( "property %#lx not implemented\n", prop->key.pid - 1 ); + return ERROR_UNKNOWN_PROPERTY; + } + + return query_property( hkey, L"Properties\\", DEVPROP_TYPE_EMPTY, prop ); +} + +static LSTATUS get_device_property( HKEY root, const struct device *dev, struct property *prop ) +{ + LSTATUS err; + HKEY hkey; + + if (!(err = open_device_key( root, dev, KEY_QUERY_VALUE, TRUE, &hkey ))) + { + err = query_device_property( hkey, prop ); + RegCloseKey( hkey ); + } + + if (err && err != ERROR_MORE_DATA) *prop->size = 0; + return err; +} + static CRITICAL_SECTION devnode_cs; static CRITICAL_SECTION_DEBUG devnode_cs_debug = { 0, 0, &devnode_cs, @@ -1397,3 +1470,57 @@ CONFIGRET WINAPI CM_Open_DevNode_Key( DEVINST node, REGSAM access, ULONG profile { return CM_Open_DevNode_Key_Ex( node, access, profile, disposition, hkey, flags, NULL ); } + +/*********************************************************************** + * CM_Get_DevNode_Registry_Property_ExW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW( DEVINST node, ULONG property, ULONG *type, void *buffer, ULONG *len, ULONG flags, HMACHINE machine ) +{ + struct property prop; + struct device dev; + LSTATUS err; + + TRACE( "node %#lx, property %#lx, type %p, buffer %p, len %p, flags %#lx, machine %p\n", node, property, type, buffer, len, flags, machine ); + if (machine) FIXME( "machine %p not implemented!\n", machine ); + if (flags) FIXME( "flags %#lx not implemented!\n", flags ); + + if (devnode_get_device( node, &dev )) return CR_INVALID_DEVNODE; + if ((err = init_registry_property( &prop, &DEVPKEY_Device_DeviceDesc, property, type, buffer, len, FALSE ))) return map_error( err ); + + return map_error( get_device_property( HKEY_LOCAL_MACHINE, &dev, &prop ) ); +} + +/*********************************************************************** + * CM_Get_DevNode_Registry_Property_ExA (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExA( DEVINST node, ULONG property, ULONG *type, void *buffer, ULONG *len, ULONG flags, HMACHINE machine ) +{ + struct property prop; + struct device dev; + LSTATUS err; + + TRACE( "node %#lx, property %#lx, type %p, buffer %p, len %p, flags %#lx, machine %p\n", node, property, type, buffer, len, flags, machine ); + if (machine) FIXME( "machine %p not implemented!\n", machine ); + if (flags) FIXME( "flags %#lx not implemented!\n", flags ); + + if (devnode_get_device( node, &dev )) return CR_INVALID_DEVNODE; + if ((err = init_registry_property( &prop, &DEVPKEY_Device_DeviceDesc, property, type, buffer, len, TRUE ))) return map_error( err ); + + return map_error( get_device_property( HKEY_LOCAL_MACHINE, &dev, &prop ) ); +} + +/*********************************************************************** + * CM_Get_DevNode_Registry_PropertyW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW( DEVINST node, ULONG property, ULONG *type, void *buffer, ULONG *len, ULONG flags ) +{ + return CM_Get_DevNode_Registry_Property_ExW( node, property, type, buffer, len, flags, NULL ); +} + +/*********************************************************************** + * CM_Get_DevNode_Registry_PropertyA (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA( DEVINST node, ULONG property, ULONG *type, void *buffer, ULONG *len, ULONG flags ) +{ + return CM_Get_DevNode_Registry_Property_ExA( node, property, type, buffer, len, flags, NULL ); +} diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index 59e628d6165..9f5ed24ebf0 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -88,10 +88,10 @@ @ stdcall CM_Get_DevNode_Property_ExW(long ptr ptr ptr ptr long ptr) setupapi.CM_Get_DevNode_Property_ExW @ stub CM_Get_DevNode_Property_Keys @ stub CM_Get_DevNode_Property_Keys_Ex -@ stdcall CM_Get_DevNode_Registry_PropertyA(long long ptr ptr ptr long) setupapi.CM_Get_DevNode_Registry_PropertyA -@ stdcall CM_Get_DevNode_Registry_PropertyW(long long ptr ptr ptr long) setupapi.CM_Get_DevNode_Registry_PropertyW -@ stdcall CM_Get_DevNode_Registry_Property_ExA(long long ptr ptr ptr long ptr) setupapi.CM_Get_DevNode_Registry_Property_ExA -@ stdcall CM_Get_DevNode_Registry_Property_ExW(long long ptr ptr ptr long ptr) setupapi.CM_Get_DevNode_Registry_Property_ExW +@ stdcall CM_Get_DevNode_Registry_PropertyA(long long ptr ptr ptr long) +@ stdcall CM_Get_DevNode_Registry_PropertyW(long long ptr ptr ptr long) +@ stdcall CM_Get_DevNode_Registry_Property_ExA(long long ptr ptr ptr long ptr) +@ stdcall CM_Get_DevNode_Registry_Property_ExW(long long ptr ptr ptr long ptr) @ stdcall CM_Get_DevNode_Status(ptr ptr long long) setupapi.CM_Get_DevNode_Status @ stdcall CM_Get_DevNode_Status_Ex(ptr ptr long long ptr) setupapi.CM_Get_DevNode_Status_Ex @ stdcall CM_Get_Device_IDA(ptr ptr long long) diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index 1babd6e52da..0bc02591129 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -3089,6 +3089,234 @@ static void test_CM_Open_DevNode_Key(void) RtlFreeUnicodeString( &user ); } +static void test_CM_Get_DevNode_Registry_Property(void) +{ + WCHAR iface[4096], instance_id[MAX_PATH], buffer[MAX_PATH]; + DWORD size, type, len; + CONFIGRET ret; + DEVINST node; + GUID guid; + + + guid = GUID_DEVINTERFACE_HID; + ret = CM_Get_Device_Interface_ListW( &guid, NULL, iface, ARRAY_SIZE(iface), CM_GET_DEVICE_INTERFACE_LIST_PRESENT ); + if (broken( !*iface )) + { + skip( "No HID device present, skipping tests\n" ); + return; + } + ok_x4( ret, ==, CR_SUCCESS ); + size = sizeof(instance_id); + ret = CM_Get_Device_Interface_PropertyW( iface, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_x4( type, ==, DEVPROP_TYPE_STRING ); + + node = 0xdeadbeef; + ret = CM_Locate_DevNodeW( &node, instance_id, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_x4( node, ==, 2 ); + + + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( 0, CM_DRP_CLASSGUID, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CLASSGUID, NULL, NULL, NULL, 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CLASSGUID, &type, buffer, NULL, 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + len = 1; + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CLASSGUID, &type, NULL, &len, 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + + len = 0; + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CLASSGUID, &type, NULL, &len, 0 ); + ok_x4( ret, ==, CR_BUFFER_SMALL ); + ok_x4( len, ==, 78 ); + len = 1; + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CLASSGUID, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_BUFFER_SMALL ); + ok_x4( len, ==, 78 ); + + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( 10, CM_DRP_CLASSGUID, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, 0, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_INVALID_PROPERTY ); + + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_DEVICEDESC, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, REG_SZ ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_HARDWAREID, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, REG_MULTI_SZ ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_COMPATIBLEIDS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, REG_MULTI_SZ ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_SERVICE, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + ok_u4( type, ==, 0xdeadbeef ); + ok_u4( len, ==, 0 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CLASS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, REG_SZ ); + ok_u4( len, ==, 18 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CLASSGUID, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, REG_SZ ); + ok_u4( len, ==, 78 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_DRIVER, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, REG_SZ ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CONFIGFLAGS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, REG_DWORD ); + ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_MFG, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_SZ ); + todo_wine ok_u4( len, >, 1 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_FRIENDLYNAME, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_LOCATION_INFORMATION, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + ok_u4( type, ==, 0xdeadbeef ); + ok_u4( len, ==, 0 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_SZ ); + todo_wine ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CAPABILITIES, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_DWORD ); + todo_wine ok_u4( len, ==, 4 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_UI_NUMBER, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_UPPERFILTERS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_LOWERFILTERS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_BUSTYPEGUID, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_BINARY ); + todo_wine ok_u4( len, ==, 16 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_LEGACYBUSTYPE, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_DWORD ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_BUSNUMBER, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_DWORD ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_ENUMERATOR_NAME, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_SZ ); + todo_wine ok_u4( len, >, 1 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_SECURITY, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_SECURITY_SDS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_DEVTYPE, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_EXCLUSIVE, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_CHARACTERISTICS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_ADDRESS, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_DWORD ); + todo_wine ok_u4( len, ==, 4 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_UI_NUMBER_DESC_FORMAT, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_DEVICE_POWER_DATA, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_BINARY ); + todo_wine ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_REMOVAL_POLICY, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_DWORD ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_REMOVAL_POLICY_HW_DEFAULT, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_DWORD ); + todo_wine ok_u4( len, ==, 4 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_REMOVAL_POLICY_OVERRIDE, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_INSTALL_STATE, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_DWORD ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_LOCATION_PATHS, &type, buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + ok_u4( type, ==, 0xdeadbeef ); + ok_u4( len, ==, 0 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_Registry_PropertyW( node, CM_DRP_BASE_CONTAINERID, &type, buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, REG_SZ ); + todo_wine ok_u4( len, ==, 78 ); +} + static void test_CM_Get_Class_Property_Keys(void) { GUID guid = GUID_DEVCLASS_HIDCLASS; @@ -3164,6 +3392,7 @@ START_TEST(cfgmgr32) test_CM_Get_Device_ID_List(); test_CM_Register_Notification(); test_CM_Open_DevNode_Key(); + test_CM_Get_DevNode_Registry_Property(); test_DevGetObjects(); test_DevCreateObjectQuery(); test_DevGetObjectProperties_invalid(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10436
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/setupapi/stubs.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index b1db3bb76dd..eccb82295c8 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -255,44 +255,6 @@ CONFIGRET WINAPI CM_Get_Device_Interface_AliasW(const WCHAR *interface, GUID *cl return CR_FAILURE; } -/*********************************************************************** - * CM_Get_DevNode_Registry_Property_ExA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExA(DEVINST dev, ULONG prop, PULONG regdatatype, - PVOID buf, PULONG len, ULONG flags, HMACHINE machine) -{ - FIXME("0x%08lx %lu %p %p %p 0x%08lx %p: stub\n", dev, prop, regdatatype, buf, len, flags, machine); - return CR_FAILURE; -} - -/*********************************************************************** - * CM_Get_DevNode_Registry_Property_ExW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW(DEVINST dev, ULONG prop, PULONG regdatatype, - PVOID buf, PULONG len, ULONG flags, HMACHINE machine) -{ - FIXME("0x%08lx %lu %p %p %p 0x%08lx %p: stub\n", dev, prop, regdatatype, buf, len, flags, machine); - return CR_FAILURE; -} - -/*********************************************************************** - * CM_Get_DevNode_Registry_PropertyA (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA(DEVINST dev, ULONG prop, PULONG regdatatype, - PVOID buf, PULONG len, ULONG flags) -{ - return CM_Get_DevNode_Registry_Property_ExA(dev, prop, regdatatype, buf, len, flags, NULL); -} - -/*********************************************************************** - * CM_Get_DevNode_Registry_PropertyW (SETUPAPI.@) - */ -CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(DEVINST dev, ULONG prop, PULONG regdatatype, - PVOID buf, PULONG len, ULONG flags) -{ - return CM_Get_DevNode_Registry_Property_ExW(dev, prop, regdatatype, buf, len, flags, NULL); -} - /*********************************************************************** * CM_Get_DevNode_Status (SETUPAPI.@) */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10436
participants (1)
-
Rémi Bernon