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

📄 usbsoftlockdevice.cpp

📁 < FPGA数字电子系统设计与开发实例导航> 一书的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//  USBSoftLockDevice::Close
//
//	Routine Description:
//		Handler for IRP_MJ_CLOSE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

NTSTATUS USBSoftLockDevice::Close(KIrp I)
{
	NTSTATUS status;

	t << "Entering USBSoftLockDevice::Close, " << I << EOL;

// TODO: Add driver specific close handling code here

	// Generally a close IRP is targeted at our FDO, so we don't need
	// to pass it down to the PDO.  We have found for some devices, the
	// PDO is not expecting this Irp and returns an error code.
	// The default wizard code, therefore completes the Irp here using
	// PnpComplete().  The following commented code could be used instead
	// of PnpComplete() to pass the Irp to the PDO, which would complete it.
	//
//	I.ForceReuseOfCurrentStackLocationInCalldown();
//	status = m_Lower.PnpCall(this, I);

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

	t << "USBSoftLockDevice::Close Status " << (ULONG)status << EOL;

    return status;
}

////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::Cleanup
//
//	Routine Description:
//		Handler for IRP_MJ_CLEANUP	
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

NTSTATUS USBSoftLockDevice::CleanUp(KIrp I)
{
	t << "Entering CleanUp, " << I << EOL;

// TODO:	Insert your code to respond to the CLEANUP message.
	return I.PnpComplete(this, STATUS_SUCCESS);
}


////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::Read
//
//	Routine Description:
//		Handler for IRP_MJ_READ
//
//	Parameters:
//		I			Current IRP
//
//	Return Value:
//		NTSTATUS	Result code
//
//	Comments:
//		This routine handles read requests.
//
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//

