Поделиться через


Получение идентификатора объекта из постоянного уникального идентификатора

Идентификаторы объектов гарантированно будут уникальными только для определенного сеанса устройства; Если пользователь устанавливает новое подключение, идентификаторы из предыдущего сеанса могут не совпадать с идентификаторами текущего сеанса. Чтобы устранить эту проблему, API WPD поддерживает постоянные уникальные идентификаторы (PUID), которые сохраняются в сеансах устройства.

Некоторые устройства хранят свои PUID в собственном коде с заданным объектом. Другие пользователи могут создавать PUID на основе хэша выбранных данных объекта. Другие могут рассматривать идентификаторы объектов как PUID (так как они могут гарантировать, что эти идентификаторы никогда не изменяются).

Функция GetObjectIdentifierFromPersistentUniqueIdentifier в модуле ContentProperties.cpp демонстрирует получение идентификатора объекта для заданного PUID.

Приложение может получить идентификатор объекта для соответствующего PUID с помощью интерфейсов, описанных в следующей таблице.

Интерфейс Описание
Интерфейс IPortableDeviceContent Предоставляет доступ к методу извлечения.
Интерфейс IPortableDevicePropVariantCollection Используется для хранения идентификатора объекта и соответствующего постоянного уникального идентификатора (PUID).

 

Первая задача, которую выполняет пример приложения, — получение PUID от пользователя.

// Prompt user to enter an unique identifier to convert to an object idenifier.
printf("Enter the Persistant Unique Identifier of the object you wish to convert into an object identifier.\n>");
hr = StringCbGetsW(szSelection,sizeof(szSelection));
if (FAILED(hr))
{
    printf("An invalid persistent object identifier was specified, aborting the query operation\n");
}

После этого пример приложения получает объект IPortableDeviceContent , который будет использоваться для вызова метода GetObjectIDsFromPersistentUniqueIDs .

if (SUCCEEDED(hr))
{
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }
}

Затем он создает объект IPortableDevicePropVariantCollection , который будет содержать puID, предоставленный пользователем.

hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      IID_PPV_ARGS(&pPersistentUniqueIDs));

После выполнения трех предыдущих шагов пример готов к получению идентификатора объекта, который соответствует puID, предоставленному пользователем. Это достигается путем вызова метода IPortableDeviceContent::GetObjectIDsFromPersistentUniqueIDs . Перед вызовом этого метода пример инициализирует структуру PROPVARIANT, записывает puID, предоставленный пользователем, в эту структуру, и добавляет его в объект IPortableDevicePropVariantCollection, на который указывает pPersistentUniqueIDs. Этот указатель передается в качестве первого аргумента методу GetObjectIDsFromPersistentUniqueIDs. Второй аргумент GetObjectIDsFromPersistentUniqueIDs — это объект IPortableDevicePropVariantCollection, который получает соответствующий идентификатор объекта.

if (SUCCEEDED(hr))
{
    if (pPersistentUniqueIDs != NULL)
    {
        PROPVARIANT pv = {0};
        PropVariantInit(&pv);

        // Initialize a PROPVARIANT structure with the object identifier string
        // that the user selected above. Notice we are allocating memory for the
        // PWSTR value.  This memory will be freed when PropVariantClear() is
        // called below.
        pv.vt      = VT_LPWSTR;
        pv.pwszVal = AtlAllocTaskWideString(szSelection);
        if (pv.pwszVal != NULL)
        {
            // Add the object identifier to the objects-to-delete list
            // (We are only deleting 1 in this example)
            hr = pPersistentUniqueIDs->Add(&pv);
            if (SUCCEEDED(hr))
            {
                // 3) Attempt to get the unique idenifier for the object from the device
                hr = pContent->GetObjectIDsFromPersistentUniqueIDs(pPersistentUniqueIDs,
                                                                   &pObjectIDs);
                if (SUCCEEDED(hr))
                {
                    PROPVARIANT pvId = {0};
                    hr = pObjectIDs->GetAt(0, &pvId);
                    if (SUCCEEDED(hr))
                    {
                        printf("The persistent unique identifier '%ws' relates to object identifier '%ws' on the device.\n", szSelection, pvId.pwszVal);
                    }
                    else
                    {
                        printf("! Failed to get the object identifier for '%ws' from the IPortableDevicePropVariantCollection, hr = 0x%lx\n",szSelection, hr);
                    }

                    // Free the returned allocated string from the GetAt() call
                    PropVariantClear(&pvId);
                }
                else
                {
                    printf("! Failed to get the object identifier from persistent object idenifier '%ws', hr = 0x%lx\n",szSelection, hr);
                }
            }
            else
            {
                printf("! Failed to get the object identifier from persistent object idenifier because we could no add the persistent object identifier string to the IPortableDevicePropVariantCollection, hr = 0x%lx\n",hr);
            }
        }
        else
        {
            hr = E_OUTOFMEMORY;
            printf("! Failed to get the object identifier because we could no allocate memory for the persistent object identifier string, hr = 0x%lx\n",hr);
        }

        // Free any allocated values in the PROPVARIANT before exiting
        PropVariantClear(&pv);
    }
}

Интерфейс IPortableDevice

Интерфейс IPortableDeviceContent

Интерфейс IPortableDevicePropVariantCollection

Руководство по программированию