驱动和应用层通信列子


驱动层,创建设备对象,实现读写函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 #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读数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#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;
}