/*++

Copyright (c) 1996  Microsoft Corporation

Module Name:

    debug.c

Abstract:

    This module contains the enumerated for the ACPI driver, NT version

Author:

    Stephane Plante (splante)

Environment:

    NT Kernel Model Driver only

--*/

#include "pch.h"

#if DBG
    #ifdef ALLOC_PRAGMA
        #pragma alloc_text(PAGE, ACPIDebugResourceDescriptor)
        #pragma alloc_text(PAGE, ACPIDebugResourceList)
        #pragma alloc_text(PAGE, ACPIDebugResourceRequirementsList)
        #pragma alloc_text(PAGE, ACPIDebugCmResourceList)
    #endif

    #define ACPI_DEBUG_BUFFER_SIZE   256

    PCCHAR  ACPIDispatchPnpTableNames[ACPIDispatchPnpTableSize] = {
            "IRP_MN_START_DEVICE",
            "IRP_MN_QUERY_REMOVE_DEVICE",
            "IRP_MN_REMOVE_DEVICE",
            "IRP_MN_CANCEL_REMOVE_DEVICE",
            "IRP_MN_STOP_DEVICE",
            "IRP_MN_QUERY_STOP_DEVICE",
            "IRP_MN_CANCEL_STOP_DEVICE",
            "IRP_MN_QUERY_DEVICE_RELATIONS",
            "IRP_MN_QUERY_INTERFACE",
            "IRP_MN_QUERY_CAPABILITIES",
            "IRP_MN_QUERY_RESOURCES",
            "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
            "IRP_MN_QUERY_DEVICE_TEXT",
            "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
            "INVALID MINOR IRP CODE",
            "IRP_MN_READ_CONFIG",
            "IRP_MN_WRITE_CONFIG",
            "IRP_MN_EJECT",
            "IRP_MN_SET_LOCK",
            "IRP_MN_QUERY_ID",
            "IRP_MN_QUERY_PNP_DEVICE_STATE",
            "IRP_MN_QUERY_BUS_INFORMATION",
            "IRP_MN_DEVICE_USAGE_NOTIFICATION",
            "IRP_MN_SURPRISE_REMOVAL",
            "UNKNOWN PNP MINOR CODE"
        };

    PCCHAR  ACPIDispatchPowerTableNames[ACPIDispatchPowerTableSize] = {
            "IRP_MN_WAIT_WAKE",
            "IRP_MN_POWER_SEQUENCE",
            "IRP_MN_SET_POWER",
            "IRP_MN_QUERY_POWER",
            "UNKNOWN POWER MINOR CODE"
        };

    PCCHAR  ACPIDispatchUnknownTableName[1] = {
            "IRP_MN_????"
        };
#endif

VOID
_ACPIInternalError(
    IN  ULONG   Bugcode
    )
{
    KeBugCheckEx (ACPI_DRIVER_INTERNAL, 0x1, Bugcode, 0, 0);
}

#if DBG
VOID
ACPIDebugPrint(
    ULONG   DebugPrintLevel,
    PCCHAR  DebugMessage,
    ...
    )
/*++

Routine Description:

    This is the debug print routine for the NT side of things. This is
    here because we don't want to use the 'shared' ACPIPrint() function
    since we can't control it.

Arguments:

    DebugPrintLevel - The bit mask that when anded with the debuglevel, must
                        equal itself
    DebugMessage    - The string to feed through vsprintf

Return Value:

    None

--*/
{
    va_list ap;

    //
    // Get the variable arguments
    //
    va_start( ap, DebugMessage );

    //
    // Call the kernel function to print the message
    //
    vDbgPrintEx( DPFLTR_ACPI_ID, DebugPrintLevel, DebugMessage, ap );

    //
    // We are done with the varargs
    //
    va_end( ap );
}

VOID
ACPIDebugDevicePrint(
    ULONG   DebugPrintLevel,
    PVOID   DebugExtension,
    PCCHAR  DebugMessage,
    ...
    )
