📄 pnp.c
字号:
Return Value:
none
--*/
{
//
// Begin by initializing all entries to point to PptPnpUnhandledIrp()
// and then override the table entries for PnP request types that
// require special handling.
//
ULONG i;
for( i=0 ; i <= MAX_PNP_IRP_MN_HANDLED ; ++i ) {
PptPnpDispatchFunctionTable[i] = PptPnpUnhandledIrp;
}
PptPnpDispatchFunctionTable[ IRP_MN_START_DEVICE ] = PptPnpStartDevice;
PptPnpDispatchFunctionTable[ IRP_MN_FILTER_RESOURCE_REQUIREMENTS ] = PptPnpFilterResourceRequirements;
PptPnpDispatchFunctionTable[ IRP_MN_QUERY_DEVICE_RELATIONS ] = PptPnpQueryDeviceRelations;
PptPnpDispatchFunctionTable[ IRP_MN_QUERY_STOP_DEVICE ] = PptPnpQueryStopDevice;
PptPnpDispatchFunctionTable[ IRP_MN_CANCEL_STOP_DEVICE ] = PptPnpCancelStopDevice;
PptPnpDispatchFunctionTable[ IRP_MN_STOP_DEVICE ] = PptPnpStopDevice;
PptPnpDispatchFunctionTable[ IRP_MN_QUERY_REMOVE_DEVICE ] = PptPnpQueryRemoveDevice;
PptPnpDispatchFunctionTable[ IRP_MN_CANCEL_REMOVE_DEVICE ] = PptPnpCancelRemoveDevice;
PptPnpDispatchFunctionTable[ IRP_MN_REMOVE_DEVICE ] = PptPnpRemoveDevice;
PptPnpDispatchFunctionTable[ IRP_MN_SURPRISE_REMOVAL ] = PptPnpSurpriseRemoval;
}
NTSTATUS
PptPnpAddDevice(
IN PDRIVER_OBJECT pDriverObject,
IN PDEVICE_OBJECT pPhysicalDeviceObject
)
/*++dvdf3
Routine Description:
This routine creates a new parport device object and attaches
the device object to the device stack.
Arguments:
pDriverObject - pointer to the driver object for this instance of parport.
pPhysicalDeviceObject - pointer to the device object that represents the port.
Return Value:
STATUS_SUCCESS - if successful.
Error Status - otherwise.
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT parentDevice;
PDEVICE_OBJECT pDeviceObject;
PDEVICE_EXTENSION Extension;
DDPnP1(("-- AddDevice\n"));
PptDump2(PARPNP1, ("pnp::PptPnpAddDevice - Enter - DriverObject = %08x , PDO = %08x\n",
pDriverObject, pPhysicalDeviceObject) );
#if DBG
PptBreak(PAR_BREAK_ON_ADD_DEVICE, ("PptPnpAddDevice(PDRIVER_OBJECT, PDEVICE_OBJECT)\n") );
#endif
//
// Create and initialize device object
//
pDeviceObject = PptBuildDeviceObject( pDriverObject, pPhysicalDeviceObject );
if( NULL == pDeviceObject ) {
PptDump2(PARERRORS, ("pnp::PptAddDevice - Create DeviceObject FAILED\n") );
return STATUS_UNSUCCESSFUL;
}
Extension = pDeviceObject->DeviceExtension;
//
// Register device interface with PnP
//
status = IoRegisterDeviceInterface(pPhysicalDeviceObject, &GUID_PARALLEL_DEVICE, NULL, &Extension->SymbolicLinkName);
if( !NT_SUCCESS( status ) ) {
PptDump2(PARERRORS, ("pnp::PptAddDevice - IoRegisterDeviceInterface FAILED, status=%x", status) );
IoDeleteDevice( pDeviceObject );
return status;
}
//
// Attach device object to device stack
//
parentDevice = IoAttachDeviceToDeviceStack( pDeviceObject, pPhysicalDeviceObject );
if( NULL == parentDevice ) {
PptDump2(PARERRORS, ("pnp::PptAddDevice - IoAttachDeviceToDeviceStack - FAILED\n") );
IoDeleteDevice( pDeviceObject );
return STATUS_UNSUCCESSFUL;
}
Extension->ParentDeviceObject = parentDevice;
//
// Tell the IO System that we have another parallel port
// (This count is used by legacy drivers.)
//
IoGetConfigurationInformation()->ParallelCount++;
//
// Done initializing - tell IO System that we are ready to receive IRPs
//
pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
PptDump2(PARPNP1, ("pnp::PptPnpAddDevice - SUCCESS\n") );
return STATUS_SUCCESS;
}
NTSTATUS
PptDispatchPnp (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++dvdf8
Routine Description:
This is the dispatch function for PnP IRPs.
- Acquire the device's RemoveLock.
- Forward the request to an appropriate handler.
Note:
The handler called by this routine must release the RemoveLock
before returning control to this routine!
Arguments:
DeviceObject - The target device for the IRP
Irp - The IRP
Return Value:
Status returned by PptAcquireRemoveLockOrFailIrp() - if unable to acquire RemoveLock
Status returned by the IrpStack->MinorFunction handler - otherwise
--*/
{
NTSTATUS status;
//
// Generate debug trace output useful in tracking PnP IRPs.
//
PptDebugDumpPnpIrpInfo( DeviceObject, Irp );
//
// Acquire RemoveLock to prevent DeviceObject from being REMOVED
// while we are using it. If we are unable to acquire the RemoveLock
// then the DeviceObject has already been REMOVED.
//
status = PptAcquireRemoveLockOrFailIrp(DeviceObject, Irp);
if( NT_SUCCESS( status ) ) {
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
UCHAR minorFunction = irpStack->MinorFunction;
//
// RemoveLock is held. Forward the request to the appropriate handler.
//
// Note that the handler must release the RemoveLock prior to returning
// control to this function.
//
if( minorFunction > MAX_PNP_IRP_MN_HANDLED ) {
//
// Do standard processing for unrecognized PnP requests.
//
status = PptPnpUnhandledIrp( DeviceObject, Irp );
} else {
//
// Forward request to appropriate handler based on type of PnP request.
//
status = PptPnpDispatchFunctionTable[ minorFunction ]( DeviceObject, Irp );
}
}
return status;
}
NTSTATUS
PptPnpStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++dvdf8
Routine Description:
This function handles PnP IRP_MN_START IRPs.
- Wait for the bus driver and any drivers beneath
us in the driver stack to handle this first.
- Get, validate, and save the resources given to us by PnP.
- Assign IDs to and get a count of 1284.3 daisy chain devices
connected to the port.
- Determine the capabilities of the chipset (BYTE, EPP, ECP).
- Set our PnP device interface state to trigger
an interface arrival callback to anyone listening
on our GUID.
Arguments:
DeviceObject - The target device for the IRP
Irp - The IRP
Return Value:
STATUS_SUCCESS - on success,
an appropriate error status - otherwise
--*/
{
PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
NTSTATUS status;
BOOLEAN foundPort = FALSE;
BOOLEAN foundIrq = FALSE;
BOOLEAN foundDma = FALSE;
//
// This IRP must be handled first by the parent bus driver
// and then by each higher driver in the device stack.
//
status = PptPnpBounceAndCatchPnpIrp(extension, Irp);
if( !NT_SUCCESS( status ) && ( status != STATUS_NOT_SUPPORTED ) ) {
// Someone below us in the driver stack explicitly failed the START.
goto targetExit;
}
//
// Extract resources from CM_RESOURCE_LIST and save them in our extension.
//
status = PptPnpStartScanCmResourceList(extension, Irp, &foundPort, &foundIrq, &foundDma);
if( !NT_SUCCESS( status ) ) {
goto targetExit;
}
//
// Do our resources appear to be valid?
//
status = PptPnpStartValidateResources(DeviceObject, foundPort, foundIrq, foundDma);
if( !NT_SUCCESS( status ) ) {
goto targetExit;
}
//
// Initialize the IEEE 1284.3 "bus" by assigning IDs [0..3] to
// the 1284.3 daisy chain devices connected to the port. This
// function also gives us a count of the number of such
// devices connected to the port.
//
extension->PnpInfo.Ieee1284_3DeviceCount = PptInitiate1284_3( extension );
//
// Determine the hardware modes supported (BYTE, ECP, EPP) by
// the parallel port chipset and save this information in our extension.
//
// Check to see if the filter parchip is there and use the modes it can set
status = PptDetectChipFilter( extension );
// if filter driver was not found use our own generic port detection
if ( !NT_SUCCESS( status ) ) {
PptDetectPortType( extension );
}
//
// Register w/WMI
//
status = PptWmiInitWmi( DeviceObject );
if( !NT_SUCCESS( status ) ) {
goto targetExit;
}
//
// Signal those who registered for PnP interface change notification
// on our GUID that we have STARTED (trigger an INTERFACE_ARRIVAL
// PnP callback).
//
status = IoSetDeviceInterfaceState(&extension->SymbolicLinkName, TRUE);
if( !NT_SUCCESS(status) ) {
status = STATUS_NOT_SUPPORTED;
}
targetExit:
if( NT_SUCCESS( status ) ) {
//
// Note in our extension that we have successfully STARTED.
//
ExAcquireFastMutex( &extension->ExtensionFastMutex );
PptSetFlags( extension->DeviceStateFlags, PPT_DEVICE_STARTED );
ExReleaseFastMutex( &extension->ExtensionFastMutex );
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
PptCompleteRequest( Irp, IO_NO_INCREMENT );
PptReleaseRemoveLock( &extension->RemoveLock, Irp );
return status;
}
NTSTATUS
PptPnpStartScanCmResourceList(
IN PDEVICE_EXTENSION Extension,
IN PIRP Irp,
OUT PBOOLEAN FoundPort,
OUT PBOOLEAN FoundIrq,
OUT PBOOLEAN FoundDma
)
/*++dvdf3
Routine Description:
This function is a helper function called by PptPnpStartDevice().
This function scans the CM_RESOURCE_LIST supplied with the Pnp
IRP_MN_START_DEVICE IRP, extracts the resources from the list,
and saves them in the device extension.
Arguments:
Extension - The device extension of the target of the START IRP
Irp - The IRP
FoundPort - Did we find a Port resource?
FoundIrq - Did we find an IRQ resource?
FoundDma - Did we find a DMA resource?
Return Value:
STATUS_SUCCESS - if we were given a resource list,
STATUS_INSUFFICIENT_RESOURCES - otherwise
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
PCM_RESOURCE_LIST ResourceList;
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
ULONG i;
PHYSICAL_ADDRESS start;
ULONG length;
BOOLEAN isPci = FALSE;
*FoundPort = FALSE;
*FoundIrq = FALSE;
*FoundDma = FALSE;
ResourceList = irpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
if (ResourceList == NULL) {
// we weren't given any resources, bail out
PptDumpP( ("START - FAIL - No Resources - AllocatedResourcesTranslated == NULL\n") );
status = STATUS_INSUFFICIENT_RESOURCES;
goto targetExit;
}
if(IsNotNEC_98) {
// The NEC_98 not have PCI-Parallel.
if( TRUE == PptIsPci( Extension, Irp ) ) {
// This appears to be a PCI card
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -