IOCTL_SCSI_PASS_THROUGH_DIRECT_EX IOCTL (ntddscsi.h)
La solicitud de código de control IOCTL_SCSI_PASS_THROUGH_DIRECT_EX es la versión extendida de la solicitud de IOCTL_SCSI_PASS_THROUGH_DIRECT . Esta solicitud proporciona compatibilidad con transferencias de datos bidireccionales y permite un bloque de datos de comandos (CDB) > de 16 bytes.
Permite que una aplicación envíe casi cualquier comando SCSI a un dispositivo de destino, con las restricciones siguientes:
- No se permiten comandos multitarget, como COPY.
- Si existe un controlador de clase para el tipo de dispositivo de destino, la solicitud debe enviarse a ese controlador de clase. Por lo tanto, una aplicación puede enviar esta solicitud directamente al controlador de puerto del sistema para una unidad lógica de destino solo si no hay ningún controlador de clase para el tipo de dispositivo conectado a esa LU.
- Esta solicitud se debe realizar si la CDB de entrada podría requerir que el controlador de miniporte subyacente acceda directamente a la memoria.
Las aplicaciones pueden enviar esta solicitud mediante una solicitud de IRP_MJ_DEVICE_CONTROL .
Los controladores de clase de almacenamiento establecen el número irP secundario en IRP_MN_SCSI_CLASS para indicar que una controlador de clase de almacenamiento ha procesado la solicitud.
Código principal
Búfer de entrada
Parameters.DeviceIoControl.InputBufferLength indica el tamaño, en bytes, del búfer en Irp->AssociatedIrp.SystemBuffer, que debe ser al menos (tamaño + de datos desentidoof(SCSI_PASS_THROUGH_DIRECT_EX)). El tamaño de la estructura de SCSI_PASS_THROUGH_DIRECT_EX es fijo.Esta estructura incluye un CDB SCSI, que el autor de la llamada debe inicializar, excepto la ruta de acceso, el identificador de destino y el LUN, que el controlador de puerto rellena. Para un comando de salida de datos, los datos que se van a transferir deben estar en un búfer alineado del dispositivo adaptador. El miembro DataInBuffer de SCSI_PASS_THROUGH_DIRECT_EX es un puntero a este búfer alineado del dispositivo adaptador. El autor de la llamada debe asignar almacenamiento adicional, siguiendo la estructura de SCSI_PASS_THROUGH_DIRECT_EX , si el autor de la llamada solicita datos de detección de solicitudes.
Longitud del búfer de entrada
Parameters.DeviceIoControl.InputBufferLength indica el tamaño, en bytes, del búfer en Irp->AssociatedIrp.SystemBuffer, que debe ser al menos (tamaño + de datos desentidoof(SCSI_PASS_THROUGH_DIRECT_EX)). El tamaño de la estructura de SCSI_PASS_THROUGH_DIRECT_EX es fijo.Búfer de salida
El controlador de puerto devuelve los datos de detección de solicitudes y la estructura de SCSI_PASS_THROUGH_DIRECT_EX al búfer en Irp-AssociatedIrp.SystemBuffer>.
Longitud del búfer de salida
SenseInfoLength y DataOutTransferLength se actualizan para indicar la cantidad de datos transferidos. El controlador de puerto devuelve los datos transferidos desde el dispositivo al búfer alineado con caché proporcionado en DataOutBuffer.
Bloque de estado
El campo Información se establece en el número de bytes devueltos en el búfer de salida en Irp-AssociatedIrp.SystemBuffer>. El campo Estado se establece en STATUS_SUCCESS, o posiblemente para STATUS_BUFFER_TOO_SMALL o STATUS_INVALID_PARAMETER si el valor de longitud de entrada en SCSI_PASS_THROUGH_DIRECT_EX se establece incorrectamente o el búfer especificado en DataInBuffer no está correctamente alineado con el dispositivo.
Comentarios
En el caso de las operaciones de transferencia de datos, se requiere un búfer con alineación que coincida con el dispositivo del adaptador. Las aplicaciones pueden recuperar la máscara de alineación del dispositivo mediante la emisión de una solicitud de código de control IOCTL_STORAGE_QUERY_PROPERTY con un tipo de consulta PropertyStandardQuery e identificador de propiedad de StorageAdapterProperty. La máscara de alineación se encuentra en el miembro AlignmentMask de la estructura STORAGE_ADAPTER_DESCRIPTOR que se devuelve. Los controladores también pueden usar el valor del miembro AlignmentMask del DeviceObject del adaptador.
En la siguiente función de ejemplo, un búfer se prepara como un búfer de transferencia de datos alineado con el dispositivo.
PVOID AllocateAlignedBuffer(ULONG size, ULONG AlignmentMask, PVOID *pUnAlignedBuffer)
{
PVOID AlignedBuffer;
ULONG_PTR FullWordMask = (ULONG_PTR)AlignmentMask;
if (AlignmentMask == 0)
{
AlignedBuffer = malloc(size);
// return the original buffer to free later
*pUnAlignedBuffer = AlignedBuffer;
}
else
{
// expand the size for the alignment window
size += AlignmentMask;
AlignedBuffer = malloc(size);
// return the original buffer to free later
*pUnAlignedBuffer = AlignedBuffer;
// adjust buffer pointer for the desired alignment
AlignedBuffer = (PVOID)(((ULONG_PTR)AlignedBuffer + FullWordMask) & ~FullWordMask);
}
return AlignedBuffer;
}
Para emitir una solicitud de IOCTL_SCSI_PASS_THROUGH_DIRECT_EX , el dispositivo de almacenamiento subyacente debe admitir srBs extendidos. Esto significa que el tipo de SRB admitido es SRB_TYPE_STORAGE_REQUEST_BLOCK. Una aplicación puede consultar la compatibilidad con SRB con la solicitud de IOCTL_STORAGE_QUERY_PROPERTY con un tipo de consulta PropertyStandardQuery y un tipo de propiedad de StorageDeviceProperty. El miembro SrbType devuelto en la estructura STORAGE_ADAPTER_DESCRIPTIOR indicará SRB_TYPE_SCSI_REQUEST_BLOCK o SRB_TYPE_STORAGE_REQUEST_BLOCK.
Requisitos
Requisito | Valor |
---|---|
Header | ntddscsi.h (incluya Ntddscsi.h) |