Proteger solicitações digitais que usam E/S direta
O exemplo de código a seguir ilustra como um driver usa uma solicitação de comando para recuperar o conteúdo do FBR (registro básico de função) de um dispositivo. Como a quantidade de dados recuperados é pequena, o exemplo usa um comando de E/S direto (chamado CMD52 na especificação SD), que instrui o motorista do barramento a transmitir os dados pela linha CMD. Para ver um exemplo de código que ilustra como usar a E/S estendida (chamada CMD53 na especificação de SD), confira Solicitações Digitais Seguras que Usam E/S Estendida.
const SDCMD_DESCRIPTOR ReadIoDirectDesc =
{SDCMD_IO_RW_DIRECT, SDCC_STANDARD, SDTD_READ,
SDTT_CMD_ONLY, SDRT_5};
PSDBUS_REQUEST_PACKET sdrp = NULL;
SD_RW_DIRECT_ARGUMENT sdIoArgument;
sdrp = ExAllocatePool(NonPagedPool,
sizeof(SDBUS_REQUEST_PACKET));
if (!sdrp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(sdrp, sizeof(SDBUS_REQUEST_PACKET));
sdrp->RequestFunction = SDRF_DEVICE_COMMAND;
sdrp->Parameters.DeviceCommand.CmdDesc = ReadIoDirectDesc;
// Set up the argument and command descriptor
sdIoArgument.u.AsULONG = 0;
sdIoArgument.u.bits.Address = Offset;
// Function # must be initialized by SdBus GetProperty call
sdIoArgument.u.bits.Function = pDevExt->FunctionNumber;
sdrp->Parameters.DeviceCommand.Argument = sdIoArgument.u.AsULONG;
// Submit the request
status = SdBusSubmitRequest(pDevExt->BusInterface.Context, sdrp);
if (NT_SUCCESS(status)) {
// for direct I/O, the data comes in the response
*Data = sdrp->ResponseData.AsUCHAR[0];
}
ExFreePool(sdrp);
Para ler o FBR, o exemplo de código executa as seguintes etapas:
Inicializar o descritor
A primeira etapa no envio de uma solicitação device-command é definir um descritor de comando SD , SDCMD_DESCRIPTOR. Normalmente, um descritor é definido como uma estrutura de dados constante. O descritor no exemplo de código define uma operação de leitura com os seguintes elementos:
Elemento Descrição A operação definida pelo descritor lê um único byte de dados do FBR, portanto, o exemplo de código usa um comando de E/S direto (CMD52), que instrui o cartão a relatar os dados solicitados na linha CMD e não nas linhas DAT. O exemplo de código indica um comando direto de E/S atribuindo um valor de SDCMD_IO_RW_DIRECT a esse membro.
As operações de leitura pertencem ao conjunto de comandos padrão (códigos de comando 0 a 63), portanto, o valor atribuído a esse membro do descritor é SDCC_STANDARD.
As operações de leitura exigem uma transferência do dispositivo para o host, portanto, o valor atribuído a esse membro do descritor é SDTD_READ.
Essa operação lê uma pequena quantidade de dados de um registro pela linha CMD. O cartão não precisa enviar dados pelas linhas da DAT, portanto, esse membro recebe um valor de SDTT_CMD_ONLY.
O descritor especifica um tipo de resposta de SDRT_5, o que significa que o cartão deve notificar o host de que a operação foi concluída com uma solicitação de interrupção. Para obter uma explicação da resposta R5, consulte a especificação associação de cartão multimídia .
Inicialize o Pacote de Solicitação concluindo as seguintes etapas:
Defina a função Request:
Depois de criar um descritor SD, o exemplo de código inicializa o pacote de solicitação SDBUS_REQUEST_PACKET. O membro RequestFunction do pacote de solicitação especifica se a solicitação contém um comando de dispositivo (valor de SDRF_DEVICE_COMMAND) ou uma operação de propriedade (valor de SDRF_GET_PROPERTY ou SDRF_SET_PROPERTY). O exemplo de código inicia um comando de dispositivo para que ele defina o membro RequestFunction como SDRF_DEVICE_COMMAND.
Carregar o Descritor de Comando: em seguida, o exemplo de código armazena o descritor recém-inicializado no membro Parameters.DeviceCommand.CmdDesc do pacote de solicitação.
Inicialize o argumento de leitura/gravação:
O pacote de solicitação contém uma estrutura SD_RW_DIRECT_ARGUMENT que contém o local dos dados que o driver de barramento recupera. Essa estrutura também armazena o número da função cujo espaço de E/S do qual o motorista do barramento lê. O código de exemplo recupera o número da função da extensão do dispositivo, o que implica que o driver recuperou anteriormente as informações do cartão (provavelmente quando iniciou o dispositivo) com uma solicitação SDRF_GET_PROPERTY e as armazenou na extensão do dispositivo.
Enviar a solicitação
Depois de inicializar o descritor e o pacote de solicitação, o exemplo de código usa a rotina de solicitação síncrona, SdBusSubmitRequest, para enviar a solicitação. A rotina de solicitação passa o pacote de solicitação e as informações de contexto da interface que o sistema forneceu ao driver quando abriu a interface SD. Como essa é uma solicitação síncrona, o driver deve estar em execução no IRQL com menos de DISPATCH_LEVEL.
Resultados do comando
Como o exemplo de código usa E/S direta, nenhum buffer de dados é necessário além do campo ResponseData no pacote de solicitação SD.