zoukankan      html  css  js  c++  java
  • 驱动程序与应用程序交互事件对象

    驱动程序代码

    #pragma once
    #define IO_CONTROL_TRANSMIT_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN,0x8080,METHOD_BUFFERED,FILE_ANY_ACCESS)
    typedef struct _DEVICE_EXTENSION
    {
        PDEVICE_OBJECT pDevObj;
        UNICODE_STRING ustrDeviceName;
        UNICODE_STRING ustrSymbolLinkName;
        KSPIN_LOCK pMySpinLock;
    }DEVICE_EXTENSION, * PDEVICE_EXTENSION;
    
    NTSTATUS unload(PDRIVER_OBJECT driver);
    
    NTSTATUS DemoDeviceControlDispatch(PDEVICE_OBJECT pDeviceObject, PIRP pIrp);
    
    NTSTATUS DeviceCreate(PDEVICE_OBJECT pDeviceObject, PIRP pIrp);
    NTSTATUS DeviceClose(PDEVICE_OBJECT pDeviceObject, PIRP pIrp);
    
    NTSTATUS DemoCreateDevice(PDRIVER_OBJECT pDriver, PCWSTR devName, PCWSTR devSymName);
    #include <ntddk.h>
    #include "FirstDriver.h"
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
    {
        NTSTATUS ntstatus = STATUS_SUCCESS;
        driver->DriverUnload = unload;
        driver->MajorFunction[IRP_MJ_CREATE] = DeviceCreate;//创建
        driver->MajorFunction[IRP_MJ_CLOSE] = DeviceClose;//关闭
        driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DemoDeviceControlDispatch;
    
        ntstatus = DemoCreateDevice(driver, L"\Device\MyDevice01", L"\??\MyDeviceSymbolLinkName01");
        if (!NT_SUCCESS(ntstatus))
        {
            DbgPrint("IoCreateDevice Failed");
            return ntstatus;
        }
    
        DbgPrint("%ws", reg_path->Buffer);
        DbgPrint("driver load success...");
        return STATUS_SUCCESS;
    }
    
    NTSTATUS DemoDeviceControlDispatch(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
    {
        NTSTATUS ntstatus = STATUS_SUCCESS;
        DbgPrint("enter DemoDeviceControlDispatch ...
    ");
        
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
        //ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
        //ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
        ULONG ctlCode = stack->Parameters.DeviceIoControl.IoControlCode;
    
        ULONG info = 0;
        switch (ctlCode)
        {
        case IO_CONTROL_TRANSMIT_EVENT:
        {
            DbgPrint("io control test ...
    ");
            HANDLE userEvent = *(HANDLE*)pIrp->AssociatedIrp.SystemBuffer;
            PKEVENT pKevent;
            ntstatus = ObReferenceObjectByHandle(userEvent, EVENT_MODIFY_STATE, *ExEventObjectType, KernelMode, (PVOID)&pKevent, NULL);
            KeSetEvent(pKevent, IO_NO_INCREMENT, FALSE);
            ObDereferenceObject(pKevent);
            break;
        }
        default:
            ntstatus = STATUS_INVALID_VARIANT;
            break;
        }
        pIrp->IoStatus.Status = ntstatus;
        pIrp->IoStatus.Information = info;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        DbgPrint("leave the demo device control dispatch ...");
        DbgPrint("device io control test success...%d", pDeviceObject->ActiveThreadCount);
        return ntstatus;
    }
    
    NTSTATUS DeviceCreate(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
    {
        //业务代码区
    
        //设置返回状态
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        pIrp->IoStatus.Information = 0;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        DbgPrint("create device success...%d", pDeviceObject->ActiveThreadCount);
        return STATUS_SUCCESS;
    }
    
    NTSTATUS DeviceClose(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
    {
        //业务代码区
    
        //设置返回状态
        pIrp->IoStatus.Status = STATUS_SUCCESS;//getLastError()得到的值
        pIrp->IoStatus.Information = 0;            //返回给3环多少数据,没有填0
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        DbgPrint("close device success...%d", pDeviceObject->ActiveThreadCount);
        return STATUS_SUCCESS;
    }
    
    
    NTSTATUS DemoCreateDevice(PDRIVER_OBJECT pDriver, PCWSTR devName, PCWSTR devSymName)
    {
        PDEVICE_OBJECT pDevice;
        PDEVICE_EXTENSION pDevExt;
    
        UNICODE_STRING DeviceName;
        UNICODE_STRING SymbolLinkName;
    
        RtlInitUnicodeString(&DeviceName, devName);
        RtlInitUnicodeString(&SymbolLinkName, devSymName);
    
        NTSTATUS ntstatus = STATUS_SUCCESS;
        ntstatus = IoCreateDevice(pDriver, sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevice);
        if (!NT_SUCCESS(ntstatus))
        {
            DbgPrint("IoCreateDevice Failed");
            return ntstatus;
        }
    
        ntstatus = IoCreateSymbolicLink(&SymbolLinkName, &DeviceName);
        if (!NT_SUCCESS(ntstatus))
        {
            DbgPrint("IoCreateSymbolicLink Failed");
            IoDeleteDevice(pDevice);
            return ntstatus;
        }
    
        pDevice->Flags |= DO_BUFFERED_IO;
    
        pDevExt = (PDEVICE_EXTENSION)pDevice->DeviceExtension;
        pDevExt->pDevObj = pDevice;
        pDevExt->ustrDeviceName = DeviceName;
        pDevExt->ustrSymbolLinkName = SymbolLinkName;
        return ntstatus;
    }
    
    
    NTSTATUS unload(PDRIVER_OBJECT driver)
    {
        PDEVICE_OBJECT pDev;
        DbgPrint("driver :%ws unload", driver->DriverName.Buffer);
        pDev = driver->DeviceObject;
        while (pDev != NULL)
        {
            PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDev->DeviceExtension;
    
            //删除符号链接
            UNICODE_STRING pLinkName = pDevExt->ustrSymbolLinkName;
            DbgPrint("this is the divice name : %ws", pLinkName.Buffer);
            IoDeleteSymbolicLink(&pLinkName);
            pDev = pDev->NextDevice;
            IoDeleteDevice(pDevExt->pDevObj);
        }
        DbgPrint("driver unload success...");
        return STATUS_SUCCESS;
    }

    用户层代码

    #include<Windows.h>
    #include <iostream>
    #include<stdio.h>
    #include<process.h>
    
    #define IO_CONTROL_TRANSMIT_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN,0x8080,METHOD_BUFFERED,FILE_ANY_ACCESS)
    
    UINT Thread1(LPVOID para)
    {
        printf("enter thread1 ...");
        HANDLE pEvent = *(HANDLE*)para;
        Sleep(5000);
        WaitForSingleObject(pEvent, INFINITE);
        Sleep(5000);
        printf("leave thread1 ...");
    
        return 0;
    }
    int main()
    {
        HANDLE hDevice = CreateFile(L"\\.\MyDeviceSymbolLinkName01", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hDevice == INVALID_HANDLE_VALUE)
        {
            printf("failed to obtain file handle to device with win32 error code %d ...
    ", GetLastError());
            return 1;
        }
    
        BOOL bRet;
        DWORD dwOutPut;
        HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (unsigned(__stdcall * )(void*))Thread1, (void*)&hEvent, 0, NULL);
        bRet = DeviceIoControl(hDevice, IO_CONTROL_TRANSMIT_EVENT, &hEvent, sizeof(hEvent), NULL, 0, &dwOutPut, NULL);
        if (hThread==0)
        {
            printf("client create thread failed ...
    ");
        }
        else
        {
            printf("client create thread success ...
    ");
            WaitForSingleObject(hThread, INFINITE);
        }
        
        return 0;
    }
  • 相关阅读:
    java入门最好的一套书
    【转载】vim的E492错误
    SESSION保存到数据库中,然后从数据库中读取
    django教程
    用vim写python代码的两个关键设置
    HTTP/1.1中文版
    SQL基础教程
    简单清晰的HTML教程
    vim中如何按一个键就保存文件
    【转载】Vim操作
  • 原文地址:https://www.cnblogs.com/a-s-m/p/12353236.html
Copyright © 2011-2022 走看看