NTModel框架与通信(含使用服务加载驱动)

Posted zhuhuibeishadiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NTModel框架与通信(含使用服务加载驱动)相关的知识,希望对你有一定的参考价值。

原代码如下

#include <ntddk.h>
 
#define     DEVICE_NAME                 L"\\device\\NTModelDrv"
#define     LINK_NAME                   L"\\dosDevices\\NTModelDrv"
 
#define IOCTL_BASE  0x8000
#define MY_CTL_CODE(i)     CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define IOCTL_HELLO MY_CTL_CODE(0)
 
typedef struct _DEVICE_EXTENSION {
    PDEVICE_OBJECT pDevice;
    UNICODE_STRING ustrDeviceName;  //设备名称
    UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
 
 
// function to dispatch the IRPs
NTSTATUS DispatchOK(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
   Irp->iostatus.Status = STATUS_SUCCESS;
   IoCompleteRequest(Irp,IO_NO_INCREMENT);
   return STATUS_SUCCESS;
}
 
VOID DriverUnload (
    IN PDRIVER_OBJECT   pDriverObject) 
{
    UNICODE_STRING strLink;
    RtlInitUnicodeString(&strLink, LINK_NAME);
 
    IoDeleteSymbolicLink(&strLink);
    IoDeleteDevice(pDriverObject->DeviceObject);
    DbgPrint("[NTModelDrv] Unloaded\n"); }
 
NTSTATUS DispatchIoctl(
    PDEVICE_OBJECT pDevObj, 
    PIRP pIrp
    )
{
    NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
    PIO_STACK_LOCATION pIrpStack;
    ULONG uIoControlCode;
    PVOID pIoBuffer;
    ULONG uInSize;
    ULONG uOutSize;
 
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
    pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
    uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
    uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
 
    switch(uIoControlCode) 
    {
        case IOCTL_HELLO: 
        {
            DbgPrint("[NTModelDrv] Hello\n");
            status = STATUS_SUCCESS;
        }
        break;
    }
 
    if(status == STATUS_SUCCESS)
        pIrp->IoStatus.Information = uOutSize;
    else
        pIrp->IoStatus.Information = 0;
     
    /////////////////////////////////////
    pIrp->IoStatus.Status = status;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
 
    return status;
}
 
//处理应用层的write()函数
NTSTATUS DispatchWrite (
    IN PDEVICE_OBJECT   pDevObj,
    IN PIRP pIrp) 
{
    NTSTATUS    status = STATUS_SUCCESS;
    PVOID       userBuffer;
    PVOID       drvBuffer;
    ULONG       xferSize;
 
    //获得IRP堆栈的当前位置
    PIO_STACK_LOCATION pIrpStack =
        IoGetCurrentIrpStackLocation( pIrp );
    //获得当前写的长度和缓冲
    xferSize = pIrpStack->Parameters.Write.Length;
    userBuffer = pIrp->AssociatedIrp.SystemBuffer;
    drvBuffer = ExAllocatePoolWithTag(PagedPool, xferSize, 'tseT');
    if (drvBuffer == NULL)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        xferSize = 0;
    }
    //将当前缓冲中的数据写入
    RtlCopyMemory( drvBuffer, userBuffer, xferSize );
    //完成IO,填写完成状态和传输的数据长度
        ExFreePool(drvBuffer);
        drvBuffer = NULL;
    pIrp->IoStatus.Status = status;
    pIrp->IoStatus.Information = xferSize;
    //完成IRP,不向下层传递
    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    return status;
}
//处理应用层的read()函数
NTSTATUS DispatchRead (
    IN PDEVICE_OBJECT   pDevObj,
    IN PIRP pIrp) 
{
    NTSTATUS    status = STATUS_SUCCESS;
    PVOID       userBuffer;
    ULONG       xferSize;
 
    //获取IRP堆栈的当前位置
    PIO_STACK_LOCATION pIrpStack =
        IoGetCurrentIrpStackLocation( pIrp );
    //获取传输的字节数和缓冲
    xferSize = pIrpStack->Parameters.Read.Length;
    userBuffer = pIrp->AssociatedIrp.SystemBuffer;   
    //从驱动中读数据
    RtlCopyMemory( userBuffer, L"Hello, world",
        xferSize );
    //填写IRP中的完成状态,结束IRP操作,不向下层发送
    pIrp->IoStatus.Status = status;
    pIrp->IoStatus.Information = xferSize;
    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    return status;
}
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
    UNICODE_STRING  DeviceName;
    UNICODE_STRING  LinkName;  
    NTSTATUS        status; 
    PDEVICE_OBJECT  pDriverDeviceObject;  
    PDEVICE_EXTENSION   pDevExt;
    ULONG i;
     
    //DbgPrint("Driver loaded.");
    pDriverObject->DriverUnload = DriverUnload;   
     
    // init strings
    RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
    RtlInitUnicodeString(&LinkName, LINK_NAME);
     
    // to communicate with usermode, we need a device
    status = IoCreateDevice(
           pDriverObject,        // ptr to caller object
           sizeof(DEVICE_EXTENSION),  // extension device allocated byte number
           &DeviceName,         // device name 
           FILE_DEVICE_UNKNOWN, 
           0,                   // no special caracteristics
           FALSE,               // we can open many handles in same time
           &pDriverDeviceObject); // [OUT] ptr to the created object
            
    if ( !NT_SUCCESS(status) ) 
       return STATUS_NO_SUCH_DEVICE;
     
    pDriverDeviceObject-> Flags |= DO_BUFFERED_IO;
        pDevExt = (PDEVICE_EXTENSION)pDriverDeviceObject->DeviceExtension;
    pDevExt->pDevice = pDriverDeviceObject;
    pDevExt->ustrDeviceName = DeviceName;
 
    // we also need a symbolic link
    status = IoCreateSymbolicLink(&LinkName,&DeviceName);
    if( !NT_SUCCESS(status) ) 
    {
        IoDeleteDevice( pDriverDeviceObject );
        return STATUS_NO_SUCH_DEVICE;
    }  
 
    pDevExt->ustrSymLinkName = LinkName;
 
    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
        pDriverObject->MajorFunction[i] = DispatchOK; 
     
    // handle IRPs
 
    pDriverObject->MajorFunction[IRP_MJ_READ]   = DispatchRead;
    pDriverObject->MajorFunction[IRP_MJ_WRITE]  = DispatchWrite;
    pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; 
 
    //Do other things...   
     
    return STATUS_SUCCESS;
}


