IWMDMStorage4
COM公式ドキュメント
IWMDMStorage4 インターフェイスは IWMDMStorage3 を拡張し、ストレージで利用可能なメタデータのサブセットを取得するメソッドと、他のストレージへの参照の一覧を設定および取得するメソッドを提供します。
メソッド 6
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
SetReferences メソッドは、参照を持つストレージ (プレイリストやアルバムなど) が保持する参照を設定します。そのストレージが以前に保持していた参照はすべて上書きされます。
| dwRefs | DWORD | in | ppIWMDMStorage に含まれる IWMDMStorage インターフェイスポインターの数。0 も有効な値であり、その場合はストレージからすべての参照が消去されます。このときストレージ自体は削除されません。 |
| ppIWMDMStorage | IWMDMStorage** | inoptional | ストレージから参照される IWMDMStorage インターフェイスポインターの配列へのポインター。この順序はストレージによって保持されます。dwRefs も 0 の場合は NULL も有効な値です。この配列の割り当てと解放は呼び出し元が行います。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次のいずれかの種類のエラーコードを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
このメソッドは、プレイリストやアルバムのように参照によって構成されるオブジェクトに参照を設定するために使用します。デバイスがメタデータをサポートしていない場合、このメソッドはサポートされない可能性が高くなります。
ppIWMDMStorage 配列には、有効な IWMDMStorage オブジェクトであればどれでも格納できます。これには、フォルダーや、それ自体が参照を指定する他のストレージ (たとえばプレイリストのプレイリストを作成する場合) も含まれます。参照先オブジェクトの個々のケースをどのように扱うかは、デバイス自体が決定します。Windows Media Device Manager は、IWMDMStorage が有効であること以外のルールを強制しません。入れ子になったプレイリスト参照を含むプレイリストの場合を考えてみます。あるデバイスではこれは許可されず、SetReferences は失敗します。別のデバイスではこれが許可され、再生時には含まれる参照のセット全体を深さ優先の順にたどるだけです。
IWMDMStorage4 インターフェイスポインターが、デバイス上にすでに存在しないストレージに対応している状況が生じることがあります。この場合は WMDM_E_INTERFACEDEAD が返されます。
GetReferences メソッドは、このストレージが指している IWMDMStorage オブジェクトへのポインターの配列を取得します。抽象アルバムや抽象プレイリストは、通常 MTP デバイス上では参照のコレクションとして格納されます。
| pdwRefs | DWORD* | out | pppIWMDMStorage によって取得された値の数へのポインター。オブジェクトが参照を持たない場合は 0 が返され、関数は S_OK を返します。 |
| pppIWMDMStorage | IWMDMStorage*** | out | ストレージ内の参照を表す IWMDMStorage インターフェイスポインターの配列へのポインターへのポインター。このような参照は、たとえばプレイリストやアルバム内の項目を表すことができます。取得される配列は、オブジェクト内に現れるのと同じ順序になります。この配列のメモリは Windows Media Device Manager によって割り当てられます。呼び出し元のアプリケーションは、この配列へのアクセスを終えたら、まずすべてのインターフェイスポインターに対して Release を呼び出し、その後 CoTaskMemFree を使用して配列のメモリを解放する必要があります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次のいずれかの種類のエラーコードを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
Windows Media Device Manager は、ストレージ上の参照を追加および削除する処理を、基になるサービスプロバイダーに委譲します。参照を持つオブジェクトとは、抽象プレイリストや抽象アルバムのような抽象オブジェクトを指します。フォルダーは参照を持つものとは見なされません。
このメソッドでエラーの原因となる非同期の削除には 2 種類あります。アプリケーションがストレージへの参照を取得した後にその参照が削除され、アプリケーションがその参照を使用しようとした場合、メソッド呼び出しは WMDM_E_INTERFACEDEAD を返します。参照が指すファイルが削除されている場合は、S_FALSE が返されます。
例
次の C++ コードは、ストレージ (pStorage) の参照を照会します。
// 参照を取得します。
CComQIPtr<IWMDMStorage4> pStorage4(pStorage);
if (pStorage4 != NULL)
{
WCHAR name[100];
DWORD numRefs = 0;
IWMDMStorage** parrReferences;
hr = pStorage4->GetReferences(&numRefs, &parrReferences);
for(int i = 0; i < numRefs; i++)
{
ZeroMemory(name, sizeof(name));
hr = parrReferences[i]->GetName(name, (sizeof(name) / sizeof(WCHAR)) - 1);
if (hr == S_OK)
// TODO: 名前を表示します。
parrReferences[i]->Release();
}
// メモリを解放します。
if (parrReferences != NULL)
CoTaskMemFree(parrReferences);
}
GetRightsWithProgress メソッドは、ストレージオブジェクトの権利情報を取得します。その際、進行状況を監視するためのコールバック機構を提供します。
| pIProgressCallback | IWMDMProgress3* | inoptional | Windows Media Device Manager がアプリケーションに進行状況を報告するために使用する IWMDMProgress3 インターフェイスへの省略可能なポインター。 |
| ppRights | WMDMRIGHTS** | out | ストレージオブジェクトの権利情報を格納する WMDMRIGHTS 構造体の配列へのポインター。この配列のメモリは Windows Media Device Manager によって割り当てられます。呼び出し元のアプリケーションは、この配列へのアクセスを終えたら、CoTaskMemFree を使用してメモリを解放する必要があります。 |
| pnRightsCount | DWORD* | out | ppRights 配列内の WMDMRIGHTS 構造体の数へのポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次のいずれかの種類のエラーコードを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
オブジェクトの権利は、デジタルメディアコンテンツの使用許諾を表します。たとえば WMDMRIGHTS 構造体には、ファイルを再生できる回数や、誰が再生できるかに関する情報を格納できます。
ライセンスされたファイルから権利を取得する処理は、時間がかかることがあります。この関数を使用すると、権利の要求を非同期に実行できます。
セキュアコンテンツプロバイダーは、進行状況の通知に加えて、コールバック pIProgressCallback 上でイベント通知を生成できます。このようなイベントの例としては、セキュアクロックの取得や DRM の初期化などがあります。これらのイベントについては IWMDMProgress3::Progress3 で説明しています。
このメソッドは IWMDMStorage::GetRights と同一ですが、進行状況を返す点と、パラメーター検証用の MAC を提供しない点が異なります。
GetSpecifiedMetadata メソッドは、ストレージから 1 つ以上の特定のメタデータプロパティを取得します。
| cProperties | DWORD | in | 取得するプロパティの数。 |
| ppwszPropNames | LPWSTR* | in | 取得するプロパティ名の配列。この配列の長さは cProperties と等しくする必要があります。アプリケーションは CoTaskMemFree を使用してこのメモリを解放する必要があります。 |
| ppMetadata | IWMDMMetaData** | out | 取得された値を格納する、返される IWMDMMetaData インターフェイスポインターへのポインター。呼び出し元は、使用を終えたらこのインターフェイスを解放する必要があります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次のいずれかの種類のエラーコードを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
このメソッドを使用すると、クライアントはどのプロパティを取得するかを制御できます。これは IWMDMStorage3::GetMetadata よりも効率的な場合があり、クライアントがストレージでサポートされるプロパティのサブセットのみを必要とする場合に推奨されます。
このメソッドを使用して Windows Portable Devices (WPD) デバイスからデータを取得した場合、データは IPortableDeviceValues オブジェクト内にバイナリ形式で返されます。実際のプロパティ値を得るには、アプリケーションがこのデータを逆シリアル化する必要があります。
指定したプロパティの一部が取得できなかった場合でも、少なくとも 1 つのプロパティが取得できていれば、このメソッドは成功し WMDM_S_NOT_ALL_PROPERTIES_RETRIEVED を返します。指定したプロパティを 1 つも取得できなかった場合、このメソッドは失敗し WMDM_E_NOTSUPPORTED を返します。
単一のプロパティを要求する場合は、このメソッドの特殊なケースになります。クライアントが単一のプロパティを要求した場合、返される可能性のあるコードは S_OK、E_INVALIDARG、WMDM_E_NOTSUPPORTED です。したがって単一プロパティの場合、このメソッドはそのプロパティの取得に成功したときにのみ成功します。
FindStorage メソッドは、永続的な一意識別子に基づいて、現在のルートストレージ内のストレージを取得します。
| findScope | WMDM_FIND_SCOPE | in | 検索するスコープを指定する WMDM_FIND_SCOPE 列挙体。 |
| pwszUniqueID | LPWSTR | in | 検索するストレージの永続的な一意識別子。ストレージの永続的な一意識別子は、そのストレージの g_wszWMDMPersistentUniqueID メタデータプロパティによって表されます。 |
| ppStorage | IWMDMStorage** | out | 見つかった場合、取得されたストレージへのポインター。呼び出し元は、使用を終えたらこのインターフェイスを解放する必要があります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次のいずれかの種類のエラーコードを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
このメソッドは、デバイス上の単一のメモリオブジェクト (フラッシュカードまたはハードディスク) のみを検索します。
永続的な一意識別子は、特定のデバイスに格納されたコンテンツを識別します。すべてのデバイスで同一のまま保たれる、コンテンツ固有のグローバル一意識別子を表すものではありません。したがって、同じコンテンツであっても異なるストレージに格納されていれば、異なる永続的な一意識別子を持ちます。同様に、異なるコンテンツであっても、異なるデバイスに格納されている場合は同じ永続的な一意識別子を持つことがあります。
永続的な一意識別子の形式はデバイスによって異なります。アプリケーションは、あらかじめストレージを取得し、その WMDM/PersistentUniqueID プロパティを照会することで、永続的な一意識別子を取得しておく必要があります。このプロパティを要求するには、GetSpecifiedMetadata メソッドまたは GetMetadata メソッドを使用します。
GetParent メソッドは、ストレージの親を取得します。
| ppStorage | IWMDMStorage** | out | 親ストレージの IWMDMStorage インターフェイスへのポインター。呼び出し元は、使用を終えたらこのインターフェイスを解放する必要があります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次のいずれかの種類のエラーコードを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
アプリケーションは、GetParent を再帰的に呼び出すことでストレージ階層をさかのぼることができます。ルートストレージに到達した後は、GetParent は S_FALSE を返し、ppStorage に NULL を設定します。
例
次の C++ 関数は、ストレージのルートの親までさかのぼります。
HRESULT BubbleUp(IWMDMStorage *pIStorage)
{
HRESULT hr = S_OK;
CComPtr<IWMDMStorage4> pStorage4;
hr = pIStorage->QueryInterface (__uuidof(IWMDMStorage4), reinterpret_cast<void**>(&pStorage4));
if (SUCCEEDED(hr))
{
while ((pStorage4 != NULL))
{
CComPtr<IWMDMStorage> pParent;
hr = pStorage4->GetParent(&pParent);
if (FAILED(hr))
{
break;
}
//
// pParent に対して何らかの処理を行います....
//
if (S_FALSE != hr)
{
hr = pParent->QueryInterface (__uuidof(IMDSPStorage4), reinterpret_cast<void**>(&pStorage4));
if (FAILED(hr))
{
break;
}
}
} // 次の親へループします。
}
return hr;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IWMDMStorage4 "{C225BAC5-A03A-40B8-9A23-91CF478C64A6}" #usecom global IWMDMStorage4 IID_IWMDMStorage4 "{807B3CE0-357A-11D3-8471-00C04F79DBC0}" #comfunc global IWMDMStorage4_SetReferences 19 int,sptr #comfunc global IWMDMStorage4_GetReferences 20 var,sptr #comfunc global IWMDMStorage4_GetRightsWithProgress 21 sptr,var,var #comfunc global IWMDMStorage4_GetSpecifiedMetadata 22 int,var,sptr #comfunc global IWMDMStorage4_FindStorage 23 int,wstr,sptr #comfunc global IWMDMStorage4_GetParent 24 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IWMDMStorage4 "{C225BAC5-A03A-40B8-9A23-91CF478C64A6}" #usecom global IWMDMStorage4 IID_IWMDMStorage4 "{807B3CE0-357A-11D3-8471-00C04F79DBC0}" #comfunc global IWMDMStorage4_SetReferences 19 int,sptr #comfunc global IWMDMStorage4_GetReferences 20 sptr,sptr #comfunc global IWMDMStorage4_GetRightsWithProgress 21 sptr,sptr,sptr #comfunc global IWMDMStorage4_GetSpecifiedMetadata 22 int,sptr,sptr #comfunc global IWMDMStorage4_FindStorage 23 int,wstr,sptr #comfunc global IWMDMStorage4_GetParent 24 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。