304 lines
5.7 KiB
C
304 lines
5.7 KiB
C
/*++
|
||
|
||
Copyright (c) 2000 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
kdlog.c
|
||
|
||
Abstract:
|
||
|
||
Kernel Debugger logging
|
||
|
||
Author:
|
||
|
||
Neil Sandlin
|
||
|
||
Environment:
|
||
|
||
Notes:
|
||
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "stdarg.h"
|
||
#include "stdio.h"
|
||
#define _NTDDK_
|
||
#include "ntos.h" // *** USES INTERNAL DEFINES ***
|
||
#include "hal.h"
|
||
#include "kdlog.h"
|
||
#include "kdlogctl.h"
|
||
|
||
|
||
|
||
|
||
NTSTATUS
|
||
DriverEntry(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath
|
||
);
|
||
|
||
NTSTATUS
|
||
KdlogDeviceControl(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
KdlogOpen(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
KdlogClose(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
VOID
|
||
KdlogUnload (
|
||
IN PDRIVER_OBJECT DriverObject
|
||
);
|
||
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(INIT,DriverEntry)
|
||
#pragma alloc_text(PAGE,KdlogDeviceControl)
|
||
#pragma alloc_text(PAGE,KdlogOpen)
|
||
#pragma alloc_text(PAGE,KdlogClose)
|
||
#pragma alloc_text(PAGE,KdlogUnload)
|
||
#endif
|
||
|
||
|
||
NTSTATUS
|
||
DriverEntry(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine initializes the stat driver.
|
||
|
||
Arguments:
|
||
|
||
DriverObject - Pointer to driver object created by system.
|
||
|
||
RegistryPath - Pointer to the Unicode name of the registry path
|
||
for this driver.
|
||
|
||
Return Value:
|
||
|
||
The function value is the final status from the initialization operation.
|
||
|
||
--*/
|
||
|
||
{
|
||
UNICODE_STRING unicodeString;
|
||
PDEVICE_OBJECT deviceObject;
|
||
NTSTATUS status;
|
||
ULONG i;
|
||
|
||
KdPrint(( "KDLOG: DriverEntry()\n" ));
|
||
|
||
//
|
||
// Create non-exclusive device object
|
||
//
|
||
|
||
RtlInitUnicodeString(&unicodeString, L"\\Device\\KdLog");
|
||
|
||
status = IoCreateDevice(
|
||
DriverObject,
|
||
0,
|
||
&unicodeString,
|
||
FILE_DEVICE_UNKNOWN, // DeviceType
|
||
0,
|
||
FALSE,
|
||
&deviceObject
|
||
);
|
||
|
||
if (status != STATUS_SUCCESS) {
|
||
KdPrint(( "Kdlog - DriverEntry: unable to create device object: %X\n", status ));
|
||
return(status);
|
||
}
|
||
|
||
deviceObject->Flags |= DO_BUFFERED_IO;
|
||
|
||
//
|
||
// Set up the device driver entry points.
|
||
//
|
||
|
||
DriverObject->MajorFunction[IRP_MJ_CREATE] = KdlogOpen;
|
||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KdlogClose;
|
||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KdlogDeviceControl;
|
||
DriverObject->DriverUnload = KdlogUnload;
|
||
|
||
return(STATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
KdlogDeviceControl(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the dispatch routine for device control requests.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to class device object.
|
||
|
||
Irp - Pointer to the request packet.
|
||
|
||
Return Value:
|
||
|
||
Kdlogus is returned.
|
||
|
||
--*/
|
||
|
||
{
|
||
PIO_STACK_LOCATION irpSp;
|
||
NTSTATUS status;
|
||
ULONG BufferLength;
|
||
PULONG Buffer;
|
||
PKD_DBG_LOG_CONTEXT pContext;
|
||
ULONG DataLength;
|
||
|
||
PAGED_CODE();
|
||
//
|
||
// Get a pointer to the current parameters for this request. The
|
||
// information is contained in the current stack location.
|
||
//
|
||
|
||
irpSp = IoGetCurrentIrpStackLocation(Irp);
|
||
|
||
//
|
||
// Case on the device control subfunction that is being performed by the
|
||
// requestor.
|
||
//
|
||
|
||
status = STATUS_SUCCESS;
|
||
try {
|
||
|
||
Buffer = (PULONG) irpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
||
BufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||
|
||
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
|
||
|
||
case KDLOG_QUERY_LOG_CONTEXT:
|
||
if (BufferLength < sizeof(KD_DBG_LOG_CONTEXT)) {
|
||
status = STATUS_BUFFER_TOO_SMALL;
|
||
break;
|
||
}
|
||
|
||
status = KdGetDebuggerLogContext(&pContext);
|
||
|
||
if (NT_SUCCESS(status)) {
|
||
RtlCopyMemory(Buffer, pContext, sizeof(KD_DBG_LOG_CONTEXT));
|
||
}
|
||
break;
|
||
|
||
case KDLOG_GET_LOG_DATA:
|
||
|
||
status = KdGetDebuggerLogContext(&pContext);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
break;
|
||
}
|
||
|
||
DataLength = pContext->EntryLength * (pContext->LastIndex + 1);
|
||
|
||
if (BufferLength < DataLength) {
|
||
status = STATUS_BUFFER_TOO_SMALL;
|
||
break;
|
||
}
|
||
|
||
RtlCopyMemory(Buffer, pContext->LogData, DataLength);
|
||
break;
|
||
|
||
default:
|
||
status = STATUS_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
} except(EXCEPTION_EXECUTE_HANDLER) {
|
||
status = GetExceptionCode();
|
||
}
|
||
|
||
|
||
//
|
||
// Request is done...
|
||
//
|
||
|
||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||
return(status);
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
KdlogOpen(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
)
|
||
{
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Complete the request and return status.
|
||
//
|
||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||
Irp->IoStatus.Information = 0;
|
||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||
return(STATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
KdlogClose(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
)
|
||
{
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Complete the request and return status.
|
||
//
|
||
|
||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||
Irp->IoStatus.Information = 0;
|
||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||
return(STATUS_SUCCESS);
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
KdlogUnload (
|
||
IN PDRIVER_OBJECT DriverObject
|
||
)
|
||
|
||
{
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// Delete the device object.
|
||
//
|
||
IoDeleteDevice(DriverObject->DeviceObject);
|
||
return;
|
||
}
|
||
|