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;i Serial_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; } }