⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drvpnp.c

📁 ddk编写的usb驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
*					FALSE			-	处理还没完,调用者应该接着执行以后的操作
* Description		:	放弃停止设备
*************************************************************************************************/
BOOLEAN hwCancelStopDevice(IN  PDEVICE_OBJECT fdo, IN PIRP Irp, IN PNTSTATUS p_ntStatus)
{
	PDEVICE_EXTENSION		dx;	
	hwDbgPrint(" -->>>>>> hwCancelStopDevice(fdo=0x%x,Irp=0x%x,p_ntStatus=0x%x)\n",fdo,Irp,p_ntStatus);	
	dx = fdo->DeviceExtension;
	(*p_ntStatus) = STATUS_SUCCESS;
	
	//------------------------------------------------------------------
	// Pnp管理器使用这个IRP来通知驱动不会停止设备
	// 重新分配资源
	//------------------------------------------------------------------
		
	// 当设备没有启动的时候可能会收到这个IRP,将这个IRP交给下层驱动处理
	if (!dx->DeviceStarted)
	{
		hwDbgPrint("IRP_MN_CANCEL_STOP_DEVICE when device not started\n");
		IoSkipCurrentIrpStackLocation (Irp);
		(*p_ntStatus) = IoCallDriver (dx->LowerDeviceObject, Irp);
		hwDecrementIoCount(fdo);
		hwDbgPrint(" hwCancelStopDevice(ntStatus = 0x%x)-->>>>>>\n",(*p_ntStatus));
		return TRUE;
	}
	// 重设这个标志,以后IOCTL和IO Irp处理将重新被允许
	dx->StopDeviceRequested = FALSE;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	(*p_ntStatus) = Irp->IoStatus.Status;
	hwDbgPrint(" hwCancelStopDevice(ntStatus = 0x%x)-->>>>>>\n",(*p_ntStatus));
	return FALSE;
}

/************************************************************************************************
* Function Type	:	private
* Parameter		:	fdo				-	pointer to our FDO (Functional Device Object )
* Return Value	:	TRUE			-	已经处理完了,调用者可以停止以后的处理
*										直接返回
*					FALSE			-	处理还没完,调用者应该接着执行以后的操作
* Description		:	移除设备
*************************************************************************************************/
BOOLEAN hwRemoveDevice(IN  PDEVICE_OBJECT fdo, IN PIRP Irp, IN PNTSTATUS p_ntStatus)
{
	PDEVICE_EXTENSION		dx;	
	UNICODE_STRING			deviceLinkUnicodeString;
	NTSTATUS				ntStatus = STATUS_SUCCESS;
	
	hwDbgPrint(" -->>>>>> hwRemoveDevice(fdo=0x%x,Irp=0x%x,p_ntStatus=0x%x)\n",fdo,Irp,p_ntStatus);	
	dx = fdo->DeviceExtension;
	(*p_ntStatus) = STATUS_SUCCESS;
	
	//------------------------------------------------------------------
	// Pnp管理器使用这个IRP来移走一个设备
	// 作为一个"礼貌"的移走设备,Pnp管理器在移走设
	// 备前先发送IRP_MN_QUERY_REMOVE_DEVICE
	//------------------------------------------------------------------
		
	hwDecrementIoCount(fdo);
		
	// 一旦DeviceRemoved标志被设置,IOCTL or read/write irps将被直接
	// 发送到下层驱动,所有的irps将很快地处理失败
	dx->DeviceRemoved = TRUE;
		
	// 如果任何管道仍然是打开的,用URB_FUNCTION_ABORT_PIPE
	// 调用USBD来放弃所有管道并关闭所有管道
	hwAbortPipes( fdo );
		
	// We don't explicitly wait for the below driver to complete, but just make
	// the call and go on, finishing cleanup
	IoCopyCurrentIrpStackLocationToNext(Irp);
		
	(*p_ntStatus) = IoCallDriver(dx->LowerDeviceObject,Irp);

	//再次减1,正在处理的IRP数量在AddDevice中
	//初始化为1,也就是说只有停止事件被
	//标记,而要想卸载事件被标记,必须多
	//减一次,当所有的IRP处理结束时,这个
	//数量才会变成0,卸载事件才会被标记	
	hwDecrementIoCount(fdo);
		
	// 等待设备所有正在处理的IO请求完成
	KeWaitForSingleObject(	&dx->RemoveEvent,
						Suspended,
						KernelMode,
						FALSE,
						NULL);
		
	dx = fdo->DeviceExtension;	
	RtlInitUnicodeString (&deviceLinkUnicodeString,dx->DeviceLinkNameBuffer);
	
	// remove the GUID-based symbolic link
	ntStatus = IoSetDeviceInterfaceState(&deviceLinkUnicodeString, FALSE);
	hwASSERT( NT_SUCCESS( ntStatus ) );

	FreeDx( dx );
	
	hwDbgPrint("Detaching from 0x%x\n",dx->LowerDeviceObject);
	IoDetachDevice(dx->LowerDeviceObject);
	hwDbgPrint("Deleting fdo = 0x%08x\n",fdo);
	IoDeleteDevice (fdo);

	hwDbgPrint(" hwRemoveDevice(ntStatus = 0x%x)-->>>>>>\n",(*p_ntStatus));

	return TRUE;
}

