IOCTL_SCSI_PASS_THROUGH_DIRECT_EX IOCTL (ntddscsi.h)
A solicitação de código de controle IOCTL_SCSI_PASS_THROUGH_DIRECT_EX é a versão estendida da solicitação de IOCTL_SCSI_PASS_THROUGH_DIRECT . Essa solicitação fornece suporte para transferências de dados bidirecionais e permite um bloco de dados de comando (CDB) > 16 bytes.
Permite que um aplicativo envie quase qualquer comando SCSI para um dispositivo de destino, com as seguintes restrições:
- Comandos multitarget, como COPY, não são permitidos.
- Se existir um driver de classe para o tipo de destino do dispositivo, a solicitação deverá ser enviada para esse driver de classe. Assim, um aplicativo poderá enviar essa solicitação diretamente para o driver de porta do sistema para uma unidade lógica de destino somente se não houver nenhum driver de classe para o tipo de dispositivo conectado a esse LU.
- Essa solicitação deve ser feita se o CDB de entrada puder exigir que o driver de miniporto subjacente acesse a memória diretamente.
Os aplicativos podem enviar essa solicitação por meio de uma solicitação IRP_MJ_DEVICE_CONTROL .
Os drivers de classe de armazenamento definem o número irp secundário como IRP_MN_SCSI_CLASS para indicar que a solicitação foi processada por um driver de classe de armazenamento.
Código principal
Buffer de entrada
Parameters.DeviceIoControl.InputBufferLength indica o tamanho, em bytes, do buffer em Irp->AssociatedIrp.SystemBuffer, que deve ser pelo menos (sense data sizeof + (SCSI_PASS_THROUGH_DIRECT_EX)). O tamanho da estrutura de SCSI_PASS_THROUGH_DIRECT_EX é fixo.Essa estrutura inclui uma CDB SCSI, que deve ser inicializada pelo chamador, exceto pelo caminho, ID de destino e LUN, que são preenchidos pelo driver de porta. Para um comando de saída de dados, os dados a serem transferidos devem estar em um buffer alinhado ao dispositivo do adaptador. O membro DataInBuffer do SCSI_PASS_THROUGH_DIRECT_EX é um ponteiro para esse buffer alinhado do dispositivo adaptador. O chamador deve alocar armazenamento adicional, seguindo a estrutura SCSI_PASS_THROUGH_DIRECT_EX , se o chamador solicitar dados de sentido de solicitação.
Comprimento do buffer de entrada
Parameters.DeviceIoControl.InputBufferLength indica o tamanho, em bytes, do buffer em Irp->AssociatedIrp.SystemBuffer, que deve ser pelo menos (sense data sizeof + (SCSI_PASS_THROUGH_DIRECT_EX)). O tamanho da estrutura de SCSI_PASS_THROUGH_DIRECT_EX é fixo.Buffer de saída
O driver de porta retorna todos os dados de sensor de solicitação e a estrutura SCSI_PASS_THROUGH_DIRECT_EX para o buffer em Irp-AssociatedIrp.SystemBuffer>.
Comprimento do buffer de saída
SenseInfoLength e DataOutTransferLength são atualizados para indicar a quantidade de dados transferidos. O driver de porta retorna todos os dados transferidos do dispositivo para o buffer alinhado ao cache fornecido no DataOutBuffer.
Bloco de status
O campo Informações é definido como o número de bytes retornados no buffer de saída em Irp-AssociatedIrp.SystemBuffer>. O campo Status é definido como STATUS_SUCCESS ou possivelmente para STATUS_BUFFER_TOO_SMALL ou STATUS_INVALID_PARAMETER se o valor length de entrada em SCSI_PASS_THROUGH_DIRECT_EX for definido incorretamente ou o buffer especificado no DataInBuffer não estiver alinhado corretamente ao dispositivo.
Comentários
Para operações de transferência de dados, é necessário um buffer com alinhamento correspondente ao dispositivo adaptador. Os aplicativos podem recuperar a máscara de alinhamento do dispositivo emitindo uma solicitação de código de controle IOCTL_STORAGE_QUERY_PROPERTY com um tipo de consulta PropertyStandardQuery e id de propriedade de StorageAdapterProperty. A máscara de alinhamento é encontrada no membro AlignmentMask da estrutura STORAGE_ADAPTER_DESCRIPTOR retornada. Os drivers também podem usar o valor no membro AlignmentMask do DeviceObject do adaptador.
Na função de exemplo a seguir, um buffer é preparado como um buffer de transferência de dados alinhado ao 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 uma solicitação de IOCTL_SCSI_PASS_THROUGH_DIRECT_EX , o dispositivo de armazenamento subjacente deve dar suporte a SRBs estendidas. Isso significa que o tipo SRB com suporte é SRB_TYPE_STORAGE_REQUEST_BLOCK. Um aplicativo pode consultar o suporte a SRB com a solicitação IOCTL_STORAGE_QUERY_PROPERTY com um tipo de consulta PropertyStandardQuery e um tipo de propriedade StorageDeviceProperty. O membro SrbType retornado na estrutura STORAGE_ADAPTER_DESCRIPTIOR indicará SRB_TYPE_SCSI_REQUEST_BLOCK ou SRB_TYPE_STORAGE_REQUEST_BLOCK.
Requisitos
Requisito | Valor |
---|---|
Cabeçalho | ntddscsi.h (inclua Ntddscsi.h) |