Compartilhar via


Comandos estendidos pelo fornecedor

Um aplicativo pode enviar um comando arbitrário para o dispositivo por meio do método IWiaItemExtras::Escape, que é descrito na documentação do SDK do Microsoft Windows. Chamando QueryInterface no item raiz, você pode recuperar um ponteiro para a interface IWiaItemExtras . Em seguida, o aplicativo pode construir um comando PTP usando qualquer opcode e parâmetros e enviar esse comando para o dispositivo. O aplicativo também pode enviar dados para ou receber dados do dispositivo.

O dispositivo informa a aplicação do resultado da operação quando o método IWiaItemExtras::Escape retorna, preenchendo um código de resposta e parâmetros de resposta em uma estrutura de PTP_VENDOR_DATA_OUT . Os membros SessionId e TransactionId da estrutura PTP_VENDOR_DATA_IN são ignorados. O driver fornece valores corretos para eles.

Para comandos definidos pelo fornecedor que não sejam ESCAPE_PTP_CLEAR_STALLS, um sinalizador especial, ESCAPE_PTP_VENDOR_COMMAND, deve ser combinado (usando um operador OR) com o comando usado no método IWiaItemExtras::Escape . Se um comando definido pelo fornecedor criar ou excluir um objeto no dispositivo usando os sinalizadores descritos a seguir, o driver adicionará ou removerá o objeto de suas estruturas internas e gerará um evento WIA. Todos os outros comandos padrão devem ser emitidos por meio da interface WIA apropriada.

O primeiro parâmetro para IWiaItemExtras::Escape é a combinação de um ou mais dos seguintes sinalizadores:

Código de escape Significado
ESCAPE_PTP_ADD_OBJ_CMD Um objeto está sendo adicionado e o identificador do objeto está em um dos parâmetros de comando.
ESCAPE_PTP_REM_OBJ_CMD Um objeto está sendo removido e o identificador do objeto está em um dos parâmetros de comando.
ESCAPE_PTP_ADD_OBJ_RESP Um objeto está sendo adicionado e o identificador do objeto está em um dos parâmetros de resposta.
ESCAPE_PTP_REM_OBJ_RESP Um objeto está sendo removido e o identificador do objeto está em um dos parâmetros de resposta.
ESCAPE_PTP_ADDREM_PARM1 O identificador do objeto adicionado ou removido está no primeiro parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM2 O identificador do objeto adicionado ou removido está no segundo parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM3 O identificador do objeto adicionado ou removido está no terceiro parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM4 O identificador do objeto adicionado ou removido está no quarto parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM5 O identificador do objeto adicionado ou removido está no quinto parâmetro do comando ou resposta.
ESCAPE_PTP_CLEAR_STALLS Limpe as condições de erro causadas por um comando estendido pelo fornecedor. Esse sinalizador não pode ser usado em combinação com nenhum dos outros sinalizadores. Para obter mais informações sobre esse sinalizador, consulte a observação que segue esta tabela.
ESCAPE_PTP_VENDOR_COMMAND O comando é um comando estendido pelo fornecedor.

Quando um aplicativo chama IWiaItemExtras::Escape com o sinalizador ESCAPE_PTP_CLEAR_STALL como o primeiro argumento para esse método, o driver emite a solicitação Obter Status do Dispositivo ptp para determinar se algum ponto de extremidade está em uma condição STALL. Se o comando Obter Status do Dispositivo for bem-sucedido, o driver emitirá o código de controle USB IOCTL_RESET_PIPE para cada ponto de extremidade. Se o comando Obter Status do Dispositivo falhar, o driver emitirá uma solicitação de Redefinição de Dispositivo PTP. Obter Status do Dispositivo e Redefinição de Dispositivo são descritos no padrão PIMA 15740:2000, Primeira Edição e Revisão 1.0 da Definição de Dispositivo de Captura de Imagem Ainda USB (USB SICDD).

O código de exemplo a seguir ilustra como usar a interface de comando estendida pelo fornecedor. Certifique-se de que seu código inclua o cabeçalho ptpusd.h , pois ele contém as definições dos códigos de escape e outras constantes e as estruturas PTP_VENDOR_DATA_IN e PTP_VENDOR_DATA_OUT . A interface IWiaItemExtras é obtida usando uma chamada para QueryInterface no item raiz. Um ponteiro para esse item raiz, pIWiaRootItem, pode ser obtido, por exemplo, por uma chamada para IWiaDevMgr::SelectDeviceDlg (descrito na documentação do SDK do Microsoft Windows).

//
// 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.
//