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;
    }
    



  • 相关阅读:
    tableView//collectionView加载时的动画
    关于collectionView和tableView的两种cell的出列方法的区别
    缓存的实现,主要是图片缓存整理
    android context获取目录详解
    Android网络传输中必用的两个加密算法:MD5 和 RSA 及Base64加密总结
    listview 与 button 焦点 在item添加下列属性
    VScode 安装必备
    centos7 安装docker
    1290
    MySQL“Another MySQL daemon already running with the same unix socket” 报错信息处理
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982512.html
Copyright © 2011-2022 走看看