/*++

Routine Description:

    This is the debug print routine for the NT side of things. This routine
    is here to handle the case where we are printing information that is
    associated with a device extension.

Arguments:

    DebugPrintLevel - The big mask that when and'ed with the debug level, must
                        equal itself
    DeviceExtension - The device associated with the message
    DebugMessage    - The string to feed through vsprintf

Return Value:

    NTSTATUS

---*/
{
    PDEVICE_EXTENSION   deviceExtension = (PDEVICE_EXTENSION) DebugExtension;
    va_list ap;

    //
    // Get the variable arguments
    //
    va_start( ap, DebugMessage );

    //
    // What kind of device extension are we looking at?
    //
    if (deviceExtension->Flags & DEV_PROP_HID) {

        //
        // Now that we have a _HID, do we also have a _UID?
        //
        if (deviceExtension->Flags & DEV_PROP_UID) {

            DbgPrintEx(
                DPFLTR_ACPI_ID,
                DebugPrintLevel,
                "%p %s-%s ",
                deviceExtension,
                deviceExtension->DeviceID,
                deviceExtension->InstanceID
                );

        } else {

            DbgPrintEx(
                DPFLTR_ACPI_ID,
                DebugPrintLevel,
                "%p %s ",
                deviceExtension,
                deviceExtension->DeviceID
                );

        }

    } else if (deviceExtension->Flags & DEV_PROP_ADDRESS) {

        DbgPrintEx(
            DPFLTR_ACPI_ID,
            DebugPrintLevel,
            "%p %x ",
            deviceExtension,
            deviceExtension->Address
            );

    } else {

        DbgPrintEx(
            DPFLTR_ACPI_ID,
            DebugPrintLevel,
            "%p ",
            deviceExtension
            );

    }

    //
    // Call the kernel function to print the message
    //
    vDbgPrintEx( DPFLTR_ACPI_ID, DebugPrintLevel, DebugMessage, ap );

    //
    // We are done with the varargs
    //
    va_end( ap );
}

PCCHAR
ACPIDebugGetIrpText(
   UCHAR MajorFunction,
   UCHAR MinorFunction
   )
/*++

Routine Description:

    This function returns a const pointer to the text string appropriate for
    the passed in major and minor IRP.

Arguments:

    MajorFunction
    MinorFunction

Return Value:

    const pointer to descriptive IRP text.

--*/
{
    ULONG index ;
    PCCHAR *minorTable ;

    switch(MajorFunction) {

        case IRP_MJ_PNP:
           index = ACPIDispatchPnpTableSize - 1;
           minorTable = ACPIDispatchPnpTableNames ;
           break;

        case IRP_MJ_POWER:
           index = ACPIDispatchPowerTableSize - 1;
           minorTable = ACPIDispatchPowerTableNames ;
           break;

        default:
           index = 0 ;
           minorTable = ACPIDispatchUnknownTableName ;
           break;
    }

    if (MinorFunction < index) {

        index = MinorFunction;

    }

    return minorTable[index];
}

VOID
ACPIDebugResourceDescriptor(
    IN  PIO_RESOURCE_DESCRIPTOR Descriptor,
    IN  ULONG                   ListCount,
    IN  ULONG                   DescCount
    )
