アプリケーションは、Microsoft Windows SDK ドキュメントで説明されている IWiaItemExtras::Escape メソッドを使用して、任意のコマンドをデバイスに送信できます。 ルート項目で QueryInterface を呼び出すことで、 IWiaItemExtras インターフェイスへのポインターを取得できます。 その後、アプリケーションは任意のオペコードとパラメーターを使用して PTP コマンドを構築し、このコマンドをデバイスに送信できます。 アプリケーションは、デバイスに対してデータを送信したり、デバイスからデータを受信したりすることもできます。
デバイスは、 IWiaItemExtras::Escape メソッドが戻ったときに操作の結果をアプリケーションに通知し、応答コードと応答パラメーターを PTP_VENDOR_DATA_OUT 構造体に入力します。 PTP_VENDOR_DATA_IN構造体の SessionId メンバーと TransactionId メンバーは無視されます。 ドライバーは、これらに対して正しい値を提供します。
ESCAPE_PTP_CLEAR_STALLS以外のベンダー定義コマンドの場合、特別なフラグESCAPE_PTP_VENDOR_COMMANDは、(OR 演算子を使用して) IWiaItemExtras::Escape メソッドで使用されるコマンドと組み合わせる必要があります。 ベンダー定義のコマンドで、次の説明に従ってデバイス上のオブジェクトを作成または削除する場合、ドライバーは内部構造からオブジェクトを追加または削除し、WIA イベントを生成します。 その他すべての標準コマンドは、適切な WIA インターフェイスを介して発行する必要があります。
IWiaItemExtras::Escape の最初のパラメーターは、次のフラグの 1 つ以上の組み合わせです。
| エスケープ コード | 意味 |
|---|---|
| ESCAPE_PTP_ADD_OBJ_CMD | オブジェクトが追加され、オブジェクトのハンドルがコマンド パラメーターの 1 つにあります。 |
| ESCAPE_PTP_REM_OBJ_CMD | オブジェクトが削除され、オブジェクトのハンドルがコマンド パラメーターの 1 つにあります。 |
| ESCAPE_PTP_ADD_OBJ_RESP | オブジェクトが追加され、オブジェクトのハンドルが応答パラメーターの 1 つにあります。 |
| ESCAPE_PTP_REM_OBJ_RESP | オブジェクトが削除され、オブジェクトのハンドルが応答パラメーターの 1 つに含まれています。 |
| ESCAPE_PTP_ADDREM_PARM1 | 追加または削除されたオブジェクトのハンドルは、コマンドまたは応答の最初のパラメーターにあります。 |
| ESCAPE_PTP_ADDREM_PARM2 | 追加または削除されたオブジェクトのハンドルは、コマンドまたは応答の 2 番目のパラメーターにあります。 |
| ESCAPE_PTP_ADDREM_PARM3 | 追加または削除されたオブジェクトのハンドルは、コマンドまたは応答の 3 番目のパラメーターにあります。 |
| ESCAPE_PTP_ADDREM_PARM4 | 追加または削除されたオブジェクトのハンドルは、コマンドまたは応答の 4 番目のパラメーターにあります。 |
| ESCAPE_PTP_ADDREM_PARM5 | 追加または削除されたオブジェクトのハンドルは、コマンドまたは応答の 5 番目のパラメーターにあります。 |
| ESCAPE_PTP_CLEAR_STALLS | ベンダー拡張コマンドによって発生するエラー状態をクリアします。 このフラグは、他のフラグと組み合わせて使用することはできません。 このフラグの詳細については、次の表に示す注を参照してください。 |
| ESCAPE_PTP_VENDOR_COMMAND | このコマンドはベンダー拡張コマンドです。 |
アプリケーションでこのメソッドの最初の引数として ESCAPE_PTP_CLEAR_STALL フラグを指定して IWiaItemExtras::Escape を呼び出すと、ドライバーは PTP Get Device Status 要求を発行して、エンドポイントが STALL 状態にあるかどうかを判断します。 デバイスの状態の取得コマンドが成功した場合、ドライバーは、このようなエンドポイントごとにIOCTL_RESET_PIPE USB コントロール コードを発行します。 [ デバイスの状態の取得] コマンドが失敗した場合、ドライバーは PTP デバイス リセット 要求を発行します。 デバイスの状態の取得 と デバイスのリセット については、USB 静止画像キャプチャ デバイス定義 (USB SICDD) の PIMA 15740:2000 標準、最初のエディション、リビジョン 1.0 で説明されています。
次のサンプル コードは、ベンダー拡張コマンド インターフェイスの使用方法を示しています。 コードに ptpusd.h ヘッダーが含まれていることを確認してください。これは、エスケープ コードとその他の定数の定義、 およびPTP_VENDOR_DATA_IN および PTP_VENDOR_DATA_OUT 構造体が含まれているためです。 IWiaItemExtras インターフェイスは、ルート項目の QueryInterface の呼び出しを使用して取得されます。 このルート項目 pIWiaRootItem へのポインターは、たとえば、 IWiaDevMgr::SelectDeviceDlg (Microsoft Windows SDK ドキュメントで説明) の呼び出しによって取得できます。
//
// Test IWiaItemExtras::Escape method
//
HRESULT hr = S_OK;
IWiaItemExtras *pIWiaItemExtras = NULL;
hr = pIWiaRootItem->QueryInterface(IID_IWiaItemExtras,
(VOID **) &pIWiaItemExtras);
if (FAILED(hr)) {
MessageBox("QueryInterface for IWiaItemExtras failed");
return;
}
PTP_VENDOR_DATA_IN *pDataIn = NULL;
PTP_VENDOR_DATA_OUT *pDataOut = NULL;
DWORD dwDataInSize = SIZEOF_REQUIRED_VENDOR_DATA_IN;
DWORD dwDataOutSize = SIZEOF_REQUIRED_VENDOR_DATA_OUT + 0x1000;
DWORD dwActualDataOutSize = 0;
pDataIn = (PTP_VENDOR_DATA_IN *) CoTaskMemAlloc(dwDataInSize);
if (!pDataIn) {
MessageBox("CoTaskMemAlloc failed");
return;
}
pDataOut = (PTP_VENDOR_DATA_OUT *) CoTaskMemAlloc(dwDataOutSize);
if (!pDataOut) {
CoTaskMemFree(pDataIn);
MessageBox("CoTaskMemAlloc failed");
return;
}
ZeroMemory(pDataIn, dwDataInSize);
ZeroMemory(pDataOut, dwDataOutSize);
pDataIn->OpCode = 0x1001;
pDataIn->SessionId = 0; // The driver will fill this in.
pDataIn->TransactionId = 0; // The driver will fill this in.
pDataIn->NumParams = 0;
//
// pDataIn->NextPhase informs the PTP driver whether to
// read data from the device (as shown), or
// write data to the device (use PTP_NEXTPHASE_WRITE_DATA),
// to neither read nor write data (use PTP_NEXTPHASE_NO_DATA).
//
pDataIn->NextPhase = PTP_NEXTPHASE_READ_DATA;
hr = pIWiaItemExtras->Escape(ESCAPE_PTP_VENDOR_COMMAND,
(BYTE *) pDataIn, dwDataInSize,
(BYTE *) pDataOut, dwDataOutSize,
&dwActualDataOutSize);
if (FAILED(hr)) {
MessageBox("Escape failed");
return;
}
//
// Data returned from device is located at pDataOut->VendorReadData.
//