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

📄 computer00usbdevice.cpp

📁 usb自定义设备编程
💻 CPP
📖 第 1 页 / 共 3 页
字号:

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

	NTSTATUS status = STATUS_SUCCESS;

	switch (I.IoctlCode())
	{

    case EP1_READ:
		status = EP1_READ_Handler(I);
		break;

    case EP1_WRITE:
		status = EP1_WRITE_Handler(I);
		break;

    case EP2_READ:
		status = EP2_READ_Handler(I);
		break;

    case EP2_WRITE:
		status = EP2_WRITE_Handler(I);
		break;

	default:
		status = STATUS_INVALID_DEVICE_REQUEST;
		break;
	}

	// If the IRP's IOCTL handler deferred processing using some driver
	// specific scheme, the status variable is set to STATUS_PENDING.
	// In this case we simply return that status, and the IRP will be
	// completed later.  Otherwise, complete the IRP using the status
	// returned by the IOCTL handler.
	if (status != STATUS_PENDING)
	{
		I.PnpComplete(this, status);
	}

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

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::EP1_READ_Handler
//		Handler for ioctl EP1_READ.  The DeviceControl
//		method will complete the IRP.
//
//	Arguments:
//		IN I 
//			the ioctl IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP1_READ_Handler(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	ULONG inputSize = I.IoctlInputBufferSize();
	ULONG outputSize = I.IoctlOutputBufferSize();

 // Buffered ioctl - using the same buffer so read the buffer before writing the buffer
 PVOID inputBuffer = I.IoctlBuffer();
 PVOID outputBuffer = I.IoctlBuffer();

	// 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(outputBuffer==NULL) //如果缓冲区为无效地址
	{
		status = STATUS_INVALID_PARAMETER;
		I.Information() = 0;
	}
	else //如果参数有效
	{
	
		// TODO: copy data
		//		 To satisfy the ioctl now, transfer data using the
		//		 caller's buffers at "inputBuffer" and/or "outputBuffer".  
		//		 Then, indicate how much data was transferred:
		/**************以下为圈圈新增代码************/
		if(outputSize==0) //如果读数据长度为0,则不用传输数据
		{
			I.Information() = 0;
		}
		else //数据长度不为0
		{
   //创建一个中断传输的URB,用来从端点1读取数据
   PURB pUrb=Ep1In.BuildInterruptTransfer(outputBuffer, //接收数据的缓冲区
              outputSize, //读数据的数据字节数
              TRUE,  //TRUE表示设备传输的字节数可以少于指定的字节数
              NULL,  //连接下一个传输的URB,这里没有,置为NULL
              NULL,  //指向一个已经存在的URB。置为NULL,分配一个新的URB
              TRUE);  //TURE表示读数据

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

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

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::EP1_WRITE_Handler
//		Handler for ioctl EP1_WRITE.  The DeviceControl
//		method will complete the IRP.
//
//	Arguments:
//		IN I 
//			the ioctl IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP1_WRITE_Handler(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	ULONG inputSize = I.IoctlInputBufferSize();
	ULONG outputSize = I.IoctlOutputBufferSize();

 // Buffered ioctl - using the same buffer so read the buffer before writing the buffer
 PVOID inputBuffer = I.IoctlBuffer();
 PVOID outputBuffer = I.IoctlBuffer();

	// 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(inputBuffer==NULL) //如果输入缓冲区为无效地址
	{
		status = STATUS_INVALID_PARAMETER;
		I.Information() = 0;
	}
	else
	{
	
		// TODO: copy data
		//		 To satisfy the ioctl now, transfer data using the
		//		 caller's buffers at "inputBuffer" and/or "outputBuffer".  
		//		 Then, indicate how much data was transferred:

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

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

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

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::EP2_READ_Handler
//		Handler for ioctl EP2_READ.  The DeviceControl
//		method will complete the IRP.
//
//	Arguments:
//		IN I 
//			the ioctl IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP2_READ_Handler(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	ULONG inputSize = I.IoctlInputBufferSize();
	ULONG outputSize = I.IoctlOutputBufferSize();

 // Buffered ioctl - using the same buffer so read the buffer before writing the buffer
 PVOID inputBuffer = I.IoctlBuffer();
 PVOID outputBuffer = I.IoctlBuffer();

	// 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(outputBuffer==NULL) //如果缓冲区为无效地址
	{
		status = STATUS_INVALID_PARAMETER;
		I.Information() = 0;
	}
	else //如果参数有效
	{
	
		// TODO: copy data
		//		 To satisfy the ioctl now, transfer data using the
		//		 caller's buffers at "inputBuffer" and/or "outputBuffer".  
		//		 Then, indicate how much data was transferred:

		/**************以下为圈圈新增代码************/
		if(outputSize==0) //如果读数据长度为0,则不用传输数据
		{
			I.Information() = 0;
		}
		else //数据长度不为0
		{
			//创建一个批量传输的URB,用来从端点2读取数据
			PURB pUrb=Ep2In.BuildBulkTransfer( outputBuffer,  //接收数据的缓冲区
														outputSize, //读数据的数据字节数
														TRUE,  //TURE表示读数据
														NULL,  //连接下一个传输的URB,这里没有,置为NULL
														TRUE,  //TRUE表示设备传输的字节数可以少于指定的字节数
														NULL);  //指向一个已经存在的URB。置为NULL,分配一个新的URB

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

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

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::EP2_WRITE_Handler
//		Handler for ioctl EP2_WRITE.  The DeviceControl
//		method will complete the IRP.
//
//	Arguments:
//		IN I 
//			the ioctl IRP
//
//	Return Value:
//		NTSTATUS
//
NTSTATUS Computer00UsbDevice::EP2_WRITE_Handler(KIrp I)
{
	T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

	NTSTATUS status = STATUS_SUCCESS;

	ULONG inputSize = I.IoctlInputBufferSize();
	ULONG outputSize = I.IoctlOutputBufferSize();

	// Buffered ioctl - using the same buffer so read the buffer before writing the buffer
 PVOID inputBuffer = I.IoctlBuffer();
 PVOID outputBuffer = I.IoctlBuffer();

	// 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(inputBuffer==NULL) //如果输入缓冲区为无效地址
	{
		status = STATUS_INVALID_PARAMETER;
		I.Information() = 0;
	}
	else
	{
		// TODO: copy data
		//		 To satisfy the ioctl now, transfer data using the
		//		 caller's buffers at "inputBuffer" and/or "outputBuffer".  
		//		 Then, indicate how much data was transferred:
		/**************以下为圈圈新增代码************/
		if(inputSize==0) //如果输出数据长度为0,则不用传输数据
		{
			I.Information() = 0;
		}
		else //数据长度不为0
		{
			//创建一个批量传输的URB,用来往端点2发送数据
			PURB pUrb=Ep2Out.BuildBulkTransfer( inputBuffer,  //发送数据的缓冲区
														inputSize, //发送数据的数据字节数
														FALSE,  //FALSE表示发送数据
														NULL,  //连接下一个传输的URB,这里没有,置为NULL
														FALSE,  //FALSE表示设备传输的字节少数不可以于指定的字节数
														NULL);  //指向一个已经存在的URB。置为NULL,分配一个新的URB

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

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

	return status;
}

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

	NTSTATUS status = STATUS_SUCCESS;

	// TODO: At this point, perform custom processing for IRP_MJ_CLEANUP

	I.PnpComplete(this, status);

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

	return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Computer00UsbDevice::Invalidate
//		This method performs resource cleanup.
//		This function is called from OnStopDevice, OnRemoveDevice and
//		OnStartDevice (in error conditions).  It calls the Invalidate
//		member funcitons for each resource to free the underlying system
//		resource if allocated.  It is safe to call Invalidate more than
//		once for a resource, or for an uninitialized resource.
//
//	Arguments:
//		none
//
//	Return Value:
//		none
//
VOID Computer00UsbDevice::Invalidate()
{
	NTSTATUS status = STATUS_SUCCESS;

	status = m_Lower.DeActivateConfiguration();
	if (!NT_SUCCESS(status))
	{
		T.Trace(TraceWarning, __FUNCTION__" DeActivateConfiguration failed, STATUS %x\n", status);
	}

	m_Lower.ReleaseResources();

    // Free our registry value buffer
    if (DeviceName != NULL)
    {
        delete DeviceName;
        DeviceName = NULL;
    }

}

⌨️ 快捷键说明

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