IWMDMDevice
COM公式ドキュメント
IWMDMDevice インターフェースは、単一のポータブルデバイスを調査および探索するためのメソッドを提供します。このインターフェースを使用すると、デバイスに関する情報を取得したり、そのストレージを列挙したりできます。IWMDMDevice2 はこのインターフェースの機能を拡張します。
メソッド 11
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
GetName メソッドは、メディアデバイスの人間が読める名前を取得します。
| pwszName | LPWSTR | out | デバイス名を格納する (Unicode) ワイド文字の null 終端文字列へのポインター。バッファーの割り当てと解放は呼び出し元が行います。 |
| nMaxChars | DWORD | in | 終端文字を含め、pwszName に格納できる最大文字数を指定する整数。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
GetManufacturer メソッドは、デバイスの製造元の名前を取得します。(IWMDMDevice.GetManufacturer)
| pwszName | LPWSTR | out | 製造元の名前を格納するワイド文字の null 終端文字列へのポインター。バッファーは呼び出し元が割り当てて解放する必要があります。 |
| nMaxChars | DWORD | in | 終端文字を含め、pwszName にコピーできる最大文字数を指定する整数。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
GetVersion メソッドは、製造元が定義したデバイスのバージョン番号を取得します。
| pdwVersion | DWORD* | out | バージョン番号を格納する DWORD へのポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
バージョン番号の形式は製造元によって決定されます。
GetType メソッドは、デバイスがサポートする操作を取得します。
| pdwType | DWORD* | out | デバイスの種類の属性を格納する DWORD へのポインター。pdwType に返される値として考えられるものを次の表に示します。Microsoft は、WMDM_DEVICE_TYPE_SDMI と WMDM_DEVICE_TYPE_NONSDMI の両方のフラグを設定することを推奨しています。
|
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
現在の Microsoft のサービスプロバイダーは、WMDM_DEVICE_TYPE_NONSDMI と WMDM_DEVICE_TYPE_SDMI を除き、デバイスに関する信頼できる情報を提供しない場合があります。すべてのデバイスは前者をサポートしていると報告されます。シリアル番号をサポートするデバイスは後者も返します。
GetSerialNumber メソッドは、デバイスを一意に識別するシリアル番号を取得します。
| pSerialNumber | WMDMID* | out | シリアル番号の情報を格納する WMDMID 構造体へのポインター。WMDID 構造体はアプリケーションが割り当てて解放します。 |
| abMac | BYTE* | inout | このメソッドのパラメーターデータに対するメッセージ認証コードを格納するバイト配列。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
すべてのデバイスがシリアル番号をサポートしているわけではありません。デバイスがシリアル番号をサポートしているかどうかを判断するため、呼び出し元はこの関数を呼び出す際に必ず戻りコードを確認する必要があります。メディアデバイスがシリアル番号をサポートしている場合、そのメディアデバイスのシリアル番号は、そのデバイスにおいて一意であることが保証されます。
このメソッドを呼び出した後、アプリケーションは abMAC パラメーターを使用して、転送中にシリアル番号が変更されていないことを検証できます。これに関するサンプルコードについては、Using Secure Authenticated Channels を参照してください。
例
次の C++ コードは、デバイスのシリアル番号を取得し、MAC を検証します。
//
// シリアル番号を取得して検証します。
//
WMDMID serialNumber;
BYTE receivedMAC[WMDM_MAC_LENGTH];
hr = pIWMDMDevice->GetSerialNumber(&serialNumber, receivedMAC);
// MAC を確認し、シリアル番号が改ざんされていないことを保証します。
if (hr == S_OK)
{
// MAC ハンドルを初期化し、
// 次にすべてのパラメーターを MAC に追加して、
// 最後に計算された MAC 値を取得します。
HMAC hMAC;
BYTE calculatedMAC[WMDM_MAC_LENGTH];
hr = m_pSAC->MACInit(&hMAC);
hr = m_pSAC->MACUpdate(hMAC, (BYTE*)(&serialNumber), sizeof(serialNumber));
hr = m_pSAC->MACFinal(hMAC, (BYTE*)calculatedMAC);
if (memcmp(calculatedMAC, receivedMAC, sizeof(calculatedMAC)) == 0)
{
// MAC は正当です。シリアル番号を出力します。
CHAR* serialNumberBuffer = new CHAR[serialNumber.SerialNumberLength + 1];
ZeroMemory(serialNumberBuffer, (serialNumber.SerialNumberLength + 1) * sizeof(CHAR));
memcpy(serialNumberBuffer, serialNumber.pID, serialNumber.SerialNumberLength * sizeof(CHAR));
// TODO: シリアル番号を表示します。
delete serialNumberBuffer;
}
else
// TODO: EnumDevices でシリアル番号の MAC が一致しないことを示すメッセージを表示します
}
GetPowerSource メソッドは、デバイスの電源に関する情報と、残っている電力の割合を取得します。
| pdwPowerSource | DWORD* | out | デバイスの電源に関する情報を格納する DWORD へのポインター。 返される可能性のある値は、次の値の 1 つ以上のビットごとの OR です。
| ||||||||||||
| pdwPercentRemaining | DWORD* | out | pdwPowerSource に WMDM_POWER_PERCENT_AVAILABLE が含まれる場合、デバイスに残っている電力の割合を格納する DWORD へのポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
GetStatus メソッドは、デバイスの状態情報を取得します。
| pdwStatus | DWORD* | out | デバイスの状態を格納する DWORD へのポインター。pdwStatus に返される値として考えられるものを次の表に示します。
|
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
GetDeviceIcon メソッドは、デバイスの接続時にデバイスの製造元が表示させたいアイコンのハンドルを取得します。
| hIcon | DWORD* | out | アイコンオブジェクトへのハンドル。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
アプリケーションはアイコンの使用を終えたら、Win32 の DestroyIcon 関数を呼び出してメモリを解放する必要があります。
EnumStorage メソッドは、デバイス上のストレージを列挙するための IWMDMEnumStorage インターフェースを取得します。
| ppEnumStorage | IWMDMEnumStorage** | out | デバイス上のストレージを列挙するための IWMDMEnumStorage インターフェースへのポインターへのポインター。これはデバイス上のルートストレージを指します。取得したインターフェースに対して Release を呼び出す責任は呼び出し元にあります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
GetFormatSupport メソッドは、コーデックやファイル形式を含め、デバイスがサポートするすべての形式を取得します。
| ppFormatEx | WAVEFORMATEX** | out | デバイスがサポートするコーデックとビットレートに関する情報を格納する _WAVEFORMATEX 構造体の配列へのポインター。このパラメーターのメモリは Windows Media Device Manager が割り当てます。呼び出し元は CoTaskMemFree を使用して解放する必要があります。 |
| pnFormatCount | DWORD* | out | ppFormatEx 配列の要素数へのポインター。 |
| pppwszMimeType | LPWSTR** | out | デバイスがサポートするファイル形式とデジタル著作権管理方式を記述した配列へのポインター。このパラメーターのメモリは Windows Media Device Manager が割り当てます。呼び出し元は CoTaskMemFree を使用して解放する必要があります。 |
| pnMimeTypeCount | DWORD* | out | pppwszMimeType 配列の要素数へのポインター。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
デバイスがサポートする形式を取得する推奨される方法は IWMDMDevice3::GetFormatCapability です。
例
次の C++ 関数は、デバイスのさまざまな機能を取得します。
// IWMDMDevice のみをサポートするデバイスについて、
// デバイスの機能を出力する関数。
void GetCaps(IWMDMDevice* pDevice)
{
HRESULT hr = S_OK;
// オーディオと MIME のサポートに関するすべての機能を取得します。
_WAVEFORMATEX* pAudioFormats;
LPWSTR* pMimeFormats;
UINT numAudioFormats = 0;
UINT numMimeFormats = 0;
hr = pDevice->GetFormatSupport(
&pAudioFormats,
&numAudioFormats,
&pMimeFormats,
&numMimeFormats);
HANDLE_HR(hr, "Got audio and mime formats in GetCaps IWMDMDevice", "Couldn't get audio and mime formats in GetCaps IWMDMDevice");
// オーディオ形式のデータを出力します。
if (numAudioFormats > 0)
{
/ /TODO: サポートされる形式の前に表示するバナーを表示します。
}
else
{
// TODO: サポートされる形式がないことを示すメッセージを表示します。
}
for(int i = 0; i < numAudioFormats; i++)
{
// TODO: 構成値を表示します。
PrintWaveFormatGuid(pAudioFormats[i].wFormatTag);
// TODO: 最大チャネル数を表示します。
// TODO: 最大サンプル数/秒を表示します。
// TODO: 最大バイト数/秒を表示します。
// TODO: ブロックアラインメント値を表示します。
// TODo: 最大ビット数/サンプルを表示します。
}
// MIME 形式を出力します。
if (numMimeFormats > 0)
// TODO: MIME 形式の一覧用のバナーを表示します。
else
/ /TODO: サポートされる MIME 形式がないことを示すメッセージを表示します。
for(i = 0; i < numMimeFormats; i++)
{
// TODO: 個々の MIME 形式を表示します。
}
e_Exit:
return;
}
SendOpaqueCommand メソッドは、Windows Media Device Manager を介して、デバイス固有のコマンドをデバイスに送信します。Windows Media Device Manager はコマンドの内容を読み取ろうとはしません。
| pCommand | OPAQUECOMMAND* | inout | コマンドの実行に必要な情報を格納する OPAQUECOMMAND 構造体へのポインター。デバイスがデータを返す場合、そのデータは pCommand の pData メンバーを通じて返されます。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェースメソッドは、次の種類のエラーコードのいずれかを返す可能性があります。
- 標準的な COM エラーコード
- HRESULT 値に変換された Windows エラーコード
- Windows Media Device Manager のエラーコード
解説(Remarks)
このメソッドは、Windows Media Device Manager の動作に影響を与えず、変更されずにそのまま渡されるデバイスコマンドを対象としています。
例
次のコードは、デバイスとの簡略化された拡張認証手続きを実行します。この手続きはデバイスに固有のものです。
// 拡張認証情報を交換するために opaque コマンドを呼び出します。
//
{
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;
// opaque コマンド構造体を設定します。
memcpy(&(Command.guidCommand), &guidCertInfoEx, sizeof(GUID));
Command.pData = (BYTE *)CoTaskMemAlloc(cbData_Send);
if (!Command.pData)
{
ExitOnFail(hr = E_OUTOFMEMORY);
}
Command.dwDataLen = cbData_Send;
// opaque コマンド内のデータを CERTINFOEX 構造体にマップし、
// 送信する証明書情報を設定します。
pCertInfoEx = (CERTINFOEX *)Command.pData;
pCertInfoEx->hr = S_OK;
pCertInfoEx->cbCert = cbData_App;
memcpy(pCertInfoEx->pbCert, bCertInfoEx_App, cbData_App);
// 送信する MAC を計算します。
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))
{
BYTE abMACVerify2[ WMDM_MAC_LENGTH ];
// 検証のために、取得した MAC を計算します。
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)
{
// opaque コマンド内のデータを CERTINFOEX 構造体にキャストします。
//
pCertInfoEx = (CERTINFOEX *)Command.pData;
// この単純な拡張認証方式では、呼び出された側は
// 正確な証明書情報を提供する必要があります。
//
if ((pCertInfoEx->cbCert != cbData_SP) ||
(memcmp(pCertInfoEx->pbCert, bCertInfoEx_SP, cbData_SP) == 0))
{
m_fExtraCertified = 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_IWMDMDevice "{1DCB3A02-33ED-11D3-8470-00C04F79DBC0}" #usecom global IWMDMDevice IID_IWMDMDevice "{807B3CDF-357A-11D3-8471-00C04F79DBC0}" #comfunc global IWMDMDevice_GetName 3 var,int #comfunc global IWMDMDevice_GetManufacturer 4 var,int #comfunc global IWMDMDevice_GetVersion 5 var #comfunc global IWMDMDevice_GetType 6 var #comfunc global IWMDMDevice_GetSerialNumber 7 var,var #comfunc global IWMDMDevice_GetPowerSource 8 var,var #comfunc global IWMDMDevice_GetStatus 9 var #comfunc global IWMDMDevice_GetDeviceIcon 10 var #comfunc global IWMDMDevice_EnumStorage 11 sptr #comfunc global IWMDMDevice_GetFormatSupport 12 var,var,var,var #comfunc global IWMDMDevice_SendOpaqueCommand 13 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IWMDMDevice "{1DCB3A02-33ED-11D3-8470-00C04F79DBC0}" #usecom global IWMDMDevice IID_IWMDMDevice "{807B3CDF-357A-11D3-8471-00C04F79DBC0}" #comfunc global IWMDMDevice_GetName 3 sptr,int #comfunc global IWMDMDevice_GetManufacturer 4 sptr,int #comfunc global IWMDMDevice_GetVersion 5 sptr #comfunc global IWMDMDevice_GetType 6 sptr #comfunc global IWMDMDevice_GetSerialNumber 7 sptr,sptr #comfunc global IWMDMDevice_GetPowerSource 8 sptr,sptr #comfunc global IWMDMDevice_GetStatus 9 sptr #comfunc global IWMDMDevice_GetDeviceIcon 10 sptr #comfunc global IWMDMDevice_EnumStorage 11 sptr #comfunc global IWMDMDevice_GetFormatSupport 12 sptr,sptr,sptr,sptr #comfunc global IWMDMDevice_SendOpaqueCommand 13 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※#usecom 末尾は CoCreateInstance 用のクラスID(コクラスCLSID, SDKから自動取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。