IWMDMStorageControl3
COM公式ドキュメント
IWMDMStorageControl3 インターフェースは、IWMDMMetaData インターフェース ポインターを受け取る Insert メソッドを提供することで、IWMDMStorageControl2 を拡張します。
メソッド 1
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
Insert3 メソッドは、ストレージ内またはストレージの隣にコンテンツを配置します。このメソッドは、送信するオブジェクトのメタデータと種類をアプリケーションが明示的に指定できるようにすることで、IWMDMStorageControl2::Insert2 を拡張したものです。
| fuMode | DWORD | in | Insert3 操作で使用する処理モード。次の表は、fuMode パラメーターに指定できる処理モードの一覧です。最初の 2 つのモードのうち 1 つ、STORAGECONTROL モードのうち 1 つ、CONTENT モードのうち 1 つを、それぞれ必ず 1 つだけ指定する必要があります。WMDM_MODE_BLOCK と WMDM_MODE_THREAD の両方を指定した場合は、ブロック モードが使用されます。WMDM_FILE_ATTR* フラグをこの関数で指定する方が、先にこの関数を呼び出し、ファイルの作成または送信後にこれらの属性を設定するよりも効率的です。
| |||||||||||||||||||||||||||||||||||||||||||||||||||
| fuType | DWORD | in | 現在のストレージを指定する、次のいずれかの種類。
| |||||||||||||||||||||||||||||||||||||||||||||||||||
| pwszFileSource | LPWSTR | inoptional | 挿入操作の対象コンテンツの場所を示す、ワイド文字の null 終端文字列へのポインター。fuMode に WMDM_CONTENT_OPERATIONINTERFACE を指定した場合、このパラメーターは NULL でなければなりません。プレイリストまたはアルバムを作成する場合は、NULL を指定できます。 | |||||||||||||||||||||||||||||||||||||||||||||||||||
| pwszFileDest | LPWSTR | inoptional | デバイス上のファイル名 (省略可能)。指定されておらず、アプリケーションが pOperation に IWMDMOperation ポインターを渡している場合、Windows Media Device Manager は IWMDMOperation::GetObjectName を呼び出して転送先の名前を要求します。指定されておらず、アプリケーションが pOperation を使用しない場合は、元のファイル名と拡張子が (パスを除いて) 使用されます。 | |||||||||||||||||||||||||||||||||||||||||||||||||||
| pOperation | IWMDMOperation* | inoptional | メディア デバイスへのコンテンツ転送を制御する IWMDMOperation インターフェースへのポインター (省略可能)。指定する場合、fuMode に WMDM_CONTENT_OPERATIONINTERFACE フラグを含める必要があります。fuMode に WMDM_CONTENT_FILE または WMDM_CONTENT_FOLDER を指定した場合、このパラメーターは NULL でなければなりません。 | |||||||||||||||||||||||||||||||||||||||||||||||||||
| pProgress | IWMDMProgress* | inoptional | 処理の進行状況をアプリケーションに報告する IWMDMProgress インターフェースへのポインター (省略可能)。このパラメーターには NULL を指定できます。 | |||||||||||||||||||||||||||||||||||||||||||||||||||
| pMetaData | IWMDMMetaData* | inoptional | メタデータ オブジェクトへのポインター (省略可能)。新しいメタデータ オブジェクトは IWMDMStorage3::CreateEmptyMetadataObject を呼び出して作成します。このパラメーターを使用すると、デバイス上でのオブジェクト作成時に設定するメタデータ (フォーマットを含む) を指定でき、後からメタデータを設定するよりも効率的です。ファイル フォーマット (g_wszWMDMFormatCode で指定) は必ず設定してください。このメソッドの使用時にファイルのフォーマット コードを指定しないと、MTP デバイスではそのファイルがユーザー インターフェイスに表示されず、MTP 以外のデバイスでは動作が予測できなくなります。 | |||||||||||||||||||||||||||||||||||||||||||||||||||
| pUnknown | IUnknown* | inoptional | セキュア コンテンツ プロバイダーに渡す任意のカスタム COM オブジェクトの IUnknown ポインター (省略可能)。これにより、アプリケーションがセキュア コンテンツ プロバイダーについて十分な情報を持っている場合に、カスタム情報をセキュア コンテンツ プロバイダーへ渡すことができます。 | |||||||||||||||||||||||||||||||||||||||||||||||||||
| ppNewObject | IWMDMStorage** | inoutoptional | 新しいコンテンツを保持する IWMDMStorage インターフェースへのポインター。呼び出し元は、使用を終えたらこのインターフェースを解放する必要があります。 |
戻り値
このメソッドは HRESULT を返します。Windows Media Device Manager のすべてのインターフェース メソッドは、次のいずれかの分類のエラー コードを返す可能性があります。
- 標準の COM エラー コード
- HRESULT 値に変換された Windows エラー コード
- Windows Media Device Manager のエラー コード
解説(Remarks)
ストレージをデバイスへ送信した後にメタデータを設定することもできますが、このメソッドの pMetaData パラメーターで情報を設定する方が効率的です。そうすることで、デバイスに追加情報が提供され、ファイルを適切に転送・処理したり (たとえば正しい場所へ保存するなど)、有用な情報 (画像に対してユーザーが記述した説明など) を表示したりできるようになります。
Windows Portable Devices (WPD) デバイスのプロパティを設定するには、アプリケーションは IPortableDeviceValues オブジェクトを作成し、各プロパティをこのコレクションに設定します。次に、アプリケーションはそのコレクションをバイナリ ラージ オブジェクト (BLOB) にシリアル化します。データをシリアル化したら、g_wszWPDPassthroughPropertyValues メタデータ定数を使用して、pMetadata 引数が参照する IWMDMMetaData に追加します。
WMDM_MODE_THREAD フラグを指定した場合は、IWMDMProgress2::End2 または IWMDMProgress3::End3 を呼び出して完了状態を取得してください。これらのメソッドは操作が完了したことを保証し、成功または失敗の情報を含む HRESULT も返します。
アプリケーションが WMDM_MODE_THREAD を使用し、null ではない pProgress パラメーターを渡す場合、Windows Media Device Manager がそのオブジェクトへ進行状況の通知を送信するため、読み取り操作が完了するまで pProgress が属するオブジェクトが破棄されないようにする必要があります。このオブジェクトは、終了通知を受け取った後にのみ破棄できます。これを守らないとアクセス違反が発生します。
プレイリストなどの参照オブジェクトを作成する場合、"挿入" されるオブジェクトは実際にはデータを含まず、他のオブジェクト (音楽ファイルなど) へのメタデータ参照の集まりとしてデバイス上に格納されるだけです。このような "抽象" オブジェクトの作成については、Creating a Playlist on the Device を参照してください。
例
次の C++ 関数は、ファイルをデバイスへ送信します。転送の一環として、新しいストレージの種類を指定するメタデータをストレージに追加する必要があります。
HRESULT mySendFile(LPCWSTR pwszFileName, IWMDMStorage* pStorage, IWMDMOperation* pOperation)
{
HRESULT hr = S_OK;
// A dummy loop to handle unrecoverable errors. When we hit an error we
// can't handle or don't like, we just use a 'break' statement.
// The custom BREAK_HR macro checks for failed HRESULT values and does this.
do
{
if (pwszFileName == NULL || pStorage == NULL)
{
BREAK_HR(E_POINTER,"","Bad pointer passed in.");
return E_POINTER;
}
// Make sure the destination is a folder.
DWORD attributes = 0;
_WAVEFORMATEX format;
hr = pStorage->GetAttributes(&attributes, &format);
if (!(attributes | WMDM_FILE_ATTR_FOLDER))
{
BREAK_HR(E_FAIL, "", "Storage submitted to mySendFile is not a folder.");
return E_FAIL;
}
// Transcode the file
hr = myTranscodeMethod(pwszFileName);
BREAK_HR(hr, "Couldn't transcode the file in mySendFile.", "Transcoded the file in mySendFile.");
//
// Let's set some metadata in the storage.
//
CComPtr<IWMDMStorage3> pStorage3;
hr = pStorage->QueryInterface(__uuidof(IWMDMStorage3), (void**)(&pStorage3));
BREAK_HR(hr, "Got an IWMDMStorage3 interface in mySendFile.","Couldn't get an IWMDMStorage3 in mySendFile.");
// First create the IWMDMMetaData interface.
IWMDMMetaData* pMetadata;
hr = pStorage3->CreateEmptyMetadataObject(&pMetadata);
BREAK_HR(hr,"Created an IWMDMMetaData interface in mySendFile.","Couldn't create an IWMDMMetaData interface in mySendFile.");
//
// Set the file format.
//
WMDM_FORMATCODE fileFormat = myGetWMDM_FORMATCODE(pwszFileName);
hr = pMetadata->AddItem(WMDM_TYPE_DWORD, g_wszWMDMFormatCode, (BYTE*)&fileFormat, sizeof(WMDM_TYPE_DWORD));
//
// Get the proper interface and transfer the file.
//
CComPtr<IWMDMStorageControl3> pStgCtl3;
CComPtr<IWMDMStorage> pNewStorage;
hr = pStorage->QueryInterface(__uuidof(IWMDMStorageControl3),(void**)(&pStgCtl3));
// Get the simple file name to use for the destination file.
wstring destFile = pwszFileName;
destFile = destFile.substr(destFile.find_last_of(L"\\") + 1);
// Get a progress indicator.
CComQIPtr<IWMDMProgress> pProgress(this);
// Set the flags for the operation.
UINT flags = WMDM_MODE_BLOCK | // Synchronous call.
WMDM_STORAGECONTROL_INSERTINTO | // Insert it into the destination folder.
WMDM_CONTENT_FILE | // We're inserting a file.
WMDM_FILE_CREATE_OVERWRITE; // Overwrite existing files.
if (pOperation != NULL)
flags |= WMDM_CONTENT_OPERATIONINTERFACE;
// Send the file and metadata.
hr = pStgCtl3->Insert3(
flags,
WMDM_FILE_ATTR_FOLDER, // The current storage is a folder.
const_cast<WCHAR*>(pwszFileName), // Source file.
NULL, // Destination file name.
pOperation, // Null to allow Windows Media Device Manager to read
// the file; non-null to present raw data bytes to
// Windows Media Device Manager.
pProgress, // Interface to send simple progress notifications.
pMetadata, // IWMDMMetaData interface previously created and filled.
NULL,
&pNewStorage);
if (FAILED(hr))
m_pLogger->LogDword(WMDM_LOG_SEV_ERROR, NULL, "Error calling Insert3 in mySendFile: %lX", hr);
BREAK_HR(hr, "Wrote a file to the device in mySendFile", "Couldn't write to the device in mySendFile.");
} while (FALSE); // End of dummy loop
return hr;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IWMDMStorageControl3 "{B3266365-D4F3-4696-8D53-BD27EC60993A}"
#usecom global IWMDMStorageControl3 IID_IWMDMStorageControl3 "{}"
#comfunc global IWMDMStorageControl3_Insert3 9 int,int,wstr,wstr,sptr,sptr,sptr,sptr,sptr
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。