廠商擴充的命令
應用程式可以透過 IWiaItemExtras::Escape 方法將任意命令傳送至裝置,如 Microsoft Windows SDK 檔中所述。 藉由在根專案上呼叫 QueryInterface ,您可以擷取 IWiaItemExtras 介面的指標。 然後,應用程式可以使用任何 opcode 和參數來建構 PTP 命令,並將此命令傳送至裝置。 應用程式也可以將數據傳送至裝置或從裝置接收數據。
當 IWiaItemExtras::Escape 方法傳回時,裝置會通知作業的結果,並在 PTP_VENDOR_DATA_OUT 結構中填入回應碼和響應參數。 忽略PTP_VENDOR_DATA_IN結構的 SessionId 和 TransactionId 成員。 驅動程式會提供正確的值給這些值。
對於ESCAPE_PTP_CLEAR_STALLS以外的廠商定義命令,必須使用 OR 運算符) 搭配 IWiaItemExtras::Escape 方法中使用的命令,將特殊旗標ESCAPE_PTP_VENDOR_COMMAND結合 (。 如果廠商定義的命令使用下列所述的旗標在裝置上建立或刪除對象,驅動程式會從其內部結構新增或移除物件,併產生 WIA 事件。 所有其他標準命令都應該透過適當的 WIA 介面發出。
IWiaItemExtras::Escape 的第一個參數是下列一或多個旗標的組合:
逸出程序代碼 | 意義 |
---|---|
ESCAPE_PTP_ADD_OBJ_CMD | 正在加入物件,而且物件的句柄位於其中一個命令參數中。 |
ESCAPE_PTP_REM_OBJ_CMD | 正在移除物件,而且物件的句柄位於其中一個命令參數中。 |
ESCAPE_PTP_ADD_OBJ_RESP | 正在加入物件,而且物件的句柄位於其中一個響應參數中。 |
ESCAPE_PTP_REM_OBJ_RESP | 正在移除物件,而且物件的句柄位於其中一個響應參數中。 |
ESCAPE_PTP_ADDREM_PARM1 | 新增或移除物件的句柄位於命令或回應的第一個參數中。 |
ESCAPE_PTP_ADDREM_PARM2 | 已新增或移除物件的句柄位於命令或回應的第二個參數中。 |
ESCAPE_PTP_ADDREM_PARM3 | 新增或移除物件的句柄位於命令或回應的第三個參數中。 |
ESCAPE_PTP_ADDREM_PARM4 | 新增或移除物件的句柄位於命令或回應的第四個參數中。 |
ESCAPE_PTP_ADDREM_PARM5 | 新增或移除物件的句柄位於命令或回應的第五個參數中。 |
ESCAPE_PTP_CLEAR_STALLS | 清除廠商擴充命令所造成的任何錯誤狀況。 此旗標不能與任何其他旗標搭配使用。 如需此旗標的詳細資訊,請參閱此表格後面的附註。 |
ESCAPE_PTP_VENDOR_COMMAND | 此命令是廠商擴充的命令。 |
當應用程式使用 ESCAPE_PTP_CLEAR_STALL 旗標呼叫 IWiaItemExtras::Escape 作為此方法的第一個自變數時,驅動程式會發出 PTP 取得裝置狀態 要求,以判斷任何端點是否處於 STALL 條件。 如果 [取得裝置狀態 ] 命令成功,驅動程式會為每個這類端點發出 IOCTL_RESET_PIPE USB 控制程式代碼。 如果 [取得裝置狀態 ] 命令失敗,驅動程式會發出 PTP 裝置重設 要求。 取得裝置狀態 和 裝置重設 會在USB仍存映像擷取裝置定義的PIMA 15740:2000 Standard、First Edition 和 Revision 1.0 中說明, (USB SICDD) 。
下列範例程式代碼說明如何使用廠商擴充的命令介面。 請確定您的程式代碼包含 ptpusd.h 標頭,因為它包含逸出程式代碼和其他常數的定義,以及 PTP_VENDOR_DATA_IN 和 PTP_VENDOR_DATA_OUT 結構。 IWiaItemExtras 介面是使用根專案上的 QueryInterface 呼叫來取得。 例如,呼叫 IWiaDevMgr::SelectDeviceDlg (Microsoft Windows SDK 中所述,即可取得此根專案的指標 pIWiaRootItem) 。
//
// 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.
//