|
|
/*++
Copyright (c) 1990-2000 Microsoft Corporation
Module Name:
pdopnp.c
Abstract:
This file contains the PNP IRP dispatch code for PDOs
Environment:
Kernel Mode Driver.
Revision History:
--*/
#include "busp.h"
#include "pnpisa.h"
#include <wdmguid.h>
#include "halpnpp.h"
#if ISOLATE_CARDS
//
// Function Prototypes
//
BOOLEAN PipFailStartPdo = FALSE; BOOLEAN PipFailStartRdp = FALSE;
NTSTATUS PiStartPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryRemoveStopPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiCancelRemoveStopPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiStopPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryDeviceRelationsPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryCapabilitiesPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryDeviceTextPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiFilterResourceRequirementsPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryIdPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryResourcesPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryResourceRequirementsPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiRemovePdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryBusInformationPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiQueryInterfacePdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiDeviceUsageNotificationPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiSurpriseRemovePdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PiIrpNotSupported( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUS PipBuildRDPResources( IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *IoResources, IN ULONG Flags );
NTSTATUS PiQueryDeviceState( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,PiDispatchPnpPdo)
#pragma alloc_text(PAGE,PiStartPdo)
#pragma alloc_text(PAGE,PiQueryRemoveStopPdo)
#pragma alloc_text(PAGE,PiRemovePdo)
#pragma alloc_text(PAGE,PiCancelRemoveStopPdo)
#pragma alloc_text(PAGE,PiStopPdo)
#pragma alloc_text(PAGE,PiQueryDeviceRelationsPdo)
#pragma alloc_text(PAGE,PiQueryInterfacePdo)
#pragma alloc_text(PAGE,PiQueryCapabilitiesPdo)
#pragma alloc_text(PAGE,PiQueryResourcesPdo)
#pragma alloc_text(PAGE,PiQueryResourceRequirementsPdo)
#pragma alloc_text(PAGE,PiQueryDeviceTextPdo)
#pragma alloc_text(PAGE,PiFilterResourceRequirementsPdo)
#pragma alloc_text(PAGE,PiSurpriseRemovePdo)
#pragma alloc_text(PAGE,PiIrpNotSupported)
#pragma alloc_text(PAGE,PiQueryIdPdo)
#pragma alloc_text(PAGE,PiQueryBusInformationPdo)
#pragma alloc_text(PAGE,PiDeviceUsageNotificationPdo)
#pragma alloc_text(PAGE,PipBuildRDPResources)
#pragma alloc_text(PAGE,PiQueryDeviceState)
#endif
//
// PNP IRP Dispatch table for PDOs - This should be updated if new IRPs are added
//
PPI_DISPATCH PiPnpDispatchTablePdo[] = { PiStartPdo, // IRP_MN_START_DEVICE
PiQueryRemoveStopPdo, // IRP_MN_QUERY_REMOVE_DEVICE
PiRemovePdo, // IRP_MN_REMOVE_DEVICE
PiCancelRemoveStopPdo, // IRP_MN_CANCEL_REMOVE_DEVICE
PiStopPdo, // IRP_MN_STOP_DEVICE
PiQueryRemoveStopPdo, // IRP_MN_QUERY_STOP_DEVICE
PiCancelRemoveStopPdo, // IRP_MN_CANCEL_STOP_DEVICE
PiQueryDeviceRelationsPdo, // IRP_MN_QUERY_DEVICE_RELATIONS
PiQueryInterfacePdo, // IRP_MN_QUERY_INTERFACE
PiQueryCapabilitiesPdo, // IRP_MN_QUERY_CAPABILITIES
PiQueryResourcesPdo, // IRP_MN_QUERY_RESOURCES
PiQueryResourceRequirementsPdo, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
PiQueryDeviceTextPdo, // IRP_MN_QUERY_DEVICE_TEXT
PiFilterResourceRequirementsPdo, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
PiIrpNotSupported, // Unused
PiIrpNotSupported, // IRP_MN_READ_CONFIG
PiIrpNotSupported, // IRP_MN_WRITE_CONFIG
PiIrpNotSupported, // IRP_MN_EJECT
PiIrpNotSupported, // IRP_MN_SET_LOCK
PiQueryIdPdo, // IRP_MN_QUERY_ID
PiQueryDeviceState, // IRP_MN_QUERY_PNP_DEVICE_STATE
PiQueryBusInformationPdo, // IRP_MN_QUERY_BUS_INFORMATION
PiDeviceUsageNotificationPdo, // IRP_MN_DEVICE_USAGE_NOTIFICATION
PiSurpriseRemovePdo, // IRP_MN_SURPRISE_REMOVAL
PiIrpNotSupported // IRP_MN_QUERY_LEGACY_BUS_INFORMATION
};
NTSTATUS PiDispatchPnpPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp )
/*++
Routine Description:
This routine handles IRP_MJ_PNP IRPs for PDOs.
Arguments:
DeviceObject - Pointer to the PDO for which this IRP applies.
Irp - Pointer to the IRP_MJ_PNP IRP to dispatch.
Return Value:
NT status.
--*/
{
PIO_STACK_LOCATION irpSp; NTSTATUS status; PVOID information = NULL;
PAGED_CODE();
//
// Get a pointer to our stack location and take appropriate action based
// on the minor function.
//
irpSp = IoGetCurrentIrpStackLocation(Irp);
if (irpSp->MinorFunction > IRP_MN_PNP_MAXIMUM_FUNCTION) {
status = Irp->IoStatus.Status;
} else {
status = PiPnpDispatchTablePdo[irpSp->MinorFunction](DeviceObject, Irp);
if ( status != STATUS_NOT_SUPPORTED ) {
//
// We understood this IRP and handled it so we need to set status before completing
//
Irp->IoStatus.Status = status;
} else {
status = Irp->IoStatus.Status; }
}
information = (PVOID)Irp->IoStatus.Information;
ASSERT(status == Irp->IoStatus.Status);
PipCompleteRequest(Irp, status, information); return status;
} //PipDispatchPnpPdo
NTSTATUS PiStartPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) {
PIO_STACK_LOCATION irpSp; NTSTATUS status; PCM_RESOURCE_LIST cmResources; PDEVICE_INFORMATION deviceInfo; UNICODE_STRING unicodeString; ULONG length; POWER_STATE newPowerState;
irpSp = IoGetCurrentIrpStackLocation(Irp);
cmResources = irpSp->Parameters.StartDevice.AllocatedResources;
if (PipDebugMask & DEBUG_PNP) { PipDumpCmResourceList(cmResources); } else if (!cmResources) { DbgPrint("StartDevice irp with empty CmResourceList\n"); }
DebugPrint((DEBUG_PNP, "*** StartDevice irp received PDO: %x\n",DeviceObject)); if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, TRUE)) {
if (deviceInfo->Flags & DF_READ_DATA_PORT) { ULONG curSize,newSize; //
if (PipFailStartRdp) { PipDereferenceDeviceInformation(deviceInfo, TRUE); return STATUS_UNSUCCESSFUL; } // Read data port is special
//
newSize=PipDetermineResourceListSize(cmResources); curSize=PipDetermineResourceListSize(deviceInfo->AllocatedResources);
//
// Check if we've been removed, or moved (the +3 is the bit mask for the RDP , we claim 4-7, need xxxi7)
//
if ( (deviceInfo->Flags & DF_REMOVED) || !(deviceInfo->Flags & DF_STOPPED) || (curSize != newSize) || (newSize != RtlCompareMemory (deviceInfo->AllocatedResources,cmResources,newSize))) {
//
// This will release the unused resources
//
status = PipStartReadDataPort (deviceInfo,deviceInfo->ParentDeviceExtension,DeviceObject,cmResources); if (NT_SUCCESS(status) || status == STATUS_NO_SUCH_DEVICE) { status = STATUS_SUCCESS; }
//
// Invalidate the device relations
//
if (NT_SUCCESS (status)) { IoInvalidateDeviceRelations ( deviceInfo->ParentDeviceExtension->PhysicalBusDevice,BusRelations); } deviceInfo->Flags &= ~(DF_STOPPED|DF_REMOVED|DF_SURPRISE_REMOVED); } else { deviceInfo->Flags &= ~DF_STOPPED; IoInvalidateDeviceRelations ( deviceInfo->ParentDeviceExtension->PhysicalBusDevice,BusRelations); status=STATUS_SUCCESS; } deviceInfo->Flags |= DF_ACTIVATED; PipDereferenceDeviceInformation(deviceInfo, TRUE);
DebugPrint((DEBUG_PNP, "StartDevice(RDP) returning: %x\n",status));
return status; }
//
if (PipFailStartPdo) { PipDereferenceDeviceInformation(deviceInfo, TRUE); return STATUS_UNSUCCESSFUL; }
// Do this first, so that we allow for no-resource devices in the ref count.
// (when we activate the RDP it won't have resources, yet)
//
// ASSERT (!(PipRDPNode->Flags & (DF_STOPPED|DF_REMOVED)));
if (PipRDPNode->Flags & (DF_STOPPED|DF_REMOVED)) { //
// If the RDP isn't running, fail the start.
//
PipDereferenceDeviceInformation(deviceInfo, TRUE);
return STATUS_UNSUCCESSFUL; }
if (cmResources) { deviceInfo->AllocatedResources = ExAllocatePool( NonPagedPool, PipDetermineResourceListSize(cmResources)); if (deviceInfo->AllocatedResources) { RtlMoveMemory(deviceInfo->AllocatedResources, cmResources, length = PipDetermineResourceListSize(cmResources)); deviceInfo->Flags &= ~(DF_REMOVED|DF_STOPPED); status = PipSetDeviceResources (deviceInfo, cmResources); if (NT_SUCCESS(status)) {
PipActivateDevice();
DebugPrint((DEBUG_STATE, "Starting CSN %d/LDN %d\n", deviceInfo->CardInformation->CardSelectNumber, deviceInfo->LogicalDeviceNumber));
deviceInfo->Flags |= DF_ACTIVATED; newPowerState.DeviceState = deviceInfo->DevicePowerState = PowerDeviceD0; PoSetPowerState(DeviceObject, DevicePowerState, newPowerState); deviceInfo->DevicePowerState = PowerDeviceD0;
if (deviceInfo->LogConfHandle) { RtlInitUnicodeString(&unicodeString, L"AllocConfig"); ZwSetValueKey(deviceInfo->LogConfHandle, &unicodeString, 0, REG_RESOURCE_LIST, cmResources, length ); } }
} else { status = STATUS_NO_MEMORY; } } else if (deviceInfo->ResourceRequirements) { status = STATUS_INSUFFICIENT_RESOURCES; } else { status = STATUS_SUCCESS; } PipDereferenceDeviceInformation(deviceInfo, TRUE); } else { status = STATUS_NO_SUCH_DEVICE; }
DebugPrint((DEBUG_PNP, "StartDevice returning: %x\n",status)); return status;
} // PiStartPdo
NTSTATUS PiQueryRemoveStopPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PDEVICE_INFORMATION deviceInfo; PIO_STACK_LOCATION irpSp;
irpSp = IoGetCurrentIrpStackLocation(Irp);
DebugPrint((DEBUG_PNP, "*** Query%s irp received PDO: %x\n", (irpSp->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) ? "Stop" : "Remove", DeviceObject)); if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) {
if (deviceInfo->Paging || deviceInfo->CrashDump) { status = STATUS_DEVICE_BUSY; } else if ( deviceInfo->Flags & DF_READ_DATA_PORT ) { if (irpSp->MinorFunction != IRP_MN_QUERY_STOP_DEVICE) { status = STATUS_SUCCESS; } else if (deviceInfo->Flags & DF_PROCESSING_RDP) { //
// If we're in the middle of the two part RDP start process,
// flag this as a device that needs to be requeried for
// resource requirements.
//
status = STATUS_RESOURCE_REQUIREMENTS_CHANGED; } else {
PSINGLE_LIST_ENTRY deviceLink; PDEVICE_INFORMATION childDeviceInfo; PPI_BUS_EXTENSION busExtension = deviceInfo->ParentDeviceExtension; //
// If trying to stop the RDP, then if any children fail it.
//
PipLockDeviceDatabase();
status = STATUS_SUCCESS; deviceLink = busExtension->DeviceList.Next; while (deviceLink) { childDeviceInfo = CONTAINING_RECORD (deviceLink, DEVICE_INFORMATION, DeviceList);
if (!(childDeviceInfo->Flags & DF_READ_DATA_PORT) && ((childDeviceInfo->Flags & DF_ENUMERATED) || !(childDeviceInfo->Flags & DF_REMOVED))) {
status = STATUS_UNSUCCESSFUL; break; } deviceLink = childDeviceInfo->DeviceList.Next; }
PipUnlockDeviceDatabase(); }
} else {
if ((irpSp->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) && !(deviceInfo->Flags & DF_ENUMERATED)) {
status = STATUS_UNSUCCESSFUL; } else {
ASSERT(!(PipRDPNode->Flags & (DF_STOPPED|DF_REMOVED))); if ((irpSp->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) && (deviceInfo->CardInformation->CardFlags & CF_ISOLATION_BROKEN)) { DebugPrint((DEBUG_ERROR, "Failed query remove due to broken isolatee\n")); status = STATUS_UNSUCCESSFUL; } else { deviceInfo->Flags |= DF_QUERY_STOPPED; status = STATUS_SUCCESS; } } }
PipDereferenceDeviceInformation(deviceInfo, FALSE); } else { status = STATUS_NO_SUCH_DEVICE; }
DebugPrint((DEBUG_PNP, "Query%s Device returning: %x\n", (irpSp->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) ? "Stop" : "Remove", status));
return status;
} // PiQueryRemoveStopPdo
NTSTATUS PiCancelRemoveStopPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PDEVICE_INFORMATION deviceInfo; PIO_STACK_LOCATION irpSp;
irpSp = IoGetCurrentIrpStackLocation(Irp);
DebugPrint((DEBUG_PNP, "*** Cancel%s irp received PDO: %x\n", (irpSp->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) ? "Stop" : "Remove", DeviceObject)); if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) {
deviceInfo->Flags &= ~DF_QUERY_STOPPED;
PipDereferenceDeviceInformation(deviceInfo, FALSE); status = STATUS_SUCCESS;
} else {
status = STATUS_NO_SUCH_DEVICE; }
DebugPrint((DEBUG_PNP, "Cancel%s Device returning: %x\n", (irpSp->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) ? "Stop" : "Remove", status));
return status;
} // PiCancelRemoteStopPdo
NTSTATUS PiStopPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PDEVICE_INFORMATION deviceInfo; POWER_STATE newPowerState;
DebugPrint((DEBUG_PNP, "PiStopPdo %x\n",DeviceObject));
if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, TRUE)) {
//
// Deselect the cards, but not the RDP node.
//
if (DeviceObject != PipRDPNode->PhysicalDeviceObject) {
PipDeactivateDevice(); DebugPrint((DEBUG_STATE, "Stopping CSN %d/LDN %d\n", deviceInfo->CardInformation->CardSelectNumber, deviceInfo->LogicalDeviceNumber));
PipReleaseDeviceResources (deviceInfo); }
if ((deviceInfo->Flags & DF_ACTIVATED)) { deviceInfo->Flags &= ~DF_ACTIVATED; newPowerState.DeviceState = deviceInfo->DevicePowerState = PowerDeviceD3; PoSetPowerState(DeviceObject, DevicePowerState, newPowerState); } deviceInfo->Flags &= ~DF_QUERY_STOPPED; deviceInfo->Flags |= DF_STOPPED;
PipDereferenceDeviceInformation(deviceInfo, TRUE); status = STATUS_SUCCESS; } else { status = STATUS_NO_SUCH_DEVICE; }
DebugPrint((DEBUG_PNP, "StopDevice returning: %x\n",status)); return status;
} // PiStopPdo
NTSTATUS PiQueryDeviceRelationsPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PDEVICE_INFORMATION deviceInfo; PIO_STACK_LOCATION irpSp;
irpSp = IoGetCurrentIrpStackLocation(Irp);
//
// The QueryDeviceRelation Irp is for devices under enumerated PnpIsa device.
//
switch (irpSp->Parameters.QueryDeviceRelations.Type) { case TargetDeviceRelation: { PDEVICE_RELATIONS deviceRelations;
deviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); if (deviceRelations == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; } else { deviceRelations->Count = 1; deviceRelations->Objects[0] = DeviceObject; ObReferenceObject(DeviceObject); Irp->IoStatus.Information = (ULONG_PTR)deviceRelations; status = STATUS_SUCCESS; } } break;
case RemovalRelations: {
PDEVICE_RELATIONS deviceRelations;
if (PipRDPNode && (DeviceObject == PipRDPNode->PhysicalDeviceObject)) {
deviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); if (deviceRelations == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; } else { //
//Don't include ourselves in the list of Removal Relations, hence the -1
//
PipLockDeviceDatabase(); status = PipQueryDeviceRelations( PipRDPNode->ParentDeviceExtension, (PDEVICE_RELATIONS *)&Irp->IoStatus.Information, TRUE );
PipUnlockDeviceDatabase(); }
} else { status = STATUS_NOT_SUPPORTED;
} } break;
default : {
status = STATUS_NOT_SUPPORTED;
break; } }
return status;
} // PiQueryDeviceRelationsPdo
NTSTATUS PiQueryCapabilitiesPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PIO_STACK_LOCATION irpSp; PDEVICE_CAPABILITIES deviceCapabilities; ULONG i; PDEVICE_POWER_STATE state;
irpSp = IoGetCurrentIrpStackLocation(Irp);
deviceCapabilities = irpSp->Parameters.DeviceCapabilities.Capabilities; deviceCapabilities->SystemWake = PowerSystemUnspecified; deviceCapabilities->DeviceWake = PowerDeviceUnspecified; deviceCapabilities->LockSupported = FALSE; deviceCapabilities->EjectSupported = FALSE; deviceCapabilities->Removable = FALSE; deviceCapabilities->DockDevice = FALSE; deviceCapabilities->UniqueID = TRUE; state = deviceCapabilities->DeviceState; //
// Init the entire DeviceState array to D3 then replace the entry
// for system state S0.
//
for (i = 0; i < sizeof(deviceCapabilities->DeviceState); i += sizeof(deviceCapabilities->DeviceState[0])) {
//
// Only supported state, currently, is off.
//
*state++ = PowerDeviceD3; } deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
//deviceCapabilities->SilentInstall = TRUE;
//deviceCapabilities->RawDeviceOK = FALSE;
if (PipRDPNode && (PipRDPNode->PhysicalDeviceObject == DeviceObject)) { deviceCapabilities->SilentInstall = TRUE; deviceCapabilities->RawDeviceOK = TRUE; }
return STATUS_SUCCESS;
} // PiQueryCapabilitiesPdo
NTSTATUS PiQueryDeviceTextPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PIO_STACK_LOCATION irpSp; PDEVICE_INFORMATION deviceInfo;
irpSp = IoGetCurrentIrpStackLocation(Irp);
if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) { PWSTR functionId;
ULONG functionIdLength;
if (irpSp->Parameters.QueryDeviceText.DeviceTextType == DeviceTextDescription) {
//
// Once we know we're going to touch the IRP
//
status = STATUS_SUCCESS;
PipGetFunctionIdentifier((PUCHAR)deviceInfo->DeviceData, &functionId, &functionIdLength);
if (!functionId) { if (deviceInfo->CardInformation) { PipGetCardIdentifier((PUCHAR)deviceInfo->CardInformation->CardData + NUMBER_CARD_ID_BYTES, &functionId, &functionIdLength); }else { functionId=NULL; } } Irp->IoStatus.Information = (ULONG_PTR)functionId; } else {
status = STATUS_NOT_SUPPORTED; } PipDereferenceDeviceInformation(deviceInfo, FALSE); } else { status = STATUS_NO_SUCH_DEVICE; }
return status;
} // PiQueryDeviceTextPdo
NTSTATUS PiFilterResourceRequirementsPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) /*++
Routine Description:
This routine ensures that the RDP doesn't get its requirements filtered.
Design Note: This code may now be extraneous now that we ensure that the DF_PROCESSING_RDP and DF_REQ_TRIMMED flags are cleared on RDP removal.
Arguments:
DeviceObject - Pointer to the PDO for which this IRP applies.
Irp - Pointer to the IRP_MJ_PNP IRP to dispatch.
Return Value:
NT status.
--*/
{ NTSTATUS status; PDEVICE_INFORMATION deviceInfo; PIO_RESOURCE_REQUIREMENTS_LIST IoResources; USHORT irqBootFlags;
if ((deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) == NULL) { return STATUS_NO_SUCH_DEVICE; }
if (deviceInfo->Flags & DF_READ_DATA_PORT) { DebugPrint((DEBUG_PNP, "Filtering resource requirements for RDP\n"));
status = PipBuildRDPResources(&IoResources, deviceInfo->Flags);
if (NT_SUCCESS(status)) { //
// if someone above us filtered the RDP resource requirements,
// free them.
if (Irp->IoStatus.Information) { ExFreePool((PVOID) Irp->IoStatus.Information); } Irp->IoStatus.Information = (ULONG_PTR) IoResources; } } else { //
// If the device's resource requirements are being filtered
// and the new requirements have only one alternative vs the n
// alternatives of the original, then we're going to assume we
// are receiving a force config. Apply our earlier derived
// IRQ level/edge settings to this force config in order to
// deal with broken force configs from NT4
//
// Design Note:
// Probably should've left out the force config test
// and done it on everything, but this is what we private
// tested.
IoResources = (PIO_RESOURCE_REQUIREMENTS_LIST) Irp->IoStatus.Information;
if (IoResources && (IoResources->AlternativeLists == 1) && (deviceInfo->ResourceRequirements->AlternativeLists > 1)) { status = PipGetBootIrqFlags(deviceInfo, &irqBootFlags); if (NT_SUCCESS(status)) { status = PipTrimResourceRequirements( &IoResources, irqBootFlags, NULL); Irp->IoStatus.Information = (ULONG_PTR) IoResources; } else { status = STATUS_NOT_SUPPORTED; } } else { status = STATUS_NOT_SUPPORTED; } }
PipDereferenceDeviceInformation(deviceInfo, FALSE);
return status; }
NTSTATUS PiQueryIdPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PIO_STACK_LOCATION irpSp; PDEVICE_INFORMATION deviceInfo; ULONG length; PWCHAR requestId = NULL, ids;
irpSp = IoGetCurrentIrpStackLocation(Irp);
if ((deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) == NULL) {
status = STATUS_NO_SUCH_DEVICE; return status; }
switch (irpSp->Parameters.QueryId.IdType) { case BusQueryCompatibleIDs:
ids = (PWCHAR)ExAllocatePool(PagedPool, 1024); if (ids) { PWCHAR p1; ULONG i;
p1 = ids; length = 0; for (i = 1; TRUE; i++) { //
// Use the -1 as a sentinel so that we get the magic RDP compat. ID and also leave the loop
//
ASSERT (i < 256); if (deviceInfo->Flags & DF_READ_DATA_PORT) { i =-1; }
status = PipGetCompatibleDeviceId( deviceInfo->DeviceData, i, &requestId); if (NT_SUCCESS(status) && requestId) { if ((length + wcslen(requestId) * sizeof(WCHAR) + 2 * sizeof(WCHAR)) <= 1024) { RtlMoveMemory(p1, requestId, wcslen(requestId) * sizeof(WCHAR)); p1 += wcslen(requestId); *p1 = UNICODE_NULL; p1++; length += wcslen(requestId) * sizeof(WCHAR) + sizeof(WCHAR); ExFreePool(requestId); } else { ExFreePool(requestId); break; } if ( i == -1 ) { break; } } else { break; } } if (length == 0) { ExFreePool(ids); ids = NULL; } else { *p1 = UNICODE_NULL; } } Irp->IoStatus.Information = (ULONG_PTR)ids; status = STATUS_SUCCESS; break;
case BusQueryHardwareIDs:
if (deviceInfo->Flags & DF_READ_DATA_PORT) { status = PipGetCompatibleDeviceId(deviceInfo->DeviceData, -1, &requestId); }else { status = PipGetCompatibleDeviceId(deviceInfo->DeviceData, 0, &requestId); }
if (NT_SUCCESS(status) && requestId) {
ULONG idLength, deviceIdLength; PWCHAR deviceId = NULL, p;
//
// create HardwareId value name. Even though it is a MULTI_SZ,
// we know there is only one HardwareId for PnpIsa.
//
// HACK - The modem inf files use the form of isapnp\xyz0001
// instead of *xyz0001 as the hardware id. To solve this
// problem we will generate two hardware Ids: *xyz0001 and
// isapnp\xyz0001 (device instance name).
//
status = PipQueryDeviceId(deviceInfo, &deviceId, 0);
if (NT_SUCCESS (status)) { idLength = wcslen(requestId) * sizeof(WCHAR); deviceIdLength = wcslen(deviceId) * sizeof(WCHAR); length = idLength + // returned ID
sizeof(WCHAR) + // UNICODE_NULL
deviceIdLength + // isapnp\id
2 * sizeof(WCHAR); // two UNICODE_NULLs
ids = p = (PWCHAR)ExAllocatePool(PagedPool, length); if (ids) { RtlMoveMemory(ids, deviceId, deviceIdLength); p += deviceIdLength / sizeof(WCHAR); *p = UNICODE_NULL; p++; RtlMoveMemory(p, requestId, idLength); p += idLength / sizeof(WCHAR); *p = UNICODE_NULL; p++; *p = UNICODE_NULL; ExFreePool(requestId); Irp->IoStatus.Information = (ULONG_PTR)ids; } else { Irp->IoStatus.Information = (ULONG_PTR)requestId; } if (deviceId) { ExFreePool(deviceId); } } } break;
case BusQueryDeviceID:
status = PipQueryDeviceId(deviceInfo, &requestId, 0); Irp->IoStatus.Information = (ULONG_PTR)requestId; break;
case BusQueryInstanceID:
status = PipQueryDeviceUniqueId (deviceInfo, &requestId); Irp->IoStatus.Information = (ULONG_PTR)requestId; break;
default:
status = STATUS_NOT_SUPPORTED; } PipDereferenceDeviceInformation(deviceInfo, FALSE);
return status;
} // PiQueryIdPdo
NTSTATUS PiQueryResourcesPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status=STATUS_SUCCESS; PDEVICE_INFORMATION deviceInfo; PCM_RESOURCE_LIST cmResources=NULL; ULONG length;
if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) { if ((deviceInfo->Flags & DF_READ_DATA_PORT) || ((deviceInfo->Flags & (DF_ENUMERATED|DF_REMOVED)) == DF_ENUMERATED)) { status = PipQueryDeviceResources ( deviceInfo, 0, // BusNumber
&cmResources, &length ); } PipDereferenceDeviceInformation(deviceInfo, FALSE); Irp->IoStatus.Information = (ULONG_PTR)cmResources; } else { status = STATUS_NO_SUCH_DEVICE; }
DebugPrint((DEBUG_PNP, "PiQueryResourcesPdo returning: %x\n",status)); return status;
} // PiQueryResourcesPdo
NTSTATUS PiQueryResourceRequirementsPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PDEVICE_INFORMATION deviceInfo; PIO_RESOURCE_REQUIREMENTS_LIST ioResources;
if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) { status = STATUS_SUCCESS;
if (deviceInfo->Flags & DF_READ_DATA_PORT) { status = PipBuildRDPResources (&ioResources, deviceInfo->Flags); } else { if (deviceInfo->ResourceRequirements && !(deviceInfo->Flags & (DF_SURPRISE_REMOVED))) {
ioResources = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool ( PagedPool, deviceInfo->ResourceRequirements->ListSize); if (ioResources == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; } else { RtlMoveMemory(ioResources, deviceInfo->ResourceRequirements, deviceInfo->ResourceRequirements->ListSize ); } } else { ioResources = NULL; } } Irp->IoStatus.Information = (ULONG_PTR)ioResources; PipDereferenceDeviceInformation(deviceInfo, FALSE); } else { status = STATUS_NO_SUCH_DEVICE; }
DebugPrint((DEBUG_PNP, "PiQueryResourceRequirementsPdo returning: %x\n",status)); return status;
} // PiQueryResourceRequirementsPdo
NTSTATUS PiRemovePdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PDEVICE_INFORMATION deviceInfo; POWER_STATE newPowerState;
//
// One of our enumerated device is being removed. Mark it and deactivate the
// device. Note, we do NOT delete its device object.
//
DebugPrint((DEBUG_PNP, "PiRemovePdo %x\n",DeviceObject));
if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) { if (!(deviceInfo->Flags & (DF_REMOVED|DF_SURPRISE_REMOVED))) { deviceInfo->Flags |= DF_REMOVED; deviceInfo->Flags &= ~DF_QUERY_STOPPED;
if (deviceInfo->Flags & DF_READ_DATA_PORT) {
PSINGLE_LIST_ENTRY deviceLink; PPI_BUS_EXTENSION busExtension = deviceInfo->ParentDeviceExtension;
//
// If the RDP is removed, mark everyone as missing, and then return only the
// RDP
//
PipLockDeviceDatabase();
deviceLink = busExtension->DeviceList.Next; while (deviceLink) { deviceInfo = CONTAINING_RECORD (deviceLink, DEVICE_INFORMATION, DeviceList); if (!(deviceInfo->Flags & DF_READ_DATA_PORT)) { deviceInfo->Flags &= ~DF_ENUMERATED; } deviceLink = deviceInfo->DeviceList.Next; }
PipUnlockDeviceDatabase();
IoInvalidateDeviceRelations ( deviceInfo->ParentDeviceExtension->PhysicalBusDevice,BusRelations); deviceInfo->Flags &= ~(DF_REQ_TRIMMED|DF_PROCESSING_RDP); }
//
// Deactivate the device
//
if (deviceInfo->Flags & DF_ACTIVATED) { deviceInfo->Flags &= ~DF_ACTIVATED;
if (!(deviceInfo->Flags & (DF_READ_DATA_PORT|DF_NOT_FUNCTIONING))) { PipWakeAndSelectDevice( (UCHAR) deviceInfo->CardInformation->CardSelectNumber, (UCHAR)deviceInfo->LogicalDeviceNumber); PipDeactivateDevice(); PipWaitForKey(); DebugPrint((DEBUG_STATE, "Removing CSN %d/LDN %d\n", deviceInfo->CardInformation->CardSelectNumber, deviceInfo->LogicalDeviceNumber)); } newPowerState.DeviceState = deviceInfo->DevicePowerState = PowerDeviceD3; PoSetPowerState(DeviceObject, DevicePowerState, newPowerState); }
PipReleaseDeviceResources (deviceInfo); }
if (!(deviceInfo->Flags & DF_ENUMERATED)) { PipDeleteDevice(DeviceObject); }
PipDereferenceDeviceInformation(deviceInfo, TRUE); status = STATUS_SUCCESS; } else { status = STATUS_NO_SUCH_DEVICE; }
DebugPrint((DEBUG_PNP, "RemoveDevice returning: %x\n",status));
return status;
} // PiRemovePdo
NTSTATUS PiQueryBusInformationPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { PPNP_BUS_INFORMATION pnpBusInfo; PVOID information = NULL; PPI_BUS_EXTENSION busExtension; NTSTATUS status;
busExtension = DeviceObject->DeviceExtension;
pnpBusInfo = (PPNP_BUS_INFORMATION) ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION)); if (pnpBusInfo) { pnpBusInfo->BusTypeGuid = GUID_BUS_TYPE_ISAPNP; pnpBusInfo->LegacyBusType = Isa; pnpBusInfo->BusNumber = busExtension->BusNumber; information = pnpBusInfo; status = STATUS_SUCCESS; } else { status = STATUS_INSUFFICIENT_RESOURCES; information = NULL; } Irp->IoStatus.Information = (ULONG_PTR) information;
return status; } // PiQueryBusInformationPdo
NTSTATUS PiDeviceUsageNotificationPdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) /*++
Routine Description:
This routine notes whether an ISAPNP device is on the crashdump or paging file path. It fails attempts to put us on the hibernation path.
Arguments:
DeviceObject - Pointer to the PDO for which this IRP applies.
Irp - Pointer to the IRP_MJ_PNP IRP to dispatch.
Return Value:
NT status.
--*/ { PDEVICE_INFORMATION deviceInfo; PIO_STACK_LOCATION irpSp; PLONG addend; NTSTATUS status = STATUS_SUCCESS;
irpSp = IoGetCurrentIrpStackLocation(Irp);
if ((deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) == NULL) {
status = STATUS_NO_SUCH_DEVICE; return status; }
DebugPrint((DEBUG_PNP, "DeviceUsage CSN %d/LSN %d: InPath %s Type %d\n", deviceInfo->CardInformation->CardSelectNumber, deviceInfo->LogicalDeviceNumber, irpSp->Parameters.UsageNotification.InPath ? "TRUE" : "FALSE", irpSp->Parameters.UsageNotification.Type));
switch (irpSp->Parameters.UsageNotification.Type) { case DeviceUsageTypePaging: addend = &deviceInfo->Paging; break; case DeviceUsageTypeHibernation: status = STATUS_DEVICE_BUSY; break; case DeviceUsageTypeDumpFile: addend = &deviceInfo->CrashDump; break; default: status = STATUS_NOT_SUPPORTED; }
if (status == STATUS_SUCCESS) { if (irpSp->Parameters.UsageNotification.InPath) { //
// Turn on broken isolation flag which causes QDR
// to use the cache instead of beating on the hardware if
// we're on the paging or crashdump paths. Some
// hardware appears unhappy during QDR and causes problems when
// we take a page fault in this routine.
//
deviceInfo->CardInformation->CardFlags |= CF_ISOLATION_BROKEN; (*addend)++; IoInvalidateDeviceState(DeviceObject); } else { (*addend)--; } } PipDereferenceDeviceInformation(deviceInfo, FALSE); return status; }
NTSTATUS PiQueryInterfacePdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) {
UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Irp);
return STATUS_NOT_SUPPORTED;
} // PiQueryInterfacePdo
NTSTATUS PiSurpriseRemovePdo( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status; PDEVICE_INFORMATION deviceInfo; PSINGLE_LIST_ENTRY deviceLink;
DebugPrint((DEBUG_PNP, "SurpriseRemove PDO %x\n", DeviceObject)); //
// One of our enumerated device is being removed. Mark it and deactivate the
// device. Note, we do NOT delete its device object.
//
if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) { if (deviceInfo->Flags & DF_READ_DATA_PORT) { //
// If the RDP is removed, mark everyone as missing, and then return only the
// RDP
//
PipLockDeviceDatabase();
deviceLink = deviceInfo->ParentDeviceExtension->DeviceList.Next; while (deviceLink) { deviceInfo = CONTAINING_RECORD (deviceLink, DEVICE_INFORMATION, DeviceList); if (!(deviceInfo->Flags & DF_READ_DATA_PORT)) { deviceInfo->Flags &= ~DF_ENUMERATED; } deviceLink = deviceInfo->DeviceList.Next; }
PipUnlockDeviceDatabase();
IoInvalidateDeviceRelations ( deviceInfo->ParentDeviceExtension->PhysicalBusDevice,BusRelations); } else { DebugPrint((DEBUG_STATE, "Surprise removing CSN %d/LDN %d\n", deviceInfo->CardInformation->CardSelectNumber, deviceInfo->LogicalDeviceNumber)); if ((deviceInfo->Flags & (DF_ACTIVATED|DF_NOT_FUNCTIONING)) == DF_ACTIVATED) { PipWakeAndSelectDevice( (UCHAR) deviceInfo->CardInformation->CardSelectNumber, (UCHAR)deviceInfo->LogicalDeviceNumber); PipDeactivateDevice(); PipWaitForKey(); }
PipReleaseDeviceResources (deviceInfo); deviceInfo->Flags |= DF_SURPRISE_REMOVED; deviceInfo->Flags &= ~(DF_QUERY_STOPPED|DF_REMOVED|DF_ACTIVATED); } PipDereferenceDeviceInformation(deviceInfo, FALSE); status = STATUS_SUCCESS; } else { status = STATUS_NO_SUCH_DEVICE; }
return status; } // PiSurpriseRemovePdo
NTSTATUS PiIrpNotSupported( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) {
return STATUS_NOT_SUPPORTED;
} // PiIrpNotSupported
NTSTATUS PipBuildRDPResources( IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *IoResources, IN ULONG Flags ) { ULONG MaxCards = 0, CardsFound; int i, j, numcases; int resSize;
ASSERT(Flags & DF_READ_DATA_PORT);
//
// We need to assemble all possible cases for the RDP
//
numcases = 2*READ_DATA_PORT_RANGE_CHOICES;
if (Flags & DF_REQ_TRIMMED) { numcases = 0; for (i = 0; i < READ_DATA_PORT_RANGE_CHOICES; i++) { CardsFound = PipReadDataPortRanges[i].CardsFound; if (MaxCards < CardsFound) { MaxCards = CardsFound; numcases = 1; } else if (MaxCards == CardsFound) { numcases++; } } } //
// need to allow for the RDP range, the address port, the cmd port and the 0
//
resSize = sizeof (IO_RESOURCE_LIST)+((numcases+3)*sizeof (IO_RESOURCE_REQUIREMENTS_LIST));
*IoResources = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool (PagedPool,resSize); if (*IoResources == NULL) { return STATUS_INSUFFICIENT_RESOURCES; }
RtlZeroMemory (*IoResources,resSize);
(*IoResources)->BusNumber=0; (*IoResources)->AlternativeLists = 1; (*IoResources)->List->Count = numcases+4; (*IoResources)->List->Version = ISAPNP_IO_VERSION; (*IoResources)->List->Revision =ISAPNP_IO_REVISION;
//
// Requirements specify 16-bit decode even though the spec
// says 12. No ill effects have ever been observed from 16
// and 12-bit decode broke some machines when tried.
//
// cmd port
//
(*IoResources)->List->Descriptors[0].Type=CM_RESOURCE_PORT_IO; (*IoResources)->List->Descriptors[0].u.Port.MinimumAddress.LowPart = COMMAND_PORT; (*IoResources)->List->Descriptors[0].u.Port.MaximumAddress.LowPart = COMMAND_PORT;
(*IoResources)->List->Descriptors[0].u.Port.Length = 1; (*IoResources)->List->Descriptors[0].u.Port.Alignment = 1; (*IoResources)->List->Descriptors[0].Flags = CM_RESOURCE_PORT_16_BIT_DECODE; (*IoResources)->List->Descriptors[0].ShareDisposition = CmResourceShareDeviceExclusive;
//
// alternative of 0 for bioses that include COMMAND_PORT in
// a PNP0C02 node.
//
(*IoResources)->List->Descriptors[1].Type=CM_RESOURCE_PORT_IO; (*IoResources)->List->Descriptors[1].u.Port.MinimumAddress.QuadPart = 0; (*IoResources)->List->Descriptors[1].u.Port.MaximumAddress.QuadPart = 0;
(*IoResources)->List->Descriptors[1].u.Port.Length = 0; (*IoResources)->List->Descriptors[1].u.Port.Alignment = 1; (*IoResources)->List->Descriptors[1].Flags = CM_RESOURCE_PORT_16_BIT_DECODE; (*IoResources)->List->Descriptors[1].ShareDisposition = CmResourceShareDeviceExclusive; (*IoResources)->List->Descriptors[1].Option = IO_RESOURCE_ALTERNATIVE;
//
// Address port
//
(*IoResources)->List->Descriptors[2].Type=CM_RESOURCE_PORT_IO; (*IoResources)->List->Descriptors[2].u.Port.MinimumAddress.LowPart = ADDRESS_PORT; (*IoResources)->List->Descriptors[2].u.Port.MaximumAddress.LowPart = ADDRESS_PORT;
(*IoResources)->List->Descriptors[2].u.Port.Length = 1; (*IoResources)->List->Descriptors[2].u.Port.Alignment = 1; (*IoResources)->List->Descriptors[2].Flags = CM_RESOURCE_PORT_16_BIT_DECODE; (*IoResources)->List->Descriptors[2].ShareDisposition = CmResourceShareDeviceExclusive; //
// alternative of 0
//
(*IoResources)->List->Descriptors[3].Type=CM_RESOURCE_PORT_IO; (*IoResources)->List->Descriptors[3].u.Port.MinimumAddress.QuadPart = 0; (*IoResources)->List->Descriptors[3].u.Port.MaximumAddress.QuadPart = 0;
(*IoResources)->List->Descriptors[3].u.Port.Length = 0; (*IoResources)->List->Descriptors[3].u.Port.Alignment = 1; (*IoResources)->List->Descriptors[3].Flags = CM_RESOURCE_PORT_16_BIT_DECODE; (*IoResources)->List->Descriptors[3].ShareDisposition = CmResourceShareDeviceExclusive; (*IoResources)->List->Descriptors[3].Option = IO_RESOURCE_ALTERNATIVE;
if (Flags & DF_REQ_TRIMMED) { j = 0; for (i = 0; i < READ_DATA_PORT_RANGE_CHOICES; i++) { if (PipReadDataPortRanges[i].CardsFound != MaxCards) { continue; } //
// An RDP alternative
//
(*IoResources)->List->Descriptors[4+j].Type=CM_RESOURCE_PORT_IO;
(*IoResources)->List->Descriptors[4+j].u.Port.MinimumAddress.LowPart = PipReadDataPortRanges[i].MinimumAddress; (*IoResources)->List->Descriptors[4+j].u.Port.MaximumAddress.LowPart = PipReadDataPortRanges[i].MaximumAddress;
(*IoResources)->List->Descriptors[4+j].u.Port.Length = PipReadDataPortRanges[i].MaximumAddress - PipReadDataPortRanges[i].MinimumAddress+1; (*IoResources)->List->Descriptors[4+j].u.Port.Alignment = 1; (*IoResources)->List->Descriptors[4+j].Flags = CM_RESOURCE_PORT_16_BIT_DECODE; (*IoResources)->List->Descriptors[4+j].ShareDisposition = CmResourceShareDeviceExclusive; (*IoResources)->List->Descriptors[4+j].Option = IO_RESOURCE_ALTERNATIVE; j++; } (*IoResources)->List->Descriptors[4].Option = 0; } else { for (i = 0;i< (numcases >> 1);i++) { //
// The RDP
//
(*IoResources)->List->Descriptors[4+i*2].Type=CM_RESOURCE_PORT_IO;
(*IoResources)->List->Descriptors[4+i*2].u.Port.MinimumAddress.LowPart = PipReadDataPortRanges[i].MinimumAddress; (*IoResources)->List->Descriptors[4+i*2].u.Port.MaximumAddress.LowPart = PipReadDataPortRanges[i].MaximumAddress;
(*IoResources)->List->Descriptors[4+i*2].u.Port.Length = PipReadDataPortRanges[i].MaximumAddress - PipReadDataPortRanges[i].MinimumAddress+1;
(*IoResources)->List->Descriptors[4+i*2].u.Port.Alignment = 1; (*IoResources)->List->Descriptors[4+i*2].Flags = CM_RESOURCE_PORT_16_BIT_DECODE; (*IoResources)->List->Descriptors[4+i*2].ShareDisposition = CmResourceShareDeviceExclusive;
//
// alternative of 0
//
(*IoResources)->List->Descriptors[4+i*2+1].Type=CM_RESOURCE_PORT_IO; (*IoResources)->List->Descriptors[4+i*2+1].u.Port.MinimumAddress.QuadPart = 0; (*IoResources)->List->Descriptors[4+i*2+1].u.Port.MaximumAddress.QuadPart = 0;
(*IoResources)->List->Descriptors[4+i*2+1].u.Port.Length = 0; (*IoResources)->List->Descriptors[4+i*2+1].u.Port.Alignment = 1; (*IoResources)->List->Descriptors[4+i*2+1].Flags = CM_RESOURCE_PORT_16_BIT_DECODE; (*IoResources)->List->Descriptors[4+i*2+1].ShareDisposition = CmResourceShareDeviceExclusive; (*IoResources)->List->Descriptors[4+i*2+1].Option = IO_RESOURCE_ALTERNATIVE;
}
} (*IoResources)->ListSize = resSize;
return STATUS_SUCCESS; }
NTSTATUS PiQueryDeviceState( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { NTSTATUS status=STATUS_NOT_SUPPORTED; PDEVICE_INFORMATION deviceInfo;
//
// One of our enumerated device is being removed. Mark it and deactivate the
// device. Note, we do NOT delete its device object.
//
if (deviceInfo = PipReferenceDeviceInformation(DeviceObject, FALSE)) {
if ((deviceInfo->Flags & DF_READ_DATA_PORT) && (deviceInfo->Flags & DF_PROCESSING_RDP)) { Irp->IoStatus.Information |= PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED | PNP_DEVICE_FAILED | PNP_DEVICE_NOT_DISABLEABLE ; status = STATUS_SUCCESS; }
if (deviceInfo->Paging || deviceInfo->CrashDump) { Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; status = STATUS_SUCCESS; } PipDereferenceDeviceInformation(deviceInfo, FALSE); } return status;
} #endif
|