Compartilhar via


IOCTL_SCSI_PASS_THROUGH_DIRECT IOCTL (ntddscsi.h)

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.
  • Não há suporte para operações de transferência de dados bidirecionais.
  • Se existir um driver de classe para o tipo de dispositivo de destino, a solicitação deverá ser enviada para esse driver de classe. Portanto, um aplicativo poderá enviar essa solicitação diretamente ao 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 deverá ser feita se o CDB de entrada puder exigir que o driver de miniporto subjacente acesse a memória diretamente.
O aplicativo de chamada cria o bloco do descritor de comando SCSI, que pode incluir uma solicitação de dados de sentido de solicitação se ocorrer uma CHECK CONDITION. Se o CDB solicitar uma operação de transferência de dados, o chamador deverá configurar um buffer alinhado ao dispositivo adaptador do qual ou para o qual o driver de miniporto pode transferir dados diretamente. Normalmente, essa solicitação é usada para transferir grandes quantidades de dados (>16K).

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.

Nota O driver de porta SCSI e os modelos de driver de miniporta SCSI podem ser alterados ou indisponíveis no futuro. Em vez disso, recomendamos usar os modelos de driver storport e driver de miniporto Storport .
 

Código principal

IRP_MJ_DEVICE_CONTROL

Buffer de entrada

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 adaptador. O membro DataBuffer do SCSI_PASS_THROUGH_DIRECT é um ponteiro para esse buffer alinhado do dispositivo adaptador. O chamador deve alocar armazenamento adicional, seguindo a estrutura SCSI_PASS_THROUGH_DIRECT , 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)). O tamanho da estrutura SCSI_PASS_THROUGH_DIRECT é 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 para o buffer em Irp-AssociatedIrp.SystemBuffer>.

Comprimento do buffer de saída

SenseInfoLength e DataTransferLength 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 DataBuffer .

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 estiver definido incorretamente ou o buffer especificado no DataBuffer 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;
}

Requisitos

Requisito Valor
Cabeçalho ntddscsi.h (inclua Ntddscsi.h)

Confira também

IOCTL_SCSI_PASS_THROUGH

IOCTL_STORAGE_QUERY_PROPERTY

SCSI_PASS_THROUGH_DIRECT