zoukankan      html  css  js  c++  java
  • windows内核编程基础知识

    /*
    1.基本的驱动数据结构
    
    //驱动对象结构体
    typedef struct _DRIVER_OBJECT {
        CSHORT Type; //结构类型
        CSHORT Size; //结构大小
        PDEVICE_OBJECT DeviceObject; //驱动设备对象 
        PDRIVER_EXTENSION DriverExtension; //驱动扩展指针 
        UNICODE_STRING DriverName;	//驱动程序的名字
        PDRIVER_UNLOAD DriverUnload; //驱动的卸载函数
        PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; //普通的分发函数
    	......                       //其他的成员没有列出
    } DRIVER_OBJECT;
    
    //定义驱动对象指针
    typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; 
    
    //************************************************************************************************************
    
    //设备对象结构体
    typedef struct _DEVICE_OBJECT { 
        CSHORT Type;//结构类型
        USHORT Size;//结构大小
        LONG ReferenceCount; //引用计数
        struct _DRIVER_OBJECT *DriverObject; //这个设备所属对象
        struct _DEVICE_OBJECT *NextDevice; //指向下一个设备。
    										//在一个驱动对象中有N个设备,这些设备通过这个指针链接起来作为一个单向链表
        ULONG Flags;                   
        struct _DEVOBJ_EXTENSION  *DeviceObjectExtension; //设备扩展结构
    	......								//其他的成员没有列出
     } DEVICE_OBJECT;
    
    //定义设备对象指针
    typedef struct _DEVICE_OBJECT *P_DEVICE_OBJECT; 
    
    //============================================================================================================
    
    2.驱动编程基本函数介绍:
    
    //Unicode字符串的初始化
     VOID  RtlInitUnicodeString(  
    						  OUT PUNICODE_STRING  DestinationString,   
    						  IN  PCWSTR           SourceString)
    
    DestinationString 需要初始化的指针PUNICODE_STRING
    SourceString 指向一个以空结尾的Unicode字符串常量,用这个字符串来初始化DestinationString。
    
    例子
    PUNICODE_STRING  s;
    RtlInitUnicodeString(s, L"宽字符");  //s=L"宽字符";
    
    //************************************************************************************************************
    
    //IoCreateDevice为驱动创建一个设备对象
    NTSTATUS   IoCreateDevice(  
    						  IN  PDRIVER_OBJECT  DriverObject,  
    						  IN  ULONG  DeviceExtensionSize,  
    						  IN  PUNICODE_STRING  DeviceName  OPTIONAL,   
    						  IN  DEVICE_TYPE  DeviceType,    
    						  IN  ULONG  DeviceCharacteristics,   
    						  IN  BOOLEAN  Exclusive,   
    						  OUT PDEVICE_OBJECT  *DeviceObject) //指针的指针
    参数:
    DriverObject 为指向驱动对象的指针。
    DeviceExtensionSize 给_DEVICE_OBJECT.DeviceExtension指定内存空间大小,具体看定义的设备扩展结构的大小
    DeviceName 设备名字,如:\Device\GetGDT0
    DeviceType 设备类型,这里我们用 FILE_DEVICE_UNKNOWN
    DeviceCharacteristics 设备特征信息 一般为0
    Exclusive 是否指定设备为独占 是为TRUE,否为FALSE
    DeviceObject 指针变量接收一个指向新创建的DEVICE_OBJECT结构。用来回传数据
    
    返回值解释:
    调用成功会返回 STATUS_SUCCESS  
    如果出错会返回下列值
    STATUS_INSUFFICIENT_RESOURCES  //资源不足
    STATUS_OBJECT_NAME_EXISTS      //指定对象名存在
    STATUS_OBJECT_NAME_COLLISION   //对象名有冲突
    
    //************************************************************************************************************
    
    //IoCreateSymbolicLink创建一个设备链接符。
    //驱动程序虽然有了设备名称,但是这种设备名称只能在内核态可见,而对于应用程序是不可见的,
    //因此,驱动程序需要暴露一个符号链接,该链接指向真正的设备名称(不是必须的)
    //只是让Ring3环应用程序连接驱动程序更容易
    
    NTSTATUS   IoCreateSymbolicLink(  
    							  IN PUNICODE_STRING  SymbolicLinkName, 
    							  IN PUNICODE_STRING  DeviceName);
    参数:
    SymbolicLinkName  Unicode字符串指针,是一个用户态可见的名称。如:\DosDevices\GetGDT0 或者 \??\GetGDT0
    DeviceName  Unicode字符串指针,是驱动程序创建的设备对象名称。如:\Device\GetGDT0
    
    返回值解释:
    如果符号链接创建成功 返回STATUS_SUCCESS  
    
    //************************************************************************************************************
    
    VOID   IoDeleteDevice(   
    					IN PDEVICE_OBJECT  DeviceObject)
    
    参数
    DeviceObject  PDEVICE_OBJECT类型的设备对象指针,指向需要删除的设备对象
    
    //============================================================================================================
    
    3.编写简单的驱动程序Demo
    
    创建设备的步骤:
          1用RtlInitUnicodeString初如化设备名称指针
          2用IoCreateDevice创建设备,如果不成功则返回
          3用IoCreateSymlicLink创建符号链接,创建成功返回 STATUS_SUCCESS;创建不成功则调用 IoDeleteDevice删除设备;
    
    简单的代码示例:
    
    //代码片段--使用C语言
    
    #define INITCODE code_seg("INIT")  //初始化时载入内存,然后可以从内存中卸掉
    
    #pragma INITCODE
    NTSTATUS CreateMyDevice (IN PDRIVER_OBJECT pDriverObject) 
    {
    	NTSTATUS status;
    
    	//用来返回创建设备
    	PDEVICE_OBJECT pDevObj; 
    
    	//创建设备名称
    	UNICODE_STRING devName;
    	UNICODE_STRING symLinkName;
    
    	//对devName初始化字串为 "\Device\XX_Device"
    	RtlInitUnicodeString(&devName,L"\Device\XX_Device"); 
    
    	//创建设备对象
    	status = IoCreateDevice(pDriverObject,
    							0,
    							&devName,
    							FILE_DEVICE_UNKNOWN,
    							0, TRUE,
    							&pDevObj);
    	if (!NT_SUCCESS(status))
    		return status;
    
    	//设置缓冲区通信方式
    	pDevObj->Flags |= DO_BUFFERED_IO;
    
    	//创建符号链接
    	RtlInitUnicodeString(&symLinkName,L"\??\XX_Device");
    	status = IoCreateSymbolicLink( &symLinkName,&devName );
    	if (!NT_SUCCESS(status)) 
    	{
    		IoDeleteDevice( pDevObj );
    		return status;
    	}
    
    	return STATUS_SUCCESS;
    }
    
    //参考资料:
    //郁金香老师讲课资料整理
    
    */

  • 相关阅读:
    SpringBoot笔记十三:引入webjar资源和国际化处理
    Mybatis笔记二:接口式编程
    Mybatis笔记一:写一个demo
    SpringBoot笔记十一:html通过Ajax获取后端数据
    MarkDown语法
    Spring Boot笔记十:IOC控制反转
    USB2.0学习笔记连载(三):通用USB驱动程序解析
    《FPGA全程进阶---实战演练》第四章之Quartus II使用技巧
    摄像头模组基础扫盲
    USB2.0学习笔记连载(二):USB基础知识简介
  • 原文地址:https://www.cnblogs.com/csnd/p/11800745.html
Copyright © 2011-2022 走看看