zoukankan      html  css  js  c++  java
  • 派遣函数学习2)直接读写

    直接方式读写设备,操作系统会将用户模式下的缓冲区锁住。然后操作系统将这段缓冲区在内核模式地址再次映射一遍

    这样 ,用户模式的缓冲区和内核模式的缓冲区指向的是同一区域的物理内存。

    在创建完设备对象后,在设置设备对象的时候,设置为 DO_DIRECT_IO 而不是DO_BUFFERED

    	//创建设备
    	status = IoCreateDevice( pDriverObject,
    						sizeof(DEVICE_EXTENSION),
    						&(UNICODE_STRING)devName,
    						FILE_DEVICE_UNKNOWN,
    						0, TRUE,
    						&pDevObj );
    	if (!NT_SUCCESS(status))
    		return status;
    
    
    	pDevObj->Flags |= DO_DIRECT_IO;


    MDL 是数据结构 内存描述符表

    驱动程序读取设备:

    NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
    								 IN PIRP pIrp) 
    {
    	KdPrint(("Enter HelloDDKRead
    "));
    
    	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
    	NTSTATUS status = STATUS_SUCCESS;
    
     	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    
     	ULONG ulReadLength = stack->Parameters.Read.Length;
    	KdPrint(("ulReadLength:%d
    ",ulReadLength));
    
    	//通过这个三个宏来获取 MDL数据结构信息
    	ULONG mdl_length = MmGetMdlByteCount(pIrp->MdlAddress);
    	PVOID mdl_address = MmGetMdlVirtualAddress(pIrp->MdlAddress);
    	ULONG mdl_offset = MmGetMdlByteOffset(pIrp->MdlAddress);
    	
    	KdPrint(("mdl_address:0X%08X
    ",mdl_address));
    	KdPrint(("mdl_length:%d
    ",mdl_length));
    	KdPrint(("mdl_offset:%d
    ",mdl_offset));
    
    	if (mdl_length!=ulReadLength)
    	{
    		//MDL的长度应该和读长度相等,否则该操作应该设为不成功
    		pIrp->IoStatus.Information = 0;
    		status = STATUS_UNSUCCESSFUL;
    	}else
    	{
    		//用MmGetSystemAddressForMdlSafe得到MDL在内核模式下的映射
    		PVOID kernel_address = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority);
    		KdPrint(("kernel_address:0X%08X
    ",kernel_address));
    		memset(kernel_address,0XAA,ulReadLength);
    		pIrp->IoStatus.Information = ulReadLength;	// bytes xfered
    	}
    	
    	pIrp->IoStatus.Status = status;
    	
    	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    	KdPrint(("Leave HelloDDKRead
    "));
    
    	return status;
    }
    



  • 相关阅读:
    浮点数越界或者无效1.#IND0
    [转]方差、协方差与相关系数
    『转』 函数、变量命名方法
    感知哈希算法——google用于图片搜索的算法
    C#传值调用与引用调用 解释
    HttpContext.Current.Request.ServerVariab
    怎么去用java经典递归算法?
    泛型的详细解释与示例
    个彻底解释 C#泛型的源代码
    VC++怎么实现Win2000下直接读写磁盘扇区
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982512.html
Copyright © 2011-2022 走看看