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

📄 computer00usbdevice.cpp

📁 usb自定义设备编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	I.CopyParametersDown();
	I.SetCompletionRoutine(LinkTo(OnQueryCapabilitiesComplete), this, TRUE, TRUE, TRUE);

	status = m_Lower.PnpCall(this, I);

	T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::OnQueryCapabilitiesComplete
//		Completion routine for IRP_MJ_PNP subfcn IRP_MN_QUERY_CAPABILITIES. 
//		The system calls OnQueryCapabilities to query the device capabilities.
//		The Bus driver fills in the device capabilities structure.
//		This method is called when the IRP is completed to alter the 
//		device capabilities reported by the bus driver.
//
//	Arguments:
//		IN	I
//			the query capabilities IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::OnQueryCapabilitiesComplete(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.");

	NTSTATUS status = I.Status();


	if (I->PendingReturned)
		I.MarkPending();

	if (NT_SUCCESS(status)) 
	{
		// TODO: Adjust device capabilities structure as required.
		I.DeviceCapabilities()->SurpriseRemovalOK = TRUE;
	}

	T.Trace(TraceInfo, __FUNCTION__"--.");

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::TestBusInterface
//		This routine uses the USB direct client interface to 
//		query information.
//
//	Arguments:
//		none
//
//	Return Value:
//		none
//
void Computer00UsbDevice::TestBusInterface()
{
#if (_WDM_ && (WDM_MAJORVERSION > 1 ||((WDM_MAJORVERSION == 1) && (WDM_MINORVERSION >= 0x20))))

	if (m_fBusIntfAvailable) 
	{
		T.Trace(TraceInfo, "USB Bus Interface Version: %u\n", m_BusIntf.Version());
		T.Trace(TraceInfo, "High Speed Device: %S\n", (m_BusIntf.IsDeviceHighSpeed()?"TRUE":"FALSE"));

		USBD_VERSION_INFORMATION UsbVerInfo;
		RtlZeroMemory(&UsbVerInfo, sizeof(USBD_VERSION_INFORMATION));
		ULONG HcdCapabilities = 0;

		m_BusIntf.GetUSBDIVersion(&UsbVerInfo, &HcdCapabilities);

		T.Trace(TraceInfo, "USBDI_Version: %u\n", UsbVerInfo.USBDI_Version);
		T.Trace(TraceInfo, "Supported_USB_Version: %u\n", UsbVerInfo.Supported_USB_Version);

		ULONG TotalBW, ConsumedBW;
		NTSTATUS Status = m_BusIntf.GetBandwidth(&TotalBW,&ConsumedBW);

		if (STATUS_SUCCESS == Status) 
		{
			T.Trace(TraceInfo, "Total Bandwidth: %u\n", TotalBW);
			T.Trace(TraceInfo, "Consumed Bandwidth: %u\n", ConsumedBW);
		}

		PWSTR HcName = NULL;
		Status = m_BusIntf.GetControllerName(HcName);

		if (STATUS_SUCCESS == Status && HcName) 
		{
			T.Trace(TraceInfo, "HC Name: %s\n", HcName);
			delete HcName;
		}

		ULONG CurrentFrame;
		m_BusIntf.QueryBusTime(&CurrentFrame);

		T.Trace(TraceInfo, "Current Frame: %u\n", CurrentFrame);
	}
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::OnDevicePowerUp
//		Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER 
//		for a request to go to power on state from low power state
//		This function was called by the framework from the completion
//		routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
//		The bus driver has completed the IRP and this driver can now
//		access the hardware device.  
//		This routine runs at DISPATCH_LEVEL.
//
//	Arguments:
//		IN	I
//			the power IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::OnDevicePowerUp(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	// TODO: Add device-specific code to:
	//		 Restore any context to the hardware device that
	//		 was saved during the handling of a power down request.
	//		 See the OnDeviceSleep function.
	//		 Do NOT complete this IRP.
    //		 The base class will handle completion of the IRP

	T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::OnDeviceSleep
//		Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER 
//		for a request to go to a low power state from a high power state
//		This function was called by the framework from the IRP_MJ_POWER 
//		dispatch handler in KPnpDevice prior to forwarding to the PDO.
//		The hardware has yet to be powered down and this driver can now
//		access the hardware device.  
//		This routine runs at PASSIVE_LEVEL.
//
//	Arguments:
//		IN	I
//			the power IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::OnDeviceSleep(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	// TODO: Add device-specific code to:
	//		 Save any context to the hardware device that will be required 
	//		 during a power up request. See the OnDevicePowerUp function.
	//		 Do NOT complete this IRP.  The base class handles forwarding
	//		 this IRP to the PDO.

	T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

	return status;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::Create
//		Dispatch routine for IRP_MJ_CREATE requests.  
//
//	Arguments:
//		IN I 
//			the create IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::Create(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	// TODO: For any IRP, to display the contents of the IRP
	//		 in a formatted way, use the KTrace << operator:
	//			 T << I;

	NTSTATUS status = STATUS_SUCCESS;

	// For devices that expose an interface instead of symbolic 
	// link, DO_EXCLUSIVE flag is not used by the I/O manager.   
	// So, exclusivity must be enforced here.
	if (m_OpenCounter.Test() > 0)
	{
		status = STATUS_SHARING_VIOLATION;

		I.Information() = 0;
		I.PnpComplete(this, status);

		T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

		return status;
	}

	// TODO: At this point, perform custom processing for IRP_MJ_CREATE
	// Generally a create IRP is targeted at our FDO, so its not needed
	// to pass it down to the PDO.  

	I.Information() = 0;
	I.PnpComplete(this, status);

	T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::Close
//		Dispatch routine for IRP_MJ_CLOSE requests.  
//
//	Arguments:
//		IN I 
//			the close IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::Close(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	// TODO: At this point, perform custom processing for IRP_MJ_CLOSE
	// Generally a close IRP is targeted at our FDO, so we don't need
	// to pass it down to the PDO.  

	I.Information() = 0;
	I.PnpComplete(this, status);

	T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::Read
//		Dispatch routine for IRP_MJ_READ requests.  
//
//	Arguments:
//		IN I 
//			the read IRP
//
//	Return Value:
//		NTSTATUS
// 注:用/**/方式注释掉的代码为向导生成的代码
NTSTATUS Computer00UsbDevice::Read(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	//原来向导生成在后面,从后面移动上来
	// Get a pointer to the caller's buffer.
	PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();
	ULONG readSize = I.ReadSize();
	ULONG bytesRead = 0;

	// TODO: Validate the parameters of the IRP.  Replace "FALSE"
	//		 in the following line with error checking code that
	//		 evaulates to TRUE if the request is not valid.
	/*if (FALSE)*/
	if(pBuffer==NULL) //如果准备的读缓冲区为无效地址,则返回参数无效
	{
		status = STATUS_INVALID_PARAMETER; //状态设置为无效参数
		I.Information() = 0; //读取字节数为0
		I.PnpComplete(status); //完成该IO操作
//调试信息
		T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

		return status; //返回状态
	}

	// Always ok to read 0 elements
	if (I.ReadSize() == 0) //如果读长度为0,那么总是成功的
	{
		I.Information() = 0; //读字节数为0
		I.PnpComplete(this, status);  //完成该IO
//调试信息
		T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

		return status;
	}

	/*
	移动到了上面
	// Get a pointer to the caller's buffer.
	PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();
	ULONG readSize = I.ReadSize();
	ULONG bytesRead = 0;
	*/

	// TODO: At this point, perform any processing for IRP_MJ_READ
	//		 To satisfy the read now, transfer data from the driver
	//		 to the caller's buffer at "pBuffer".  Then, indicate
	//		 how much data was transferred:
 
	/**************以下为圈圈新增代码************/
 //创建一个中断传输的URB,用来从端点1读取数据
 PURB pUrb=Ep1In.BuildInterruptTransfer( pBuffer, //接收数据的缓冲区
            readSize, //读数据的数据字节数
            TRUE,  //TRUE表示设备传输的字节数可以少于指定的字节数
            NULL,  //连接下一个传输的URB,这里没有,置为NULL
            NULL,  //指向一个已经存在的URB。置为NULL,分配一个新的URB
            TRUE); //TURE表示读数据

	if(pUrb==NULL)  //如果分配失败
 {
  status=STATUS_INSUFFICIENT_RESOURCES;  //设置状态为资源不足
 }
 else
 {
  //提交URB,并设置等待3秒后就超时
  status=Ep1In.SubmitUrb(pUrb,NULL,NULL,3000);
  //获取实际读到的数据字节数
  bytesRead=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  delete pUrb; //删除刚刚分配的URB
 }
	/*************新增代码完毕****************/

	//保存传输数据的字节数
	I.Information() = bytesRead;
 //完成该IRP
	I.PnpComplete(this, status);

	T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::Write
//		Dispatch routine for IRP_MJ_WRITE requests.  
//
//	Arguments:
//		IN I 
//			the write IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::Write(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

 //原来向导生成在后面,从后面移动上来
	// Get a pointer to the caller's buffer.
	PUCHAR pBuffer = (PUCHAR) I.BufferedWriteSource();
	ULONG writeSize = I.WriteSize();
	ULONG bytesSent = 0;

	// TODO: Validate the parameters of the IRP.  Replace "FALSE"
	//		 in the following line with error checking code that
	//		 evaulates to TRUE if the request is not valid.
	/*if (FALSE)*/
	if(pBuffer==NULL) //如果要发送的数据缓冲区为无效地址,则返回参数无效
	{
		status = STATUS_INVALID_PARAMETER; //状态为无效参数
		I.Information() = 0; //传输字节为0
		I.PnpComplete(status); //完成该IRP

		T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

		return status;
	}

	// Always ok to write 0 elements
	if (I.WriteSize() == 0)  //如果读长度为0,那么总是成功的
	{
		I.Information() = 0;
		I.PnpComplete(this, status);

		T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

		return status;
	}

	/*
	移动到了上面
	// Get a pointer to the caller's buffer.
	//PUCHAR pBuffer = (PUCHAR) I.BufferedWriteSource();
	//ULONG writeSize = I.WriteSize();
	//ULONG bytesSent = 0;
 */

	// TODO: At this point, perform any processing for IRP_MJ_WRITE
	//		 To satisfy the write now, transfer data to the driver
	//		 from the caller's buffer at "pBuffer".  Then, indicate
	//		 how much data was transferred:

	/**************以下为圈圈新增代码************/
 //创建一个中断传输的URB,用来往端点1发送数据
 PURB pUrb=Ep1Out.BuildInterruptTransfer( pBuffer,  //发送数据的缓冲区
            writeSize, //发送数据的数据字节数
            FALSE, //FALSE表示设备传输的字节少数不可以于指定的字节数
            NULL,  //连接下一个传输的URB,这里没有,置为NULL
            NULL,  //指向一个已经存在的URB。置为NULL,分配一个新的URB
            FALSE);  //FALSE表示发送数据

	if(pUrb==NULL)  //如果分配失败
 {
  status=STATUS_INSUFFICIENT_RESOURCES;  //设置状态为资源不足
 }
 else
 {
  //提交URB,并无限等待
  status=Ep1Out.SubmitUrb(pUrb,NULL,NULL,0);
  //获取实际发送的数据字节数
  bytesSent=pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  delete pUrb; //删除刚刚分配的URB
 }
	/*************新增代码完毕****************/

	I.Information() = bytesSent;

	I.PnpComplete(this, status);

	T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

	return status;
}

⌨️ 快捷键说明

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