/*++

Routine Description:

    This function dumps the contents of a single resource descriptor.

Arguments:

    Descriptor  - What to dump
    ListCount   - The number of the current list
    DescCount   - The number of the current descriptor

--*/
{
    PAGED_CODE();
    ASSERT( Descriptor != NULL );

    //
    // Dump the appropriate info
    //
    switch (Descriptor->Type) {
        case CmResourceTypePort:
            ACPIPrint( (
                ACPI_PRINT_RESOURCES_1,
                "[%2d] [%2d] %-9s  MininumAddress = %#08lx  MaximumAddress = %#08lx\n"
                "                     Length         = %#08lx  Alignment      = %#08lx\n",
                ListCount,
                DescCount,
                "Port",
                Descriptor->u.Port.MinimumAddress.LowPart,
                Descriptor->u.Port.MaximumAddress.LowPart,
                Descriptor->u.Port.Length,
                Descriptor->u.Port.Alignment
                ) );
            break;
        case CmResourceTypeMemory:
            ACPIPrint( (
                ACPI_PRINT_RESOURCES_1,
                "[%2d] [%2d] %-9s  MinimumAddress = %#08lx  MaximumAddress = %#08lx\n"
                "                     Length         = %#08lx  Alignment      = %#08lx\n",
                ListCount,
                DescCount,
                "Memory",
                Descriptor->u.Memory.MinimumAddress.LowPart,
                Descriptor->u.Memory.MaximumAddress.LowPart,
                Descriptor->u.Memory.Length,
                Descriptor->u.Memory.Alignment
                ) );
            break;
        case CmResourceTypeInterrupt:
            ACPIPrint( (
                ACPI_PRINT_RESOURCES_1,
                "[%2d] [%2d] %-9s  MinimumVector  = %#08lx  MaximumVector  = %#08lx\n",
                ListCount,
                DescCount,
                "Interrupt",
                Descriptor->u.Interrupt.MinimumVector,
                Descriptor->u.Interrupt.MaximumVector
                ) );
            break;
        case CmResourceTypeDma:
            ACPIPrint( (
                ACPI_PRINT_RESOURCES_1,
                "[%2d] [%2d] %-9s  MinimumChannel = %#08lx  MaximumChannel = %#08lx\n",
                ListCount,
                DescCount,
                "Dma",
                Descriptor->u.Dma.MinimumChannel,
                Descriptor->u.Dma.MaximumChannel
                ) );
            break;
        default:
            ACPIPrint( (
                ACPI_PRINT_RESOURCES_1,
                "[%2d] [%2d] Type = (%d)\n",
                ListCount,
                DescCount,
                Descriptor->Type
                ) );

    } // switch

    //
    // Dump the common info
    //
    ACPIPrint( (
        ACPI_PRINT_RESOURCES_1,
        "                     Option,Share   = %#04lx%#04lx  Flags          = %#08lx\n",
        ListCount,
        DescCount,
        Descriptor->Option,
        Descriptor->ShareDisposition
        ) );

} // for

VOID
ACPIDebugResourceList(
    IN  PIO_RESOURCE_LIST       List,
    IN  ULONG                   Count
    )
/*++

Routine Description:

    This functions displays the contents of a single resource list, so that it
    can be checked by a human

Arguments:

    List    - List to dump
    Count   - The List number (for visual reference)

Return Value:

    None

--*/
{
    ULONG   i;

    PAGED_CODE();

    ASSERT( List != NULL );

    ACPIPrint( (
        ACPI_PRINT_RESOURCES_1,
        "[%2d]      %#04x       Version        = %#08lx  Revision       = %#08lx\n",
        Count,
        List->Count,
        List->Version,
        List->Revision
        ) );

    for (i = 0; i < List->Count; i++ ) {

        //
        // Print the info on the current element
        //
        ACPIDebugResourceDescriptor( &(List->Descriptors[i]), Count, i );

    }

}

VOID
ACPIDebugResourceRequirementsList(
    IN  PIO_RESOURCE_REQUIREMENTS_LIST  List,
    IN  PDEVICE_EXTENSION               DeviceExtension
    )
/*++

Routine Description:

    This function displays a resource list in a method that can be checked
    for accuracy when the driver is loading up

Arguments:

    List    - The list to dump
    Object  - NameSpace object associated with this list

Return Value:

    None

--*/
{
    PUCHAR                  buffer;
    PIO_RESOURCE_LIST       list;
    ULONG                   i;
    ULONG                   size;

    PAGED_CODE();

    ACPIDevPrint( (
        ACPI_PRINT_RESOURCES_1,
        DeviceExtension,
        "IoResourceRequirementsList @ %x\n",
        List
        ) );

    if (List == NULL) {

        return;

    }

    ACPIPrint( (
        ACPI_PRINT_RESOURCES_1,
        "%x size: %xb alternatives: %x bus type: %x bus number %x\n",
        List,
        List->ListSize,
        List->AlternativeLists,
        List->InterfaceType,
        List->BusNumber
        ) );

    //
    // Point to the first list
    //
    list = &(List->List[0]);
    buffer = (PUCHAR) list;
    for (i = 0; i < List->AlternativeLists && buffer < ( (PUCHAR)List + List->ListSize ); i++) {

        //
        // Dump the current list
        //
        ACPIDebugResourceList( list, i );

        //
        // Determine the size of the list, and find the next one
        //
        size = sizeof(IO_RESOURCE_LIST) + (list->Count - 1) * sizeof(IO_RESOURCE_DESCRIPTOR);
        buffer += size;

        //
        // This should be pointing at a list
        //
        list = (PIO_RESOURCE_LIST) buffer;

    }

}

