zoukankan      html  css  js  c++  java
  • 派遣函数学习1)缓冲区方式读写


    符号   ??HelloDDK    -》\.

    ??HelloDDK ->\.HelloDDK   ->  C语言字符串   \\.\HelloDDK

    HANDLE hDevice = 
    		CreateFile("\\.\HelloDDK",
    					GENERIC_READ | GENERIC_WRITE,
    					0,		// share mode none
    					NULL,	// no security
    					OPEN_EXISTING,
    					FILE_ATTRIBUTE_NORMAL,
    					NULL );		// no template
    
    	if (hDevice == INVALID_HANDLE_VALUE)
    	{
    		printf("Failed to obtain file handle to device: "
    			"%s with Win32 error code: %d
    ",
    			"MyWDMDevice", GetLastError() );
    		return 1;
    	}
    
    	CloseHandle(hDevice);//触发MJ_CLEANUP  MJ_CLOSE
    设备对象一共有3中读写方式:

    1)缓冲区方式读写

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

    用程序提供缓冲区的数据复制到内核模式下的中,无论操作系统怎么切换,内核模式地址都不会改变

    缺点:   影响了运行效率

    下面为 利用缓冲区 方式读设备:(写入数据   

    pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;

    IRP_MJ_READ  的派遣函数主要任务是把任务断的数据复制到AssociatedIrp.SystemBuffer


    NTSTATUS HelloDDKRead(IN PDEV0CE_OBJECT pDevObj,
    								 IN PIRP pIrp) 
    {
    	KdPrint(("Enter HelloDDKRead
    "));
    
    	//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作
    	NTSTATUS status = STATUS_SUCCESS;
    
    	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    	ULONG ulReadLength = stack->Parameters.Read.Length;
    	
    	// 完成IRP
    	//设置IRP完成状态
    	pIrp->IoStatus.Status = status;
    
    	//设置IRP操作了多少字节
    	pIrp->IoStatus.Information = ulReadLength;	// bytes xfered
    
    	memset(pIrp->AssociatedIrp.SystemBuffer,0xAA,ulReadLength);
    
    	//处理IRP
    	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    
    	KdPrint(("Leave HelloDDKRead
    "));
    
    	return status;
    }

    下面为 程序 读取

    	HANDLE hDevice = 
    		CreateFile("\\.\HelloDDK",
    					GENERIC_READ | GENERIC_WRITE,
    					0,		// share mode none
    					NULL,	// no security
    					OPEN_EXISTING,
    					FILE_ATTRIBUTE_NORMAL,
    					NULL );		// no template
    
    
    	if (hDevice == INVALID_HANDLE_VALUE)
    	{
    		printf("Failed to obtain file handle to device: "
    			"%s with Win32 error code: %d
    ",
    			"MyWDMDevice", GetLastError() );
    		return 1;
    	}
    
    
    	UCHAR buffer[10];
    	ULONG ulRead;
    	BOOL bRet = ReadFile(hDevice,buffer,10,&ulRead,NULL);
    	if (bRet)
    	{
    		printf("Read %d bytes:",ulRead);
    		for (int i=0;i<(int)ulRead;i++)
    		{
    			printf("%02X ",buffer[i]);
    		}
    
    
    		printf("
    ");
    	}
    
    
    	CloseHandle(hDevice);
    	return 0;

    下面是程序写入设备 WriteFile 内部产生 IRP_MJ_WRITE 类型的IRP

    派遣函数需要将传送进来的数据保存起来,以便读取该设备的时候读取

    NTSTATUS HelloDDKWrite(IN PDEVICE_OBJECT pDevObj,
    					  IN PIRP pIrp) 
    {
    	KdPrint(("Enter HelloDDKWrite
    "));
    	
    	//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作
    	NTSTATUS status = STATUS_SUCCESS;
    	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
    	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    	ULONG ulWriteLength = stack->Parameters.Write.Length;
    	
    	ULONG ulWriteOffset = (ULONG)stack->Parameters.Write.ByteOffset.QuadPart;
    
    	if (ulWriteOffset + ulWriteLength > 1024)
    	{
    		status = STATUS_FILE_INVALID;
    		ulWriteOffset = 0;
    	}
    	else
    	{
    		memcpy(pDevExt->buffer+ulWriteOffset,
    			pIrp->AssociatedIrp.SystemBuffer,
    			ulWriteLength);
    		status = STATUS_SUCCESS;
    		if (ulWriteLength + ulWriteOffset > pDevExt->File_length)
    		{
    			pDevExt->File_length = ulWriteLength + ulWriteOffset;
    		}
    	}
    	pIrp->IoStatus.Status = status;
    	pIrp->IoStatus.Information = ulWriteLength;
    
    	//处理IRP
    	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    	
    	KdPrint(("Leave HelloDDKWrite
    "));
    	
    	return status;
    }




















  • 相关阅读:
    QQ机器人
    MySQL Hash索引和B-Tree索引的区别
    python format
    Python csv模块的使用
    Python 随机数函数
    关于Python Profilers性能分析器
    数据结构之排序算法Java实现(6)—— 插入类排序之折半插入排序算法
    数据结构之排序算法Java实现(5)—— 插入类排序之直接插入排序算法
    数据结构之排序算法Java实现(4)—— 交换类排序之快速排序算法
    数据结构之排序算法Java实现(3)—— 交换类排序之冒泡排序算法
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982513.html
Copyright © 2011-2022 走看看