365 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			365 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*--         
 | 
						|
Copyright (c) 1998, 1999  Microsoft Corporation
 | 
						|
 | 
						|
Module Name:
 | 
						|
 | 
						|
    log.c
 | 
						|
 | 
						|
Abstract:
 | 
						|
 | 
						|
Environment:
 | 
						|
 | 
						|
    Kernel mode only.
 | 
						|
 | 
						|
Notes:
 | 
						|
 | 
						|
 | 
						|
--*/
 | 
						|
 | 
						|
#include "usbverfy.h"
 | 
						|
 | 
						|
#ifdef ALLOC_PRAGMA
 | 
						|
#pragma alloc_text (PAGE, UsbVerify_DestroyLog)
 | 
						|
#endif
 | 
						|
 | 
						|
PCHAR ErrorStrings[] =
 | 
						|
{
 | 
						|
    { "Urb is using an invalid pipe." },
 | 
						|
    { "Urb is had the UrbLink set (currently unimplemented)." },
 | 
						|
    { "The device has been removed and the urb was not cancelled." },  // IDS_STALE_URB
 | 
						|
};
 | 
						|
 | 
						|
VOID
 | 
						|
UsbVerify_ResizeLog(
 | 
						|
    PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension,
 | 
						|
    ULONG NewSize
 | 
						|
    )
 | 
						|
{
 | 
						|
    PUSB_VERIFY_LOG_ENTRY oldLog;
 | 
						|
    ULONG                 oldLogSize;
 | 
						|
 | 
						|
    oldLog = DeviceExtension->Log;
 | 
						|
    oldLogSize = DeviceExtension->LogSize;
 | 
						|
 | 
						|
    DeviceExtension->Log = AllocStruct(NonPagedPool, USB_VERIFY_LOG_ENTRY, NewSize);
 | 
						|
    if (DeviceExtension->Log) {
 | 
						|
        DeviceExtension->LogSize = NewSize;
 | 
						|
        DeviceExtension->CurrentLogEntry = DeviceExtension->Log + oldLogSize;
 | 
						|
 | 
						|
        if (oldLog) {
 | 
						|
            RtlCopyMemory(DeviceExtension->Log, oldLog, oldLogSize);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        // 
 | 
						|
        // no more memory, restore the old log and never log again
 | 
						|
        //
 | 
						|
        DeviceExtension->LogFlags = 0x0;
 | 
						|
        DeviceExtension->CurrentLogEntry = NULL;
 | 
						|
 | 
						|
        DeviceExtension->Log = oldLog;
 | 
						|
        DeviceExtension->LogSize = oldLogSize;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
VOID 
 | 
						|
UsbVerify_Log (
 | 
						|
    PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension,
 | 
						|
    PUSB_VERIFY_LOG_ENTRY LogEntry
 | 
						|
    )
 | 
						|
{
 | 
						|
    LARGE_INTEGER tick;
 | 
						|
 | 
						|
    if (DeviceExtension->CurrentLogEntry >=
 | 
						|
        DeviceExtension->Log + DeviceExtension->LogSize) {
 | 
						|
        UsbVerify_ResizeLog(DeviceExtension, DeviceExtension->LogSize * 2);
 | 
						|
    }
 | 
						|
 | 
						|
    if (DeviceExtension->CurrentLogEntry) {
 | 
						|
        KeQueryTickCount(&LogEntry->CurrentTick);
 | 
						|
        *DeviceExtension->CurrentLogEntry = *LogEntry;
 | 
						|
        DeviceExtension->CurrentLogEntry++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
UsbVerify_LogError(
 | 
						|
    ULONG StringIndex,
 | 
						|
    PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension,
 | 
						|
    PIRP Irp,
 | 
						|
    PURB Urb
 | 
						|
    )
 | 
						|
{
 | 
						|
    //
 | 
						|
    // NOTE: figure out the semantics of logging the error.  
 | 
						|
    //
 | 
						|
    // do we want to select (via a flag) what are actions are?  ie, record the
 | 
						|
    //  error, dump it to the debugger, etc etc
 | 
						|
    //
 | 
						|
 | 
						|
    //
 | 
						|
    // For right now, dump it to the debugger
 | 
						|
    //
 | 
						|
    UsbVerify_Assert(ErrorStrings[StringIndex],
 | 
						|
                     DeviceExtension->Self,
 | 
						|
                     Irp,
 | 
						|
                     Urb,
 | 
						|
                     NULL);
 | 
						|
}
 | 
						|
 | 
						|
VOID 
 | 
						|
UsbVerify_InitLog (
 | 
						|
    PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension
 | 
						|
    )
 | 
						|
{
 | 
						|
    NTSTATUS    status;
 | 
						|
    HANDLE      hKey, hParameters;
 | 
						|
    ULONG       logSize;
 | 
						|
 | 
						|
    logSize = LOG_SIZE_DEFAULT;
 | 
						|
 | 
						|
    hParameters = UsbVerify_OpenServiceParameters(DeviceExtension);
 | 
						|
    if (hParameters != NULL) {
 | 
						|
        UsbVerify_QueryKey(hParameters,
 | 
						|
                           USB_VERIFY_LOGSIZE_SZ,
 | 
						|
                           &logSize,
 | 
						|
                           sizeof(logSize));
 | 
						|
 | 
						|
        ZwClose(hParameters);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Devnode value has higher precedence over the services\parameters value
 | 
						|
    // so query this after
 | 
						|
    //
 | 
						|
    status = IoOpenDeviceRegistryKey(DeviceExtension->PDO,
 | 
						|
                                     PLUGPLAY_REGKEY_DEVICE, 
 | 
						|
                                     STANDARD_RIGHTS_READ,
 | 
						|
                                     &hKey);
 | 
						|
 | 
						|
    if (NT_SUCCESS(status)) {
 | 
						|
        UsbVerify_QueryKey(hKey,
 | 
						|
                           USB_VERIFY_LOGSIZE_SZ,
 | 
						|
                           &logSize,
 | 
						|
                           sizeof(logSize));
 | 
						|
                           
 | 
						|
        ZwClose(hKey);
 | 
						|
    }
 | 
						|
 | 
						|
    UsbVerify_ResizeLog(DeviceExtension, logSize);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
UsbVerify_DestroyLog(
 | 
						|
    PUSB_VERIFY_DEVICE_EXTENSION DeviceExtension
 | 
						|
    )
 | 
						|
{
 | 
						|
    PAGED_CODE();
 | 
						|
 | 
						|
    if (DeviceExtension->Log) {
 | 
						|
        ExFreePool(DeviceExtension->Log);
 | 
						|
        DeviceExtension->Log = NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
UCHAR ShutUp = 0x0;
 | 
						|
ULONG GlobalAssertState = 0x0;
 | 
						|
 | 
						|
ULONG
 | 
						|
DbgPrompt(
 | 
						|
    IN PCHAR Prompt,
 | 
						|
    OUT PCHAR Response,
 | 
						|
    IN ULONG MaximumResponseLength
 | 
						|
    );
 | 
						|
 | 
						|
VOID
 | 
						|
UsbVerify_Assert(
 | 
						|
    PCHAR Msg,
 | 
						|
    PDEVICE_OBJECT DeviceObject,
 | 
						|
    PIRP  Irp,
 | 
						|
    PURB  Urb,
 | 
						|
    PULONG AssertState
 | 
						|
    )
 | 
						|
{
 | 
						|
    ULONG                           state = 0x0;
 | 
						|
    BOOLEAN                         done, validResponse;
 | 
						|
    CHAR                            response[2];
 | 
						|
    PUSB_VERIFY_DEVICE_EXTENSION    devExt;
 | 
						|
 | 
						|
    if (AssertState != NULL) {
 | 
						|
        state = *AssertState;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Check to see if the assert has been disabled or all asserts have been
 | 
						|
    // disabled
 | 
						|
    //
 | 
						|
    if ((state & ASSERT_REMOVED) !=  0 || 
 | 
						|
        (GlobalAssertState & ASSERT_REMOVED) != 0) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    done = FALSE;
 | 
						|
    while (done == FALSE) {
 | 
						|
 | 
						|
        if (ShutUp == 0) {
 | 
						|
            // BEEP!
 | 
						|
            DbgPrint("%c", 7);
 | 
						|
        }
 | 
						|
    
 | 
						|
        DbgPrint("\nASSERTION ""%s"" failed\n", Msg);
 | 
						|
    
 | 
						|
        if (ARGUMENT_PRESENT(DeviceObject)) 
 | 
						|
        {
 | 
						|
            //
 | 
						|
            // Display the device object, device extension, 
 | 
						|
            //  top of stack device object and physical device object.
 | 
						|
            //
 | 
						|
 | 
						|
            devExt = 
 | 
						|
                (PUSB_VERIFY_DEVICE_EXTENSION) DeviceObject -> DeviceExtension;
 | 
						|
 | 
						|
            DbgPrint("\t!DevObj 0x%x DevExt 0x%x\n",
 | 
						|
                     DeviceObject, devExt);
 | 
						|
 | 
						|
            DbgPrint("\t!DevObj 0x%x --> TopOfStackObject\n",
 | 
						|
                     devExt -> TopOfStack);
 | 
						|
 | 
						|
            DbgPrint("\t!DevObj 0x%x --> PhysicalDeviceObject\n",
 | 
						|
                     devExt -> PDO);
 | 
						|
        }
 | 
						|
 | 
						|
        if (ARGUMENT_PRESENT(Irp)) {
 | 
						|
            DbgPrint("\t!Irp 0x%x\n", Irp);
 | 
						|
        }
 | 
						|
    
 | 
						|
        if (ARGUMENT_PRESENT(Urb)) {
 | 
						|
            DbgPrint("\t!Urb 0x%x\n", Urb);
 | 
						|
        }
 | 
						|
 | 
						|
        if (state & ASSERT_AS_WARNING) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
#if WIN95_BUILD
 | 
						|
        if (AssertState) {
 | 
						|
            DbgPrint("e %x to change assert\n", AssertState);
 | 
						|
            DbgPrint("set 0x01 to convert into a warning\n"
 | 
						|
                     "set 0x10 to remove the assert\n");
 | 
						|
        }
 | 
						|
        DbgPrint("\nset %x to 1 to disable ALL asserts\n", &GlobalAssertState);
 | 
						|
        DbgBreakPoint();
 | 
						|
 | 
						|
        done = TRUE;
 | 
						|
#else
 | 
						|
 | 
						|
        //
 | 
						|
        // Wait for input...
 | 
						|
        //
 | 
						|
        validResponse = FALSE;
 | 
						|
        while (validResponse == FALSE) {
 | 
						|
 | 
						|
            done = TRUE;
 | 
						|
 | 
						|
            if (ARGUMENT_PRESENT(AssertState)) {
 | 
						|
                DbgPrompt( "Break, Ignore, convert to Warning, Remove, Disable all (biwrd)? ", response, sizeof( response ));
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                DbgPrompt( "Break, Ignore (bi)? ", response, sizeof( response ));
 | 
						|
            }
 | 
						|
    
 | 
						|
            switch (response[0]) {
 | 
						|
    
 | 
						|
            case 'B':
 | 
						|
            case 'b':
 | 
						|
                DbgPrint("Breaking in... (press g<enter> to return to assert menu)\n");
 | 
						|
                DbgBreakPoint();
 | 
						|
                validResponse = TRUE;
 | 
						|
                done = FALSE;
 | 
						|
                break;
 | 
						|
    
 | 
						|
            case 'I':
 | 
						|
            case 'i':
 | 
						|
                validResponse = TRUE;
 | 
						|
                break;
 | 
						|
    
 | 
						|
            case 'W':
 | 
						|
            case 'w':
 | 
						|
                if (ARGUMENT_PRESENT(AssertState)) {
 | 
						|
                   DbgPrint("Assert is now a warning (OS will print text, beep, and return)\n");
 | 
						|
                   state |= ASSERT_AS_WARNING;
 | 
						|
                   validResponse = TRUE;
 | 
						|
                }
 | 
						|
                break;
 | 
						|
 | 
						|
            case 'R':
 | 
						|
            case 'r':
 | 
						|
                if (ARGUMENT_PRESENT(AssertState)) {
 | 
						|
                   DbgPrint("Breakpoint removed\n") ;
 | 
						|
                   state |= ASSERT_REMOVED;
 | 
						|
                   validResponse = TRUE;
 | 
						|
                }
 | 
						|
                break;
 | 
						|
    
 | 
						|
            case 'D':
 | 
						|
            case 'd':
 | 
						|
                GlobalAssertState |= ASSERT_REMOVED;
 | 
						|
                DbgPrint("USB Verification asserts disabled.\n");
 | 
						|
                validResponse = TRUE;
 | 
						|
                break;
 | 
						|
    
 | 
						|
            }
 | 
						|
        }
 | 
						|
#endif
 | 
						|
    }
 | 
						|
 | 
						|
#if WIN95_BUILD
 | 
						|
#else
 | 
						|
    DbgPrint("\n");
 | 
						|
 | 
						|
    if (AssertState) {
 | 
						|
        *AssertState = state;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
UsbVerify_Warning(
 | 
						|
    PCHAR Msg,
 | 
						|
    PDEVICE_OBJECT DeviceObject,
 | 
						|
    PIRP  Irp,
 | 
						|
    PURB  Urb,
 | 
						|
    PULONG WarningState
 | 
						|
    )
 | 
						|
{
 | 
						|
    PUSB_VERIFY_DEVICE_EXTENSION devExt = GetExtension(DeviceObject);
 | 
						|
 | 
						|
    if (devExt->TreatWarningsAsErrors) {
 | 
						|
        UsbVerify_Assert(Msg, DeviceObject, Irp, Urb, WarningState);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (ShutUp == 0) {
 | 
						|
        // BEEP!
 | 
						|
        DbgPrint("%c", 7);
 | 
						|
    }
 | 
						|
 | 
						|
    DbgPrint("WARNING %s failed\n", Msg);
 | 
						|
 | 
						|
    if (ARGUMENT_PRESENT(DeviceObject)) {
 | 
						|
        //
 | 
						|
        // NOTE: we should get the PDO / top of the stack for this DO and print
 | 
						|
        //         it as well
 | 
						|
        //
 | 
						|
        DbgPrint("\tDeviceObject = 0x%x, DevExt 0x%x\n", DeviceObject, devExt);
 | 
						|
    }
 | 
						|
 | 
						|
    if (ARGUMENT_PRESENT(Irp)) {
 | 
						|
        DbgPrint("\tIrp = 0x%x\n", Irp);
 | 
						|
    }
 | 
						|
 | 
						|
    if (ARGUMENT_PRESENT(Urb)) {
 | 
						|
        DbgPrint("\tUrb = 0x%x\n", Urb);
 | 
						|
    }
 | 
						|
}
 |