IOCTL_SCSI_PASS_THROUGH_DIRECT IOCTL (ntddscsi.h)
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.
- No se admiten las operaciones de transferencia de datos bidireccionales.
- 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 debe realizarse si el CDB de entrada podría requerir que el controlador de miniport 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
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 dataBuffer de SCSI_PASS_THROUGH_DIRECT es un puntero a este búfer alineado del dispositivo adaptador. El autor de la llamada debe asignar almacenamiento adicional, siguiendo la estructura SCSI_PASS_THROUGH_DIRECT, 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 (detectar el tamaño de los datos + tamaño de (SCSI_PASS_THROUGH_DIRECT)). El tamaño de la estructura SCSI_PASS_THROUGH_DIRECT 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 al búfer en Irp->AssociatedIrp.SystemBuffer.
Longitud del búfer de salida
SenseInfoLength y dataTransferLength 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 DataBuffer .
Bloque de estado
El campo información de 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 en STATUS_BUFFER_TOO_SMALL o STATUS_INVALID_PARAMETER si el valor de longitud de entrada en SCSI_PASS_THROUGH_DIRECT está establecido incorrectamente o el búfer especificado en dataBuffer no está alineado correctamente con el dispositivo.
Observaciones
Para las operaciones de transferencia de datos, se requiere un búfer con alineación que coincida con el dispositivo adaptador. Las aplicaciones pueden recuperar la máscara de alineación del dispositivo emitiendo una solicitud de código de control IOCTL_STORAGE_QUERY_PROPERTY con un tipo de consulta de 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 alignmentMask miembro 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;
}
Requisitos
Requisito | Valor |
---|---|
encabezado de | ntddscsi.h (incluya Ntddscsi.h) |