上面是真正的框架
下面是测试使用的框架:


#include <ntddk.h>
 
#define DEVICE_NAME L"\\device\\ntmodeldrv"
#define LINK_NAME L"\\dosdevices\\ntmodeldrv"
 
#define IOCTRL_BASE 0x800
 
#define MYIOCTRL_CODE(i)     CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTRL_BASE+i, METHOD_BUFFERED,FILE_ANY_ACCESS)
 
#define CTL_HELLO MYIOCTRL_CODE(0)
#define CTL_PRINT MYIOCTRL_CODE(1)
#define CTL_BYE MYIOCTRL_CODE(2)
 
NTSTATUS DispatchCommon(PDEVICE_OBJECT pObject, PIRP pIrp)
{
    pIrp->IoStatus.Status=STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
 
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
 
    return STATUS_SUCCESS;
}
 
NTSTATUS DispatchCreate(PDEVICE_OBJECT pObject, PIRP pIrp)
{
    pIrp->IoStatus.Status=STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
 
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
 
    return STATUS_SUCCESS;
}
 
NTSTATUS DispatchRead(PDEVICE_OBJECT pObject, PIRP pIrp)
{
    PVOID pReadBuffer = NULL;
    ULONG uReadLength = 0;
    PIO_STACK_LOCATION pStack = NULL;
    ULONG uMin = 0;
    ULONG uHelloStr = 0;
 
    uHelloStr = (wcslen(L"hello world")+1)*sizeof(WCHAR);
 
    pReadBuffer = pIrp->AssociatedIrp.SystemBuffer;
    pStack = IoGetCurrentIrpStackLocation(pIrp);
 
    uReadLength = pStack->Parameters.Read.Length;
    uMin = uReadLength>uHelloStr?uHelloStr:uReadLength;
 
    RtlCopyMemory(pReadBuffer, L"hello world", uMin);
 
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = uMin;
 
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
 
    return STATUS_SUCCESS;
 
}
 
