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

📄 pcmciadevice.cpp

📁 一个简单的基于WDM的PCMCIA驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

NTSTATUS PcmciaDevice::Create(KIrp I)
{
	NTSTATUS status;

	t << "Entering PcmciaDevice::Create, " << I << EOL;

// TODO: Add driver specific create handling code here

	// Generally a create 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 << "PcmciaDevice::Create Status " << (ULONG)status << EOL;

	return status;
}


////////////////////////////////////////////////////////////////////////
//  PcmciaDevice::Close
//
//	Routine Description:
//		Handler for IRP_MJ_CLOSE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		NTSTATUS - Result code
//
//	Comments:
//

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

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

    return status;
}

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

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

// TODO:	Insert your code to respond to the CLEANUP message.
//			This code cleans up the single Wizard created queue.  If you
//			have created additional queues,	or have any outstanding Irps
//			stored in some other fashion in your driver, you should clean
//			these up as well for the file object specified in the cleanup Irp.

	m_DriverManagedQueue.PnpCleanUp(this, I.FileObject());
	return I.PnpComplete(this, STATUS_SUCCESS);
}

////////////////////////////////////////////////////////////////////////
//  PcmciaDevice::SerialRead
//	
//	Routine Description:
//		Handler for serialized READ
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		None
//
//	Comments:
//		This routine is called when the IRP is removed from the
//		STARTIO queue.  This guarantees that multiple requests are
//		never processed simultaneously.
//
//		This routine is called at dispatch level.
//

void PcmciaDevice::SerialRead(KIrp I)
{
	t << "Entering PcmciaDevice::SerialRead, " << I << EOL;
	NTSTATUS status		= STATUS_SUCCESS;

	// Declare a memory object
	KMemory Mem(I.Mdl());
	// Use the memory object to create a pointer to the caller's buffer
	PUCHAR	pBuffer		= (PUCHAR) Mem.MapToSystemSpace();

	ULONG   dwTotalSize = I.ReadSize(CURRENT);	// Requested read size
	ULONG   dwBytesRead = 0;					// Count of bytes read

// TODO:	If the read can be satisfied immediately, set the Information
//			and Status fields now, then call NextIrp to complete this IRP
//			and start processing the next IRP in the queue.

// TODO:	If the data is not yet available, initiate a request to the
//			physical device here, and defer the Information, Status,
//			and NextIrp handling until the hardware indicates that the
//			read is complete.  Typically, this might be handled in a
//			DPC that is called after the hardware finishes transferring
//			the data.

// TODO:	To satisfy the read now, transfer data from the device to
//			caller's buffer at "pBuffer".  Then, indicate how much data was
//			transferred:

	I.Information() = dwBytesRead;

	I.Status() = status;


	// PnpNextIrp completes this IRP and starts processing 
	// for the next IRP in the driver managed queue.
// TODO:	The Wizard creates a single queue for all Irps.
//			If you have created additional queues, select
//			the appropriate queue for this Irp here.
	m_DriverManagedQueue.PnpNextIrp(I);
}


////////////////////////////////////////////////////////////////////////
//  PcmciaDevice::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 PcmciaDevice::Read(KIrp I) 
{
	t << "Entering PcmciaDevice::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);
	}

	// Queue the IRP for processing in the driver managed queue.
	// The actual read function is performed in SerialRead
// TODO:	The Wizard creates a single queue for all Irps.
//			If you have created additional queues, select
//			the appropriate queue for this Irp here.
	return m_DriverManagedQueue.QueueIrp(I);
}

////////////////////////////////////////////////////////////////////////
//  PcmciaDevice::SerialWrite
//	
//	Routine Description:
//		Handler for serialized WRITE
//
//	Parameters:
//		I - Current IRP
//
//	Return Value:
//		None
//
//	Comments:
//		This routine is called when the IRP is removed from the
//		STARTIO queue.  This guarantees that multiple requests are
//		never processed simultaneously.
//