NTSTATUS USBSoftLockDevice::Read(KIrp I) 
{
	t << "Entering USBSoftLockDevice::Read, " << I << EOL;
// TODO:	Check the incoming request.  Replace "FALSE" in the following
//			line with a check that returns TRUE if the request is not valid.

    if (FALSE)		// If (Request is invalid)
	{
		// Invalid parameter in the Read request
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
	}

	// Always ok to read 0 elements.
	if (I.ReadSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	// Declare a memory object
	KMemory Mem(I.Mdl());

    ULONG dwTotalSize = I.ReadSize(CURRENT);
	ULONG dwMaxSize = m_Endpoint2IN.MaximumTransferSize();

	// If the total requested read size is greater than the Maximum Transfer
	// Size for the Pipe, request to read only the Maximum Transfer Size since
	// the bus driver will fail an URB with a TransferBufferLength of greater
	// than the Maximum Transfer Size. 
	if (dwTotalSize > dwMaxSize)
	{
		ASSERT(dwMaxSize);
		dwTotalSize = dwMaxSize;
	}

	// Allocate a new context structure for Irp completion
	USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
	if (pCompInfo == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

// TODO:	Select the correct pipe to read from

	// Create an URB to do actual Bulk read from the pipe
	PURB pUrb = m_Endpoint2IN.BuildBulkTransfer(
			    	Mem,      		// Where is data coming from?
					dwTotalSize,  	// How much data to read?
					TRUE,         	// direction (TRUE = IN)
					NULL,			// Link to next URB
					TRUE			// Allow a short transfer
					);        		

	if (pUrb == NULL)
	{
		delete pCompInfo;
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	// Initialize context structure
	pCompInfo->m_pClass = this;
	pCompInfo->m_pUrb = pUrb;

    // Submit the URB to our USB device
	NTSTATUS status;
	status = m_Endpoint2IN.SubmitUrb(I, pUrb, LinkTo(ReadComplete), pCompInfo, 0);
	return status;
}

////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::ReadComplete
//
//	Routine Description:
//		Completion Handler for IRP_MJ_READ
//
//	Parameters:
//		I - IRP just completed by USB
//		pContext - Context structure containing pointer to Urb
//
//	Parameters:
//		NTSTATUS - STATUS_SUCCESS
//
//	Comments:
//		This routine is called when USBD completes the read request
//

NTSTATUS USBSoftLockDevice::ReadComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
	// Normal completion routine code to propagate pending flag

	if (I->PendingReturned) 
	{
		I.MarkPending();
	}
	
	NTSTATUS status = I.Status();
	PURB pUrb = pContext->m_pUrb;
	ULONG nBytesRead = 0;

	if ( NT_SUCCESS(status) ) 
	{
		nBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
		if (nBytesRead > 0) 
			t << "Read() got " << nBytesRead<< " bytes from USB\n";
    }

	// Deallocate Urb and context structure
	delete pUrb;
	delete pContext;

	// set returned count
	I.Information() = nBytesRead;
	
	// Plug and Play accounting
	DecrementOutstandingRequestCount();

	// allow IRP completion processing
	return STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::Write
//
//	Routine Description:
//		Handler for IRP_MJ_WRITE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//		This routine handles write requests.
//
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//

NTSTATUS USBSoftLockDevice::Write(KIrp I) 
{
	t << "Entering USBSoftLockDevice::Write, " << I << EOL;
// TODO:	Check the incoming request.  Replace "FALSE" in the following
//			line with a check that returns TRUE if the request is not valid.
    if (FALSE)
	{
		// Invalid parameter in the Write request
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
	}

	// Always ok to write 0 elements.
	if (I.WriteSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}
	ULONG dwTotalSize = I.WriteSize(CURRENT);
	ULONG dwMaxSize = m_Endpoint2OUT.MaximumTransferSize();

	// If the total requested read size is greater than the Maximum Transfer
	// Size for the Pipe, request to read only the Maximum Transfer Size since
	// the bus driver will fail an URB with a TransferBufferLength of greater
	// than the Maximum Transfer Size. 
	if (dwTotalSize > dwMaxSize)
	{
		ASSERT(dwMaxSize);
		dwTotalSize = dwMaxSize;
	}

	// Declare a memory object
	KMemory Mem(I.Mdl());

	// Allocate a new context structure for Irp completion
	USB_COMPLETION_INFO* pCompInfo = new (NonPagedPool) USB_COMPLETION_INFO;
	if (pCompInfo == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

// TODO:	Select the correct pipe to write to

	// Create an URB to do actual Bulk write to the pipe
	PURB pUrb = m_Endpoint2OUT.BuildBulkTransfer(
					Mem,          // Where is data coming from?
					dwTotalSize,  // How much data to read?
					FALSE,        // direction (FALSE = OUT)
					NULL		  // Link to next URB
					);	        

	if (pUrb == NULL)
	{
		delete pCompInfo;
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	// Initialize context structure
	pCompInfo->m_pClass = this;
	pCompInfo->m_pUrb = pUrb;

    // Submit the URB to our USB device
	NTSTATUS status;
	status = m_Endpoint2OUT.SubmitUrb(I, pUrb, LinkTo(WriteComplete), pCompInfo, 0);
	return status;
}

////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::WriteComplete
//
//	Routine Description:
//		Completion Handler for IRP_MJ_WRITE
//
//	Parameters:
//		I - IRP just completed by USB
//		pContext - Context structure containing pointer to Urb
//
//	Return Value:
//		NTSTATUS	STATUS_SUCCESS
//
//	Comments:
//		This routine is called when USBD completes the write request
//

NTSTATUS USBSoftLockDevice::WriteComplete(KIrp I, USB_COMPLETION_INFO* pContext)
{
	// Normal completion routine code to propagate pending flag

	if (I->PendingReturned) 
	{
		I.MarkPending();
	}
	
	NTSTATUS status = I.Status();
	PURB pUrb = pContext->m_pUrb;
	ULONG nBytesWritten = 0;

	if ( NT_SUCCESS(status) ) 
	{
		nBytesWritten = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
		if (nBytesWritten > 0) 
			t << "Wrote " << nBytesWritten	<< " bytes to USB\n";
    }

	// Deallocate Urb and context structure
	delete pUrb;
	delete pContext;

	// set returned count
	I.Information() = nBytesWritten;
	
	// Plug and Play accounting
	DecrementOutstandingRequestCount();

	// allow IRP completion processing
	return STATUS_SUCCESS;
}

////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::DeviceControl
//
//	Routine Description:
//		Handler for IRP_MJ_DEVICE_CONTROL
//
//	Parameters:
//		I - Current IRP
// 
//	Return Value:
//		None
//
//	Comments:
//		This routine is the first handler for Device Control requests.
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//

NTSTATUS USBSoftLockDevice::DeviceControl(KIrp I) 
{
	NTSTATUS status;

	t << "Entering USBSoftLockDevice::Device Control, " << I << EOL;
	switch (I.IoctlCode())
	{
		case USBSOFTLOCK_IOCTL_GET_PASSWORD:
			status = USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler(I);
			break;

		case USBSOFTLOCK_IOCTL_SET_PASSWORD:
			status = USBSOFTLOCK_IOCTL_SET_PASSWORD_Handler(I);
			break;

		default:
			// Unrecognized IOCTL request
			status = STATUS_INVALID_PARAMETER;
			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)
	{
		return status;
	}
	else
	{
		return I.PnpComplete(this, status);
	}
}

////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler
//
//	Routine Description:
//		Handler for IO Control Code USBSOFTLOCK_IOCTL_GET_PASSWORD
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the USBSOFTLOCK_IOCTL_GET_PASSWORD function.
//		This routine runs at passive level.
//

NTSTATUS USBSoftLockDevice::USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering USBSoftLockDevice::USBSOFTLOCK_IOCTL_GET_PASSWORD_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the USBSOFTLOCK_IOCTL_GET_PASSWORD request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.

	t << "IOctrlBuffer address is " << (LONG)(I.IoctlBuffer()) << EOL;
	t << "BufferedReadDest address is " << (LONG)(I.BufferedReadDest()) << EOL;
	t << "BufferedWriteSource address is " << (LONG)(I.BufferedWriteSource()) << EOL;
	t << "IoctlOutputBufferSize is " << (LONG)(I.IoctlOutputBufferSize()) << EOL;

	UCHAR buffer[8];

	// build vendor request
	PURB pUrb = m_Lower.BuildVendorRequest(
		buffer,
		PASSWORD_LENGTH,
		0,
		REQUEST_GET_PASSWORD,
		0,
		TRUE );
	status = m_Lower.SubmitUrb(pUrb, NULL, NULL, OPERATION_TIMEOUT);

	if (status == STATUS_SUCCESS) {
		t << "Received buffer is ";
		for (int i=0;i<PASSWORD_LENGTH;i++) {
			t << " " << buffer[i];
		} 
		t << EOL;
		PUCHAR output_buffer = (PUCHAR)(I.IoctlBuffer());
		memcpy(output_buffer, buffer, PASSWORD_LENGTH);
	}
	else {
	}

	return status;
}

////////////////////////////////////////////////////////////////////////
//  USBSoftLockDevice::USBSOFTLOCK_IOCTL_SET_PASSWORD_Handler
//
//	Routine Description:
//		Handler for IO Control Code USBSOFTLOCK_IOCTL_SET_PASSWORD
//
//	Parameters:
//		I - IRP containing IOCTL request
//
//	Return Value:
//		NTSTATUS - Status code indicating success or failure
//
//	Comments:
//		This routine implements the USBSOFTLOCK_IOCTL_SET_PASSWORD function.
//		This routine runs at passive level.
//

NTSTATUS USBSoftLockDevice::USBSOFTLOCK_IOCTL_SET_PASSWORD_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering USBSoftLockDevice::USBSOFTLOCK_IOCTL_SET_PASSWORD_Handler, " << I << EOL;
// TODO:	Verify that the input parameters are correct
//			If not, return STATUS_INVALID_PARAMETER

// TODO:	Handle the the USBSOFTLOCK_IOCTL_SET_PASSWORD request, or 
//			defer the processing of the IRP (i.e. by queuing) and set
//			status to STATUS_PENDING.

// TODO:	Assuming that the request was handled here. Set I.Information
//			to indicate how much data to copy back to the user.
	I.Information() = PASSWORD_LENGTH;
	UCHAR buffer[PASSWORD_LENGTH];
	memset(buffer, 0, PASSWORD_LENGTH);

	PUCHAR input_buffer = (PUCHAR)(I.IoctlBuffer());
	memcpy(buffer, input_buffer, PASSWORD_LENGTH);

	t << "Buffer to send is ";
	for (int i=0;i<PASSWORD_LENGTH;i++) {
		t << " " << buffer[i];
	} 
	t << EOL;

	// build vendor request
	PUSHORT value, index; 
	PURB pUrb;

	value = (PUSHORT)buffer;
	index = (PUSHORT)(buffer+2);
	
	pUrb = m_Lower.BuildVendorRequest(
		NULL,
		0,
		0,
		REQUEST_SET_PASSWORD_HIGH,
		(*value),
		FALSE,
		FALSE,
		NULL,
		(*index));
	status = m_Lower.SubmitUrb(pUrb, NULL, NULL, OPERATION_TIMEOUT);

	value = (PUSHORT)(buffer+4);
	index = (PUSHORT)(buffer+6);
	pUrb = m_Lower.BuildVendorRequest(
		NULL,
		0,
		0,
		REQUEST_SET_PASSWORD_LOW,
		(*value),
		FALSE,
		FALSE,
		NULL,
		(*index));
	status = m_Lower.SubmitUrb(pUrb, NULL, NULL, OPERATION_TIMEOUT);

	return status;
}

⌨️ 快捷键说明

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