www.pudn.com > pci9054.rar > PCI9054Device.cpp


// PCI9054Device.cpp 
// Implementation of PCI9054Device device class 
// 
// Generated by DriverWizard version DriverStudio 2.6.0 (Build 336) 
// Requires Compuware's DriverWorks classes 
// 
 
#pragma warning(disable:4065) // Allow switch statement with no cases 
		   
#include  
 
#include "PCI9054.h" 
#include "PCI9054Device.h" 
#include "..\PCI9054ioctl.h" 
 
#pragma hdrstop("PCI9054.pch") 
 
extern KTrace t;			// Global driver trace object	 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::PCI9054Device 
// 
//	Routine Description: 
//		This is the constructor for the Functional Device Object, or FDO. 
//		It is derived from KPnpDevice, which builds in automatic 
//	    dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP to 
//		virtual member functions. 
// 
//	Parameters: 
//		Pdo - Physical Device Object - this is a pointer to a system 
//			device object that represents the physical device. 
// 
//		Unit - Unit number. This is a number to append to the device's 
//			base device name to form the Logical Device Object's name 
// 
//	Return Value: 
//		None    
// 
//	Comments: 
//		The object being constructed contains a data member (m_Lower) of type 
//		KPnpLowerDevice. By initializing it, the driver binds the FDO to the 
//		PDO and creates an interface to the upper edge of the system class driver. 
// 
 
PCI9054Device::PCI9054Device(PDEVICE_OBJECT Pdo, ULONG Unit) : 
	KPnpDevice(Pdo, NULL) 
{ 
	t << "Entering PCI9054Device::PCI9054Device (constructor)\n"; 
 
 
	// Check constructor status 
    if ( ! NT_SUCCESS(m_ConstructorStatus) ) 
	{ 
	    return; 
	} 
 
	// Remember our unit number 
	m_Unit = Unit; 
 
	// Initialize the lower device 
	m_Lower.Initialize(this, Pdo); 
 
    // Inform the base class of the lower edge device object 
	SetLowerDevice(&m_Lower); 
 
	// Initialize the PnP Policy settings to the "standard" policy 
	SetPnpPolicy(); 
 
// TODO:	Customize the PnP Policy for this device by setting 
//			flags in m_Policies. 
 
	// Initialize the Power Policy settings to the "standard" policy 
	SetPowerPolicy(); 
 
// TODO:	Customize the Power Policy for this device by setting 
//			flags in m_PowerPolicies. 
 
} 
 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::~PCI9054Device 
// 
//	Routine Description: 
//		This is the destructor for the Functional Device Object, or FDO. 
// 
//	Parameters: 
//		None 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		None 
// 
 
