驱动层,创建设备对象,实现读写函数:
#include <ntddk.h>
NTSTATUS Unload(PDRIVER_OBJECT driver)
{
DbgPrint("unload driver");
return STATUS_SUCCESS;
}
NTSTATUS CompleteIrp(PIRP Irp, NTSTATUS status = STATUS_SUCCESS, ULONG_PTR info = 0)
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, 0);
return status;
}
NTSTATUS ZeroRead(PDEVICE_OBJECT, PIRP Irp) {
auto stack = IoGetCurrentIrpStackLocation(Irp);
auto len = stack->Parameters.Read.Length;
if (len == 0)
return CompleteIrp(Irp, STATUS_INVALID_BUFFER_SIZE);
auto buffer = MmGetSystemAddressForMdl(Irp->MdlAddress, NormalPagePriority);
if (!buffer){
return CompleteIrp(Irp, STATUS_INSUFFICIENT_RESOURCES);
}
memset(buffer, 0, len);
return CompleteIrp(Irp, STATUS_SUCCESS, len);
}
NTSTATUS ZeroWrite(PDEVICE_OBJECT, PIRP Irp) {
auto stack = IoGetCurrentIrpStackLocation(Irp);
auto len = stack->Parameters.Write.Length;
return CompleteIrp(Irp, STATUS_SUCCESS, len);
}
NTSTATUS CreateClose(PDEVICE_OBJECT, PIRP Irp) {
return CompleteIrp(Irp);
}
extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING RegPath)
{
DbgPrint("Driver Entry");
driver->DriverUnload = (PDRIVER_UNLOAD)Unload;
driver->MajorFunction[IRP_MJ_CREATE] = CreateClose;
driver->MajorFunction[IRP_MJ_READ] = ZeroRead;
driver->MajorFunction[IRP_MJ_WRITE] = ZeroWrite;
driver->MajorFunction[IRP_MJ_CLOSE] = CreateClose;
UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\Zero");
UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\Zero");
PDEVICE_OBJECT DeviceObject = nullptr;
auto status = STATUS_SUCCESS;
do{
status = IoCreateDevice(driver, 0, &devName, FILE_DEVICE_UNKNOWN, 0, false, &DeviceObject);
if (!NT_SUCCESS(status)){
DbgPrint("CreateDevice Failed");
break;
}
DeviceObject->Flags |= DO_DIRECT_IO;
IoCreateSymbolicLink(&symLink, &devName);
if (!NT_SUCCESS(status)){
DbgPrint("CreateSymLink Failed");
IoDeleteDevice(DeviceObject);
break;
}
} while (FALSE);
return status;
}
应用层打开设备对象,并使用ReadFile读数据:
#include <windows.h>
#include <iostream>
int Error(const char* msg) {
printf("%s: error=%d\n", msg, ::GetLastError());
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = CreateFile(L"\\\\.\\Zero", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
if (hFile == INVALID_HANDLE_VALUE){
printf("OpenDevice Failed");
return -1;
}
BYTE buffer[64];
DWORD bytes;
// store some non-zero data
for (int i = 0; i < sizeof(buffer); ++i)
buffer[i] = i + 1;
bool ok = ReadFile(hFile, buffer, 64, &bytes, nullptr);
if (!ok){
Error("ReadFailed");
}
long total = 0;
for (auto i : buffer){
total += i;
}
if (total != 0){
printf("Wrong Read");
}
else{
printf("ReadOK");
}
CloseHandle(hFile);
return 0;
}