VOID
ACPIDebugCmResourceList(
    IN  PCM_RESOURCE_LIST   List,
    IN  PDEVICE_EXTENSION   DeviceExtension
    )
/*++

Routine Description:

    This function displays a resource list in a method that can be checked
    for accuracy when the driver is loading up

Arguments:

    List    - The list to dump
    Device  - The associated device extension

Return Value:

    None

--*/
{
    PCM_FULL_RESOURCE_DESCRIPTOR    fullDesc;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR partDesc;
    PUCHAR                          buffer;
    ULONG                           i;
    ULONG                           j;
    ULONG                           size;

    PAGED_CODE();

    ACPIDevPrint( (
        ACPI_PRINT_RESOURCES_1,
        DeviceExtension,
        "CmResourceList @ %x\n",
        List
        ) );

    if (List == NULL) {

        return;

    }
    if (List->Count == 0) {

        ACPIDevPrint( (
            ACPI_PRINT_RESOURCES_1,
            DeviceExtension,
            "There are no full resource descriptors in the list\n"
            ) );
        return;

    }

    //
    // Start to walk this data structure
    //
    fullDesc = &(List->List[0]);
    buffer = (PUCHAR) fullDesc;

    for (i = 0; i < List->Count; i++) {

        //
        // How long is the current list
        //
        size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
            (fullDesc->PartialResourceList.Count - 1) *
            sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);

        //
        // Point the buffer there
        //
        buffer += size;

        //
        // Dump the information about the current list
        //
        ACPIPrint( (
            ACPI_PRINT_RESOURCES_1,
            "[%2d] BusNumber = %#04x  Interface = %#04x\n"
            "[%2d]     Count = %#04x    Version = %#04x Revision = %#04x\n",
            i,
            fullDesc->BusNumber,
            fullDesc->InterfaceType,
            i,
            fullDesc->PartialResourceList.Count,
            fullDesc->PartialResourceList.Version,
            fullDesc->PartialResourceList.Revision
            ) );

        //
        // Walk this list
        //
        for (j = 0; j < fullDesc->PartialResourceList.Count; j++) {

            //
            // Current item
            //
            partDesc = &(fullDesc->PartialResourceList.PartialDescriptors[j]);

            //
            // Dump Principal Information...
            //
            switch (partDesc->Type) {
                case CmResourceTypePort:

                    ACPIPrint( (
                        ACPI_PRINT_RESOURCES_1,
                        "[%2d] [%2d] %12s  Start: %#08lx  Length: %#08lx\n",
                        i,
                        j,
                        "Port",
                        partDesc->u.Port.Start.LowPart,
                        partDesc->u.Port.Length
                        ) );
                    break;

                case CmResourceTypeInterrupt:

                    ACPIPrint( (
                        ACPI_PRINT_RESOURCES_1,
                        "[%2d] [%2d] %12s  Level: %#02x  Vector: %#02x  Affinity: %#08lx\n",
                        i,
                        j,
                        "Interrupt",
                        partDesc->u.Interrupt.Level,
                        partDesc->u.Interrupt.Vector,
                        partDesc->u.Interrupt.Affinity
                        ) );
                    break;

                case CmResourceTypeMemory:

                    ACPIPrint( (
                        ACPI_PRINT_RESOURCES_1,
                        "[%2d] [%2d] %12s  Start: %#08lx  Length: %#08lx\n",
                        i,
                        j,
                        "Memory",
                        partDesc->u.Memory.Start.LowPart,
                        partDesc->u.Memory.Length
                        ) );
                    break;

                case CmResourceTypeDma:

                    ACPIPrint( (
                        ACPI_PRINT_RESOURCES_1,
                        "[%2d] [%2d] %12s  Channel: %#02x  Port: %#02x  Reserved: %#02x\n",
                        i,
                        j,
                        "Dma",
                        partDesc->u.Dma.Channel,
                        partDesc->u.Dma.Port,
                        partDesc->u.Dma.Reserved1
                        ) );
                    break;

                default:

                    ACPIPrint( (
                        ACPI_PRINT_RESOURCES_1,
                        "[%2d] [%2d] Type: %2d   1: %#08lx  2: %#08lx  3: %#08lx\n",
                        i,
                        j,
                        partDesc->Type,
                        partDesc->u.DeviceSpecificData.DataSize,
                        partDesc->u.DeviceSpecificData.Reserved1,
                        partDesc->u.DeviceSpecificData.Reserved2
                        ) );
                    break;

            }

            //
            // Dump ancillary info
            //
            ACPIPrint( (
                ACPI_PRINT_RESOURCES_1,
                "                        Flags: %#08lx  Share: %#08lx\n",
                partDesc->Flags,
                partDesc->ShareDisposition
                ) );


        }

        //
        // Grab new list
        //
        fullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) buffer;

    }

}

