【驱动学习一】 DeviceIoControl

友情提示:网上代码慎用,坑人无限

应用层和驱动层通过DeviceIoControl来通信。

驱动代码如下:

#ifndef __HELLOWORLD_C__
#define __HELLOWORLD_C__
#define DEBUGMSG
#include <ntddk.h>
#define DEVICE_HELLO_INDEX 0x860
//2个IOCTL宏
#define START_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define STOP_HELLPWORLD  CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define NT_DEVICE_NAME L"\\Device\\HelloWorld"        //设备名称
#define DOS_DEVICE_NAME L"\\DosDevices\\HelloWorld"   //符号连接


NTSTATUS HelloWorldDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);
VOID HelloWorldUnLoad (IN PDRIVER_OBJECT DriverObject);
//驱动入口
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS ntStatus=STATUS_SUCCESS;
    PDEVICE_OBJECT lpDeviceObject=NULL;       //指向设备对象的指针
    UNICODE_STRING DeviceNameString={0};      //设备名称
    UNICODE_STRING DeviceLinkString={0};      //符号连接
    //调试信息
    #ifdef DEBUGMSG
           DbgPrint("Starting DriverEntry()\n");
    #endif
    RtlInitUnicodeString(&DeviceNameString,NT_DEVICE_NAME);  //初始化Unicode字符串
    //创建设备
    ntStatus=IoCreateDevice(DriverObject,0,&DeviceNameString,FILE_DEVICE_UNKNOWN,0,FALSE,&lpDeviceObject);
    //使用NT_SUCCESS宏检测函数调用是否成功
    if (!NT_SUCCESS(ntStatus))
    {
        #ifdef DEBUGMSG
               DbgPrint("IoCreateDevice() error reports 0x%08X\n",ntStatus);
        #endif
        return ntStatus;
    }
    
    RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
    //创建符号连接
    ntStatus=IoCreateSymbolicLink(&DeviceLinkString,&DeviceNameString);
    if (!NT_SUCCESS(ntStatus))
    {
        #ifdef DEBUGMSG
               DbgPrint("IoCreateSymbolicLink() error reports 0x%08X\n",ntStatus);
        #endif
        if (lpDeviceObject)
            IoDeleteDevice(lpDeviceObject);
        return ntStatus;
    }
    //设置IRP派遣例程和卸载例程
    DriverObject->MajorFunction[IRP_MJ_CREATE]=HelloWorldDispatch;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]=HelloWorldDispatch;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=HelloWorldDispatch;
    DriverObject->DriverUnload=HelloWorldUnLoad;
    
    //lpDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; //取消设备初始化标志
    return ntStatus;
}
NTSTATUS HelloWorldDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
    NTSTATUS ntStatus=STATUS_SUCCESS;
    PIO_STACK_LOCATION IrpStack=NULL;   //IRP堆栈
    ULONG IoControlCodes=0;             //I/O控制代码
    //设置IRP状态
    pIrp->IoStatus.Status=STATUS_SUCCESS;
    pIrp->IoStatus.Information=0;
    #ifdef DEBUGMSG
           DbgPrint("Starting HelloWorldDispatch()\n");
    #endif
    IrpStack=IoGetCurrentIrpStackLocation(pIrp);    //得到当前调用者的IRP
    switch (IrpStack->MajorFunction)
    {
            case IRP_MJ_CREATE:
                 #ifdef DEBUGMSG
                        DbgPrint("IRP_MJ_CREATE\n");
                 #endif
                 break;
            case IRP_MJ_CLOSE:
                 #ifdef DEBUGMSG
                        DbgPrint("IRP_MJ_CLOSE\n");
                 #endif
                 break;
            case IRP_MJ_DEVICE_CONTROL:
                 #ifdef DEBUGMSG
                        DbgPrint("IRP_MJ_DEVICE_CONTROL\n");
                 #endif
                 //取得I/O控制代码
                 IoControlCodes=IrpStack->Parameters.DeviceIoControl.IoControlCode;
                 switch (IoControlCodes)
                 {
                         //启动
                         case START_HELLPWORLD:
                              DbgPrint("Starting \"Hello World\"\n");
                              break;
                         //停止
                         case STOP_HELLPWORLD:
                              DbgPrint("Stoping \"Hello World\"\n");
                              break;
                         default:
                              pIrp->IoStatus.Status=STATUS_INVALID_PARAMETER;
                              break;
                 }
                 break;
            default:
                 break;
    }
    ntStatus=pIrp->IoStatus.Status;
    IoCompleteRequest(pIrp,IO_NO_INCREMENT);
    return ntStatus;
}
VOID HelloWorldUnLoad (IN PDRIVER_OBJECT DriverObject)
{
     UNICODE_STRING DeviceLinkString={0};
     PDEVICE_OBJECT DeviceObjectTemp1=NULL;
     PDEVICE_OBJECT DeviceObjectTemp2=NULL;
     #ifdef DEBUGMSG
            DbgPrint("Starting HelloWorldUnLoad()\n");
     #endif
     RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
     if (DeviceLinkString.Buffer)
         IoDeleteSymbolicLink(&DeviceLinkString);
     if (DriverObject)
     {
         DeviceObjectTemp1=DriverObject->DeviceObject;
         while (DeviceObjectTemp1)
         {
                DeviceObjectTemp2=DeviceObjectTemp1;
                DeviceObjectTemp1=DeviceObjectTemp1->NextDevice;
                IoDeleteDevice(DeviceObjectTemp2);
         }
     }
}
#endif

