Valutazione di un metodo di controllo senza argomenti di input
Per valutare in modo sincrono un metodo di controllo che non accetta argomenti di input, un driver per un dispositivo invia una richiesta di IOCTL_ACPI_EVAL_METHOD o una richiesta di IOCTL_ACPI_EVAL_METHOD_EX al dispositivo. La procedura generale per l'uso di entrambe queste richieste è descritta in Valutazione dei metodi di controllo ACPI in modo sincrono. La differenza specifica tra l'uso di queste due richieste è la seguente:
Se il metodo di controllo è un oggetto figlio immediato del dispositivo, il driver invia una richiesta di IOCTL_ACPI_EVAL_METHOD e fornisce una struttura di input ACPI_EVAL_INPUT_BUFFER .
Se il metodo di controllo è un oggetto figlio nello spazio dei nomi ACPI del dispositivo, ma non è un oggetto figlio immediato del dispositivo, il driver invia una richiesta di IOCTL_ACPI_EVAL_METHOD_EX e fornisce una struttura ACPI_EVAL_INPUT_BUFFER_EX .
L'esempio di funzione GetAbcData fornita in questo argomento illustra come un driver per un dispositivo può usare una richiesta di IOCTL_ACPI_EVAL_METHOD per valutare un metodo di controllo denominato 'ABCD' supportato dal dispositivo. Il metodo di controllo "ABCD" è un figlio immediato del dispositivo nello spazio dei nomi ACPI e non accetta argomenti di input o argomenti di output restituiti.
Se il metodo di controllo 'ABCD' non era un oggetto figlio immediato, le modifiche necessarie al codice di esempio sono le seguenti:
Inviare una richiesta di IOCTL_ACPI_EVAL_METHOD_EX anziché una richiesta di IOCTL_ACPI_EVAL_METHOD.
Specificare una struttura ACPI_EVAL_INPUT_BUFFER_EX anziché una struttura ACPI_EVAL_INPUT_BUFFER.
GetAbcData alloca prima un input della struttura ACPI_EVAL_INPUT_BUFFER Buffer e imposta il membro MethodNameAsUlong sul nome del metodo di controllo e imposta il membro Signature su ACPI_EVAL_INPUT_BUFFER_SIGNATURE.
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
GetAbcData alloca anche un output della struttura ACPI_EVAL_OUTPUT_BUFFER Buffer, ma non imposta alcun membro dell'outputBuffer.
GetAbcData chiama quindi una funzione fornita dal driver denominata SendDownStreamIrp che esegue le operazioni seguenti:
Chiama IoBuildDeviceIoControlRequest per compilare la richiesta.
Chiama IoCallDriver per inviare la richiesta nello stack di dispositivi.
Attende che il gestore di I/O segnali il driver che i driver di livello inferiore hanno completato la richiesta.
SendDownStreamIrp restituisce dopo che il gestore I/O segnala che i driver di livello inferiore hanno completato la richiesta. L'esempio di codice indicato in precedenza esegue le operazioni seguenti:
Controlla lo stato della richiesta e restituisce senza elaborazione aggiuntiva se i driver di livello inferiore non restituiscono STATUS_SUCCESS.
Controlla la validità degli argomenti di output. Per consentire all'outputBuffer di contenere dati di output validi, la firma deve essere impostata su ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE e Count deve essere impostata su maggiore di zero.
Elabora gli argomenti di output passati al driver ACPI.
Anche se questo passaggio non è incluso nel codice di esempio, il driver deve anche chiamare IoCompleteRequest dopo aver elaborato i dati di output per completare la richiesta di IOCTL_ACPI_EVAL_METHOD in sospeso o IOCTL_ACPI_EVAL_METHOD richiesta inviata dal driver per valutare un metodo di controllo.
Le strutture di dati e le costanti ACPI usate nell'esempio seguente sono definite in Acpioct.h.
NTSTATUS
GetAbcdData(
IN PDEVICE_OBJECT Pdo,
OUT PULONG ReturnStatus
)
/*++
Routine Description:
Evaluates the ABCD method on the device in the ACPI namespace referenced by Pdo
Parameters
Pdo - PDO for the device
ReturnStatus - Pointer to where the status data is placed
Return Value:
NT Status of the operation
--*/
{
ACPI_EVAL_INPUT_BUFFER inputBuffer;
ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
NTSTATUS status;
PACPI_METHOD_ARGUMENT argument;
.
.
ASSERT( ReturnStatus != NULL );
*ReturnStatus = 0x0;
// Fill in the input data
inputBuffer.MethodNameAsUlong = (ULONG) ('DCBA');
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
// Send the request along
status = SendDownStreamIrp(
Pdo,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
&outputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER)
);
if (!NT_SUCCESS(status)) {
return status;
}
// Verify the data
if (outputBuffer != NULL) {
if ( ( (PACPI_EVAL_OUTPUT_BUFFER) outputBuffer->Signature !=
ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE ||
( (PACPI_EVAL_OUTPUT_BUFFER) outputBuffer->Count == 0) {
return STATUS_ACPI_INVALID_DATA;
}
}
// Retrieve the output argument
argument = outputBuffer.Argument;
// Process the output argument
.
.
.
return status;
}