/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo			-	pointer to our FDO (Functional Device Object )
* Return Value	:	NT status code
* Description		:	停止一个给定的USB设备实例
*					基本上我们只是告诉这个设备现在是'没有配置'的状态
*************************************************************************************************/
NTSTATUS hwStopDevice(IN  PDEVICE_OBJECT fdo)
{
	PDEVICE_EXTENSION		dx;
	NTSTATUS				ntStatus = STATUS_SUCCESS;
	PURB					urb;
	ULONG					siz;

	//------------------------------------------------------------------
	// Pnp 管理器发送这个IRP来停止一个设备,因此它
	// 能重新配置硬件资源。Pnp管理器只是在
	// IRP_MN_QUERY_STOP_DEVICE成功处理后才发送这个IRP的
	//------------------------------------------------------------------
		
	hwDbgPrint(" -->>>>>> hwStopDevice(fdo=0x%x)\n",fdo);	
	dx = fdo->DeviceExtension;
	
	//------------------------------------------------------------------
	// 发送选择配置的urb且配置句柄用NULL,这里将关闭配置
	// 将设备置为没有"没有配置"的状态
	//------------------------------------------------------------------
	
	siz = sizeof(struct _URB_SELECT_CONFIGURATION);
	
	urb = ExAllocatePool(NonPagedPool, siz);
	
	if (urb)
	{
		UsbBuildSelectConfigurationRequest(urb,(USHORT) siz,NULL);
		ntStatus = hwCallUSBD(fdo, urb);
		hwDbgPrint("hwCallUSBD() Configuration Closed status = 0x%x usb status = 0x%x\n", ntStatus, urb->UrbHeader.Status);
		FreeIfAllocated(urb);
	}	
	else 
	{
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
	}	
	
	if (NT_SUCCESS(ntStatus))
	{
		dx->DeviceStarted = FALSE;
	}
	
	dx->StopDeviceRequested = FALSE;
	
	hwDbgPrint("hwStopDevice() (ntStatus = %x)-->>>>>>\n", ntStatus);
	
	return ntStatus;
}

/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo					-	pointer to fdo pointer to return created device object.
*					deviceLinkUnicodeString -	Points to a unicode string structure allocated by the caller. 
*											If this routine is successful, it initializes the unicode string and allocates 
*											the string buffer containing the kernel-mode path to the symbolic link for this 
*											device interface. 
* Return Value	:	STATUS_SUCCESS			-	if successful,
*					STATUS_UNSUCCESSFUL	-	otherwise
* Description		:	This routine is called to create and initialize
*					a GUID-based symbolic link to our device to be used to open/create 
*					instances of us from user mode.
*					Called from hwCreateDeviceObject() to create the link. 
*************************************************************************************************/
NTSTATUS hwRegisterSymbolicLink
(
	IN PDEVICE_OBJECT		pdo,
	IN PDEVICE_OBJECT		fdo,
	IN OUT PUNICODE_STRING	deviceLinkUnicodeString
)
{
	NTSTATUS					ntStatus = STATUS_SUCCESS;
	PDEVICE_EXTENSION			dx = fdo->DeviceExtension;
	
	//------------------------------------------------------------------
	//生成一个符号连接,IoRegisterDeviceInterfaceAPI将注册一个供
	//应用程序或其他系统组件使用的设备功能接口
	//------------------------------------------------------------------
	ntStatus = IoRegisterDeviceInterface(
									 pdo,
									 (LPGUID)&GUID_CLASS_zjHMCFUsb_BULK,
									 NULL,
									 deviceLinkUnicodeString);
	hwDbgPrint("%s to IoRegisterDeviceInterface()\n",NT_SUCCESS(ntStatus)?"Success":"Fail");
	if (NT_SUCCESS(ntStatus))
	{
		// 将设备连接名拷贝到设备扩展结构体中
		RtlCopyMemory (	dx->DeviceLinkNameBuffer,
					deviceLinkUnicodeString->Buffer,
					deviceLinkUnicodeString->Length );
		hwDbgPrint ( "SymbolicLink : %s\n",	dx->DeviceLinkNameBuffer );
		// IoSetDeviceInterfaceState 函数禁用或启用一个先前已经注册的符号连接
		ntStatus = IoSetDeviceInterfaceState(deviceLinkUnicodeString, TRUE);
		hwDbgPrint("%s  to IoSetDeviceInterfaceState()\n",NT_SUCCESS(ntStatus)?"Success":"Fail");
	}

	return ntStatus;
}