应用层代码如下:

#define DEBUGMSG
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <tchar.h>
#define DEVICE_FILTER_INDEX 0x860
#define START_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_FILTER_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define STOP_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_FILTER_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define erron GetLastError()
#define MY_DEVICE_NAME _T("\\\\.\\HelloWorld")
#define MY_DEVICE_START _T("-start")
#define MY_DEVICE_STOP _T("-stop")

VOID Usage( TCHAR *Parameter);
BOOL DriverControl (TCHAR *Maik);

int main (int argc,TCHAR *argv[])
{	
	if ( argc != 2 )
	{
		Usage( argv[0] );
		return 0;
	}
	if( _tcscmp(argv[1],MY_DEVICE_START)==0 || _tcscmp(argv[1],MY_DEVICE_STOP)==0 )
	{
		DriverControl( argv[1]);
	}
	else
	{
		Usage(argv[0]);
		return 0;
	}

    return 0;
}
BOOL DriverControl (TCHAR *Maik)
{
     HANDLE hDevice	 = NULL;  //设备句柄
	 DWORD  dwReturn = 0;
     //获得设备句柄

     hDevice=CreateFile(MY_DEVICE_NAME,FILE_ALL_ACCESS ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
     if (hDevice==INVALID_HANDLE_VALUE)
     {
         #ifdef DEBUGMSG
                wprintf(MY_DEVICE_NAME);
                wprintf( L"\nCreateFile() GetLastError reports %d\n",erron);
         #endif
         return FALSE;
     }
	 if ( !_tcscmp(Maik,MY_DEVICE_START) )
	 {
		 //传递启动的I/O控制代码
		 if (!(DeviceIoControl(hDevice,START_HELLPWORLD,NULL,0,NULL,0,&dwReturn,NULL)))
		 {
			 #ifdef DEBUGMSG
					wprintf(L"DeviceIoControl() GetLastError reports %d\n",erron);
			 #endif
			 CloseHandle(hDevice);
			 return FALSE;
		 }
	 }
	 else if ( !_tcscmp(Maik,MY_DEVICE_STOP) )
	 {
		 //传递启动的I/O控制代码
		 if (!(DeviceIoControl(hDevice,START_HELLPWORLD,NULL,0,NULL,0,&dwReturn,NULL)))
		 {
			 #ifdef DEBUGMSG
				wprintf(L"DeviceIoControl() GetLastError reports %d\n",erron);
			 #endif
			 CloseHandle(hDevice);
			 return FALSE;
		 }
	 }

     if (hDevice)
         CloseHandle(hDevice);  //关闭句柄
     return TRUE;
}

VOID Usage( TCHAR* Parameter)
{
    printf("===================================================\n");
    printf("%s [-start | -stop]\n",Parameter);
    printf("===================================================\n");
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值