NTSTATUS DispatchWrite(PDEVICE_OBJECT pObject, PIRP pIrp)
{
    PVOID pWriteBuff = NULL;
    ULONG uWriteLength = 0;
    PIO_STACK_LOCATION pStack = NULL;
 
    PVOID pBuffer = NULL;
 
    pWriteBuff = pIrp->AssociatedIrp.SystemBuffer;
 
    pStack = IoGetCurrentIrpStackLocation(pIrp);
    uWriteLength = pStack->Parameters.Write.Length;
 
    pBuffer = ExAllocatePoolWithTag(PagedPool, uWriteLength, 'TSET');
    if(pBuffer == NULL)
    {
        pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
        pIrp->IoStatus.Information = 0;
        IoCompleteRequest(pIrp,IO_NO_INCREMENT);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
 
    memset(pBuffer, 0, uWriteLength);
 
    RtlCopyMemory(pBuffer, pWriteBuff, uWriteLength);
 
    ExFreePool(pBuffer);
    pBuffer=NULL;
 
 
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = uWriteLength;
 
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
 
    return STATUS_SUCCESS;
 
}
 
NTSTATUS DispatchIoctrl(PDEVICE_OBJECT pObject, PIRP pIrp)
{
    ULONG uIoctrlCode = 0;
    PVOID pInputBuff = NULL;
    PVOID pOutputBuff = NULL;
 
    ULONG uInputLength = 0;
    ULONG uOutputLength = 0;
    PIO_STACK_LOCATION pStack = NULL;
 
    pInputBuff = pOutputBuff = pIrp->AssociatedIrp.SystemBuffer;
 
    pStack = IoGetCurrentIrpStackLocation(pIrp);
    uInputLength = pStack->Parameters.DeviceIoControl.InputBufferLength;
    uOutputLength = pStack->Parameters.DeviceIoControl.OutputBufferLength;
 
 
    uIoctrlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
 
    switch(uIoctrlCode)
    {
    case CTL_HELLO:
        DbgPrint("Hello iocontrol\n");
        break;
    case CTL_PRINT:
        DbgPrint("%ws\n", pInputBuff);
        break;
    case CTL_BYE:
        DbgPrint("Goodbye iocontrol\n");
        break;
    default:
        DbgPrint("Unknown iocontrol\n");
 
    }
 
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
 
    return STATUS_SUCCESS;
 
}
 
NTSTATUS DispatchClean(PDEVICE_OBJECT pObject, PIRP pIrp)
{
    pIrp->IoStatus.Status=STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
 
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
 
    return STATUS_SUCCESS;
}
 
NTSTATUS DispatchClose(PDEVICE_OBJECT pObject, PIRP pIrp)
{
    pIrp->IoStatus.Status=STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
 
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
 
    return STATUS_SUCCESS;
}
 
 
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
    UNICODE_STRING uLinkName={0};
    RtlInitUnicodeString(&uLinkName, LINK_NAME);
    IoDeleteSymbolicLink(&uLinkName);
 
    IoDeleteDevice(pDriverObject->DeviceObject);
 
    DbgPrint("Driver unloaded\n");
 
}
 
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,
                     PUNICODE_STRING pRegPath)
{
    UNICODE_STRING uDeviceName = {0};
    UNICODE_STRING uLinkName={0};
    NTSTATUS ntStatus = 0;
    PDEVICE_OBJECT pDeviceObject = NULL;
    ULONG i=0;
 
    DbgPrint("Driver load begin\n");
 
    RtlInitUnicodeString(&uDeviceName, DEVICE_NAME);
    RtlInitUnicodeString(&uLinkName,LINK_NAME);
 
    ntStatus = IoCreateDevice(pDriverObject,
     0,&uDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&pDeviceObject);
     
    if(!NT_SUCCESS(ntStatus))
    {
        DbgPrint("IoCreateDevice failed:%x", ntStatus);
        return ntStatus;
    }
 
    pDeviceObject->Flags |= DO_BUFFERED_IO;
 
    ntStatus = IoCreateSymbolicLink(&uLinkName,&uDeviceName);
    if(!NT_SUCCESS(ntStatus))
    {
        IoDeleteDevice(pDeviceObject);
        DbgPrint("IoCreateSymbolicLink failed:%x\n", ntStatus);
        return ntStatus;
    }
 
    for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION+1;i++)
    {
        pDriverObject->MajorFunction[i] = DispatchCommon;
    }
 
    pDriverObject->MajorFunction[IRP_MJ_CREATE]=DispatchCreate;
    pDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;
    pDriverObject->MajorFunction[IRP_MJ_WRITE]=DispatchWrite;
    pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchIoctrl;
    pDriverObject->MajorFunction[IRP_MJ_CLEANUP]=DispatchClean;
    pDriverObject->MajorFunction[IRP_MJ_CLOSE]=DispatchClose;
 
    pDriverObject->DriverUnload=DriverUnload;
 
    DbgPrint("Driver load ok!\n");
 
    return STATUS_SUCCESS;
}


