• 内核层和用户层通讯的三种方式


    内核层

    #include <ntddk.h>

    #define CTRL_CODE1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
    #define CTRL_CODE2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
    #define CTRL_CODE3 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_NEITHER, FILE_ANY_ACCESS)

    // 创建一个设备对象
    NTSTATUS CreateDevice(PDRIVER_OBJECT DriverObject, PUNICODE_STRING DeviceName, PUNICODE_STRING SymbolName, UINT32 DO)
    {
    PDEVICE_OBJECT DeviceObject = NULL;

    // 1. 创建一个设备对象
    NTSTATUS Status = IoCreateDevice(DriverObject, 0, DeviceName,
    FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);

    if (NT_SUCCESS(Status))
    {
    // 2. 添加符号链接名
    Status = IoCreateSymbolicLink(SymbolName, DeviceName);

    // 3. 设置设备的通讯方式
    DeviceObject->Flags |= DO;
    }

    // 4. 设置返回值
    return Status;
    }

    NTSTATUS DefaultProc(struct _DEVICE_OBJECT *DeviceObject, struct _IRP *Irp)
    {
    UNREFERENCED_PARAMETER(DeviceObject);

    // 1. 设置处理的字节数量
    Irp->IoStatus.Information = 0;
    // 2. 设置状态
    Irp->IoStatus.Status = STATUS_SUCCESS;
    // 3. 表示已完成所有IRP处理
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    // 4. 设置返回值
    return STATUS_SUCCESS;
    }

    NTSTATUS CreateProc(struct _DEVICE_OBJECT *DeviceObject, struct _IRP *Irp)
    {
    UNREFERENCED_PARAMETER(DeviceObject);

    // 1. 设置处理的字节数量
    Irp->IoStatus.Information = 0;
    // 2. 设置状态
    Irp->IoStatus.Status = STATUS_SUCCESS;
    // 3. 表示已完成所有IRP处理
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    // 4. 设置返回值
    return Irp->IoStatus.Status;
    }

    NTSTATUS WriteProc(struct _DEVICE_OBJECT *DeviceObject, struct _IRP *Irp)
    {
    UNREFERENCED_PARAMETER(DeviceObject);

    PIO_STACK_LOCATION pstack = IoGetCurrentIrpStackLocation(Irp);
    ULONG WriteSize = pstack->Parameters.Write.Length;

    char *Buffer = NULL;
    // 判断读写方式
    if (Irp->AssociatedIrp.SystemBuffer)
    Buffer = Irp->AssociatedIrp.SystemBuffer;
    else if (Irp->MdlAddress)
    Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
    else if (Irp->UserBuffer)
    Buffer = Irp->UserBuffer;

    // 对该地址区域写入一些数据,让程序读出去
    KdPrint(("%S ", Buffer));

    Irp->IoStatus.Information = WriteSize;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
    }

    NTSTATUS ReadProc(struct _DEVICE_OBJECT *DeviceObject, struct _IRP *Irp)
    {
    UNREFERENCED_PARAMETER(DeviceObject);

    char *Buffer = NULL;
    // 判断读写方式

    if (Irp->AssociatedIrp.SystemBuffer)
    Buffer = Irp->AssociatedIrp.SystemBuffer;
    else if (Irp->MdlAddress)
    Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
    else if (Irp->UserBuffer)
    Buffer = Irp->UserBuffer;

    // 对该地址区域写入一些数据,让程序读出去
    RtlCopyMemory(Buffer, L"Hello 15PB", 22);


    Irp->IoStatus.Information = 1;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
    }

    NTSTATUS DeviceIoCtrlProc(struct _DEVICE_OBJECT *DeviceObject, struct _IRP *Irp)
    {
    UNREFERENCED_PARAMETER(DeviceObject);

    PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(Irp);
    ULONG CtrlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
    ULONG OutputLength = pStack->Parameters.DeviceIoControl.OutputBufferLength;
    ULONG Information = 0;

    switch (CtrlCode)
    {
    case CTRL_CODE1:
    {
    char *Buffer = Irp->AssociatedIrp.SystemBuffer;
    KdPrint(("%S ", Buffer));
    Information = 64;
    Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
    RtlCopyMemory(Buffer, L"CTRL_CODE1 - METHOD_IN_DIRECT ", Information);
    break;
    }
    case CTRL_CODE2:
    {
    char *Buffer = Irp->AssociatedIrp.SystemBuffer;
    KdPrint(("%S ", Buffer));
    Information = 62;
    RtlCopyMemory(Buffer, L"CTRL_CODE2 - METHOD_BUFFERED ", Information);
    break;
    }
    case CTRL_CODE3:
    {
    char *Buffer = Irp->UserBuffer;
    Information = 60;
    RtlCopyMemory(Buffer, L"CTRL_CODE3 - METHOD_NEITHER ", Information);
    break;
    }
    default:
    KdPrint(("failed! "));
    break;
    }


    // 1. 设置处理的字节数量
    Irp->IoStatus.Information = OutputLength;
    // 2. 设置状态
    Irp->IoStatus.Status = STATUS_SUCCESS;
    // 3. 表示已完成所有IRP处理
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    // 4. 设置返回值
    return STATUS_SUCCESS;
    }

    // 卸载函数
    void DriverUnload(PDRIVER_OBJECT DriverObject)
    {
    // 获取设备对象链表
    PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
    for (int i = 0; i < 3; ++i)
    {
    IoDeleteDevice(DriverObject->DeviceObject);
    DeviceObject = DeviceObject->NextDevice;
    }

    // 卸载设备符号名
    UNICODE_STRING SymbolLinkName1 = RTL_CONSTANT_STRING(L"\DosDevices\devicelink1");
    UNICODE_STRING SymbolLinkName2 = RTL_CONSTANT_STRING(L"\DosDevices\devicelink2");
    UNICODE_STRING SymbolLinkName3 = RTL_CONSTANT_STRING(L"\DosDevices\devicelink3");
    IoDeleteSymbolicLink(&SymbolLinkName1);
    IoDeleteSymbolicLink(&SymbolLinkName2);
    IoDeleteSymbolicLink(&SymbolLinkName3);
    }

    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING UnicodeString)
    {
    DbgBreakPoint();

    UNREFERENCED_PARAMETER(UnicodeString);

    // 创建不同读写方式的设备
    UNICODE_STRING DeviceName1 = RTL_CONSTANT_STRING(L"\Device\device1");
    UNICODE_STRING SymbolName1 = RTL_CONSTANT_STRING(L"\DosDevices\devicelink1");
    if (NT_SUCCESS(CreateDevice(DriverObject, &DeviceName1, &SymbolName1, DO_BUFFERED_IO)))

    KdPrint(("Create device success: \Device\device1 "));
    UNICODE_STRING DeviceName2 = RTL_CONSTANT_STRING(L"\Device\device2");
    UNICODE_STRING SymbolName2 = RTL_CONSTANT_STRING(L"\DosDevices\devicelink2");

    if (NT_SUCCESS(CreateDevice(DriverObject, &DeviceName2, &SymbolName2, DO_DIRECT_IO)))
    KdPrint(("Create device success: \Device\device2 "));
    UNICODE_STRING DeviceName3 = RTL_CONSTANT_STRING(L"\Device\device3");
    UNICODE_STRING SymbolName3 = RTL_CONSTANT_STRING(L"\DosDevices\devicelink3");
    if (NT_SUCCESS(CreateDevice(DriverObject, &DeviceName3, &SymbolName3, 0)))
    KdPrint(("Create device success: \Device\device3 "));

    // 设置卸载函数
    DriverObject->DriverUnload = DriverUnload;

    // 初始化IRP派遣函数
    for (UINT32 i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    DriverObject->MajorFunction[i] = DefaultProc;
    DriverObject->MajorFunction[IRP_MJ_CREATE] = CreateProc;
    DriverObject->MajorFunction[IRP_MJ_READ] = ReadProc;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = WriteProc;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoCtrlProc;

    return STATUS_SUCCESS;
    }

    应用层

    #include <cstdio>
    #include <windows.h>

    #define CTRL_CODE1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
    #define CTRL_CODE2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
    #define CTRL_CODE3 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_NEITHER, FILE_ANY_ACCESS)

    int main()
    {
    // 创建内核对象的设备对象连接
    HANDLE DeviceHandle1 = CreateFile(L"\\.\devicelink1", FILE_ALL_ACCESS,
    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE DeviceHandle2 = CreateFile(L"\\.\devicelink2", FILE_ALL_ACCESS,
    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE DeviceHandle3 = CreateFile(L"\\.\devicelink3", FILE_ALL_ACCESS,
    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);

    WCHAR ReadBuffer[100] = { 0 };
    DWORD ReadByte = 0;

    // 发送消息
    printf("device1 - DO_BUFFERED_IO: ");
    WriteFile(DeviceHandle1, L"device1 - DO_BUFFERED_IO", 52, &ReadByte, NULL);
    printf("device1 - Write: %d ", ReadByte);
    ReadFile(DeviceHandle1, ReadBuffer, 100, &ReadByte, NULL);
    wprintf(L"device1 - Read: %d(%s) ", ReadByte, ReadBuffer);

    printf("device2 - DO_DIRECT_IO: ");
    WriteFile(DeviceHandle2, L"device1 - DO_DIRECT_IO", 48, &ReadByte, NULL);
    printf("device2 - Write: %d ", ReadByte);
    ReadFile(DeviceHandle2, ReadBuffer, 100, &ReadByte, NULL);
    wprintf(L"device2 - Read: %d(%s) ", ReadByte, ReadBuffer);

    /*printf("device3 - NULL: ");
    WriteFile(DeviceHandle3, L"device1 - NULL", 32, &ReadByte, NULL);
    printf("device3 - Write: %d ", ReadByte);
    ReadFile(DeviceHandle3, ReadBuffer, 100, &ReadByte, NULL);
    printf("device3 - Read: %d(%Ls) ", ReadByte, ReadBuffer);*/

    DeviceIoControl(DeviceHandle1, CTRL_CODE1, (LPVOID)L"CTRL_CODE1", 24, ReadBuffer, 100, &ReadByte, NULL);
    wprintf(L"device1 - CTRL_CODE1: %d - %s ", ReadByte, ReadBuffer);
    DeviceIoControl(DeviceHandle1, CTRL_CODE2, (LPVOID)L"CTRL_CODE2", 24, ReadBuffer, 100, &ReadByte, NULL);
    wprintf(L"device1 - CTRL_CODE2: %d - %s ", ReadByte, ReadBuffer);
    DeviceIoControl(DeviceHandle1, CTRL_CODE3, (LPVOID)L"CTRL_CODE3", 24, ReadBuffer, 100, &ReadByte, NULL);
    wprintf(L"device1 - CTRL_CODE3: %d - %s ", ReadByte, ReadBuffer);
    system("pause");

    return 0;
    }
  • 相关阅读:
    构建一个应用,并在docker compose里运行起来
    docker engine docker-compose部署
    django 返回数据的几种常用姿势
    fiddler+httprunner 零编码实现接口自动化DEMO
    选择排序
    曾经学的那些表示时间复杂度的公式怎么来的?
    python+Airtest+android使用AirtestIDE编写一个DEMO
    怎么计算时间复杂度?
    算法_冒泡排序python+java实现
    2020年1月16日(多进程)
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11432800.html
Copyright © 2020-2023  润新知