/************************************************************************************************
* Function Type	:	global
* Parameter		:	DriverObject			-	pointer to the driver object for device
*					pdo	-	pointer to a device object created by the bus
*					fdo					-	pointer to fdo pointer to return created device object.
* Return Value	:	STATUS_SUCCESS			-	if successful,
*					STATUS_UNSUCCESSFUL	-	otherwise
* Description		:	根据系统提供的驱动对象、物理设备对象创建一个功能
*					设备对象
*************************************************************************************************/
NTSTATUS hwCreateDeviceObject
(
	IN	PDRIVER_OBJECT		DriverObject,
	IN	PDEVICE_OBJECT		pdo,
	OUT	PDEVICE_OBJECT		*ppDeviceObject
)
{
	NTSTATUS ntStatus;
	PDEVICE_EXTENSION dx;
	USHORT i;
	
	hwDbgPrint(" -->>>>>> hwCreateDeviceObject()\n");
	hwDbgPrint ( "DriverObject=0x%x\n",DriverObject );
	hwDbgPrint ( "pdo=0x%x\n",pdo );
	hwDbgPrint ( "ppDeviceObject=0x%x\n",ppDeviceObject );
	
	//IoCreateDevice函数申请内存并初始化一个驱动使用的设备对象
	//设备对象就是驱动所支持的物理、虚拟或逻辑设备
	ntStatus = IoCreateDevice (
				DriverObject,						//Points to the driver object for the caller. 
													//Each driver receives a pointer to its driver 
													//object in a parameter to its DriverEntry 
													//routine. PnP function and filter drivers also 
													//receive a driver object pointer in their 
													//AddDevice routines. 
													
				sizeof (DEVICE_EXTENSION),			//设备扩展结构的大小
				
				NULL,								//设备名字,过滤驱动和功
													//能驱动一般不命名,核心
													//的总线驱动则指定一个
													//unicode字符串作为设备的名字
													
				FILE_DEVICE_UNKNOWN,				//设备类型(such as FILE_DEVICE_DISK, FILE_DEVICE_KEYBOARD, etc.) 
				
				FILE_AUTOGENERATED_DEVICE_NAME,	//提供设备附加信息
													//FILE_AUTOGENERATED_DEVICE_NAME表示
													//设备名字由I/O管理器自动创建,这样
													//可以保证名字的唯一性
													
				FALSE,								//不是一个排他性的设备,I/O管理器允许打开该设备的多个句柄
													
				ppDeviceObject						//指向新生成的设备对象
				);
	if (!NT_SUCCESS(ntStatus))
	{
		hwDbgPrint("IoCreateDevice() FAILED\n");
		goto done;
	}
	hwDbgPrint("IoCreateDevice() SUCCESS\n");
	dx = (PDEVICE_EXTENSION) ((*ppDeviceObject)->DeviceExtension);
	if ( !InitDx ( dx ) )
	{
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		IoDeleteDevice( *ppDeviceObject );
		goto done;
	}
	
done:
	hwDbgPrint(" hwCreateDeviceObject() -->>>>>> \n");
	return ntStatus;
}
/************************************************************************************************
* Function Type	:	global
* Parameter		:	fdo				-	Pointer to the device object for the class device.
*					Irp				-	Irp completed.
*					Context			-	Driver defined context, in this case a pointer to an event.
* Return Value	:	The function value is the final status from the operation.
* Description		:	这是一个最简单的irp完成例程,只是将事件置个信号
*					以通知正在等待的调用者
*************************************************************************************************/
NTSTATUS hwIRPCompletionRoutine
(
	IN	PDEVICE_OBJECT		fdo,
	IN	PIRP					Irp,
	IN	PVOID				Context
)
{
	PKEVENT event = (PKEVENT)Context;

	KeSetEvent(	event,
				1,		// 正在等待的线程优先权增加
				FALSE);	// Flag this call is not immediately followed by wait.

	// 这个例程必须返回STATUS_MORE_PROCESSING_REQUIRED,因为我们在这
	// 个irp上从未调用过IoFreeIrp()
	return STATUS_MORE_PROCESSING_REQUIRED;
}

/************************************************************************************************
* Function Type	:	private
* Parameter		:	LowerDeviceObject			-	在这个设备栈下层的设备对象.
*					DeviceCapabilities			-	设备性能对象指针

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -