Partager via


IOCTL_SCSISCAN_CMD IOCTL (scsiscan.h)

Crée un bloc de descripteur de contrôle SCSI (CDB) personnalisé et l’envoie au pilote d’image fixe 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

Irp->IoStatus.Status est défini sur STATUS_SUCCESS si la demande 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 de 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, lpOutBuffer de la fonction DeviceIoControl 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 à image fixe.

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

Configuration requise

Condition requise Valeur
En-tête scsiscan.h (inclure Scsiscan.h)

Voir aussi

Création de requêtes IOCTL dans les pilotes

WdfIoTargetSendInternalIoctlOthersSynchronously

WdfIoTargetSendInternalIoctlSynchronously

WdfIoTargetSendIoctlSynchronously