永続的な一意の ID からオブジェクト ID を取得する
オブジェクト識別子は、特定のデバイス セッションに対してのみ一意であることが保証されます。ユーザーが新しい接続を確立した場合、以前のセッションの識別子が現在のセッションの識別子と一致しない可能性があります。 この問題を解決するために、WPD API では、デバイス セッション間で保持される永続的な一意識別子 (PUID) がサポートされています。
一部のデバイスでは、特定のオブジェクトを使用して PUID をネイティブに格納します。 他のユーザーは、選択したオブジェクト データのハッシュに基づいて PUID を生成できます。 他のユーザーは、オブジェクト識別子を PUID として扱う場合があります (これらの識別子が変更されないことを保証できるため)。
ContentProperties.cpp モジュールの GetObjectIdentifierFromPersistentUniqueIdentifier 関数は、特定の 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");
}
この後、サンプル アプリケーションは、GetObjectIDsFromPersistentUniqueIDs メソッドの呼び出しに使用する IPortableDeviceContent オブジェクトを取得します。
if (SUCCEEDED(hr))
{
hr = pDevice->Content(&pContent);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
}
}
次に、ユーザーが指定した PUID を保持する IPortableDevicePropVariantCollection オブジェクトを作成します。
hr = CoCreateInstance(CLSID_PortableDevicePropVariantCollection,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pPersistentUniqueIDs));
前の 3 つの手順を実行すると、サンプルは、ユーザーによって提供された PUID に一致するオブジェクト識別子を取得する準備が整います。 これは、 IPortableDeviceContent::GetObjectIDsFromPersistentUniqueIDs メソッドを呼び出すことによって実現されます。 このメソッドを呼び出す前に、このサンプルは PROPVARIANT 構造体を初期化し、ユーザーが指定した PUID をこの構造体に書き込み、pPersistentUniqueIDs が指す IPortableDevicePropVariantCollection オブジェクトに追加します。 このポインターは、GetObjectIDsFromPersistentUniqueIDs メソッドの最初の引数として渡されます。 GetObjectIDsFromPersistentUniqueIDs の 2 番目の引数は、一致するオブジェクト識別子を受け取る 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);
}
}
関連トピック