下面是R3加载驱动和通信代码:

#include <windows.h>  
#include <winsvc.h>  
#include <conio.h>  
#include <stdio.h>
#include <winioctl.h>
 
#define DRIVER_NAME "ntmodeldrv"
#define DRIVER_PATH ".\\ntmodeldrv.sys"
 
#define IOCTRL_BASE 0x8000
 
#define MYIOCTRL_CODE(i)     CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTRL_BASE+i, METHOD_BUFFERED,FILE_ANY_ACCESS)
 
#define CTL_HELLO MYIOCTRL_CODE(0)
#define CTL_PRINT MYIOCTRL_CODE(1)
#define CTL_BYE MYIOCTRL_CODE(2)
 
//装载NT驱动程序
BOOL LoadDriver(char* lpszDriverName,char* lpszDriverPath)
{
    //char szDriverImagePath[256] = "D:\\DriverTest\\ntmodelDrv.sys";
    char szDriverImagePath[256] = {0};
    //得到完整的驱动路径
    GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
 
    BOOL bRet = FALSE;
 
    SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
    SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
 
    //打开服务控制管理器
    hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
 
    if( hServiceMgr == NULL )  
    {
        //OpenSCManager失败
        printf( "OpenSCManager() Failed %d ! \n", GetLastError() );
        bRet = FALSE;
        goto BeforeLeave;
    }
    else
    {
        ////OpenSCManager成功
        printf( "OpenSCManager() ok ! \n" );  
    }
 
    //创建驱动所对应的服务
    hServiceDDK = CreateService( hServiceMgr,
        lpszDriverName, //驱动程序的在注册表中的名字  
        lpszDriverName, // 注册表驱动程序的 DisplayName 值  
        SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  
        SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  
        SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  自动启动 开机启动 手动启动 禁用
        SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  
        szDriverImagePath, // 注册表驱动程序的 ImagePath 值  
        NULL,  //GroupOrder HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GroupOrderList
        NULL,  
        NULL,  
        NULL,  
        NULL);  
 
    DWORD dwRtn;
    //判断服务是否失败
    if( hServiceDDK == NULL )  
    {  
        dwRtn = GetLastError();
        if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )  
        {  
            //由于其他原因创建服务失败
            printf( "CrateService() Failed %d ! \n", dwRtn );  
            bRet = FALSE;
            goto BeforeLeave;
        }  
        else 
        {
            //服务创建失败,是由于服务已经创立过
            printf( "CrateService() Failed Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );  
        }
 
        // 驱动程序已经加载,只需要打开  
        hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );  
        if( hServiceDDK == NULL )  
        {
            //如果打开服务也失败,则意味错误
            dwRtn = GetLastError();  
            printf( "OpenService() Failed %d ! \n", dwRtn );  
            bRet = FALSE;
            goto BeforeLeave;
        }  
        else
        {
            printf( "OpenService() ok ! \n" );
        }
    }  
    else 
    {
        printf( "CrateService() ok ! \n" );
    }
 
    //开启此项服务
    bRet= StartService( hServiceDDK, NULL, NULL );  
    if( !bRet )  
    {  
        DWORD dwRtn = GetLastError();  
        if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )  
        {  
            printf( "StartService() Failed %d ! \n", dwRtn );  
            bRet = FALSE;
            goto BeforeLeave;
        }  
        else 
        {  
            if( dwRtn == ERROR_IO_PENDING )  
            {  
                //设备被挂住
                printf( "StartService() Failed ERROR_IO_PENDING ! \n");
                bRet = FALSE;
                goto BeforeLeave;
            }  
            else 
            {  
                //服务已经开启
                printf( "StartService() Failed ERROR_SERVICE_ALREADY_RUNNING ! \n");
                bRet = TRUE;
                goto BeforeLeave;
            }  
        }  
    }
    bRet = TRUE;
//离开前关闭句柄
BeforeLeave:
    if(hServiceDDK)
    {
        CloseServiceHandle(hServiceDDK);
    }
    if(hServiceMgr)
    {
        CloseServiceHandle(hServiceMgr);
    }
    return bRet;
}
 
//卸载驱动程序  
BOOL UnloadDriver( char * szSvrName )  
{
    BOOL bRet = FALSE;
    SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
    SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
    SERVICE_STATUS SvrSta;
    //打开SCM管理器
    hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );  
    if( hServiceMgr == NULL )  
    {
        //带开SCM管理器失败
        printf( "OpenSCManager() Failed %d ! \n", GetLastError() );  
        bRet = FALSE;
        goto BeforeLeave;
    }  
    else 
    {
        //带开SCM管理器失败成功
        printf( "OpenSCManager() ok ! \n" );  
    }
    //打开驱动所对应的服务
    hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );  
 
    if( hServiceDDK == NULL )  
    {
        //打开驱动所对应的服务失败
        printf( "OpenService() Failed %d ! \n", GetLastError() );  
        bRet = FALSE;
        goto BeforeLeave;
    }  
    else 
    {  
        printf( "OpenService() ok ! \n" );  
    }  
    //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  
    if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )  
    {  
        printf( "ControlService() Failed %d !\n", GetLastError() );  
    }  
    else 
    {
        //打开驱动所对应的失败
        printf( "ControlService() ok !\n" );  
    } 
     
 
    //动态卸载驱动程序。  
 
    if( !DeleteService( hServiceDDK ) )  
    {
        //卸载失败
        printf( "DeleteSrevice() Failed %d !\n", GetLastError() );  
    }  
    else 
    {  
        //卸载成功
        printf( "DelServer:deleteSrevice() ok !\n" );  
    }  
 
    bRet = TRUE;
BeforeLeave:
//离开前关闭打开的句柄
    if(hServiceDDK)
    {
        CloseServiceHandle(hServiceDDK);
    }
    if(hServiceMgr)
    {
        CloseServiceHandle(hServiceMgr);
    }
    return bRet;    
} 
 
void TestDriver()
{
    //测试驱动程序  
    HANDLE hDevice = CreateFile("\\\\.\\NTmodeldrv",  
        GENERIC_WRITE | GENERIC_READ,  
        0,  
        NULL,  
        OPEN_EXISTING,  
        0,  
        NULL);  
    if( hDevice != INVALID_HANDLE_VALUE )  
    {
        printf( "Create Device ok ! \n" );  
    }
    else 
    {
        printf( "Create Device Failed %d ! \n", GetLastError() ); 
        return;
    }
    CHAR bufRead[1024]={0};
    WCHAR bufWrite[1024]=L"Hello, world";
 
    DWORD dwRead = 0;
    DWORD dwWrite = 0;
 
    ReadFile(hDevice, bufRead, 1024, &dwRead, NULL);
    printf("Read done!\n");
    WriteFile(hDevice, bufWrite, (wcslen(bufWrite)+1)*sizeof(WCHAR), &dwWrite, NULL);
 
    printf("Write done!\n");
 
    CHAR bufInput[1024] ="Hello, world";
    CHAR bufOutput[1024] = {0};
    DWORD dwRet = 0;
 
    WCHAR bufFileInput[1024] =L"c:\\docs\\hi.txt";
 
    DeviceIoControl(hDevice, 
        CTL_PRINT, 
        bufFileInput, 
        sizeof(bufFileInput), 
        bufOutput, 
        sizeof(bufOutput), 
        &dwRet, 
        NULL);
    DeviceIoControl(hDevice, 
        CTL_HELLO, 
        NULL, 
        0, 
        NULL, 
        0, 
        &dwRet, 
        NULL);
 
    DeviceIoControl(hDevice, 
        CTL_BYE, 
        NULL, 
        0, 
        NULL, 
        0, 
        &dwRet, 
        NULL);
    printf("DeviceIoControl done!\n");
    CloseHandle( hDevice );
} 
 
int main(int argc, char* argv[])  
{
    //加载驱动
    BOOL bRet = LoadDriver(DRIVER_NAME,DRIVER_PATH);
    if (!bRet)
    {
        printf("LoadNTDriver error\n");
        return 0;
    }
    //加载成功
 
    printf( "press any key to create device!\n" );  
    getch();  
 
    TestDriver();
 
    //这时候你可以通过注册表,或其他查看符号连接的软件验证。  
    printf( "press any key to stop service!\n" );  
    getch();  
 
    //卸载驱动
    bRet = UnloadDriver(DRIVER_NAME);
    if (!bRet)
    {
        printf("UnloadNTDriver error\n");
        return 0;
    }
 
 
    return 0;  
}


下面是我自己的驱动模板

通信代码依旧是上面的 只是改了设备名和驱动名 和 testDriver中打开驱动的名称

#include <ntddk.h>

#define DEVICE_NAME L"\\device\\DjWow"
#define LINK_NAME L"\\dosdevices\\DjWow" //\\??\\xxxx


#define IOCTRL_BASE 0x800

#define IOCTL_CODE(i)	CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTRL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define CTL_HELLO IOCTL_CODE(0)
#define CTL_ULONG IOCTL_CODE(1)
#define CTL_WCHAR IOCTL_CODE(2)


NTSTATUS DispatchCommon(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;

	UNREFERENCED_PARAMETER(pDeviceObject);

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}


NTSTATUS DispatchCreate(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;

	UNREFERENCED_PARAMETER(pDeviceObject);

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}


NTSTATUS DispatchClose(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;

	UNREFERENCED_PARAMETER(pDeviceObject);

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}


NTSTATUS DispatchClear(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;

	UNREFERENCED_PARAMETER(pDeviceObject);

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}


NTSTATUS DispatchRead(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	PVOID pBuff = 0;
	ULONG pBuffLen = 0;
	ULONG pStackLen = 0;
	PIO_STACK_LOCATION pStack = 0;
	ULONG uMin = 0;

	UNREFERENCED_PARAMETER(pDeviceObject);

	pBuff = pIrp->AssociatedIrp.SystemBuffer;

	pStack = IoGetCurrentIrpStackLocation(pIrp);

	pStackLen = pStack->Parameters.Read.Length;

	pBuffLen = (wcslen(L"hello world") + 1) * sizeof(WCHAR);

	uMin = pBuffLen < pStackLen ? pBuffLen:pStackLen;

	RtlCopyMemory(pBuff, L"hello wolrd", uMin);

	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = uMin;

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}


