Partager via


IOCTL_SCSISCAN_CMD IOCTL (scsiscan.h)

Crée un bloc de descripteur de contrôle SCSI personnalisé (CDB) et l’envoie au pilote d’image en mode noyau pour les bus SCSI.

Code principal

IRP_MJ_DEVICE_CONTROL

Mémoire tampon d’entrée

Pointeur vers une structure SCSISCAN_CMD.

Longueur de la mémoire tampon d’entrée

Taille de la mémoire tampon d’entrée.

Mémoire tampon de sortie

Pointeur vers une mémoire tampon de données. Selon le type d’opération d’E/S, cette mémoire tampon peut fournir ou recevoir des données.

Longueur de la mémoire tampon de sortie

Taille de la mémoire tampon de sortie.

Bloc d’état

> IoStatus.Status est défini sur STATUS_SUCCESS si la requête réussit. Sinon, état à la condition d’erreur appropriée en tant que code NTSTATUS.

Remarques

Lorsque la fonction DeviceloControl est appelée avec le code de contrôle d’E/S IOCTL_SCSISCAN_CMD, l’appelant doit spécifier l’adresse d’une structure SCSISCAN_CMD comme paramètre lpInBuffer de la fonction. Cette structure spécifie le type d’opération demandé. Le pilote en mode noyau construit un bloc de requête SCSI (SRB) à partir du contenu de la structure SCSISCAN_CMD.

Pour les commandes SCSI qui impliquent des transferts de données, le DeviceIoControl fonction lpOutBuffer doit pointer vers une mémoire tampon de données. Pour les opérations de lecture, cette mémoire tampon reçoit les données lues à partir de l’appareil. Pour les opérations d’écriture, la mémoire tampon doit contenir les données à écrire.

Pour plus d’informations, consultez Accès aux pilotes Kernel-Mode pour les appareils toujours image.

Exemple de code

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
      );
    }
  }
}

Exigences

Exigence Valeur
d’en-tête scsiscan.h (include Scsiscan.h)

Voir aussi

création de requêtes IOCTL dans les pilotes

WdfIoTargetSendInternalIoctlOthersSynchronously

WdfIoTargetSendInternalIoctlSynchronously

WdfIoTargetSendIoctlSynchronously