Partilhar 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 . O aplicativo pode então construir um comando PTP usando qualquer opcode e parâmetros, e enviar esse comando para o dispositivo. O aplicativo também pode enviar 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 PTP_VENDOR_DATA_OUT . Os membros SessionId e TransactionId da estrutura PTP_VENDOR_DATA_IN são ignorados. O driver fornece valores corretos para estes.

Para comandos definidos pelo fornecedor que não sejam o ESCAPE_PTP_CLEAR_STALLS, um indicador especial, ESCAPE_PTP_VENDOR_COMMAND, deve ser combinado (usando um operador OR) com o comando utilizado no método IWiaItemExtras::Escape. Se um comando definido pelo fornecedor cria ou exclui um objeto no dispositivo usando os seguintes sinalizadores descritos, o driver adiciona ou remove o objeto de suas estruturas internas e gera um evento WIA. Todos os outros comandos padrão devem ser emitidos através da interface WIA apropriada.

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

Código de fuga Significado
ESCAPE_PTP_ADD_OBJ_CMD Um objeto está sendo adicionado e o identificador para o 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á a ser adicionado e o identificador para o objeto está em um dos parâmetros de resposta.
ESCAPE_PTP_REM_OBJ_RESP Um objeto está a ser removido e o identificador do objeto está num dos parâmetros de resposta.
ESCAPE_PTP_ADDREM_PARM1 O identificador para o objeto adicionado ou removido está no primeiro parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM2 O identificador do objeto que foi adicionado ou removido encontra-se no segundo parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM3 O identificador para o objeto adicionado ou removido está no terceiro parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM4 O identificador para o objeto adicionado ou removido está no quarto parâmetro do comando ou resposta.
ESCAPE_PTP_ADDREM_PARM5 O identificador para o objeto adicionado ou removido está no quinto parâmetro do comando ou resposta.
ESCAPE_PTP_CLEAR_STALLS Limpe todas as condições de erro causadas por um comando estendido pelo fornecedor. Esta bandeira não pode ser usada em combinação com nenhuma das outras bandeiras. 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 uma aplicação chama IWiaItemExtras::Escape com o sinalizador ESCAPE_PTP_CLEAR_STALL como o primeiro argumento para este método, o controlador emite o pedido PTP Get Device Status para determinar se algum endpoint está em uma condição de STALL. Se o comando Get Device Status for bem-sucedido, o driver emitirá o código de controlo USB IOCTL_RESET_PIPE para cada endpoint. Se o comando Get Device Status falhar, o driver emitirá uma solicitação PTP Device Reset . 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 Estática USB (USB SICDD).

O código de exemplo a seguir ilustra como usar a interface de comando estendida do 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.
//