PCI9054Device::~PCI9054Device() 
{ 
	t << "Entering PCI9054Device::~PCI9054Device() (destructor)\n"; 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PNPMinorFunctionName 
// 
//	Routine Description: 
//		Return a string describing the Plug and Play minor function	 
// 
//	Parameters: 
//		mn - Minor function code 
// 
//	Return Value: 
//		char * - Ascii name of minor function 
// 
//	Comments: 
//		This function is used for tracing the IRPs.  Remove the function, 
//		or conditionalize it for debug-only builds, if you want to save 
//		space in the driver image. 
// 
	 
char *PNPMinorFunctionName(ULONG mn) 
{ 
	static char* minors[] = { 
		"IRP_MN_START_DEVICE", 
		"IRP_MN_QUERY_REMOVE_DEVICE", 
		"IRP_MN_REMOVE_DEVICE", 
		"IRP_MN_CANCEL_REMOVE_DEVICE", 
		"IRP_MN_STOP_DEVICE", 
		"IRP_MN_QUERY_STOP_DEVICE", 
		"IRP_MN_CANCEL_STOP_DEVICE", 
		"IRP_MN_QUERY_DEVICE_RELATIONS", 
		"IRP_MN_QUERY_INTERFACE", 
		"IRP_MN_QUERY_CAPABILITIES", 
		"IRP_MN_QUERY_RESOURCES", 
		"IRP_MN_QUERY_RESOURCE_REQUIREMENTS", 
		"IRP_MN_QUERY_DEVICE_TEXT", 
		"IRP_MN_FILTER_RESOURCE_REQUIREMENTS", 
		"", 
		"IRP_MN_READ_CONFIG", 
		"IRP_MN_WRITE_CONFIG", 
		"IRP_MN_EJECT", 
		"IRP_MN_SET_LOCK", 
		"IRP_MN_QUERY_ID", 
		"IRP_MN_QUERY_PNP_DEVICE_STATE", 
		"IRP_MN_QUERY_BUS_INFORMATION", 
		"IRP_MN_DEVICE_USAGE_NOTIFICATION", 
		"IRP_MN_SURPRISE_REMOVAL" 
	}; 
 
	if (mn > IRP_MN_SURPRISE_REMOVAL)  
		return ""; 
	else 
		return minors[mn]; 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::DefaultPnp 
// 
//	Routine Description: 
//		Default handler for IRP_MJ_PNP 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result returned from lower device 
// 
//	Comments: 
//		This routine just passes the IRP through to the lower device. It is  
//		the default handler for IRP_MJ_PNP. IRPs that correspond to 
//		any virtual members of KpnpDevice that handle minor functions of 
//		IRP_MJ_PNP and that are not overridden get passed to this routine. 
// 
 
NTSTATUS PCI9054Device::DefaultPnp(KIrp I)  
{ 
	t << "Entering PCI9054Device::DefaultPnp with IRP minor function=" 
	  << PNPMinorFunctionName(I.MinorFunction()) << EOL; 
 
	I.ForceReuseOfCurrentStackLocationInCalldown(); 
	return m_Lower.PnpCall(this, I); 
} 
 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::DefaultPower 
// 
//	Routine Description: 
//		Default handler for IRP_MJ_POWER  
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result returned from lower device 
// 
//	Comments: 
//		This routine just passes the IRP through to the lower device. It is  
//		the default handler for IRP_MJ_POWER. 
// 
 
NTSTATUS PCI9054Device::DefaultPower(KIrp I)  
{ 
	t << "Entering PCI9054Device::DefaultPower\n"; 
 
	I.IndicatePowerIrpProcessed(); 
	I.CopyParametersDown(); 
	return m_Lower.PnpPowerCall(this, I); 
} 
 
//////////////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::SystemControl 
// 
//	Routine Description: 
//		Default handler for IRP_MJ_SYSTEM_CONTROL 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result returned from lower device 
// 
//	Comments: 
//		This routine just passes the IRP through to the next device since this driver 
//		is not a WMI provider. 
// 
 
NTSTATUS PCI9054Device::SystemControl(KIrp I)  
{ 
	t << "Entering PCI9054Device::SystemControl\n"; 
 
	I.ForceReuseOfCurrentStackLocationInCalldown(); 
	return m_Lower.PnpCall(this, I); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Invalidate 
// 
//	Routine Description: 
//		Calls Invalidate methods for system resources 
// 
//	Parameters: 
//		None 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		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. 
 
VOID PCI9054Device::Invalidate() 
{ 
 
 
 
	// For each memory mapped region, release the underlying system resoruce. 
	m_MemoryRange0_ForBase0.Invalidate(); 
	m_MemoryRange1_ForBase2.Invalidate(); 
 
	// For each I/O port mapped region, release the underlying system resource. 
	m_IoPortRange0_ForBase1.Invalidate(); 
	m_IoPortRange1_ForBase3.Invalidate(); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::OnStartDevice 
// 
//	Routine Description: 
//		Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
//		Initialize the physical device. Typically, the driver initializes 
//		physical resources here.  Call I.AllocatedResources() for a list 
//		of the raw resources that the system has assigned to the device, 
//		or I.TranslatedResources() for the translated resource list. 
// 
 
NTSTATUS PCI9054Device::OnStartDevice(KIrp I) 
{ 
	t << "Entering PCI9054Device::OnStartDevice\n"; 
 
	NTSTATUS status = STATUS_SUCCESS; 
 
	I.Information() = 0; 
 
	// The default Pnp policy has already cleared the IRP with the lower device 
	// Initialize the physical device object. 
 
	// Get the list of raw resources from the IRP 
	PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources(); 
	// Get the list of translated resources from the IRP 
	PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources(); 
 
	// Create an instance of KPciConfiguration so we can map Base Address 
	// Register indicies to ordinals for memory or I/O port ranges. 
	KPciConfiguration PciConfig(m_Lower.TopOfStack()); 
 
	// For each memory mapped region, initialize the memory mapped range 
	// using the resources provided by NT. Once initialized, each memory 
	// range's base virtual address in system space can be obtained by calling 
	// member Base(). Each memory range's physical address in CPU space can 
	// obtained by calling CpuPhysicalAddress(). To access the memory mapped 
	// range use member functions such as inb/outb, or the array element operator.  
	status = m_MemoryRange0_ForBase0.Initialize( 
		pResListTranslated, 
		pResListRaw, 
		PciConfig.BaseAddressIndexToOrdinal(0) 
		); 
	if (!NT_SUCCESS(status)) 
	{ 
		Invalidate(); 
		return status;		 
	} 
 
	status = m_MemoryRange1_ForBase2.Initialize( 
		pResListTranslated, 
		pResListRaw, 
		PciConfig.BaseAddressIndexToOrdinal(2) 
		); 
	if (!NT_SUCCESS(status)) 
	{ 
		Invalidate(); 
		return status;		 
	} 
 
 
	// For each I/O port mapped region, initialize the I/O port range using 
	// the resources provided by NT. Once initialized, use member functions such as 
	// inb/outb, or the array element operator to access the ports range. 
	status = m_IoPortRange0_ForBase1.Initialize( 
		pResListTranslated, 
		pResListRaw, 
		PciConfig.BaseAddressIndexToOrdinal(1) 
		); 
	if (!NT_SUCCESS(status)) 
	{ 
		Invalidate(); 
		return status;		 
	} 
 
	status = m_IoPortRange1_ForBase3.Initialize( 
		pResListTranslated, 
		pResListRaw, 
		PciConfig.BaseAddressIndexToOrdinal(3) 
		); 
	if (!NT_SUCCESS(status)) 
	{ 
		Invalidate(); 
		return status;		 
	} 
 
 
// TODO:	Add device-specific code to start your device. 
 
    // The base class will handle completion 
 
	return status; 
} 
 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::OnStopDevice 
// 
//	Routine Description: 
//		Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
//		The system calls this when the device is stopped. 
//		The driver should release any hardware resources 
//		in this routine. 
// 
//		The base class passes the irp to the lower device. 
// 
 
NTSTATUS PCI9054Device::OnStopDevice(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::OnStopDevice\n"; 
 
	// Device stopped, release the system resources. 
	Invalidate(); 
 
// TODO:	Add device-specific code to stop your device    
 
	return status; 
	 
	// The following macro simply allows compilation at Warning Level 4 
	// If you reference this parameter in the function simply remove the macro. 
	UNREFERENCED_PARAMETER(I); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::OnRemoveDevice 
// 
//	Routine Description: 
//		Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
//		The system calls this when the device is removed. 
//		Our PnP policy will take care of  
//			(1) giving the IRP to the lower device 
//			(2) detaching the PDO 
//			(3) deleting the device object 
// 
 
NTSTATUS PCI9054Device::OnRemoveDevice(KIrp I) 
{ 
	t << "Entering PCI9054Device::OnRemoveDevice\n"; 
 
	// Device removed, release the system resources. 
	Invalidate(); 
 
 
 
// TODO:	Add device-specific code to remove your device    
 
	return STATUS_SUCCESS; 
 
	// The following macro simply allows compilation at Warning Level 4 
	// If you reference this parameter in the function simply remove the macro. 
	UNREFERENCED_PARAMETER(I); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::OnDevicePowerUp 
// 
//	Routine Description: 
//		Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER 
//		for a request to go to power on state from low power state 
// 
//	Parameters: 
//		I - IRP containing POWER request 
// 
//	Return Value: 
//		NTSTATUS - Status code indicating success or failure 
// 
//	Comments: 
//		This routine implements the OnDevicePowerUp function. 
//		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. 
//	 
 
NTSTATUS PCI9054Device::OnDevicePowerUp(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::OnDevicePowerUp\n"; 
 
// TODO:	Service the device. 
//			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. 
// 
	return status; 
 
	// The following macro simply allows compilation at Warning Level 4 
	// If you reference this parameter in the function simply remove the macro. 
	UNREFERENCED_PARAMETER(I); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::OnDeviceSleep 
// 
//	Routine Description: 
//		Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER 
//		for a request to go to a low power state from a high power state 
// 
//	Parameters: 
//		I - IRP containing POWER request 
// 
//	Return Value: 
//		NTSTATUS - Status code indicating success or failure 
// 
//	Comments: 
//		This routine implements the OnDeviceSleep function. 
//		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. 
//	 
 
NTSTATUS PCI9054Device::OnDeviceSleep(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::OnDeviceSleep\n"; 
 
// TODO:	Service the device. 
//			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. 
// 
	return status; 
 
	// The following macro simply allows compilation at Warning Level 4 
	// If you reference this parameter in the function simply remove the macro. 
	UNREFERENCED_PARAMETER(I); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Create 
// 
//	Routine Description: 
//		Handler for IRP_MJ_CREATE 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
// 
 
NTSTATUS PCI9054Device::Create(KIrp I) 
{ 
	NTSTATUS status; 
 
	t << "Entering PCI9054Device::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 << "PCI9054Device::Create Status " << (ULONG)status << EOL; 
 
	return status; 
} 
 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Close 
// 
//	Routine Description: 
//		Handler for IRP_MJ_CLOSE 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
// 
 
NTSTATUS PCI9054Device::Close(KIrp I) 
{ 
	NTSTATUS status; 
 
	t << "Entering PCI9054Device::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 << "PCI9054Device::Close Status " << (ULONG)status << EOL; 
 
    return status; 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Cleanup 
// 
//	Routine Description: 
//		Handler for IRP_MJ_CLEANUP	 
// 
//	Parameters: 
//		I - Current IRP 
// 
//	Return Value: 
//		NTSTATUS - Result code 
// 
//	Comments: 
// 
 
NTSTATUS PCI9054Device::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); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::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 PCI9054Device::DeviceControl(KIrp I)  
{ 
	NTSTATUS status; 
 
	t << "Entering PCI9054Device::Device Control, " << I << EOL; 
	switch (I.IoctlCode()) 
	{ 
		case PCI9054_IOCTL_800_ReadBase0: 
// TODO:	If you have created multiple driver managed queues, select the 
//			appropriate queue here.    
 
			// Queue this request for serialized handling 
		    status = m_DriverManagedQueue.QueueIrp(I); 
			break; 
 
		case PCI9054_IOCTL_801_WriteBase0: 
// TODO:	If you have created multiple driver managed queues, select the 
//			appropriate queue here.    
 
			// Queue this request for serialized handling 
		    status = m_DriverManagedQueue.QueueIrp(I); 
			break; 
 
		case PCI9054_IOCTL_802_ReadBase2: 
// TODO:	If you have created multiple driver managed queues, select the 
//			appropriate queue here.    
 
			// Queue this request for serialized handling 
		    status = m_DriverManagedQueue.QueueIrp(I); 
			break; 
 
		case PCI9054_IOCTL_803_WriteBase2: 
// TODO:	If you have created multiple driver managed queues, select the 
//			appropriate queue here.    
 
			// Queue this request for serialized handling 
		    status = m_DriverManagedQueue.QueueIrp(I); 
			break; 
 
		case PCI9054_IOCTL_804_ReadBase3: 
// TODO:	If you have created multiple driver managed queues, select the 
//			appropriate queue here.    
 
			// Queue this request for serialized handling 
		    status = m_DriverManagedQueue.QueueIrp(I); 
			break; 
 
		case PCI9054_IOCTL_805_WriteBase3: 
// TODO:	If you have created multiple driver managed queues, select the 
//			appropriate queue here.    
 
			// Queue this request for serialized handling 
		    status = m_DriverManagedQueue.QueueIrp(I); 
			break; 
 
		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); 
	} 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Serial_PCI9054_IOCTL_800_ReadBase0_Handler 
// 
//	Routine Description: 
//		Handler for IO Control Code PCI9054_IOCTL_800_ReadBase0 
// 
//	Parameters: 
//		I - IRP containing IOCTL request 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		This routine implements the PCI9054_IOCTL_800_ReadBase0 function. 
//		This function was queued through StartIo, so this 
//		handler is serialized with other StartIo requests. 
//		This routine runs at dispatch level. 
// 
 
VOID PCI9054Device::Serial_PCI9054_IOCTL_800_ReadBase0_Handler(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::Serial_PCI9054_IOCTL_800_ReadBase0_Handler, " << I << EOL; 
// TODO:	Verify that the input parameters are correct 
//			If not, return STATUS_INVALID_PARAMETER 
 
// TODO:	Handle the the PCI9054_IOCTL_800_ReadBase0 request, or setup for further processing. 
 
// TODO:	Assuming that the request was handled in this routine, set 
//			I.Information to indicate how much data to copy back to the user, 
//			and set I.Status to indicate the outcome of the IRP.  Then 
//			complete this IRP and start the next IRP on the queue. 
	KMemory Mem(I.Mdl());      
	// Use the memory object to create a pointer to the caller's buffer 
	PULONG	pOutBuffer		= (PULONG) Mem.MapToSystemSpace();  //输出缓冲区 
 
	ULONG   Offset=0x10; 
	ULONG   count=1; 
     
	m_MemoryRange0_ForBase0.ind(Offset,pOutBuffer,count); 
 
	I.Information() = count; 
	I.Status() = status; 
// 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); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Serial_PCI9054_IOCTL_801_WriteBase0_Handler 
// 
//	Routine Description: 
//		Handler for IO Control Code PCI9054_IOCTL_801_WriteBase0 
// 
//	Parameters: 
//		I - IRP containing IOCTL request 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		This routine implements the PCI9054_IOCTL_801_WriteBase0 function. 
//		This function was queued through StartIo, so this 
//		handler is serialized with other StartIo requests. 
//		This routine runs at dispatch level. 
// 
 
VOID PCI9054Device::Serial_PCI9054_IOCTL_801_WriteBase0_Handler(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::Serial_PCI9054_IOCTL_801_WriteBase0_Handler, " << I << EOL; 
// TODO:	Verify that the input parameters are correct 
//			If not, return STATUS_INVALID_PARAMETER 
 
// TODO:	Handle the the PCI9054_IOCTL_801_WriteBase0 request, or setup for further processing. 
 
// TODO:	Assuming that the request was handled in this routine, set 
//			I.Information to indicate how much data to copy back to the user, 
//			and set I.Status to indicate the outcome of the IRP.  Then 
//			complete this IRP and start the next IRP on the queue. 
	PULONG  pInBuffer       = (PULONG) I.IoctlBuffer();     //输入缓冲区 
    
	m_MemoryRange0_ForBase0.outd(0x10,pInBuffer,1); 
	I.Information() = 1; 
	I.Status() = status; 
// 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); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Serial_PCI9054_IOCTL_802_ReadBase2_Handler 
// 
//	Routine Description: 
//		Handler for IO Control Code PCI9054_IOCTL_802_ReadBase2 
// 
//	Parameters: 
//		I - IRP containing IOCTL request 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		This routine implements the PCI9054_IOCTL_802_ReadBase2 function. 
//		This function was queued through StartIo, so this 
//		handler is serialized with other StartIo requests. 
//		This routine runs at dispatch level. 
// 
 
VOID PCI9054Device::Serial_PCI9054_IOCTL_802_ReadBase2_Handler(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::Serial_PCI9054_IOCTL_802_ReadBase2_Handler, " << I << EOL; 
 
	KMemory Mem(I.Mdl());      
	// Use the memory object to create a pointer to the caller's buffer 
	PUSHORT	pOutBuffer	= (PUSHORT) Mem.MapToSystemSpace();  //输出缓冲区指针,传出读取的数据 
  
	PUSHORT  pInBuffer  = (PUSHORT) I.IoctlBuffer();    //输入缓冲区,传来应用程序的一些参数 
	                                                    //以便通过应用程序指定读取的位置和数据个数 
 
	USHORT   Offset;    //从应用程序中获取传来的读取的偏移地址 
	Offset   = *pInBuffer; 
 
	USHORT   count;     //从应用程序中获取传来的读取的数据个数 
	count    = *(pInBuffer+1); 
 
	m_MemoryRange1_ForBase2.inw(Offset,pOutBuffer,count); 
 
	I.Information() = count*2;  //字节数 
	I.Status() = status; 
// 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); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Serial_PCI9054_IOCTL_803_WriteBase2_Handler 
// 
//	Routine Description: 
//		Handler for IO Control Code PCI9054_IOCTL_803_WriteBase2 
// 
//	Parameters: 
//		I - IRP containing IOCTL request 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		This routine implements the PCI9054_IOCTL_803_WriteBase2 function. 
//		This function was queued through StartIo, so this 
//		handler is serialized with other StartIo requests. 
//		This routine runs at dispatch level. 
// 
 
VOID PCI9054Device::Serial_PCI9054_IOCTL_803_WriteBase2_Handler(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::Serial_PCI9054_IOCTL_803_WriteBase2_Handler, " << I << EOL; 
 
	PUSHORT  pInBuffer  = (PUSHORT) I.IoctlBuffer(); //输入缓冲区,应用程序通过它来指定写入的参数 
	                                                 //参数包括要写入的数据个数和偏移地址 
	                                                 //I.IoctlBuffer()对应着应用程序传过来的一个数组 
	                                                 //该数组结构是:第一个元素是写入的数据的起始偏移地址 
	                                                 //第二个元素是共写入的数据个数 
	                                                 //第三个元素及其其它元素,为写入的数据 
		 
	//从输入缓冲区获得的要写入的数据的偏移地址 
	USHORT   offset;      
	offset=*pInBuffer;	 
	 
	//从输入缓冲区获得的要写入的数据个数 
	USHORT   count;        
	count=*(pInBuffer+1); 
 
	//指向要写入的数据,该数据为传入的数组的第三个元素及其之后的元素 
	PUSHORT  pBuffer  = pInBuffer+2;        
 
	m_MemoryRange1_ForBase2.outw(offset,pBuffer,count); 
 
	I.Information() = count*2;  //字节数 
	I.Status() = status; 
// 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); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Serial_PCI9054_IOCTL_804_ReadBase3_Handler 
// 
//	Routine Description: 
//		Handler for IO Control Code PCI9054_IOCTL_804_ReadBase3 
// 
//	Parameters: 
//		I - IRP containing IOCTL request 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		This routine implements the PCI9054_IOCTL_804_ReadBase3 function. 
//		This function was queued through StartIo, so this 
//		handler is serialized with other StartIo requests. 
//		This routine runs at dispatch level. 
// 
 
VOID PCI9054Device::Serial_PCI9054_IOCTL_804_ReadBase3_Handler(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::Serial_PCI9054_IOCTL_804_ReadBase3_Handler, " << I << EOL; 
 
	KMemory Mem(I.Mdl());      
	// Use the memory object to create a pointer to the caller's buffer 
	PULONG	pOutBuffer	= (PULONG) Mem.MapToSystemSpace();  //输出缓冲区指针,传出读取的数据 
  
	PULONG  pInBuffer       = (PULONG) I.IoctlBuffer();     //输入缓冲区指针 
 
	ULONG   Offset;                     //读取的偏移地址 
	Offset   = *pInBuffer; 
 
	ULONG   count;                      //读取的数据个数 
	count    = *(pInBuffer+1); 
 
	m_IoPortRange1_ForBase3.ind(Offset,pOutBuffer,count); 
 
	I.Information() = count; 
	I.Status() = status; 
// 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); 
} 
 
//////////////////////////////////////////////////////////////////////// 
//  PCI9054Device::Serial_PCI9054_IOCTL_805_WriteBase3_Handler 
// 
//	Routine Description: 
//		Handler for IO Control Code PCI9054_IOCTL_805_WriteBase3 
// 
//	Parameters: 
//		I - IRP containing IOCTL request 
// 
//	Return Value: 
//		None 
// 
//	Comments: 
//		This routine implements the PCI9054_IOCTL_805_WriteBase3 function. 
//		This function was queued through StartIo, so this 
//		handler is serialized with other StartIo requests. 
//		This routine runs at dispatch level. 
// 
 
VOID PCI9054Device::Serial_PCI9054_IOCTL_805_WriteBase3_Handler(KIrp I) 
{ 
	NTSTATUS status = STATUS_SUCCESS; 
 
	t << "Entering PCI9054Device::Serial_PCI9054_IOCTL_805_WriteBase3_Handler, " << I << EOL; 
 
	PULONG  pInBuffer  = (PULONG) I.IoctlBuffer(); //输入缓冲区指针 
	 
	ULONG   count;                        //从输入缓冲区要写入的数据个数 
	count=*(pInBuffer+1); 
 
	ULONG   offset;                       //偏移地址 
	offset=*pInBuffer; 
 
	PULONG  pBuffer  = pInBuffer+2;       //指向要写入的数据 
/* 
	for(ULONG i=0;iSerial_PCI9054_IOCTL_800_ReadBase0_Handler(I); 
					break; 
 
				case PCI9054_IOCTL_801_WriteBase0: 
					pDev->Serial_PCI9054_IOCTL_801_WriteBase0_Handler(I); 
					break; 
 
				case PCI9054_IOCTL_802_ReadBase2: 
					pDev->Serial_PCI9054_IOCTL_802_ReadBase2_Handler(I); 
					break; 
 
				case PCI9054_IOCTL_803_WriteBase2: 
					pDev->Serial_PCI9054_IOCTL_803_WriteBase2_Handler(I); 
					break; 
 
				case PCI9054_IOCTL_804_ReadBase3: 
					pDev->Serial_PCI9054_IOCTL_804_ReadBase3_Handler(I); 
					break; 
 
				case PCI9054_IOCTL_805_WriteBase3: 
					pDev->Serial_PCI9054_IOCTL_805_WriteBase3_Handler(I); 
					break; 
 
				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; 
	} 
}