IWMDMStorage
COM公式ドキュメント
IWMDMStorage インターフェイスのインスタンスは、デバイス上のストレージ(ファイル、フォルダー、プレイリストなど、データオブジェクトやコレクションオブジェクトの総称)を調査および探索するためのメソッドを提供します。
メソッド 9
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
SetAttributes メソッドは、ストレージの属性を設定します。
| dwAttributes | DWORD | in | 設定する属性を指定する DWORD。次の表に、このパラメーターで設定できる属性を示します。
| ||||||||||||||||||||||||||
| pFormat | WAVEFORMATEX* | inoptional | オブジェクトのオーディオ情報を指定する _WAVEFORMATEX 構造体への省略可能なポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
GetAttributes に記載されている属性の多くは設定できないため、SetAttributes の属性表には記載されていません。
GetStorageGlobals メソッドは、このストレージのルートストレージの IWMDMStorageGlobals インターフェイスを取得します。
| ppStorageGlobals | IWMDMStorageGlobals** | out | シリアル番号や機能などのデバイス情報を提供する IWMDMStorageGlobals インターフェイスへのポインター。呼び出し元は、使用が終わったらこのインターフェイスを解放する必要があります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
返される IWMDMStorageGlobals インターフェイスは、現在のストレージのルートストレージに関するグローバル情報へアクセスするためのメソッドを提供します。このインターフェイスはデバイスのグローバル情報を公開するため、アプリケーションは 1 つのメモリコンテナー内のいずれかのストレージに対して、このメソッドを一度呼び出すだけで済みます。
GetAttributes メソッドは、ストレージの属性を取得します。
| pdwAttributes | DWORD* | out | 次の属性のうち 1 つ以上をビットごとの OR で組み合わせて指定する DWORD へのポインター。
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pFormat | WAVEFORMATEX* | inoutoptional | オブジェクトのオーディオ属性を指定する _WAVEFORMATEX 構造体への省略可能なポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
GetName メソッドは、ストレージの表示名を取得します。
| pwszName | LPWSTR | out | ストレージ名を格納する、null で終わるワイド文字文字列へのポインター。オブジェクトの表示名は、パス情報を含まないファイル名です。このバッファーの割り当てと解放は呼び出し元が行います。 |
| nMaxChars | DWORD | in | 名前文字列にコピーできる最大文字数を示す整数。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
GetDate メソッドは、ストレージが最後に変更された日付を取得します。
| pDateTimeUTC | WMDMDATETIME* | out | ストレージオブジェクト(ファイルまたはフォルダー)が最後に変更された日付を指定する WMDMDATETIME 構造体へのポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
時刻は協定世界時 (UTC) で指定されます。
例
次の C++ コードは、渡されたストレージから「最終更新日時」の値を取得します。
// 「最終更新日時」を取得します。
WMDMDATETIME lastModified;
hr = pStorage->GetDate(&lastModified);
// TODO: 最終更新の年月日を表示します。
GetSize メソッドは、ストレージのサイズをバイト単位で取得します。
| pdwSizeLow | DWORD* | out | ストレージオブジェクトのサイズ(バイト単位)の下位部分を指定する DWORD へのポインター。 |
| pdwSizeHigh | DWORD* | out | ストレージオブジェクトのサイズ(バイト単位)の上位部分を指定する DWORD へのポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
フォルダーや抽象オブジェクト(抽象プレイリストなど)の場合、サイズは 0 です。
例
次の C++ コードは、ファイルのサイズをキロバイト単位で取得します。
// ファイルのサイズをキロバイト単位で取得します。
DWORD lowSize = 0;
DWORD highSize = 0;
hr = pStorage->GetSize(&lowSize, &highSize);
//TODO: ファイルサイズを表示します。
GetRights メソッドは、ライセンスされたストレージの権利情報を取得します。
| ppRights | WMDMRIGHTS** | out | ストレージの権利を格納する WMDMRIGHTS 構造体の配列へのポインター。このパラメーターはメッセージ認証コードに含まれます。このメモリは Windows Media Device Manager が割り当てるため、アプリケーションは CoTaskMemFree で解放する必要があります。 |
| pnRightsCount | DWORD* | out | ppRights 配列に含まれる WMDMRIGHTS 構造体の数へのポインター。このパラメーターはメッセージ認証コードに含まれます。 |
| abMac | BYTE* | inout | このメソッドのパラメーターデータに対するメッセージ認証コード (MAC) を格納するバイト配列。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
オブジェクトの権利は、デジタルメディアコンテンツの使用許諾を表します。たとえば、WMDMRIGHTS 構造体には、ファイルを再生できる回数や再生できるユーザーに関する情報を格納できます。ライセンスされたファイルでない場合、このメソッドは失敗します。
ppRights 配列はこのメソッドによって割り当てられるため、アプリケーションは標準の Win32 関数である CoTaskMemFree を使用して解放する必要があります。
この呼び出しの進行状況イベントを受け取るには、IWMDMStorage4::GetRightsWithProgress を使用します。
このメソッドを呼び出した後、アプリケーションはパラメーターのメッセージ認証コード (MAC) 値を計算し、出力された MAC 値と比較することで、パラメーターが改ざんされていないことを確認できます。次のサンプルコードは、その一例を示しています。
例
CSecureChannelClient *pSCClient;
IWMDMStorage *pStorgae;
HMAC hMAC;
BYTE abMAC[WMDM_MAC_LENGTH];
BYTE abMACVerify[WMDM_MAC_LENGTH];
hr = pStorage->GetRights(&pRights, &nRightsCount, abMAC);
if (SUCCEEDED(hr))
{
//
// まず、取得した権利の整合性を検証します。
//
pSCClient->MACInit(&hMAC);
pSCClient->MACUpdate(hMAC, (BYTE*)(pRights),
sizeof(WMDMRIGHTS) * nRightsCount);
pSCClient->MACUpdate(hMAC, (BYTE*)(&nRightsCount),
sizeof(nRightsCount));
pSCClient->MACFinal(hMAC, (BYTE*)abMACVerify);
if (memcmp(abMACVerify, abMAC, sizeof(abMAC)) != 0)
{
hr = WMDM_E_MAC_CHECK_FAILED;
}
}
EnumStorage メソッドは、現在のストレージの直下の子ストレージを列挙するために IWMDMEnumStorage インターフェイスを取得します。
| pEnumStorage | IWMDMEnumStorage** | out | IWMDMEnumStorage インターフェイスへのポインター。呼び出し元は、使用が終わったらこのインターフェイスを解放する必要があります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
取得される IWMDMEnumStorage インターフェイスは、このオブジェクトの直下の子を列挙します。このメソッドにより、アプリケーションはデバイスの内容を再帰的にたどることができます。
SendOpaqueCommand メソッドは、Windows Media Device Manager を介して、コマンドを処理せずにストレージへ送信します。
| pCommand | OPAQUECOMMAND* | inout | 実行するコマンドを格納する OPAQUECOMMAND 構造体へのポインター。データは、アプリケーションからデバイスへ、および呼び出しの完了時にデバイスからアプリケーションへという 2 つの方向で受け渡しできます。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェイスメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準の COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
このメソッドは、Windows Media Device Manager の動作に影響を与えず、変更せずにそのまま渡すべきストレージメディアコマンドを対象としています。
例
次の C++ コードは、SendOpaqueCommand を呼び出して、デバイスとの簡単なカスタム認証手順を実行します。呼び出し元は自身の証明書と MAC をデバイスに送信し、デバイスは自身の証明書と MAC を返します。アプリケーションは、取得した証明書を保持している証明書と比較し、一致した場合(かつ MAC が正しい場合)に bExtraCertified を TRUE に設定します。
// SendOpaqueCommand を呼び出して、拡張認証情報を交換します。
{
HMAC hMAC;
OPAQUECOMMAND Command;
CERTINFOEX *pCertInfoEx;
DWORD cbData_App = sizeof(bCertInfoEx_App)/sizeof(bCertInfoEx_App[0]);
DWORD cbData_SP = sizeof(bCertInfoEx_SP)/sizeof(bCertInfoEx_SP[0]);
DWORD cbData_Send = sizeof(CERTINFOEX) + cbData_App;
// 不透明コマンド構造体にアプリケーションの証明書を設定します。
memcpy(&(Command.guidCommand), &guidCertInfoEx, sizeof(GUID));
Command.pData = (BYTE *)CoTaskMemAlloc(cbData_Send);
if (!Command.pData)
{
ExitOnFail(hr = E_OUTOFMEMORY);
}
Command.dwDataLen = cbData_Send;
// 不透明コマンド内のデータを CERTINFOEX 構造体にマップし、
// 送信する証明書情報を設定します。
pCertInfoEx = (CERTINFOEX *)Command.pData;
pCertInfoEx->hr = S_OK;
pCertInfoEx->cbCert = cbData_App;
memcpy(pCertInfoEx->pbCert, bCertInfoEx_App, cbData_App);
// データの MAC を計算し、OPAQUECOMMAND 構造体に追加します。
g_cWmdm.m_pSAC->MACInit(&hMAC);
g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.guidCommand)), sizeof(GUID));
g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.dwDataLen)), sizeof(Command.dwDataLen));
if (Command.pData)
{
g_cWmdm.m_pSAC->MACUpdate(hMAC, Command.pData, Command.dwDataLen);
}
g_cWmdm.m_pSAC->MACFinal(hMAC, Command.abMAC);
// 不透明コマンドを送信します。
hr = pDevice->SendOpaqueCommand(&Command);
if (SUCCEEDED(hr))
{
// 次に、取得した MAC を検証します。
BYTE abMACVerify2[ WMDM_MAC_LENGTH ];
g_cWmdm.m_pSAC->MACInit(&hMAC);
g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.guidCommand)), sizeof(GUID));
g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.dwDataLen)), sizeof(Command.dwDataLen));
if (Command.pData)
{
g_cWmdm.m_pSAC->MACUpdate(hMAC, Command.pData, Command.dwDataLen);
}
g_cWmdm.m_pSAC->MACFinal(hMAC, abMACVerify2);
// MAC が一致するか確認します。
if (memcmp(abMACVerify2, Command.abMAC, WMDM_MAC_LENGTH) == 0)
{
// 一致した場合は、取得した証明書を検証します。
// 不透明コマンド内のデータを CERTINFOEX 構造体にマップします。
//
pCertInfoEx = (CERTINFOEX *)Command.pData;
// この単純な拡張認証方式では、呼び出される側が
// 完全に一致する証明書情報を提供する必要があります。
//
if ((pCertInfoEx->cbCert != cbData_SP) &&
(memcmp(pCertInfoEx->pbCert, bCertInfoEx_SP, cbData_SP) == 0))
{
bExtraCertified = TRUE;
}
}
}
if (Command.pData)
{
CoTaskMemFree(Command.pData);
}
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IWMDMStorage "{1DCB3A06-33ED-11D3-8470-00C04F79DBC0}" #usecom global IWMDMStorage IID_IWMDMStorage "{807B3CE0-357A-11D3-8471-00C04F79DBC0}" #comfunc global IWMDMStorage_SetAttributes 3 int,var #comfunc global IWMDMStorage_GetStorageGlobals 4 sptr #comfunc global IWMDMStorage_GetAttributes 5 var,var #comfunc global IWMDMStorage_GetName 6 var,int #comfunc global IWMDMStorage_GetDate 7 var #comfunc global IWMDMStorage_GetSize 8 var,var #comfunc global IWMDMStorage_GetRights 9 var,var,var #comfunc global IWMDMStorage_EnumStorage 10 sptr #comfunc global IWMDMStorage_SendOpaqueCommand 11 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IWMDMStorage "{1DCB3A06-33ED-11D3-8470-00C04F79DBC0}" #usecom global IWMDMStorage IID_IWMDMStorage "{807B3CE0-357A-11D3-8471-00C04F79DBC0}" #comfunc global IWMDMStorage_SetAttributes 3 int,sptr #comfunc global IWMDMStorage_GetStorageGlobals 4 sptr #comfunc global IWMDMStorage_GetAttributes 5 sptr,sptr #comfunc global IWMDMStorage_GetName 6 sptr,int #comfunc global IWMDMStorage_GetDate 7 sptr #comfunc global IWMDMStorage_GetSize 8 sptr,sptr #comfunc global IWMDMStorage_GetRights 9 sptr,sptr,sptr #comfunc global IWMDMStorage_EnumStorage 10 sptr #comfunc global IWMDMStorage_SendOpaqueCommand 11 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。