#include <ntddk.h>
#define CTLBUFFERED CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define CTLDIRECTIN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define CTLDIRECTOUT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
typedef struct _DevExt
{
ULONG Flags;
}DevExt, *PDevExt;
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS DispatchGeneric(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DispatchIoDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\IoDeviceControl");
UNICODE_STRING DeviceSymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\IoDeviceControl");
PDEVICE_OBJECT DeviceObject = NULL;
ULONG sub = 0;
UNREFERENCED_PARAMETER(RegistryPath);
KdPrint(("驱动加载\n"));
for (sub = 0; sub <= IRP_MJ_MAXIMUM_FUNCTION; sub++)
{
DriverObject->MajorFunction[sub] = DispatchGeneric;
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoDeviceControl;
status = IoCreateDevice(DriverObject, sizeof(DevExt), &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
if (!NT_SUCCESS(status))
{
KdPrint(("创建设备失败:%x\n", status));
return status;
}
status = IoCreateSymbolicLink(&DeviceSymbolicLinkName, &DeviceName);
if (!NT_SUCCESS(status))
{
KdPrint(("创建符号链接失败:%x", status));
IoDeleteDevice(DeviceObject);
DeviceObject = NULL;
return status;
}
DeviceObject->Flags |= DO_BUFFERED_IO;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
DriverObject->DriverUnload = DriverUnload;
return status;
}
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING DeviceSymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\IoDeviceControl");
UNREFERENCED_PARAMETER(DriverObject);
KdPrint(("驱动卸载\n"));
if (DriverObject->DeviceObject != NULL)
{
IoDeleteSymbolicLink(&DeviceSymbolicLinkName);
IoDeleteDevice(DriverObject->DeviceObject);
}
}
NTSTATUS DispatchGeneric(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DispatchIoDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
PDevExt devExt = (PDevExt)DeviceObject->DeviceExtension;
ULONG IoCode = stack->Parameters.DeviceIoControl.IoControlCode;
ULONG InputLength = 0;
ULONG OutputLength = 0;
PVOID InputBuffer = NULL;
PVOID OutputBuffer = NULL;
ULONG ReturnLength = 0;
__try
{
devExt->Flags = 0;
switch (IoCode)
{
case CTLBUFFERED:
{
InputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputLength = stack->Parameters.DeviceIoControl.InputBufferLength;
OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
OutputLength = stack->Parameters.DeviceIoControl.OutputBufferLength;
KdPrint(("***********************************************\n"));
KdPrint(("Input Data:%s\nOutput Data:%s\n", InputBuffer, OutputBuffer));
KdPrint(("Input Address:%x\nInput Length:%d\nOutput Address:%x\nOutput Length:%d\n", InputBuffer, InputLength, OutputBuffer, OutputLength));
RtlCopyMemory(OutputBuffer, "这是IO缓冲区方式", strlen("这是IO缓冲区方式"));
ReturnLength = (ULONG)strlen("这是IO缓冲区方式");
}
break;
case CTLDIRECTIN:
{
InputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputLength = stack->Parameters.DeviceIoControl.InputBufferLength;
OutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
OutputLength = stack->Parameters.DeviceIoControl.OutputBufferLength;
KdPrint(("***********************************************\n"));
KdPrint(("Input Data:%s\nOutput Data:%s\n", InputBuffer, OutputBuffer));
KdPrint(("Input Address:%x\nInput Length:%d\nOutput Address:%x\nOutput Length:%d\n", InputBuffer, InputLength, OutputBuffer, OutputLength));
ReturnLength = 0;
}
break;
case CTLDIRECTOUT:
{
InputBuffer = Irp->AssociatedIrp.SystemBuffer;
InputLength = stack->Parameters.DeviceIoControl.InputBufferLength;
OutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
OutputLength = stack->Parameters.DeviceIoControl.OutputBufferLength;
KdPrint(("***********************************************\n"));
KdPrint(("Input Data:%s\nOutput Data:%s\n", InputBuffer, OutputBuffer));
KdPrint(("Input Address:%x\nInput Length:%d\nOutput Address:%x\nOutput Length:%d\n", InputBuffer, InputLength, OutputBuffer, OutputLength));
RtlCopyMemory(OutputBuffer, "这是直接访问方式", strlen("这是直接访问方式"));
ReturnLength = (ULONG)strlen("这是直接访问方式");
}
break;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
ReturnLength = 0;
}
Irp->IoStatus.Information = ReturnLength;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
#include <Windows.h>
#include <stdio.h>
#include <winioctl.h>
#define IOBUFTEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IODIRECTIN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IODIRECTOUT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0800, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
int main(int argc, char* argv[])
{
HANDLE hDevice = CreateFile(L"\\\\.\\IoDeviceControl", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("设备打开失败:%d\n", GetLastError());
getchar();
return -1;
}
CHAR buf[1024] = { 0 };
DWORD dwRet = 0;
DeviceIoControl(hDevice, IOBUFTEST, (LPVOID)"这是用户缓冲区方式", (DWORD)strlen("这是用户缓冲区方式") + 1, buf, 1024, &dwRet, NULL);
printf("%s\n", buf);
DeviceIoControl(hDevice, IODIRECTIN, (LPVOID)"这是用户缓冲区方式", (DWORD)strlen("这是用户缓冲区方式") + 1, NULL, 0, &dwRet, NULL);
DeviceIoControl(hDevice, IODIRECTOUT, NULL, 0, buf, 1024, &dwRet, NULL);
printf("%s\n", buf);
CloseHandle(hDevice);
getchar();
return 0;
}