• 派遣函数学习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;
    }
    



  • 相关阅读:
    BZOJ4827: [Hnoi2017]礼物(FFT 二次函数)
    洛谷P3586 [POI2015]LOG(贪心 权值线段树)
    BZOJ4373: 算术天才⑨与等差数列(线段树 hash?)
    cf711D. Directed Roads(环)
    洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
    洛谷P2045 方格取数加强版(费用流)
    cf900D. Unusual Sequences(容斥 莫比乌斯反演)
    agc007D
    hdu 4287Intelligent IME(简单hash)
    Python Post and Get 登陆web后台系统并抓取页面
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982512.html
Copyright © 2020-2023  润新知