void PcmciaDevice::SerialWrite(KIrp I)
{
	t << "Entering PcmciaDevice::SerialWrite, " << I << EOL;
	NTSTATUS status		= STATUS_SUCCESS;

	// Declare a memory object
	KMemory Mem(I.Mdl());
	// Use the memory object to create a pointer to the caller's buffer
	PUCHAR	pBuffer		= (PUCHAR) Mem.MapToSystemSpace();

	ULONG   dwTotalSize = I.WriteSize(CURRENT);
	ULONG   dwBytesSent = 0;

// TODO:	If the write can be satisfied immediately, set the Information
//			and Status fields now, then call NextIrp to complete this IRP
//			and start processing the next IRP in the queue.

// TODO:	If the device cannot accept all of the data yet, initiate a 
//			request to the physical device here, and defer the Information,
//			Status, and NextIrp handling until the hardware indicates that
//			the write is complete.  Typically, this might be handled in a
//			DPC that is called after the hardware finishes transferring
//			the data.

// TODO:	To satisfy the write now, transfer data to the device
//			from caller's buffer at "pBuffer".  Then, indicate how much
//			data was transferred:

	I.Information() = dwBytesSent;

	I.Status() = status;


	// PnpNextIrp completes this IRP and starts processing 
	// for the next IRP in the driver managed queue.
// TODO:	The Wizard creates a single queue for all Irps.
//			If you have created additional queues, select
//			the appropriate queue for this Irp here.
	m_DriverManagedQueue.PnpNextIrp(I);
}


////////////////////////////////////////////////////////////////////////
//  PcmciaDevice::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 PcmciaDevice::Write(KIrp I) 
{
	t << "Entering PcmciaDevice::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);
	}

	// Queue the IRP for processing in the driver managed queue.
	// The actual write function is performed in SerialWrite

// TODO:	The Wizard creates a single queue for all Irps.
//			If you have created additional queues, select
//			the appropriate queue for this Irp here.
	return m_DriverManagedQueue.QueueIrp(I);
}

////////////////////////////////////////////////////////////////////////
//  PcmciaDevice::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.
//		Some function codes may be handled immediately, 
//		while others may be serialized through the StartIo routine.
//		
//		The KPnpDevice class handles restricting IRP flow
//		if the device is stopping or being removed.
//

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

	t << "Entering PcmciaDevice::Device Control, " << I << EOL;
	switch (I.IoctlCode())
	{
		default:
			// Unrecognized IOCTL request
			status = STATUS_INVALID_PARAMETER;
			break;
	}

	// If the IRP was queued, or its 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);
	}
}

////////////////////////////////////////////////////////////////////////////////
//  PcmciaDevice_DriverManagedQueue::StartIo
//	
//	Routine Description:
//		This routine is called when an IRP is taken off
//		the Driver Managed Queue (used for serializing I/O) and
//		presented for processing.
//
//	Parameters:
//		I - IRP removed from queue
//
//	Return Value:
//		None
//
//	Comments:
//

VOID PcmciaDevice_DriverManagedQueue::StartIo(KIrp I)
{
	t  << "Entering PcmciaDevice_DriverManagedQueue StartIo, " << I;

	// The KDriverManagedQueueEx class gives us the Irp in a non-cancelable state
	// (cancel routine set to NULL) so we can process it without having to worry
	// about clearing the cancel routine first, as is the case with system queuing,
	// or the legacy class KDriverManagedQueue. You may want to set a different cancel
	// routine here, or at other points during the processing of this Irp.

	// Find the device class so we can call the serialized
	// routines in the device class.  The handlers can be
	// moved to the DriverManagedQueue class if it is more
	// convenient.
	PcmciaDevice *pDev = (PcmciaDevice *) KDevicePTR(I.DeviceObject());

	// Start processing request.

	// Switch on the IRP's function:
	switch (I.MajorFunction())
	{
		case IRP_MJ_READ:
			pDev->SerialRead(I);
			break;

		case IRP_MJ_WRITE:
			pDev->SerialWrite(I);
			break;

		case IRP_MJ_DEVICE_CONTROL:
			switch (I.IoctlCode())
			{
				default:
					// We queued a request that shouldn't have been queued
					// (should never get here)
					ASSERT(FALSE);
					break;
			}
			break;

		default:
			// Error - unexpected IRP received
			// NextIrp completes this IRP and starts processing
			// for the next IRP in the queue.
			ASSERT(FALSE);
			I.Status() = STATUS_INVALID_PARAMETER;
			PnpNextIrp(I);
			break;
	}
}


⌨️ 快捷键说明

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