VOID
ACPIDebugDeviceCapabilities(
    IN  PDEVICE_EXTENSION       DeviceExtension,
    IN  PDEVICE_CAPABILITIES    DeviceCapabilities,
    IN  PUCHAR                  Message
    )
/*++

Routine Description:

    This will display the device capabilities in an interesting format

Arguments:

    DeviceExtension     The device whose' capabilities we are dumping
    DeviceCapabilites   The capabilities that we are interested in
    Message             Message to print

Return Value:

    None

--*/
{
    SYSTEM_POWER_STATE  index;

    ACPIDevPrint( (
        ACPI_PRINT_SXD,
        DeviceExtension,
        " - %s - Capabilities @ %08lx\n",
        Message,
        DeviceCapabilities
        ) );
    ACPIDevPrint( (
        ACPI_PRINT_SXD,
        DeviceExtension,
        " -"
        ) );

    for (index = PowerSystemWorking; index < PowerSystemMaximum; index++) {

        if (DeviceCapabilities->DeviceState[index] == PowerSystemUnspecified) {

            ACPIPrint( (
                ACPI_PRINT_SXD,
                " S%d -> None",
                (index - 1)
                ) );

        } else {

            ACPIPrint( (
                ACPI_PRINT_SXD,
                " S%d -> D%x",
                (index - 1),
                (DeviceCapabilities->DeviceState[index] - 1)
                ) );

        }

    }
    ACPIPrint( (
        ACPI_PRINT_SXD,
        "\n"
        ) );
    ACPIDevPrint( (
        ACPI_PRINT_SXD,
        DeviceExtension,
        " -"
        ) );

    if (DeviceCapabilities->SystemWake == PowerSystemUnspecified) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " SystemWake = None"
            ) );

    } else {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " SystemWake = S%d",
            (DeviceCapabilities->SystemWake - 1)
            ) );

    }

    if (DeviceCapabilities->DeviceWake == PowerDeviceUnspecified) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceWake = None"
            ) );

    } else {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceWake = D%d",
            (DeviceCapabilities->DeviceWake - 1)
            ) );

    }

    if (DeviceCapabilities->DeviceD1) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceD1"
            ) );

    }
    if (DeviceCapabilities->DeviceD2) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceD2"
            ) );

    }
    if (DeviceCapabilities->WakeFromD0) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD0"
            ) );

    }
    if (DeviceCapabilities->WakeFromD1) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD1"
            ) );

    }
    if (DeviceCapabilities->WakeFromD2) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD2"
            ) );

    }
    if (DeviceCapabilities->WakeFromD3) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD3"
            ) );

    }

    ACPIPrint( (
        ACPI_PRINT_SXD,
        "\n"
        ) );
}

VOID
ACPIDebugPowerCapabilities(
    IN  PDEVICE_EXTENSION       DeviceExtension,
    IN  PUCHAR                  Message
    )
