#include <wdm.h>
#include <ntddk.h>
#include <Wdmsec.h>
#define MY_GUID L"a952eebb-84fc-4bd3-9708-3a8dc94f0c2c" //这段guid在实际使用中请自行调用CoCreateCuid生成
#define MY_CDO_NAME L"\\Device\\my_test_name"
#define MY_SYB_NAME L"\\??\\my_test_sybname123"
#define MEM_TAG 'MyTt'
char
* DeviceBuffer = NULL;
int
Length = -1;
NTSTATUS DispatchWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
PDEVICE_OBJECT my_cdo = NULL;
VOID
DriverUnload(PDRIVER_OBJECT driver)
{
DbgPrint(
"first:our driver is unloading..r\n"
);
UNICODE_STRING my_syb_name = RTL_CONSTANT_STRING(MY_SYB_NAME);
IoDeleteSymbolicLink(&my_syb_name);
if
(DeviceBuffer)
{
ExFreePoolWithTag(DeviceBuffer, MEM_TAG);
}
if
(my_cdo)
{
IoDeleteDevice(driver->DeviceObject);
}
}
NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
PVOID
buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG
length = irpSp->Parameters.Read.Length;
if
(DeviceBuffer == NULL || Length == -1)
{
DbgPrint(
"Device buffer is uninitialized!"
);
Irp->IoStatus.Status = STATUS_NO_DATA_DETECTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_NO_DATA_DETECTED;
}
if
(length == 0)
{
DbgPrint(
"Invalid read length!"
);
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_INVALID_PARAMETER;
}
RtlCopyMemory(buffer, DeviceBuffer, Length);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_SUCCESS;
}
NTSTATUS DispatchWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
PVOID
buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG
length = irpSp->Parameters.Write.Length;
if
(DeviceBuffer == NULL || length == -1)
{
DbgBreakPoint();
DeviceBuffer = (
char
*)ExAllocatePoolWithTag(NonPagedPool, length, MEM_TAG);
Length = length;
}
else
if
(length > 0x10)
{
DbgPrint(
"buffer too big"
);
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_INVALID_PARAMETER;
}
if
(DeviceBuffer != NULL)
{
RtlCopyMemory(DeviceBuffer, buffer, length);
Length = length;
DbgPrint(
"all right"
);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = length;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_SUCCESS;
}
else
{
DbgPrint(
"Memory allocation failed!\n"
);
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_INSUFFICIENT_RESOURCES;
}
}
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return
STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
UNREFERENCED_PARAMETER(reg_path);
NTSTATUS status;
UNICODE_STRING my_cdo_name = RTL_CONSTANT_STRING(MY_CDO_NAME);
UNICODE_STRING my_sddl = RTL_CONSTANT_STRING(L
"D:P(A;;GA;;;WD)"
);
status = IoCreateDeviceSecure(
driver,
0, &my_cdo_name,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
TRUE, &my_sddl,
(LPCGUID)&MY_GUID,
&my_cdo
);
if
(!NT_SUCCESS(status))
{
DbgPrint(
"IoCreateDeviceSecure error"
);
return
status;
}
my_cdo->Flags |= DO_BUFFERED_IO;
my_cdo->Flags &= ~DO_DEVICE_INITIALIZING;
UNICODE_STRING my_syb_name = RTL_CONSTANT_STRING(MY_SYB_NAME);
status = IoCreateSymbolicLink(
&my_syb_name,
&my_cdo_name
);
if
(!NT_SUCCESS(status))
{
DbgPrint(
"IoCreateSymbolicLink error"
);
IoDeleteDevice(driver->DeviceObject);
return
status;
}
driver->DriverUnload = DriverUnload;
driver->MajorFunction[IRP_MJ_READ] = DispatchRead;
driver->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
driver->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
driver->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
return
STATUS_SUCCESS;
}