Lomuto
Lomuto

Reputation: 65

how to get serial number via win32 wpd api

as shown in title, i search on google for this question, but there seems that no way get serial number via WPD(Windows Portable Device) api, and in MSDN, i found the WPD_DEVICE_SERIAL_NUMBER property of Portable Device, can anyone tell me how to get this property using wpd api?

Upvotes: 3

Views: 1413

Answers (2)

Bondolin
Bondolin

Reputation: 3121

Bit of a process. Basic steps are as follows:

  1. Get and populate a IPortableDeviceValues of your client info
    // Create our client information collection
    ThrowIfFailed(CoCreateInstance(
        CLSID_PortableDeviceValues,
        nullptr,
        CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&clientInfo)));

    // We have to provide at the least our name, version, revision
    ThrowIfFailed(clientInfo->SetStringValue(
        WPD_CLIENT_NAME,
        L"My super cool WPD client"));

    ThrowIfFailed(clientInfo->SetUnsignedIntegerValue(
        WPD_CLIENT_MAJOR_VERSION,
        1));

    ThrowIfFailed(clientInfo->SetUnsignedIntegerValue(
        WPD_CLIENT_MINOR_VERSION,
        0));

    ThrowIfFailed(clientInfo->SetUnsignedIntegerValue(
        WPD_CLIENT_REVISION,
        1));
  1. Get an IPortableDevice with CoCreateInstance
    // A WPD device is represented by an IPortableDevice instance
    ThrowIfFailed(CoCreateInstance(
        CLSID_PortableDevice,
        nullptr,
        CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&device)));
  1. Connect to the device using IPortableDevice::Open, passing the device's ID and the above client info
    device->Open(deviceId.c_str(), clientInfo);
  1. Get the device's IPortableDeviceContent using IPortableDevice::Content
    CComPtr<IPortableDeviceContent> retVal;

    ThrowIfFailedWithMessage(
        device.Content(&retVal),
        L"! Failed to get IPortableDeviceContent from IPortableDevice");
  1. Get the content's IPortableDeviceProperties using IPortableDeviceContent::Properties
    CComPtr<IPortableDeviceProperties> retVal;

    ThrowIfFailedWithMessage(
        content.Properties(&retVal),
        L"! Failed to get IPortableDeviceProperties from IPortableDeviceContent");
  1. Get the properties' IPortableDeviceValues using IPortableDeviceProperties::GetValues, passing "DEVICE" for pszObjectID and nullptr for pKeys
    CComPtr<IPortableDeviceValues> retVal;

    ThrowIfFailedWithMessage(
        properties.GetValues(objectId.c_str(), nullptr, &retVal),
        L"! Failed to get IPortableDeviceValues from IPortableDeviceProperties");
  1. Get the serial number from the values using IPortableDeviceValues::GetStringValue, passing WPD_DEVICE_SERIAL_NUMBER for key
    propertyKey = WPD_DEVICE_SERIAL_NUMBER;

    LPWSTR value = nullptr;
    ThrowIfFailedWithMessage(
        values.GetStringValue(propertyKey, &value),
        L"! Failed to get string value from IPortableDeviceValues");

    propertyValue = value;
    if (value != nullptr)
    {
        CoTaskMemFree(value);
    }

By no means a complete listing, sorry. The ThrowIf* functions are just basic helpers I wrote to go from checking HRESULTs to throwing exceptions. Hopefully this points you in the right direction.

Additional references:

Upvotes: 1

Jacob Seleznev
Jacob Seleznev

Reputation: 8151

The C++ sample can be found here and here

Upvotes: 0

Related Questions