From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/cfgmgr32/cfgmgr32.c | 151 +++++++++++++++- dlls/cfgmgr32/cfgmgr32.spec | 4 +- dlls/cfgmgr32/cfgmgr32_private.h | 5 +- dlls/cfgmgr32/tests/cfgmgr32.c | 297 +++++++++++++++++++++++++++++++ 4 files changed, 448 insertions(+), 9 deletions(-) diff --git a/dlls/cfgmgr32/cfgmgr32.c b/dlls/cfgmgr32/cfgmgr32.c index 280f10dd4db..42cd5a42d28 100644 --- a/dlls/cfgmgr32/cfgmgr32.c +++ b/dlls/cfgmgr32/cfgmgr32.c @@ -137,7 +137,7 @@ LSTATUS init_property( struct property *prop, const DEVPROPKEY *key, DEVPROPTYPE if (!key) return ERROR_INVALID_PARAMETER; if (!(prop->type = type) || !(prop->size = size)) return ERROR_INVALID_USER_BUFFER; if (!(prop->buffer = buffer) && (*prop->size)) return ERROR_INVALID_USER_BUFFER; - prop->ansi = FALSE; + prop->flags = PROP_FLAG_BINARY; prop->key = *key; prop->reg_type = NULL; return ERROR_SUCCESS; @@ -148,7 +148,7 @@ static LSTATUS init_registry_property( struct property *prop, const DEVPROPKEY * if (!(prop->size = size)) return ERROR_INVALID_USER_BUFFER; if (!(prop->buffer = buffer) && (*prop->size)) return ERROR_INVALID_USER_BUFFER; prop->type = NULL; - prop->ansi = ansi; + prop->flags = ansi ? PROP_FLAG_ANSI : 0; memcpy( &prop->key, base, sizeof(prop->key) ); prop->key.pid = property + 1; prop->reg_type = type; @@ -175,13 +175,25 @@ static LSTATUS query_named_property( HKEY hkey, const WCHAR *nameW, DEVPROPTYPE { LSTATUS err; - if (!prop->ansi) err = RegQueryValueExW( hkey, nameW, NULL, prop->reg_type, prop->buffer, prop->size ); - else + if (prop->flags & PROP_FLAG_ANSI) { char nameA[MAX_PATH]; if (nameW) WideCharToMultiByte( CP_ACP, 0, nameW, -1, nameA, sizeof(nameA), NULL, NULL ); err = RegQueryValueExA( hkey, nameW ? nameA : NULL, NULL, prop->reg_type, prop->buffer, prop->size ); } + else if (type == DEVPROP_TYPE_GUID && (prop->flags & PROP_FLAG_BINARY)) + { + WCHAR buffer[39]; + DWORD len = *prop->size >= sizeof(GUID) ? sizeof(buffer) : 0; + + if (!(err = RegQueryValueExW( hkey, nameW, NULL, prop->reg_type, (BYTE *)buffer, &len ))) + err = guid_from_string( buffer, prop->buffer ); + *prop->size = sizeof(GUID); + } + else + { + err = RegQueryValueExW( hkey, nameW, NULL, prop->reg_type, prop->buffer, prop->size ); + } if (!err && !prop->buffer) err = ERROR_MORE_DATA; if ((!err || err == ERROR_MORE_DATA) && prop->type) *prop->type = type; @@ -203,6 +215,11 @@ static LSTATUS return_property_bool( struct property *prop, DEVPROP_BOOLEAN valu return return_property( prop, DEVPROP_TYPE_BOOLEAN, &value, sizeof(value) ); } +static LSTATUS return_property_string( struct property *prop, const WCHAR *value ) +{ + return return_property( prop, DEVPROP_TYPE_STRING, value, (wcslen( value ) + 1) * sizeof(WCHAR) ); +} + static LSTATUS enum_objects_size( HKEY hkey, const void *object, const WCHAR *path, UINT path_len, void *context ) { UINT *total = context; @@ -612,10 +629,85 @@ static const struct property_desc device_properties[] = { &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" }, + /* unicode-only properties */ + { &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_DevNodeStatus, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_ProblemCode, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_EjectionRelations, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_RemovalRelations, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_PowerRelations, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_BusRelations, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_Parent, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_Children, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_Siblings, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_TransportRelations, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_ProblemStatus, DEVPROP_TYPE_NTSTATUS }, + { &DEVPKEY_Device_Reported, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_Legacy, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_ContainerId, DEVPROP_TYPE_GUID, L"ContainerId" }, + { &DEVPKEY_Device_InLocalMachineContainer, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_Model, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_ModelId, DEVPROP_TYPE_GUID }, + { &DEVPKEY_Device_FriendlyNameAttributes, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_ManufacturerAttributes, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_PresenceNotForDevice, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_SignalStrength, DEVPROP_TYPE_INT32 }, + { &DEVPKEY_Device_IsAssociateableByUserAction, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_ShowInUninstallUI, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_Numa_Proximity_Domain, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_DHP_Rebalance_Policy, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_Numa_Node, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_BusReportedDeviceDesc, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_IsPresent, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_HasProblem, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_ConfigurationId, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_ReportedDeviceIdsHash, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_PhysicalDeviceLocation, DEVPROP_TYPE_BINARY }, + { &DEVPKEY_Device_BiosDeviceName, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_DriverProblemDesc, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_DebuggerSafe, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_PostInstallInProgress, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_Stack, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_ExtendedConfigurationIds, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_IsRebootRequired, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_FirmwareDate, DEVPROP_TYPE_FILETIME }, + { &DEVPKEY_Device_FirmwareVersion, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_FirmwareRevision, DEVPROP_TYPE_STRING }, + { &DEVPKEY_Device_DependencyProviders, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_DependencyDependents, DEVPROP_TYPE_STRING_LIST }, + { &DEVPKEY_Device_SoftRestartSupported, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_ExtendedAddress, DEVPROP_TYPE_UINT64 }, + { &DEVPKEY_Device_SessionId, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_InstallDate, DEVPROP_TYPE_FILETIME }, + { &DEVPKEY_Device_FirstInstallDate, DEVPROP_TYPE_FILETIME }, + { &DEVPKEY_Device_LastArrivalDate, DEVPROP_TYPE_FILETIME }, + { &DEVPKEY_Device_LastRemovalDate, DEVPROP_TYPE_FILETIME }, + { &DEVPKEY_Device_DriverDate, DEVPROP_TYPE_FILETIME, L"DriverDateData" }, + { &DEVPKEY_Device_DriverVersion, DEVPROP_TYPE_STRING, L"DriverVersion" }, + { &DEVPKEY_Device_DriverDesc, DEVPROP_TYPE_STRING, L"DriverDesc" }, + { &DEVPKEY_Device_DriverInfPath, DEVPROP_TYPE_STRING, L"InfPath" }, + { &DEVPKEY_Device_DriverInfSection, DEVPROP_TYPE_STRING, L"InfSection" }, + { &DEVPKEY_Device_DriverInfSectionExt, DEVPROP_TYPE_STRING, L"InfSectionExt" }, + { &DEVPKEY_Device_MatchingDeviceId, DEVPROP_TYPE_STRING, L"MatchingDeviceId" }, + { &DEVPKEY_Device_DriverProvider, DEVPROP_TYPE_STRING, L"ProviderName" }, + { &DEVPKEY_Device_DriverPropPageProvider, DEVPROP_TYPE_STRING, L"EnumPropPages32" }, + { &DEVPKEY_Device_DriverCoInstallers, DEVPROP_TYPE_STRING_LIST, L"CoInstallers32" }, + { &DEVPKEY_Device_ResourcePickerTags, DEVPROP_TYPE_STRING, L"ResourcePickerTags" }, + { &DEVPKEY_Device_ResourcePickerExceptions, DEVPROP_TYPE_STRING, L"ResourcePickerExceptions" }, + { &DEVPKEY_Device_DriverRank, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_DriverLogoLevel, DEVPROP_TYPE_UINT32 }, + { &DEVPKEY_Device_NoConnectSound, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_GenericDriverInstalled, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_AdditionalSoftwareRequested, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_SafeRemovalRequired, DEVPROP_TYPE_BOOLEAN }, + { &DEVPKEY_Device_SafeRemovalRequiredOverride, DEVPROP_TYPE_BOOLEAN }, }; -static LSTATUS query_device_property( HKEY hkey, struct property *prop ) +static LSTATUS query_device_property( HKEY hkey, const struct device *dev, struct property *prop ) { + if (!memcmp( &DEVPKEY_Device_InstanceId, &prop->key, sizeof(prop->key) )) + return return_property_string( prop, dev->instance ); + for (UINT i = 0; i < ARRAY_SIZE(device_properties); i++) { const struct property_desc *desc = device_properties + i; @@ -640,7 +732,7 @@ static LSTATUS get_device_property( HKEY root, const struct device *dev, struct if (!(err = open_device_key( root, dev, KEY_QUERY_VALUE, TRUE, &hkey ))) { - err = query_device_property( hkey, prop ); + err = query_device_property( hkey, dev, prop ); RegCloseKey( hkey ); } @@ -1524,3 +1616,50 @@ CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA( DEVINST node, ULONG property { return CM_Get_DevNode_Registry_Property_ExA( node, property, type, buffer, len, flags, NULL ); } + +/*********************************************************************** + * CM_Get_DevNode_Property_ExW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_Property_ExW( DEVINST node, const DEVPROPKEY *key, DEVPROPTYPE *type, BYTE *buffer, ULONG *size, ULONG flags, HMACHINE machine ) +{ + struct property prop; + struct device dev; + LSTATUS err; + + TRACE( "node %#lx, key %s, type %p, buffer %p, size %p, flags %#lx, machine %p\n", node, debugstr_DEVPROPKEY(key), type, buffer, size, 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_property( &prop, key, type, buffer, size ))) return map_error( err ); + + return map_error( get_device_property( HKEY_LOCAL_MACHINE, &dev, &prop ) ); +} + +/*********************************************************************** + * CM_Get_DevNode_PropertyW (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_PropertyW( DEVINST node, const DEVPROPKEY *key, DEVPROPTYPE *type, BYTE *buffer, ULONG *size, ULONG flags ) +{ + return CM_Get_DevNode_Property_ExW( node, key, type, buffer, size, flags, NULL ); +} + +/*********************************************************************** + * CM_Get_DevNode_Property_Keys_Ex (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_Property_Keys_Ex( DEVINST node, DEVPROPKEY *keys, ULONG *count, ULONG flags, HMACHINE machine ) +{ + TRACE( "node %#lx, keys %p, count %p, flags %#lx, machine %p\n", node, keys, count, flags, machine ); + if (machine) FIXME( "machine %p not implemented!\n", machine ); + if (flags) FIXME( "flags %#lx not implemented!\n", flags ); + + return CR_CALL_NOT_IMPLEMENTED; +} + +/*********************************************************************** + * CM_Get_DevNode_Property_Keys (cfgmgr32.@) + */ +CONFIGRET WINAPI CM_Get_DevNode_Property_Keys( DEVINST node, DEVPROPKEY *keys, ULONG *count, ULONG flags ) +{ + return CM_Get_DevNode_Property_Keys_Ex( node, keys, count, flags, NULL ); +} diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index 9f5ed24ebf0..a728a908a2e 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -84,8 +84,8 @@ @ stub CM_Get_DevNode_Custom_PropertyW @ stub CM_Get_DevNode_Custom_Property_ExA @ stub CM_Get_DevNode_Custom_Property_ExW -@ stdcall CM_Get_DevNode_PropertyW(long ptr ptr ptr ptr long) setupapi.CM_Get_DevNode_PropertyW -@ stdcall CM_Get_DevNode_Property_ExW(long ptr ptr ptr ptr long ptr) setupapi.CM_Get_DevNode_Property_ExW +@ stdcall CM_Get_DevNode_PropertyW(long ptr ptr ptr ptr long) +@ stdcall CM_Get_DevNode_Property_ExW(long ptr ptr ptr ptr long ptr) @ 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) diff --git a/dlls/cfgmgr32/cfgmgr32_private.h b/dlls/cfgmgr32/cfgmgr32_private.h index 81ebd413c12..f614e594c58 100644 --- a/dlls/cfgmgr32/cfgmgr32_private.h +++ b/dlls/cfgmgr32/cfgmgr32_private.h @@ -50,9 +50,12 @@ static inline const char *debugstr_DEVPROPCOMPKEY( const DEVPROPCOMPKEY *key ) debugstr_w( key->LocaleName ) ); } +#define PROP_FLAG_ANSI 1 +#define PROP_FLAG_BINARY 2 + struct property { - BOOL ansi; + UINT flags; DEVPROPKEY key; DEVPROPTYPE *type; DWORD *reg_type; diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index 8fe2b9e7241..540b38f12ca 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -3317,6 +3317,302 @@ static void test_CM_Get_DevNode_Registry_Property(void) todo_wine ok_u4( len, ==, 78 ); } +static void test_CM_Get_DevNode_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_PropertyW( 0, &DEVPKEY_Device_ClassGuid, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ClassGuid, NULL, (BYTE *)NULL, NULL, 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ClassGuid, &type, (BYTE *)buffer, NULL, 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + len = 1; + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ClassGuid, &type, (BYTE *)NULL, &len, 0 ); + ok_x4( ret, ==, CR_INVALID_POINTER ); + + len = 0; + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ClassGuid, &type, (BYTE *)NULL, &len, 0 ); + ok_x4( ret, ==, CR_BUFFER_SMALL ); + ok_x4( len, ==, 16 ); + len = 1; + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ClassGuid, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_BUFFER_SMALL ); + ok_x4( len, ==, 16 ); + + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( 10, &DEVPKEY_Device_ClassGuid, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_INVALID_DEVNODE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, 0, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_FAILURE ); + + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_DeviceDesc, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_STRING ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_HardwareIds, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_STRING_LIST ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_CompatibleIds, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_STRING_LIST ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Service, &type, (BYTE *)buffer, &len, 0 ); + ok( ret == CR_NO_SUCH_VALUE || ret == CR_SUCCESS, "got ret == %#lx\n", ret ); + ok( type == 0xdeadbeef || type == DEVPROP_TYPE_STRING, "got type == %#lx\n", type ); + ok( len == 0 || len == 14, "got len == %#lx\n", len ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Class, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_STRING ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ClassGuid, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_GUID ); + ok_u4( len, ==, 0x10 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Driver, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_STRING ); + ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ConfigFlags, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Manufacturer, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_STRING ); + todo_wine ok_u4( len, >, 1 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_FriendlyName, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_LocationInfo, &type, (BYTE *)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_PropertyW( node, &DEVPKEY_Device_PDOName, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_STRING ); + todo_wine ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Capabilities, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + todo_wine ok_u4( len, ==, 4 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_UINumber, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_UpperFilters, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_LowerFilters, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_BusTypeGuid, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_GUID ); + todo_wine ok_u4( len, ==, 16 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_LegacyBusType, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_BusNumber, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_EnumeratorName, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_STRING ); + todo_wine ok_u4( len, >, 1 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Security, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_SecuritySDS, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_DevType, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Exclusive, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Characteristics, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Address, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + todo_wine ok_u4( len, ==, 4 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_UINumberDescFormat, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_PowerData, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_BINARY ); + todo_wine ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_RemovalPolicy, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_RemovalPolicyDefault, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + todo_wine ok_u4( len, ==, 4 ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_RemovalPolicyOverride, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_InstallState, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_UINT32 ); + todo_wine ok_u4( len, ==, 4 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_LocationPaths, &type, (BYTE *)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_PropertyW( node, &DEVPKEY_Device_BaseContainerId, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_GUID ); + todo_wine ok_u4( len, ==, 0x10 ); + + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_InstanceId, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_STRING ); + ok_u4( len, >, 1 ); + + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_EjectionRelations, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_RemovalRelations, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_PowerRelations, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_BusRelations, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Parent, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Children, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_NO_SUCH_VALUE ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_Siblings, &type, (BYTE *)buffer, &len, 0 ); + ok( ret == CR_SUCCESS || ret == CR_NO_SUCH_VALUE, "got %#lx\n", ret ); + if (ret == CR_SUCCESS) + { + ok_u4( type, ==, DEVPROP_TYPE_STRING_LIST ); + ok_u4( len, >, 1 ); + } + + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_ContainerId, &type, (BYTE *)buffer, &len, 0 ); + ok_x4( ret, ==, CR_SUCCESS ); + ok_u4( type, ==, DEVPROP_TYPE_GUID ); + ok_u4( len, ==, 0x10 ); + + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_DriverDate, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_FILETIME ); + todo_wine ok_u4( len, ==, 8 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_DriverVersion, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_STRING ); + todo_wine ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_DriverDesc, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_STRING ); + todo_wine ok_u4( len, >, 1 ); + type = 0xdeadbeef; + len = sizeof(buffer); + ret = CM_Get_DevNode_PropertyW( node, &DEVPKEY_Device_DriverInfPath, &type, (BYTE *)buffer, &len, 0 ); + todo_wine ok_x4( ret, ==, CR_SUCCESS ); + todo_wine ok_u4( type, ==, DEVPROP_TYPE_STRING ); + todo_wine ok_u4( len, >, 1 ); +} + static void test_CM_Get_Class_Property_Keys(void) { GUID guid = GUID_DEVCLASS_HIDCLASS; @@ -3393,6 +3689,7 @@ START_TEST(cfgmgr32) test_CM_Register_Notification(); test_CM_Open_DevNode_Key(); test_CM_Get_DevNode_Registry_Property(); + test_CM_Get_DevNode_Property(); test_DevGetObjects(); test_DevCreateObjectQuery(); test_DevGetObjectProperties_invalid(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10584