DevGetObjectProperties function (devquery.h)

Synchronously retrieve a set of properties for a specified object

Syntax

HRESULT DevGetObjectProperties(
  [in]  DEV_OBJECT_TYPE      ObjectType,
  [in]  PCWSTR               pszObjectId,
  [in]  ULONG                QueryFlags,
  [in]  ULONG                cRequestedProperties,
  [in]  const DEVPROPCOMPKEY *pRequestedProperties,
  [out] PULONG               pcPropertyCount,
  [out] const DEVPROPERTY    **ppProperties
);

Parameters

[in] ObjectType

A value from the DEV_OBJECT_TYPE that determines the type of object for which properties are to be retrieved.

[in] pszObjectId

The identity of the object for which properties are to be retrieved.

[in] QueryFlags

A combination of DEV_QUERY_FLAGS values that are combined by using a bitwise OR operation. It is not valid to pass either DevQueryFlagUpdateResults or DevQueryFlagAsyncClose to this function.

[in] cRequestedProperties

The number of DEVPROPCOMPKEY structures provided in pRequestedProperties. If DevQueryFlagAllProperties is specified, this must be set to 0.

[in] pRequestedProperties

Provides an array of DEVPROPCOMPKEY structures that specify the properties that should be retrieved for the specified object.

The LocaleName field of the DEVPROPCOMPKEY structure is ignored and must be set to NULL.

If cRequestedProperties is 0, this must be NULL.

[out] pcPropertyCount

The number of DEVPROPERTY structures returned in ppProperties.

[out] ppProperties

Pointer that receives the newly allocated array of DEVPROPERTY results. Callers must free the pointer using DevFreeObjectProperties.

Return value

S_OK is returned if the function successfully evaluated the search criteria and returned matching objects; otherwise, an appropriate error value.

Remarks

This function is an efficient way to synchronously retrieve a set of properties from an object given its type and identity. The array of properties that are returned must be freed using DevFreeObjectProperties. If a requested property does not exist, ppProperties will still contain an entry for that property but the entry will have a type of DEVPROP_TYPE_EMPTY.

Example

The following example demonstrates calling DevGetObjectProperties to retrieve a set of requested properties and then calling DevFindProperty to find a particular property within an array of DEVPROPERTY structures.

void
Example1(PCWSTR DeviceInstancePath)
{
    HRESULT hr = S_OK;
    const DEVPROPERTY* TempProperty = NULL;
    ULONG PropertyCount = 0;
    const DEVPROPERTY* PropertyList = NULL;
    DEVPROPCOMPKEY RequestedProperties[] =
    {
        { DEVPKEY_Device_HardwareIds, DEVPROP_STORE_SYSTEM, NULL },
        { DEVPKEY_Device_CompatibleIds, DEVPROP_STORE_SYSTEM, NULL }
    };

    hr = DevGetObjectProperties(DevObjectTypeDevice,
                                DeviceInstancePath,
                                DevQueryFlagNone,
                                RTL_NUMBER_OF(RequestedProperties),
                                RequestedProperties,
                                &PropertyCount,
                                &PropertyList);

    if (FAILED(hr))
    {
        wprintf(L"Failed to retrieve properties. hr = 0x%08x\n", hr);
        goto exit;
    }

    wprintf(L"Hardware IDs:\n");
    TempProperty = DevFindProperty(&DEVPKEY_Device_HardwareIds,
                                   DEVPROP_STORE_SYSTEM,
                                   NULL,
                                   PropertyCount,
                                   PropertyList);

    if ((TempProperty == NULL) ||
        (TempProperty->Type == DEVPROP_TYPE_EMPTY) ||
        (TempProperty->Buffer == NULL))
    {
        wprintf(L"<none>\n");
    }
    else if ((TempProperty->Type != DEVPROP_TYPE_STRING_LIST) ||
             (TempProperty->BufferSize < sizeof(WCHAR)))
    {
        wprintf(L"Device '%ws' has a corrupted Hardware IDs property.\n",
                DeviceInstancePath);
    }
    else
    {
        for (PCWSTR CurrentId = (PCWSTR)TempProperty->Buffer;
             *CurrentId != L'\0';
             CurrentId += wcslen(CurrentId) + 1)
        {
            wprintf(L"%ws\n", CurrentId);
        }
    }

    wprintf(L"\nCompatible IDs:\n");
    TempProperty = DevFindProperty(&DEVPKEY_Device_CompatibleIds,
                                   DEVPROP_STORE_SYSTEM,
                                   NULL,
                                   PropertyCount,
                                   PropertyList);

    if ((TempProperty == NULL) ||
        (TempProperty->Type == DEVPROP_TYPE_EMPTY) ||
        (TempProperty->Buffer == NULL))
    {
        wprintf(L"<none>\n");
    }
    else if ((TempProperty->Type != DEVPROP_TYPE_STRING_LIST) ||
             (TempProperty->BufferSize < sizeof(WCHAR)))
    {
        wprintf(L"Device '%ws' has a corrupted Compatible IDs property.\n",
                DeviceInstancePath);
    }
    else
    {
        for (PCWSTR CurrentId = (PCWSTR)TempProperty->Buffer;
             *CurrentId != L'\0';
             CurrentId += wcslen(CurrentId) + 1)
        {
            wprintf(L"%ws\n", CurrentId);
        }
    }

  exit:

    if (PropertyList != NULL)
    {
        DevFreeObjectProperties(PropertyCount, PropertyList);
    }

    return;
}

Requirements

Requirement Value
Minimum supported client Windows 10 version 1809
Minimum supported server Windows Server 2019
Header devquery.h
Library Onecore.lib
DLL Cfgmgr32.dll