/*++

Routine Description:

    This will display the device capabilities in an interesting format

Arguments:

    DeviceExtension     The device whose' capabilities we are dumping
    Message             Identify where capabilities are fron

Return Value:

--*/
{
    PACPI_POWER_INFO    powerInfo = &(DeviceExtension->PowerInfo);
    SYSTEM_POWER_STATE  index;

    ACPIDevPrint( (
        ACPI_PRINT_SXD,
        DeviceExtension,
        " - %s - Internal Capabilities\n",
        Message
        ) );
    ACPIDevPrint( (
        ACPI_PRINT_SXD,
        DeviceExtension,
        " -"
        ) );


    for (index = PowerSystemWorking; index < PowerSystemMaximum; index++) {

        if (powerInfo->DevicePowerMatrix[index] == PowerSystemUnspecified) {

            ACPIPrint( (
                ACPI_PRINT_SXD,
                " S%d -> None",
                (index - 1)
                ) );

        } else {

            ACPIPrint( (
                ACPI_PRINT_SXD,
                " S%d -> D%x",
                (index - 1),
                (powerInfo->DevicePowerMatrix[index] - 1)
                ) );

        }

    }

    ACPIPrint( (
        ACPI_PRINT_SXD,
        "\n"
        ) );
    ACPIDevPrint( (
        ACPI_PRINT_SXD,
        DeviceExtension,
        " -"
        ) );
    if (powerInfo->SystemWakeLevel == PowerSystemUnspecified) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " SystemWake = None"
            ) );

    } else {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " SystemWake = S%d",
            (powerInfo->SystemWakeLevel - 1)
            ) );

    }

    if (powerInfo->DeviceWakeLevel == PowerDeviceUnspecified) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceWake = None"
            ) );

    } else {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceWake = D%d",
            (powerInfo->DeviceWakeLevel - 1)
            ) );

    }
    if (powerInfo->SupportDeviceD1) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceD1"
            ) );

    }
    if (powerInfo->SupportDeviceD2) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " DeviceD2"
            ) );

    }
    if (powerInfo->SupportWakeFromD0) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD0"
            ) );

    }
    if (powerInfo->SupportWakeFromD1) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD1"
            ) );

    }
    if (powerInfo->SupportWakeFromD2) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD2"
            ) );

    }
    if (powerInfo->SupportWakeFromD3) {

        ACPIPrint( (
            ACPI_PRINT_SXD,
            " WakeD3"
            ) );

    }

    ACPIPrint( (
        ACPI_PRINT_SXD,
        "\n"
        ) );

}

VOID
ACPIDebugThermalPrint(
    ULONG       DebugPrintLevel,
    PVOID       DebugExtension,
    ULONGLONG   DebugTime,
    PCCHAR      DebugMessage,
    ...
    )
/*++

Routine Description:

    This is the debug print routine for the NT side of things. This routine
    is here to handle the case where we are printing information that is
    associated with a device extension.

Arguments:

    DebugPrintLevel - The big mask that when and'ed with the debug level, must
                        equal itself
    DeviceExtension - The device associated with the message
    DebugTime       - The time that event occured
    DebugMessage    - The string to feed through vsprintf

Return Value:

    NTSTATUS

---*/
{
    PDEVICE_EXTENSION   deviceExtension = (PDEVICE_EXTENSION) DebugExtension;
    LARGE_INTEGER       curTime;
    TIME_FIELDS         exCurTime;
    va_list             ap;

    va_start( ap, DebugMessage );

    //
    // What kind of device extension are we looking at?
    //
    if (deviceExtension->Flags & DEV_PROP_HID) {

        //
        // Now that we have a _HID, do we also have a _UID?
        //
        if (deviceExtension->Flags & DEV_PROP_UID) {

            DbgPrintEx(
                DPFLTR_ACPI_ID,
                DebugPrintLevel,
                "%p %s-%s ",
                deviceExtension,
                deviceExtension->DeviceID,
                deviceExtension->InstanceID
                );

        } else {

            DbgPrintEx(
                DPFLTR_ACPI_ID,
                DebugPrintLevel,
                "%p %s ",
                deviceExtension,
                deviceExtension->DeviceID
                );

        }

    } else if (deviceExtension->Flags & DEV_PROP_ADDRESS) {

        DbgPrintEx(
            DPFLTR_ACPI_ID,
            DebugPrintLevel,
            "%p %x ",
            deviceExtension,
            deviceExtension->Address
            );

    } else {

        DbgPrintEx(
            DPFLTR_ACPI_ID,
            DebugPrintLevel,
            "%p ",
            deviceExtension
            );

    }

    //
    // Print the time string
    //
    curTime.QuadPart = DebugTime;
    RtlTimeToTimeFields( &curTime, &exCurTime );
    DbgPrintEx(
        DPFLTR_ACPI_ID,
        DebugPrintLevel,
        "%d:%02d:%02d.%03d ",
        exCurTime.Hour,
        exCurTime.Minute,
        exCurTime.Second,
        exCurTime.Milliseconds
        );

    //
    // Call the kernel function to print the message
    //
    vDbgPrintEx( DPFLTR_ACPI_ID, DebugPrintLevel, DebugMessage, ap );

    //
    // We are done with the varargs
    //
    va_end( ap );
}

#endif