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

📄 d12_driverdevice.cpp

📁 用DriverWizard开发的D12开发板驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//	Comments:
//

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

	t << "Entering D12_DriverDevice::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 << "D12_DriverDevice::Close Status " << (ULONG)status << EOL;

    return status;
}

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

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

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

////////////////////////////////////////////////////////////////////////
//  D12_DriverDevice::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 D12_DriverDevice::DeviceControl(KIrp I) 
{
	NTSTATUS status;

	t << "Entering D12_DriverDevice::Device Control, " << I << EOL;
	switch (I.IoctlCode())
	{
		case D12_DRIVER_READ:
			status = D12_DRIVER_READ_Handler(I);
			break;

		case D12_DRIVER_WRITE:
			status = D12_DRIVER_WRITE_Handler(I);
			break;
		case D12_DRIVER_BULK_IN:
			status = D12_DRIVER_BULK_IN_Handler(I);
			break;

		case D12_DRIVER_BULK_OUT:
			status = D12_DRIVER_BULK_OUT_Handler(I);
			break;
		case D12_DRIVER_VENDOR_REQUEST:
			status = D12_DRIVER_VENDOR_REQUEST_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);
	}
}

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

NTSTATUS D12_DriverDevice::D12_DRIVER_READ_Handler(KIrp I)
{
	PURB pUrb;
	NTSTATUS status;

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

// TODO:	Handle the the D12_DRIVER_READ 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.
	// Always ok to read 0 elements.
	if (I.IoctlOutputBufferSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	// Declare a memory object

    ULONG dwTotalSize = I.IoctlInputBufferSize(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;
	}
    ULONG dwBytesRead = 0;

	pUrb = m_Endpoint1In.BuildInterruptTransfer(
				(unsigned char *)I.IoctlBuffer(),		// transfer buffer
				I.IoctlInputBufferSize(),								// transfer buffer size
				TRUE,							// Short Ok
				NULL,							// link urb
				NULL							// new urb
				);

	if ( pUrb != NULL)
	{
	    // Submit the URB to our USB device, synchronously - say less is OK
//		pUrb->UrbBulkOrInterruptTransfer.TransferFlags =
//				(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK);

        status = m_Endpoint1In.SubmitUrb(pUrb, NULL, NULL,300);

        if ( NT_SUCCESS(status) ) 
        {
	            dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;

				if (dwBytesRead > 0) 
					t << "Read got " << dwTotalSize	<< " bytes from USB\n";
	    }

		delete pUrb;
	}
	else
	{
		status=STATUS_INSUFFICIENT_RESOURCES;
	}

	
    I.Information() = dwBytesRead;
    return status;
}

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

NTSTATUS D12_DriverDevice::D12_DRIVER_WRITE_Handler(KIrp I)
{
	PURB pUrb;
	NTSTATUS status;

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

// TODO:	Handle the the D12_DRIVER_WRITE 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.
	if (I.IoctlOutputBufferSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	// Declare a memory object

    ULONG dwTotalSize = I.IoctlOutputBufferSize(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;
	}
    ULONG dwBytesRead = 0;

	pUrb = m_Endpoint1Out.BuildInterruptTransfer(
				(unsigned char *)I.IoctlBuffer(),		// transfer buffer
				I.IoctlOutputBufferSize(),								// transfer buffer size
				TRUE,							// Short Ok
				NULL,							// link urb
				NULL							// new urb
				);

	if ( pUrb != NULL)
	{
	    // Submit the URB to our USB device, synchronously - say less is OK

        status = m_Endpoint1Out.SubmitUrb(pUrb, NULL, NULL);

        if ( NT_SUCCESS(status) ) 
        {
	            dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;

				if (dwBytesRead > 0) 
					t << "Write got " << dwTotalSize	<< " bytes from USB\n";
	    }

		delete pUrb;
	}
	else
	{
		status=STATUS_INSUFFICIENT_RESOURCES;
	}

	
    I.Information() = dwBytesRead;
    return status;
}



VOID D12_DriverDevice::Cancel(KIrp I)
{
	t << "Cancel(KIrp I)\n";
	if ( (PIRP)I == CurrentIrp() )
	{
		CurrentIrp() = NULL;
		CancelSpinLock::Release(I.CancelIrql());
		I.Information() = 0;
		I.PnpComplete(this, STATUS_CANCELLED);
		IncrementOutstandingRequestCount();
		m_pItem.Queue(LinkTo(Workitem), this);
	}
	else
		CancelSpinLock::Release(I.CancelIrql());
}

VOID D12_DriverDevice::Workitem()
{
	m_Endpoint1In.Abort();
	m_Endpoint1Out.Abort();
	m_Endpoint2In.Abort();
	m_Endpoint2Out.Abort();
	DecrementOutstandingRequestCount();
}


NTSTATUS D12_DriverDevice::OnQueryCapabilities(KIrp I)
{
	I.CopyParametersDown();
	I.SetCompletionRoutine(LinkTo(OnQueryCapabilitiesComplete), this);
	return m_Lower.PnpCall(this, I);
}


NTSTATUS D12_DriverDevice::OnQueryCapabilitiesComplete(KIrp I)
{
	t << "Capabilities Completion routine\n";
	if (I->PendingReturned)
		I.MarkPending();
  	I.DeviceCapabilities()->SurpriseRemovalOK = TRUE;
	return STATUS_SUCCESS;
}

NTSTATUS D12_DriverDevice::D12_DRIVER_BULK_OUT_Handler(KIrp I)
{
	PURB pUrb;
	NTSTATUS status;

	t << "D12_DRIVER_BULK_OUT_Handler, " << I << EOL ;
	if (I.IoctlOutputBufferSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	// Declare a memory object

    ULONG dwTotalSize = I.IoctlOutputBufferSize(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;
	}
    ULONG dwBytesRead = 0;


	pUrb = m_Endpoint2Out.BuildBulkTransfer(
				(unsigned char *)I.IoctlBuffer(),		// transfer buffer
				I.IoctlOutputBufferSize(),		// transfer buffer size
				FALSE,							// Device To Host
				NULL,							// link urb
				FALSE,							// Short Ok
				NULL							// new urb
				);

	if ( pUrb != NULL)
	{
	    // Submit the URB to our USB device, synchronously - say less is OK

        status = m_Endpoint2Out.SubmitUrb(pUrb, NULL, NULL);

        if ( NT_SUCCESS(status) ) 
        {
	            dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;

				if (dwBytesRead > 0) 
					t << "BULK_OUT got " << dwTotalSize	<< " bytes from USB\n";
	    }

		delete pUrb;
	}
	else
	{
		status=STATUS_INSUFFICIENT_RESOURCES;
	}

	
    I.Information() = dwBytesRead;
    return status;
}



NTSTATUS D12_DriverDevice::D12_DRIVER_VENDOR_REQUEST_Handler(KIrp I)
{
	PURB pUrb;
	NTSTATUS status;
//	UCHAR buffer1[]={0,0,0,0x20,0,0x80};

	t << "D12_DRIVER_VENDOR_REQUEST_Handler, " << I << EOL;
	pUrb = m_Lower.BuildVendorRequest(
				(unsigned char *)I.IoctlBuffer(),		// transfer buffer
				I.IoctlInputBufferSize(),				// transfer buffer size
//				buffer1,
//				6,
				0,										// ReservedBits
				0x0c,									// Request
				0,										// Value
				0,										// Direction
				0,										// bShortOk
				NULL,									// Link
				0x0471,									// wIndex
				URB_FUNCTION_VENDOR_DEVICE,				// Function
				NULL									//pUrb 
				);

	if ( pUrb == NULL )
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
	}
	else
	{
		// submit the URB to USBD
		status = m_Lower.SubmitUrb(pUrb);
		delete pUrb;
	}

	return status;
}

NTSTATUS D12_DriverDevice::D12_DRIVER_BULK_IN_Handler(KIrp I)
{
	PURB pUrb;
	NTSTATUS status;
	t << "Entering DddDevice::BULK_IN, " << 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 (I.IoctlOutputBufferSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	// Declare a memory object

    ULONG dwTotalSize = I.IoctlInputBufferSize(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;
	}
    ULONG dwBytesRead = 0;
	// Create an URB to do actual Bulk read from the pipe
	pUrb = m_Endpoint2In.BuildBulkTransfer(
				(unsigned char *)I.IoctlBuffer(),		// transfer buffer
				dwTotalSize,								// transfer buffer size
				TRUE,							// Host To Device
				NULL,							// link urb
				FALSE,							// Short Ok
				NULL						// new urb
				);

	if ( pUrb != NULL)
	{
	    // Submit the URB to our USB device, synchronously - say less is OK
//		pUrb->UrbBulkOrInterruptTransfer.TransferFlags =
//				(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK);

        status = m_Endpoint1In.SubmitUrb(pUrb, NULL, NULL,300);

        if ( NT_SUCCESS(status) ) 
        {
	            dwBytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;

				if (dwBytesRead > 0) 
					t << "BULK_IN got " << dwTotalSize	<< " bytes from USB\n";
	    }

		delete pUrb;
	}
	else
	{
		status=STATUS_INSUFFICIENT_RESOURCES;
	}

	
    I.Information() = dwBytesRead;
    return status;
}


⌨️ 快捷键说明

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