Compartilhar via


IOCTL_SCSISCAN_CMD IOCTL (scsiscan.h)

Cria um CDB (bloco de descritor de controle SCSI) personalizado e o envia para o driver de imagem ainda no modo kernel para barramentos SCSI.

Código principal

IRP_MJ_DEVICE_CONTROL

Buffer de entrada

Ponteiro para uma estrutura SCSISCAN_CMD .

Comprimento do buffer de entrada

Tamanho do buffer de entrada.

Buffer de saída

Ponteiro para um buffer de dados. Dependendo do tipo de operação de E/S, esse buffer pode fornecer ou receber dados.

Comprimento do buffer de saída

Tamanho do buffer de saída.

Bloco de status

Irp->IoStatus.Status será definido como STATUS_SUCCESS se a solicitação for bem-sucedida. Caso contrário, Status para a condição de erro apropriada como um código NTSTATUS .

Comentários

Quando a função DeviceloControl é chamada com o código de controle de E/S IOCTL_SCSISCAN_CMD, o chamador deve especificar o endereço de uma estrutura SCSISCAN_CMD como o parâmetro lpInBuffer da função. Essa estrutura especifica o tipo de operação que está sendo solicitada. O driver do modo kernel constrói um SRB (Bloco de Solicitação SCSI) com base no conteúdo da estrutura SCSISCAN_CMD.

Para comandos SCSI que envolvem transferências de dados, o lpOutBuffer da função DeviceIoControl deve apontar para um buffer de dados. Para operações de leitura, esse buffer receberá dados lidos do dispositivo. Para operações de gravação, o buffer deve conter os dados a serem gravados.

Para obter mais informações, consulte Acessando drivers de Kernel-Mode para dispositivos de imagem ainda.

Exemplo de código

SCSISCAN_CMD  Cmd;
UCHAR         SrbStatus;

// Construct the SCSISCAN_CMD structure and
// clear out the sense buffer.
memset(&Cmd, 0, sizeof(Cmd));
memset(SenseBuffer,0, sizeof(SenseBuffer));

Cmd.Size = sizeof(SCSISCAN_CMD);
Cmd.SrbFlags = SRB_FLAGS_DATA_OUT;
Cmd.CdbLength = 6;
Cmd.SenseLength = 18;
Cmd.TransferLength = len;
Cmd.pSrbStatus = &SrbStatus;
Cmd.pSenseBuffer = SenseBuffer;

Cmd.Cdb[0] = 0x0A;
Cmd.Cdb[4] = ((PFOUR_BYTE)&len) -> Byte0;
Cmd.Cdb[3] = ((PFOUR_BYTE)&len) -> Byte1;
Cmd.Cdb[2] = ((PFOUR_BYTE)&len) -> Byte2;
Cmd.Cdb[5] = 0;

DeviceIoControl(
           gb_Scan_Handle,
           (DWORD) IOCTL_SCSISCAN_CMD,
           &Cmd,
           sizeof(Cmd),
           buf,
           len,
           amount_written_ptr,
           NULL
           );

if (SRB_STATUS_SUCCESS != SRB_STATUS(SrbStatus))
{
  fprintf(stderr, "WriteScanner error.\n");
  if (SRB_STATUS_DATA_OVERRUN == SrbStatus)
  {
    fprintf(stderr, "Data over/under run. This is ok.\n");
  }
  else if ((SenseBuffer[2] & 0xf) == SCSI_SENSE_UNIT_ATTENTION)
  {
    fprintf(stderr, "Unit attention.  Retrying request....\n");
    memset(SenseBuffer,0, sizeof(SenseBuffer));
    SrbStatus = 0;
    DeviceIoControl(
      gb_Scan_Handle,
      (DWORD) IOCTL_SCSISCAN_CMD,
      &Cmd,
      sizeof(Cmd),
      buf,
      len,
      amount_written_ptr,
      NULL
      );
    }
  }
}

Requisitos

Requisito Valor
Cabeçalho scsiscan.h (inclua Scsiscan.h)

Confira também

Criando solicitações IOCTL em drivers

WdfIoTargetSendInternalIoctlOthersSynchronously

WdfIoTargetSendInternalIoctlSynchronously

WdfIoTargetSendIoctlSynchronously