NTSTATUS DispatchWrite(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	PVOID pWriteBuff = 0;
	PVOID pBuff = 0;
	ULONG uWriteBuffLen = 0;
	PIO_STACK_LOCATION pStack = 0;

	UNREFERENCED_PARAMETER(pDeviceObject);

	pWriteBuff = pIrp->AssociatedIrp.SystemBuffer;

	pStack = IoGetCurrentIrpStackLocation(pIrp);

	uWriteBuffLen = pStack->Parameters.Write.Length;

	pBuff = ExAllocatePoolWithTag(PagedPool, uWriteBuffLen,'TSET');

	if(pBuff == NULL)
	{
		pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		pIrp->IoStatus.Information = 0;
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlZeroMemory(pBuff, uWriteBuffLen);

	RtlCopyMemory(pBuff,pWriteBuff, uWriteBuffLen);

	ExFreePool(pBuff);
	pBuff = 0;

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = uWriteBuffLen;

	return STATUS_SUCCESS;
}


NTSTATUS DispatchIoctrl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	PIO_STACK_LOCATION pStack = 0;
	PVOID pBuff = 0;
	ULONG uOutLen = 0;
	ULONG uInLen = 0;
	ULONG uCtlCode = 0;

	UNREFERENCED_PARAMETER(pDeviceObject);

	pStack = IoGetCurrentIrpStackLocation(pIrp);

	uOutLen = pStack->Parameters.DeviceIoControl.OutputBufferLength;
	uInLen = pStack->Parameters.DeviceIoControl.InputBufferLength;

	pBuff = pIrp->AssociatedIrp.SystemBuffer;

	uCtlCode = pStack->Parameters.DeviceIoControl.IoControlCode;

	switch (uCtlCode)
	{
	case CTL_HELLO:
		DbgPrint("hello!\n");
		break;
	case CTL_ULONG:
		{
			DbgPrint("pid:%d\n",*(ULONG*)pBuff);
			RtlCopyMemory(pBuff,L"ok",uOutLen);
			break;
		}
	case CTL_WCHAR:
			DbgPrint("%ws",pBuff);
			break;
	default:
		DbgPrint("UNKNUW CTLCODE!\n");
	}

	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = uOutLen;

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
	UNICODE_STRING strLinkName ={0};

	RtlInitUnicodeString(&strLinkName,LINK_NAME);

	IoDeleteSymbolicLink(&strLinkName);

	if(pDriverObject->DeviceObject)
	{
		IoDeleteDevice(pDriverObject->DeviceObject);
	}
	
	DbgPrint("DriverUnload");

	return;
}


NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
	UNICODE_STRING strDeviceName = {0};
	UNICODE_STRING strLinkName = {0};
	NTSTATUS status = 0;
	PDEVICE_OBJECT pDeviceObject = 0;
	ULONG i = 0;

	DbgPrint("[DJWOW]DriverEntry!\n");

	UNREFERENCED_PARAMETER(pRegPath);

	RtlInitUnicodeString(&strDeviceName, DEVICE_NAME);
	RtlInitUnicodeString(&strLinkName, LINK_NAME);

	status = IoCreateDevice(pDriverObject, 0, &strDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);

	if(!NT_SUCCESS(status))
	{
		DbgPrint("CretaDevice Faild:0x%x\n",status);
		return status;
	}

	pDeviceObject->Flags |= DO_BUFFERED_IO;

	status = IoCreateSymbolicLink(&strLinkName,&strDeviceName);

	if(!NT_SUCCESS(status))
	{
		IoDeleteDevice(pDeviceObject);
		DbgPrint("IoCreateSymbolicdLink Faild:0x%x\n",status);
		return status;
	}

	for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
	{
		pDriverObject->MajorFunction[i] = DispatchCommon;
	}

	pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
	pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
	pDriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctrl;
	pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
	pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchClear;

	pDriverObject->DriverUnload = DriverUnload;

	return STATUS_SUCCESS;

}


以上是关于NTModel框架与通信(含使用服务加载驱动)的主要内容,如果未能解决你的问题,请参考以下文章

RK3399驱动开发 | 04 - WK2124串口芯片驱动浅析

RK3399驱动开发 | 04 - WK2124串口芯片驱动浅析

ajax与commet

手撕JDBC笔记(含源码),进阶框架必备

手撕JDBC笔记(含源码),进阶框架必备

手撕JDBC笔记(含源码),进阶框架必备