You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
380 lines
7.4 KiB
380 lines
7.4 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
DBGSRVIC.C
|
|
|
|
Abstract:
|
|
|
|
Devug services exported by USBD
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Notes:
|
|
|
|
|
|
|
|
Revision History:
|
|
|
|
09-29-95 : created
|
|
|
|
--*/
|
|
|
|
|
|
#include "wdm.h"
|
|
#include "stdarg.h"
|
|
#include "stdio.h"
|
|
|
|
|
|
#include "usbdi.h" //public data structures
|
|
#include "hcdi.h"
|
|
|
|
#include "usbd.h" //private data strutures
|
|
|
|
#if DBG
|
|
|
|
// default debug trace level is 0
|
|
|
|
#ifdef DEBUG1
|
|
ULONG USBD_Debug_Trace_Level = 1;
|
|
#else
|
|
#ifdef DEBUG2
|
|
ULONG USBD_Debug_Trace_Level = 2;
|
|
#else
|
|
#ifdef DEBUG3
|
|
ULONG USBD_Debug_Trace_Level = 3;
|
|
#else
|
|
ULONG USBD_Debug_Trace_Level = 0;
|
|
#endif /* DEBUG3 */
|
|
#endif /* DEBUG2 */
|
|
#endif /* DEBUG1 */
|
|
|
|
LONG USBDTotalHeapAllocated = 0;
|
|
#endif /* DBG */
|
|
|
|
#ifdef DEBUG_LOG
|
|
struct USBD_LOG_ENTRY {
|
|
CHAR le_name[4]; // Identifying string
|
|
ULONG_PTR le_info1; // entry specific info
|
|
ULONG_PTR le_info2; // entry specific info
|
|
ULONG_PTR le_info3; // entry specific info
|
|
}; /* USBD_LOG_ENTRY */
|
|
|
|
|
|
struct USBD_LOG_ENTRY *LStart = 0; // No log yet
|
|
struct USBD_LOG_ENTRY *LPtr;
|
|
struct USBD_LOG_ENTRY *LEnd;
|
|
#endif /* DEBUG_LOG */
|
|
|
|
VOID
|
|
USBD_Debug_LogEntry(
|
|
IN CHAR *Name,
|
|
IN ULONG_PTR Info1,
|
|
IN ULONG_PTR Info2,
|
|
IN ULONG_PTR Info3
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Adds an Entry to USBD log.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
#ifdef DEBUG_LOG
|
|
if (LStart == 0)
|
|
return;
|
|
|
|
if (LPtr > LStart)
|
|
LPtr -= 1; // Decrement to next entry
|
|
else
|
|
LPtr = LEnd;
|
|
|
|
RtlCopyMemory(LPtr->le_name, Name, 4);
|
|
// LPtr->le_ret = (stk[1] & 0x00ffffff) | (CurVMID()<<24);
|
|
LPtr->le_info1 = Info1;
|
|
LPtr->le_info2 = Info2;
|
|
LPtr->le_info3 = Info3;
|
|
|
|
#endif /* DEBUG_LOG */
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef DEBUG_LOG
|
|
VOID
|
|
USBD_LogInit(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Init the debug log - remember interesting information in a circular buffer
|
|
|
|
Arguments:
|
|
|
|
LogSize - maximum size of log in pages
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG LogSize = 4096; //1 page of log entries
|
|
|
|
LStart = ExAllocatePool(NonPagedPool,
|
|
LogSize);
|
|
|
|
if (LStart) {
|
|
LPtr = LStart;
|
|
|
|
// Point the end (and first entry) 1 entry from the end of the segment
|
|
LEnd = LStart + (LogSize / sizeof(struct USBD_LOG_ENTRY)) - 1;
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif /* DEBUG_LOG */
|
|
|
|
//
|
|
// tag buffer we use to mark heap blocks we allocate
|
|
//
|
|
|
|
typedef struct _HEAP_TAG_BUFFER {
|
|
ULONG Sig;
|
|
ULONG Length;
|
|
} HEAP_TAG_BUFFER, *PHEAP_TAG_BUFFER;
|
|
|
|
|
|
PVOID
|
|
USBD_Debug_GetHeap(
|
|
IN POOL_TYPE PoolType,
|
|
IN ULONG NumberOfBytes,
|
|
IN ULONG Signature,
|
|
IN PLONG TotalAllocatedHeapSpace
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Debug routine, used to debug heap problems. We are using this since
|
|
most NT debug functions are not supported by NTKERN.
|
|
|
|
Arguments:
|
|
|
|
PoolType - pool type passed to ExAllocatePool
|
|
|
|
NumberOfBytes - number of bytes for item
|
|
|
|
Signature - four byte signature supplied by caller
|
|
|
|
TotalAllocatedHeapSpace - pointer to variable where client stores
|
|
the total accumulated heap space allocated.
|
|
|
|
Return Value:
|
|
|
|
pointer to allocated memory
|
|
|
|
--*/
|
|
{
|
|
PUCHAR p;
|
|
#ifdef DEBUG_HEAP
|
|
ULONG *stk = NULL;
|
|
PHEAP_TAG_BUFFER tagBuffer;
|
|
|
|
// we call ExAllocatePoolWithTag but no tag will be added
|
|
// when running under NTKERN
|
|
|
|
#ifdef _M_IX86
|
|
_asm mov stk, ebp
|
|
#endif
|
|
|
|
p = (PUCHAR) ExAllocatePoolWithTag(PoolType,
|
|
NumberOfBytes + sizeof(HEAP_TAG_BUFFER),
|
|
Signature);
|
|
|
|
if (p) {
|
|
tagBuffer = (PHEAP_TAG_BUFFER) p;
|
|
tagBuffer->Sig = Signature;
|
|
tagBuffer->Length = NumberOfBytes;
|
|
p += sizeof(HEAP_TAG_BUFFER);
|
|
*TotalAllocatedHeapSpace += NumberOfBytes;
|
|
}
|
|
|
|
LOGENTRY((PUCHAR) &Signature, 0, 0, 0);
|
|
#ifdef _M_IX86
|
|
LOGENTRY("GetH", p, NumberOfBytes, stk[1] & 0x00FFFFFF);
|
|
#else
|
|
LOGENTRY("GetH", p, NumberOfBytes, 0);
|
|
#endif
|
|
#else
|
|
p = (PUCHAR) ExAllocatePoolWithTag(PoolType,
|
|
NumberOfBytes,
|
|
Signature);
|
|
|
|
#endif /* DEBUG_HEAP */
|
|
return p;
|
|
}
|
|
|
|
|
|
VOID
|
|
USBD_Debug_RetHeap(
|
|
IN PVOID P,
|
|
IN ULONG Signature,
|
|
IN PLONG TotalAllocatedHeapSpace
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Debug routine, used to debug heap problems. We are using this since
|
|
most NT debug functions are not supported by NTKERN.
|
|
|
|
Arguments:
|
|
|
|
P - pointer to free
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
{
|
|
#ifdef DEBUG_HEAP
|
|
PHEAP_TAG_BUFFER tagBuffer;
|
|
ULONG *stk = NULL ;
|
|
|
|
USBD_ASSERT(P != 0);
|
|
|
|
#ifdef _M_IX86
|
|
_asm mov stk, ebp
|
|
#endif
|
|
|
|
tagBuffer = (PHEAP_TAG_BUFFER) ((PUCHAR)P - sizeof(HEAP_TAG_BUFFER));
|
|
|
|
*TotalAllocatedHeapSpace -= tagBuffer->Length;
|
|
|
|
LOGENTRY((PUCHAR) &Signature, 0, 0, 0);
|
|
#ifdef _M_IX86
|
|
LOGENTRY("RetH", P, tagBuffer->Length, stk[1] & 0x00FFFFFF);
|
|
#else
|
|
LOGENTRY("RetH", P, tagBuffer->Length, 0);
|
|
#endif
|
|
|
|
USBD_ASSERT(*TotalAllocatedHeapSpace >= 0);
|
|
USBD_ASSERT(tagBuffer->Sig == Signature);
|
|
|
|
// fill the buffer with bad data
|
|
RtlFillMemory(P, tagBuffer->Length, 0xff);
|
|
tagBuffer->Sig = USBD_FREE_TAG;
|
|
|
|
// free the original block
|
|
ExFreePool(tagBuffer);
|
|
#else
|
|
ExFreePool(P);
|
|
#endif /* DEBUG_HEAP */
|
|
}
|
|
|
|
|
|
#if DBG
|
|
ULONG
|
|
_cdecl
|
|
USBD_KdPrintX(
|
|
PCH Format,
|
|
...
|
|
)
|
|
{
|
|
va_list list;
|
|
int i;
|
|
int arg[5];
|
|
|
|
va_start(list, Format);
|
|
for (i=0; i<4; i++)
|
|
arg[i] = va_arg(list, int);
|
|
|
|
DbgPrint(Format, arg[0], arg[1], arg[2], arg[3]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
VOID
|
|
USBD_Warning(
|
|
PUSBD_DEVICE_DATA DeviceData,
|
|
PUCHAR Message,
|
|
BOOLEAN DebugBreak
|
|
)
|
|
{
|
|
DbgPrint("USBD: Warning ****************************************************************\n");
|
|
if (DeviceData) {
|
|
DbgPrint("Device PID %04.4x, VID %04.4x\n",
|
|
DeviceData->DeviceDescriptor.idProduct,
|
|
DeviceData->DeviceDescriptor.idVendor);
|
|
}
|
|
DbgPrint("%s", Message);
|
|
|
|
DbgPrint("******************************************************************************\n");
|
|
|
|
if (DebugBreak) {
|
|
DBGBREAK();
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
USBD_Assert(
|
|
IN PVOID FailedAssertion,
|
|
IN PVOID FileName,
|
|
IN ULONG LineNumber,
|
|
IN PCHAR Message
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Debug Assert function.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - pointer to a device object
|
|
|
|
Irp - pointer to an I/O Request Packet
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
{
|
|
#ifdef NTKERN
|
|
// this makes the compiler generate a ret
|
|
ULONG stop = 1;
|
|
|
|
assert_loop:
|
|
#endif
|
|
// just call the NT assert function and stop
|
|
// in the debugger.
|
|
RtlAssert( FailedAssertion, FileName, LineNumber, Message );
|
|
|
|
// loop here to prevent users from going past
|
|
// are assert before we can look at it
|
|
#ifdef NTKERN
|
|
DBGBREAK();
|
|
if (stop) {
|
|
goto assert_loop;
|
|
}
|
|
#endif
|
|
return;
|
|
}
|
|
#endif /* DBG */
|