⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.c

📁 This is the library for all storage drivers. It simplifies writing a storage driver by implementing
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (C) Microsoft Corporation, 1991 - 1999

Module Name:

    debug.c

Abstract:

    CLASSPNP debug code and data

Environment:

    kernel mode only

Notes:


Revision History:

--*/


#include "classp.h"
#include "debug.h"

#if DBG

    //
    // default to not breaking in for lost irps, five minutes before we even
    // bother checking for lost irps, using standard debug print macros, and
    // using a 64k debug print buffer
    //

    #ifndef     CLASS_GLOBAL_BREAK_ON_LOST_IRPS
        #error "CLASS_GLOBAL_BREAK_ON_LOST_IRPS undefined"
        #define CLASS_GLOBAL_BREAK_ON_LOST_IRPS 0
    #endif   // CLASS_GLOBAL_BREAK_ON_LOST_IRPS

    #ifndef     CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB
        #error "CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB undefined"
        #define CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB 300
    #endif   // CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB

    #ifndef     CLASS_GLOBAL_BUFFERED_DEBUG_PRINT
        #error "CLASS_GLOBAL_BUFFERED_DEBUG_PRINT undefined"
        #define CLASS_GLOBAL_BUFFERED_DEBUG_PRINT 0
    #endif   // CLASS_GLOBAL_BUFFERED_DEBUG_PRINT

    #ifndef     CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE
        #error "CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE undefined"
        #define CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE 512
    #endif   // CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE

    #ifndef     CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS
        #error "CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS undefined"
        #define CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS 512
    #endif   // CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS

    #pragma data_seg("NONPAGE")



    CLASSPNP_GLOBALS ClasspnpGlobals;

    //
    // the low sixteen bits are used to see if the debug level is high enough
    // the high sixteen bits are used to singly enable debug levels 1-16
    //
    LONG ClassDebug = 0x00000000;

    BOOLEAN DebugTrapOnWarn = FALSE;

    VOID ClasspInitializeDebugGlobals()
    {
        KIRQL irql;

        if (InterlockedCompareExchange(&ClasspnpGlobals.Initializing, 1, 0) == 0) {

            KeInitializeSpinLock(&ClasspnpGlobals.SpinLock);

            KeAcquireSpinLock(&ClasspnpGlobals.SpinLock, &irql);

            DebugPrint((1, "CLASSPNP.SYS => Initializing ClasspnpGlobals...\n"));

            ClasspnpGlobals.Buffer = NULL;
            ClasspnpGlobals.Index = -1;
            ClasspnpGlobals.BreakOnLostIrps = CLASS_GLOBAL_BREAK_ON_LOST_IRPS;
            ClasspnpGlobals.EachBufferSize = CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFER_SIZE;
            ClasspnpGlobals.NumberOfBuffers = CLASS_GLOBAL_BUFFERED_DEBUG_PRINT_BUFFERS;
            ClasspnpGlobals.SecondsToWaitForIrps = CLASS_GLOBAL_SECONDS_TO_WAIT_FOR_SYNCHRONOUS_SRB;

            //
            // this should be the last item set
            //

            ClasspnpGlobals.UseBufferedDebugPrint = CLASS_GLOBAL_BUFFERED_DEBUG_PRINT;

            KeReleaseSpinLock(&ClasspnpGlobals.SpinLock, irql);

            InterlockedExchange(&ClasspnpGlobals.Initialized, 1);

        }
    }



    /*++////////////////////////////////////////////////////////////////////////////

    ClassDebugPrint()

    Routine Description:

        Debug print for all class drivers, NOOP on FRE versions.
        Allows printing to a debug buffer (with auto fallback to kdprint) by
        properly setting the Globals in classpnp on CHK versions.

    Arguments:

        Debug print level, or from 0 to 3 for legacy drivers.

    Return Value:

        None

    --*/
    VOID ClassDebugPrint(CLASS_DEBUG_LEVEL DebugPrintLevel, PCCHAR DebugMessage, ...)
    {
        va_list ap;
        va_start(ap, DebugMessage);

        if ((DebugPrintLevel <= (ClassDebug & 0x0000ffff)) ||
            ((1 << (DebugPrintLevel + 15)) & ClassDebug)) {

            if (ClasspnpGlobals.UseBufferedDebugPrint &&
                ClasspnpGlobals.Buffer == NULL) {

                //
                // this double-check prevents always taking
                // a spinlock just to ensure we have a buffer
                //

                KIRQL irql;

                KeAcquireSpinLock(&ClasspnpGlobals.SpinLock, &irql);
                if (ClasspnpGlobals.Buffer == NULL) {

                    SIZE_T bufferSize;
                    bufferSize = ClasspnpGlobals.NumberOfBuffers *
                                 ClasspnpGlobals.EachBufferSize;
                    DbgPrintEx(DPFLTR_CLASSPNP_ID, DPFLTR_ERROR_LEVEL,
                               "ClassDebugPrint: Allocating %x bytes for "
                               "classdebugprint buffer\n", bufferSize);
                    ClasspnpGlobals.Index       = -1;
                    ClasspnpGlobals.Buffer =
                        ExAllocatePoolWithTag(NonPagedPool, bufferSize, 'bDcS');
                    DbgPrintEx(DPFLTR_CLASSPNP_ID, DPFLTR_ERROR_LEVEL,
                               "ClassDebugPrint: Allocated buffer at %p\n",
                               ClasspnpGlobals.Buffer);

                }
                KeReleaseSpinLock(&ClasspnpGlobals.SpinLock, irql);

            }

            if (ClasspnpGlobals.UseBufferedDebugPrint &&
                ClasspnpGlobals.Buffer != NULL) {

                //
                // we never free the buffer, so once it exists,
                // we can just print to it with immunity
                //

                ULONG index;
                PUCHAR buffer;
                index = InterlockedIncrement(&ClasspnpGlobals.Index);
                index %= ClasspnpGlobals.NumberOfBuffers;
                index *= (ULONG)ClasspnpGlobals.EachBufferSize;

                buffer = ClasspnpGlobals.Buffer;
                buffer += index;

                _vsnprintf(buffer, ClasspnpGlobals.EachBufferSize, DebugMessage, ap);

            } else {

                //
                // either we could not allocate a buffer for debug prints
                // or buffered debug prints are disabled
                //

                vDbgPrintEx(DPFLTR_CLASSPNP_ID, DPFLTR_INFO_LEVEL, DebugMessage, ap);

            }

        }

        va_end(ap);

    }


    char *DbgGetIoctlStr(ULONG ioctl)
    {
        char *ioctlStr = "?";

        switch (ioctl){

            #undef MAKE_CASE
            #define MAKE_CASE(ioctlCode) case ioctlCode: ioctlStr = #ioctlCode; break;

            MAKE_CASE(IOCTL_STORAGE_CHECK_VERIFY)
            MAKE_CASE(IOCTL_STORAGE_CHECK_VERIFY2)
            MAKE_CASE(IOCTL_STORAGE_MEDIA_REMOVAL)
            MAKE_CASE(IOCTL_STORAGE_EJECT_MEDIA)
            MAKE_CASE(IOCTL_STORAGE_LOAD_MEDIA)
            MAKE_CASE(IOCTL_STORAGE_LOAD_MEDIA2)
            MAKE_CASE(IOCTL_STORAGE_RESERVE)
            MAKE_CASE(IOCTL_STORAGE_RELEASE)
            MAKE_CASE(IOCTL_STORAGE_FIND_NEW_DEVICES)
            MAKE_CASE(IOCTL_STORAGE_EJECTION_CONTROL)
            MAKE_CASE(IOCTL_STORAGE_MCN_CONTROL)
            MAKE_CASE(IOCTL_STORAGE_GET_MEDIA_TYPES)
            MAKE_CASE(IOCTL_STORAGE_GET_MEDIA_TYPES_EX)
            MAKE_CASE(IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER)
            MAKE_CASE(IOCTL_STORAGE_GET_HOTPLUG_INFO)
            MAKE_CASE(IOCTL_STORAGE_RESET_BUS)
            MAKE_CASE(IOCTL_STORAGE_RESET_DEVICE)
            MAKE_CASE(IOCTL_STORAGE_GET_DEVICE_NUMBER)
            MAKE_CASE(IOCTL_STORAGE_PREDICT_FAILURE)
            MAKE_CASE(IOCTL_STORAGE_QUERY_PROPERTY)
            MAKE_CASE(OBSOLETE_IOCTL_STORAGE_RESET_BUS)
            MAKE_CASE(OBSOLETE_IOCTL_STORAGE_RESET_DEVICE)
        }

        return ioctlStr;
    }

    char *DbgGetScsiOpStr(PSCSI_REQUEST_BLOCK Srb)
    {
        PCDB pCdb = (PCDB)Srb->Cdb;
        UCHAR scsiOp = pCdb->CDB6GENERIC.OperationCode;
        char *scsiOpStr = "?";

        switch (scsiOp){

            #undef MAKE_CASE
            #define MAKE_CASE(scsiOpCode) case scsiOpCode: scsiOpStr = #scsiOpCode; break;

            MAKE_CASE(SCSIOP_TEST_UNIT_READY)
            MAKE_CASE(SCSIOP_REWIND)    // aka SCSIOP_REZERO_UNIT
            MAKE_CASE(SCSIOP_REQUEST_BLOCK_ADDR)
            MAKE_CASE(SCSIOP_REQUEST_SENSE)
            MAKE_CASE(SCSIOP_FORMAT_UNIT)
            MAKE_CASE(SCSIOP_READ_BLOCK_LIMITS)
            MAKE_CASE(SCSIOP_INIT_ELEMENT_STATUS)   // aka SCSIOP_REASSIGN_BLOCKS
            MAKE_CASE(SCSIOP_RECEIVE)       // aka SCSIOP_READ6
            MAKE_CASE(SCSIOP_SEND)  // aka SCSIOP_WRITE6, SCSIOP_PRINT
            MAKE_CASE(SCSIOP_SLEW_PRINT)    // aka SCSIOP_SEEK6, SCSIOP_TRACK_SELECT
            MAKE_CASE(SCSIOP_SEEK_BLOCK)
            MAKE_CASE(SCSIOP_PARTITION)
            MAKE_CASE(SCSIOP_READ_REVERSE)
            MAKE_CASE(SCSIOP_FLUSH_BUFFER)      // aka SCSIOP_WRITE_FILEMARKS
            MAKE_CASE(SCSIOP_SPACE)
            MAKE_CASE(SCSIOP_INQUIRY)
            MAKE_CASE(SCSIOP_VERIFY6)
            MAKE_CASE(SCSIOP_RECOVER_BUF_DATA)
            MAKE_CASE(SCSIOP_MODE_SELECT)
            MAKE_CASE(SCSIOP_RESERVE_UNIT)
            MAKE_CASE(SCSIOP_RELEASE_UNIT)
            MAKE_CASE(SCSIOP_COPY)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -