#include <ntddk.h>
#include <stdio.h>
#if DBG
#define dprintf DbgPrint
#else
#define dprintf
#endif
#define kprintf DbgPrint
#define NT_DEVICE_NAME L"//Device//GDTDump"
#define DOS_DEVICE_NAME L"//DosDevices//GDTDump"
#define MAKELONG(a,b) ((unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned short) (b))) << 16))
#include "GDTDump.h"
NTSTATUS
GdtdumpDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GdtdumpDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
GdtdumpDispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
GdtdumpUnload(
IN PDRIVER_OBJECT DriverObject
);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING ntDeviceName, dosDeviceName;
PDEVICE_EXTENSION DeviceExtension;
BOOLEAN fSymbolicLink = FALSE;
dprintf("[GDTDump] DriverEntry: %S/n", RegistryPath->Buffer);
//
// A real driver would:
//
// 1. Report it's resources (IoReportResourceUsage)
//
// 2. Attempt to locate the device(s) it supports
//
// OK, we've claimed our resources & found our h/w, so create
// a device and initialize stuff...
//
RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
//
// Create an EXCLUSIVE device, i.e. only 1 thread at a time can send
// i/o requests.
//
ntStatus = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION), // DeviceExtensionSize
&ntDeviceName, // DeviceName
FILE_DEVICE_GDTDUMP, // DeviceType
0, // DeviceCharacteristics
TRUE, // Exclusive
&DeviceObject // [OUT]
);
if (!NT_SUCCESS(ntStatus))
{
dprintf("[GDTDump] IoCreateDevice=0x%x/n", ntStatus);
goto __failed;
}
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
//
// Set up synchronization objects, state info,, etc.
//
//
// Create a symbolic link that Win32 apps can specify to gain access
// to this driver/device
//
RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);
ntStatus = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
if (!NT_SUCCESS(ntStatus))
{
dprintf("[GDTDump] IoCreateSymbolicLink=0x%x/n", ntStatus);
goto __failed;
}
fSymbolicLink = TRUE;
//
// Create dispatch points for device control, create, close.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = GdtdumpDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = GdtdumpDispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GdtdumpDispatchDeviceControl;
DriverObject->DriverUnload = GdtdumpUnload;
if (!NT_SUCCESS(ntStatus))
goto __failed;
return ntStatus;
__failed:
if (fSymbolicLink)
IoDeleteSymbolicLink(&dosDeviceName);
if (DeviceObject)
IoDeleteDevice(DeviceObject);
return ntStatus;
}
NTSTATUS
GdtdumpDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
dprintf("[GDTDump] IRP_MJ_CREATE/n");
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
NTSTATUS
GdtdumpDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
dprintf("[GDTDump] IRP_MJ_CLOSE/n");
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;
}
NTSTATUS
GdtdumpDispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
PVOID lpInOutBuffer;
ULONG nInBufferSize, nOutBufferSize, dwIoControlCode;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get the pointer to the input/output buffer and it's length
//
lpInOutBuffer = Irp->AssociatedIrp.SystemBuffer;
nInBufferSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
nOutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
dprintf("[GDTDump] IRP_MJ_DEVICE_CONTROL/n");
dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
switch (dwIoControlCode)
{
case IOCTL_GDTDUMP_HELLO:
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
unsigned long count;
_asm sidt idt_info
idt_entries=(IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
for(count=0;count<= 256;count++)
{
char _t[255];
IDTENTRY * i=&idt_entries[count];
unsigned long addr=0;
addr=MAKELONG(i->LowOffset,i->HiOffset);
_snprintf(_t,253,"Interrup %d:ISR 0x%80x",count,addr);
DbgPrint(_t);
}
//
// Some app is saying hello
//
break;
}
default:
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
dprintf("[GDTDump] unknown IRP_MJ_DEVICE_CONTROL/n");
break;
}
//
// DON'T get cute and try to use the status field of
// the irp in the return status. That IRP IS GONE as
// soon as you call IoCompleteRequest.
//
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// We never have pending operation so always return the status code.
//
return ntStatus;
}
VOID
GdtdumpUnload(
IN PDRIVER_OBJECT DriverObject
)
{
UNICODE_STRING dosDeviceName;
//
// Free any resources
//
//
// Delete the symbolic link
//
RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&dosDeviceName);
//
// Delete the device object
//
IoDeleteDevice(DriverObject->DeviceObject);
dprintf("[GDTDump] unloaded/n");
}