Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Een stuurprogramma gebruikt doorgaans een reeks van twee IOCTL_ACPI_ENUM_CHILDREN aanvragen om de objecten te inventariseren die van belang zijn in de naamruimte van het apparaat waarnaar de aanvraag wordt verzonden. Het stuurprogramma verzendt de eerste aanvraag om de grootte te verkrijgen van een door het stuurprogramma toegewezen uitvoerbuffer die nodig is om het pad en de naam van de objecten te bevatten. Het stuurprogramma verzendt de tweede aanvraag om het pad en de naam van de objecten in een door het stuurprogramma toegewezen uitvoerbuffer te retourneren.
Het volgende codevoorbeeld toont hoe u een reeks van twee synchrone IOCTL_ACPI_ENUM_CHILDREN-aanvragen verzendt om alle onderliggende apparaten van het bovenliggende apparaat, waarheen de aanvragen worden verzonden, te inventariseren. De code voert de volgende reeks bewerkingen uit om de eerste aanvraag te verwerken:
Hiermee stelt u de invoerbuffer voor de eerste aanvraag in. De invoerbuffer is een ACPI_ENUM_CHILDREN_INPUT_BUFFER structuur met Handtekening ingesteld op ENUM_CHILDREN_INPUT_BUFFER_SIGNATURE en vlaggen die zijn ingesteld op ENUM_CHILDREN_MULTILEVEL.
Hiermee stelt u de uitvoerbuffer voor de eerste aanvraag in. De uitvoerbuffer is ingesteld op een ACPI_ENUM_CHILDREN_OUTPUT_BUFFER structuur. Deze uitvoerbuffer bevat slechts één ACPI_ENUM_CHILD structuur die niet groot genoeg is om een naam van een apparaat te retourneren.
Roept een door de aanroeper opgegeven SendDownStreamIrp-functie aan om de eerste aanvraag synchroon naar het bovenliggende apparaat te verzenden.
Controleert of het ACPI-stuurprogramma de retourstatus instelt op STATUS_BUFFER_OVERFLOW. Als er een andere status is geretourneerd, geeft dit aan dat er een fout is opgetreden en de code wordt beëindigd.
Hiermee wordt gecontroleerd of het ACPI-stuurprogramma het Signature-lid instelt op ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE en NumberOfChildren instelt op een waarde die groter is dan of gelijk is aan de grootte van(ACPI_ENUM_CHILDREN_OUTPUT_BUFFER). Als beide waar zijn, is de waarde van NumberOfChildren de grootte, in bytes, van de uitvoerbuffer die nodig is om de aangevraagde onderliggende objectnamen te bevatten.
Nadat de voorbeeldcode de vereiste grootte van de uitvoerbuffer heeft verkregen, voert deze de volgende reeks bewerkingen uit om de tweede aanvraag te verwerken, waarmee het pad en de naam van de aangevraagde onderliggende objecten worden geretourneerd:
Hiermee wordt een uitvoerbuffer van de vereiste grootte in bytes toegewezen.
Roept de door het stuurprogramma geleverde SendDownStreamIrp-functie aan om de tweede aanvraag synchroon naar het bovenliggende apparaat te verzenden.
Controleert of het ACPI-stuurprogramma het handtekeninglid heeft ingesteld op ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE, stelt NumberOfChildren in op een of meer (waarmee wordt aangegeven dat het pad en de naam van ten minste één object is geretourneerd) en stelt het informatielid van de IO_STATUS_BLOCK in op de toegewezen grootte van de uitvoerbuffer.
Hiermee wordt de array van kindobjectnamen in de uitvoerbuffer verwerkt.
#define MY_TAG 'gTyM' // Pool tag for memory allocation
ACPI_ENUM_CHILDREN_INPUT_BUFFER inputBuffer;
ACPI_ENUM_CHILDREN_OUTPUT_BUFFER outputSizeBuffer = { 0 };
ACPI_ENUM_CHILDREN_OUTPUT_BUFFER outputBuffer = { 0 };
ULONG bufferSize;
PACPI_ENUM_CHILD childObject = NULL;
ULONG index;
NTSTATUS status;
ASSERT( ReturnStatus != NULL );
*ReturnStatus = 0x0;
// Fill in the input data
inputBuffer.Signature = ACPI_ENUM_CHILDREN_INPUT_BUFFER_SIGNATURE;
inputBuffer.Flags = ENUM_CHILDREN_MULTILEVEL;
// Send the request along
status = SendDownStreamIrp(
Pdo,
IOCTL_ACPI_ENUM_CHILDREN,
&inputBuffer,
sizeof(inputBuffer),
&outputSizeBuffer,
sizeof(outputSizeBuffer)
);
if (Status != STATUS_BUFFER_OVERFLOW) {
// There should be at least one child device (that is the device itself)
// Return error return status
}
// Verify the data
// NOTE: The NumberOfChildren returned by ACPI actually contains the required size
// when the status returned is STATUS_BUFFER_OVERFLOW
if ((outputSizeBuffer.Signature != ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE) ||
(outputSizeBuffer.NumberOfChildren < sizeof(ACPI_ENUM_CHILDREN_OUTPUT_BUFFER)))
{
return STATUS_ACPI_INVALID_DATA;
}
//
// Allocate a buffer to hold all the child devices
//
bufferSize = outputSizeBuffer.NumberOfChildren;
outputBuffer = (PACPI_ENUM_CHILDREN_OUTPUT_BUFFER)
ExAllocatePoolWithTag(PagedPool, bufferSize, MY_TAG);
if (outputBuffer == NULL){
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(outputBuffer, bufferSize);
// Allocate a new IRP with the new output buffer
// Send another request together with the new output buffer
status = SendDownStreamIrp(
Pdo,
IOCTL_ACPI_ENUM_CHILDREN,
&inputBuffer,
sizeof(inputBuffer),
&outputBuffer,
bufferSize
);
// Verify the data
if ((outputBuffer->Signature != ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE) ||
(outputBuffer->NumberOfChildren == 0) ||
(IoStatusBlock.Information != bufferSize)) {
return STATUS_ACPI_INVALID_DATA;
}
// Skip the first child device because ACPI returns the device itself
// as the first child device
childObject = &(outputBuffer->Children[0]);
for (index = 1; index < outputBuffer->NumberOfChildren; ++index) {
// Proceed to the next ACPI child device.
childObject = ACPI_ENUM_CHILD_NEXT(childObject);
// Process each child device.
}