📄 debug.c
字号:
/*++
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 + -