#include "ntddk.h"
#define DEVICE_SEND CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_WRITE_DATA)
#define DEVICE_REC CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_READ_DATA)
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\drv_call_wdm");
UNICODE_STRING SymLinkName = RTL_CONSTANT_STRING(L"\\??\\drv_call_wdm_link");
// UNICODE_STRING SymLinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\drv_call_wdm_link");
PDEVICE_OBJECT DeviceObject = NULL;
VOID Unload(IN PDRIVER_OBJECT DriverObject) {
IoDeleteSymbolicLink(&SymLinkName);
IoDeleteDevice(DeviceObject);
DbgPrint("Driver unload\r\n");
}
NTSTATUS DispatchPassThru(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
switch (irpsp->MajorFunction) {
case IRP_MJ_CREATE:
DbgPrint("Create request\r\n");
/*KdPrint(("Create request\r\n"));*/
break;
case IRP_MJ_CLOSE:
DbgPrint("Close request\r\n");
/*KdPrint(("Close request\r\n"));*/
break;
//case IRP_MJ_READ:
// DbgPrint("Read request\r\n");
// KdPrint(("Read request\r\n"));
// break;
default:
status = STATUS_INVALID_PARAMETER;
break;
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DispathDevCTL(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
ULONG returnLength = 0;
PVOID buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG inLength = irpsp->Parameters.DeviceIoControl.InputBufferLength;
ULONG outLength = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
WCHAR *demo = L"sample return from driver";
switch (irpsp->Parameters.DeviceIoControl.IoControlCode) {
case DEVICE_SEND:
DbgPrint("Send data is %ws \r\n", buffer);
returnLength = (wcsnlen(buffer, 511) + 1) * 2;
break;
case DEVICE_REC:
wcsncpy(buffer, demo, 511);
returnLength = (wcsnlen(buffer, 511) + 1) * 2;
DbgPrint("receive data is %ws \r\n", buffer);
break;
default:
status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = returnLength;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) // main
{
DriverObject->DriverUnload = Unload;
UNICODE_STRING string = RTL_CONSTANT_STRING(L"hello driver\r\n");
DbgPrint("%wZ", &string); // printf()
NTSTATUS status = IoCreateDevice(DriverObject, 0, &DeviceName,
FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN,
FALSE, &DeviceObject);
if (!NT_SUCCESS(status)) {
DbgPrint("Create device failed\r\n");
return status;
}
status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
if (!NT_SUCCESS(status)) {
DbgPrint("create symbolic link failed\r\n");
IoDeleteDevice(DeviceObject);
return status;
}
for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i) {
DriverObject->MajorFunction[i] = DispatchPassThru;
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispathDevCTL;
DbgPrint("Driver load\r\n");
return STATUS_SUCCESS;
}