Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

pnpirp.c File Reference

#include "iop.h"

Go to the source code of this file.

Classes

struct  _DEVICE_COMPLETION_CONTEXT
struct  _LOCK_MOUNTABLE_DEVICE_CONTEXT

Defines

#define PnpIrpStatusTracking(Status, IrpCode, Device)
#define HASH_UNICODE_STRING(_pustr, _phash)
#define MAX_PARENT_PREFIX   (8 + 8 + 8 + 2)

Typedefs

typedef _DEVICE_COMPLETION_CONTEXT DEVICE_COMPLETION_CONTEXT
typedef _DEVICE_COMPLETION_CONTEXTPDEVICE_COMPLETION_CONTEXT
typedef _LOCK_MOUNTABLE_DEVICE_CONTEXT LOCK_MOUNTABLE_DEVICE_CONTEXT
typedef _LOCK_MOUNTABLE_DEVICE_CONTEXTPLOCK_MOUNTABLE_DEVICE_CONTEXT

Functions

NTSTATUS IopAsynchronousCall (IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION TopStackLocation, IN PDEVICE_COMPLETION_CONTEXT CompletionContext, IN PVOID CompletionRoutine)
NTSTATUS IopDeviceEjectComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
NTSTATUS IopDeviceStartComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
NTSTATUS IopDeviceRelationsComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
PDEVICE_OBJECT IopFindMountableDevice (IN PDEVICE_OBJECT DeviceObject)
PDEVICE_OBJECT IopLockMountedDeviceForRemove (IN PDEVICE_OBJECT DeviceObject, IN ULONG IrpMinorCode, OUT PLOCK_MOUNTABLE_DEVICE_CONTEXT Context)
VOID IopUnlockMountedDeviceForRemove (IN PDEVICE_OBJECT DeviceObject, IN ULONG IrpMinorCode, IN PLOCK_MOUNTABLE_DEVICE_CONTEXT Context)
NTSTATUS IopFilterResourceRequirementsCall (IN PDEVICE_OBJECT DeviceObject, IN PIO_RESOURCE_REQUIREMENTS_LIST ResReqList, OUT PVOID *Information)
VOID IopUncacheInterfaceInformation (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IopSynchronousCall (IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION TopStackLocation, OUT PVOID *Information)
VOID IopStartDevice (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IopEjectDevice (IN PDEVICE_OBJECT DeviceObject, IN OUT PPENDING_RELATIONS_LIST_ENTRY PendingEntry)
NTSTATUS IopRemoveDevice (IN PDEVICE_OBJECT TargetDevice, IN ULONG IrpMinorCode)
NTSTATUS IopQueryDeviceRelations (IN DEVICE_RELATION_TYPE Relations, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AsyncOk, OUT PDEVICE_RELATIONS *DeviceRelations)
NTSTATUS IopQueryDeviceId (IN PDEVICE_OBJECT DeviceObject, OUT PWCHAR *DeviceId)
NTSTATUS IopQueryUniqueId (IN PDEVICE_OBJECT DeviceObject, OUT PWCHAR *UniqueId)
NTSTATUS IopMakeGloballyUniqueId (IN PDEVICE_OBJECT DeviceObject, IN PWCHAR UniqueId, OUT PWCHAR *GloballyUniqueId)
NTSTATUS IopQueryCompatibleIds (IN PDEVICE_OBJECT DeviceObject, IN BUS_QUERY_ID_TYPE IdType, OUT PWCHAR *CompatibleIds, OUT ULONG *Length)
NTSTATUS IopQueryDeviceResources (IN PDEVICE_OBJECT DeviceObject, IN ULONG ResourceType, OUT PVOID *Resource, OUT ULONG *Length)
NTSTATUS IopQueryResourceHandlerInterface (IN RESOURCE_HANDLER_TYPE HandlerType, IN PDEVICE_OBJECT DeviceObject, IN UCHAR ResourceType, IN OUT PVOID *Interface)
NTSTATUS IopQueryReconfiguration (IN UCHAR Request, IN PDEVICE_OBJECT DeviceObject)
NTSTATUS IopQueryLegacyBusInformation (IN PDEVICE_OBJECT DeviceObject, OUT LPGUID InterfaceGuid, OPTIONAL OUT INTERFACE_TYPE *InterfaceType, OPTIONAL OUT ULONG *BusNumber OPTIONAL)
NTSTATUS IopQueryPnpBusInformation (IN PDEVICE_OBJECT DeviceObject, OUT LPGUID InterfaceGuid, OPTIONAL OUT INTERFACE_TYPE *InterfaceType, OPTIONAL OUT ULONG *BusNumber OPTIONAL)
NTSTATUS IopQueryDeviceState (IN PDEVICE_OBJECT DeviceObject)
VOID IopIncDisableableDepends (IN OUT PDEVICE_NODE DeviceNode)
VOID IopDecDisableableDepends (IN OUT PDEVICE_NODE DeviceNode)
NTSTATUS IopQueryDeviceSerialNumber (IN PDEVICE_OBJECT DeviceObject, OUT PWCHAR *SerialNumber)
NTSTATUS IopQueryDockRemovalInterface (IN PDEVICE_OBJECT DeviceObject, IN OUT PDOCK_INTERFACE *DockInterface)

Variables

ULONG PnpIrpMask
PCHAR IrpName []


Define Documentation

#define HASH_UNICODE_STRING _pustr,
_phash   ) 
 

Value:

{ \ PWCHAR _p = (_pustr)->Buffer; \ PWCHAR _ep = _p + ((_pustr)->Length/sizeof(WCHAR)); \ ULONG _chHolder =0; \ \ while( _p < _ep ) { \ _chHolder = 37 * _chHolder + (unsigned int) (*_p++); \ } \ \ *(_phash) = abs(314159269 * _chHolder) % 1000000007; \ }

Definition at line 72 of file pnpirp.c.

Referenced by IopMakeGloballyUniqueId().

#define MAX_PARENT_PREFIX   (8 + 8 + 8 + 2)
 

Definition at line 85 of file pnpirp.c.

Referenced by IopMakeGloballyUniqueId().

#define PnpIrpStatusTracking Status,
IrpCode,
Device   ) 
 

Value:

if (PnpIrpMask & (1 << IrpCode)) { \ if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) { \ DbgPrint(" ++ %s Driver ( %wZ ) return status %08lx\n", \ IrpName[IrpCode], \ &Device->DriverObject->DriverName, \ Status); \ } \ }

Definition at line 26 of file pnpirp.c.

Referenced by IopDeviceRelationsComplete(), IopDeviceStartComplete(), IopFilterResourceRequirementsCall(), and IopSynchronousCall().


Typedef Documentation

typedef struct _DEVICE_COMPLETION_CONTEXT DEVICE_COMPLETION_CONTEXT
 

typedef struct _LOCK_MOUNTABLE_DEVICE_CONTEXT LOCK_MOUNTABLE_DEVICE_CONTEXT
 

typedef struct _DEVICE_COMPLETION_CONTEXT * PDEVICE_COMPLETION_CONTEXT
 

Referenced by IopDeviceRelationsComplete(), IopDeviceStartComplete(), IopQueryDeviceRelations(), and IopStartDevice().

typedef struct _LOCK_MOUNTABLE_DEVICE_CONTEXT * PLOCK_MOUNTABLE_DEVICE_CONTEXT
 


Function Documentation

NTSTATUS IopAsynchronousCall IN PDEVICE_OBJECT  DeviceObject,
IN PIO_STACK_LOCATION  TopStackLocation,
IN PDEVICE_COMPLETION_CONTEXT  CompletionContext,
IN PVOID  CompletionRoutine
 

Definition at line 262 of file pnpirp.c.

References ASSERT, _VPB::DeviceObject, FALSE, IoAllocateIrp(), IoCallDriver, IoGetAttachedDevice(), IoGetNextIrpStackLocation, IoSetCompletionRoutine, _IRP::IoStatus, IRP_SYSTEM_RESTRICTED, KernelMode, NTSTATUS(), NULL, PAGED_CODE, PsGetCurrentThread, _IRP::RequestorMode, SPECIALIRP_WATERMARK_IRP, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserEvent, _IRP::UserIosb, _DEVICE_OBJECT::Vpb, and VPB_MOUNTED.

Referenced by IopQueryDeviceRelations(), and IopStartDevice().

00271 : 00272 00273 This function sends an Asynchronous irp to the top level device 00274 object which roots on DeviceObject. 00275 00276 Parameters: 00277 00278 DeviceObject - Supplies the device object of the device being removed. 00279 00280 TopStackLocation - Supplies a pointer to the parameter block for the irp. 00281 00282 CompletionContext - 00283 00284 CompletionRoutine - 00285 00286 Return Value: 00287 00288 NTSTATUS code. 00289 00290 --*/ 00291 00292 { 00293 PDEVICE_OBJECT deviceObject; 00294 PIRP irp; 00295 PIO_STACK_LOCATION irpSp; 00296 NTSTATUS status; 00297 00298 PAGED_CODE(); 00299 00300 // 00301 // If the target device object has a VPB associated with it and a file 00302 // system is mounted, make the filesystem's volume device object the 00303 // irp target. 00304 // 00305 // BUGBUG - I don't think we need to do this. The filesystem 00306 // driver should attach to the PDO chain or registered for device 00307 // change registration. 00308 // 00309 00310 if ((TargetDevice->Vpb != NULL) && (TargetDevice->Vpb->Flags & VPB_MOUNTED)) { 00311 deviceObject = TargetDevice->Vpb->DeviceObject; 00312 } else { 00313 deviceObject = TargetDevice; 00314 } 00315 00316 ASSERT(deviceObject != NULL); 00317 00318 // 00319 // Get a pointer to the topmost device object in the stack of devices, 00320 // beginning with the deviceObject. 00321 // 00322 00323 deviceObject = IoGetAttachedDevice(deviceObject); 00324 00325 // 00326 // Allocate an I/O Request Packet (IRP) for this device removal operation. 00327 // 00328 00329 irp = IoAllocateIrp( (CCHAR) (deviceObject->StackSize), FALSE ); 00330 if (!irp) { 00331 return STATUS_INSUFFICIENT_RESOURCES; 00332 } 00333 00334 SPECIALIRP_WATERMARK_IRP(irp, IRP_SYSTEM_RESTRICTED); 00335 00336 // 00337 // Initialize it to failure. 00338 // 00339 00340 irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 00341 irp->IoStatus.Information = 0; 00342 00343 // 00344 // Get a pointer to the next stack location in the packet. This location 00345 // will be used to pass the function codes and parameters to the first 00346 // driver. 00347 // 00348 00349 irpSp = IoGetNextIrpStackLocation (irp); 00350 00351 // 00352 // Fill in the IRP according to this request. 00353 // 00354 00355 irp->Tail.Overlay.Thread = PsGetCurrentThread(); 00356 irp->RequestorMode = KernelMode; 00357 irp->UserIosb = NULL; 00358 irp->UserEvent = NULL; 00359 00360 // 00361 // Copy in the caller-supplied stack location contents 00362 // 00363 00364 *irpSp = *TopStackLocation; 00365 #if DBG 00366 CompletionContext->Id = irp; 00367 #endif 00368 IoSetCompletionRoutine(irp, 00369 CompletionRoutine, 00370 CompletionContext, /* Completion context */ 00371 TRUE, /* Invoke on success */ 00372 TRUE, /* Invoke on error */ 00373 TRUE /* Invoke on cancel */ 00374 ); 00375 00376 status = IoCallDriver( deviceObject, irp ); 00377 return status; 00378 }

VOID IopDecDisableableDepends IN OUT PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 3152 of file pnpirp.c.

References NULL.

Referenced by IopQueryDeviceState(), and IopRemoveDevice().

03157 : 03158 03159 Decrements the DisableableDepends field of this devicenode 03160 and potentially every parent device node up the tree 03161 A parent devicenode is only decremented if the child in question 03162 is decremented from 1 to 0 03163 03164 Parameters: 03165 03166 DeviceNode - Supplies the device node where the depends is to be decremented 03167 03168 Return Value: 03169 03170 none. 03171 03172 --*/ 03173 { 03174 03175 while (DeviceNode != NULL) { 03176 03177 LONG newval; 03178 03179 newval = InterlockedDecrement(& DeviceNode->DisableableDepends); 03180 if (newval != 0) { 03181 // 03182 // we are still non-disableable, so we don't have to bother parent 03183 // 03184 break; 03185 } 03186 03187 DeviceNode = DeviceNode ->Parent; 03188 03189 } 03190 03191 }

NTSTATUS IopDeviceEjectComplete IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context
 

Definition at line 896 of file pnpirp.c.

References ASSERT, DelayedWorkQueue, _PENDING_RELATIONS_LIST_ENTRY::EjectIrp, ExInitializeWorkItem, ExQueueWorkItem(), IoFreeIrp(), IopProcessCompletedEject(), Irp, NULL, and _PENDING_RELATIONS_LIST_ENTRY::WorkItem.

Referenced by IopEjectDevice().

00901 { 00902 PPENDING_RELATIONS_LIST_ENTRY entry = (PPENDING_RELATIONS_LIST_ENTRY)Context; 00903 PIRP ejectIrp; 00904 00905 ejectIrp = InterlockedExchangePointer(&entry->EjectIrp, NULL); 00906 00907 ASSERT(ejectIrp == NULL || ejectIrp == Irp); 00908 00909 // 00910 // Queue a work item to finish up the eject. We queue a work item because 00911 // we are probably running at dispatch level in some random context. 00912 // 00913 00914 ExInitializeWorkItem( &entry->WorkItem, 00915 IopProcessCompletedEject, 00916 entry); 00917 00918 ExQueueWorkItem( &entry->WorkItem, DelayedWorkQueue ); 00919 00920 IoFreeIrp( Irp ); 00921 00922 return STATUS_MORE_PROCESSING_REQUIRED; 00923 00924 }

NTSTATUS IopDeviceRelationsComplete IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context
 

Definition at line 1496 of file pnpirp.c.

References ASSERT, DNF_BEING_ENUMERATED, DNF_ENUMERATION_REQUEST_PENDING, DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING, ERESOURCE_THREAD, ExFreePool(), FALSE, _DEVICE_NODE::Flags, IoFreeIrp(), IopPnPSpinLock, IopReleaseEnumerationLockForThread, IopRequestDeviceAction(), _IRP::IoStatus, Irp, IRP_MN_QUERY_DEVICE_RELATIONS, NT_SUCCESS, NULL, _DEVICE_NODE::OverUsed1, PDEVICE_COMPLETION_CONTEXT, _DEVICE_NODE::PhysicalDeviceObject, PnpIrpStatusTracking, ReenumerateDeviceTree, RestartEnumeration, and TRUE.

Referenced by IopQueryDeviceRelations().

01504 : 01505 01506 Completion function for a QueryDeviceRelations IRP. T 01507 01508 Arguments: 01509 01510 DeviceObject - NULL. 01511 Irp - SetPower irp which has completed 01512 Context - a pointer to the DEVICE_CHANGE_COMPLETION_CONTEXT. 01513 01514 Return Value: 01515 01516 STATUS_MORE_PROCESSING_REQUIRED is returned to IoCompleteRequest 01517 to signify that IoCompleteRequest should not continue processing 01518 the IRP. 01519 01520 --*/ 01521 { 01522 PDEVICE_NODE deviceNode = ((PDEVICE_COMPLETION_CONTEXT)Context)->DeviceNode; 01523 ERESOURCE_THREAD LockingThread = ((PDEVICE_COMPLETION_CONTEXT)Context)->Thread; 01524 KIRQL oldIrql; 01525 BOOLEAN requestEnumeration = FALSE; 01526 01527 #if DBG 01528 if (((PDEVICE_COMPLETION_CONTEXT)Context)->Id != (PVOID)Irp) { 01529 ASSERT(0); 01530 IoFreeIrp (Irp); 01531 ExFreePool(Context); 01532 return STATUS_MORE_PROCESSING_REQUIRED; 01533 } 01534 #endif 01535 01536 PnpIrpStatusTracking(Irp->IoStatus.Status, IRP_MN_QUERY_DEVICE_RELATIONS, deviceNode->PhysicalDeviceObject); 01537 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 01538 deviceNode->Flags &= ~DNF_BEING_ENUMERATED; 01539 01540 // 01541 // Read state from Irp. 01542 // 01543 01544 if (NT_SUCCESS(Irp->IoStatus.Status) && (Irp->IoStatus.Information)) { 01545 01546 // 01547 // It is VERY important that we set PendingDeviceRealtions field before 01548 // checking DNF_ENUMERATION_REQUEST_PENDING. 01549 // 01550 01551 ASSERT(deviceNode->OverUsed1.PendingDeviceRelations == NULL); 01552 deviceNode->OverUsed1.PendingDeviceRelations = (PDEVICE_RELATIONS)Irp->IoStatus.Information; 01553 } 01554 01555 if (deviceNode->Flags & DNF_ENUMERATION_REQUEST_PENDING) { 01556 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01557 01558 if (deviceNode->OverUsed1.PendingDeviceRelations) { 01559 01560 // 01561 // If the query_device_relations irp returns something, we will 01562 // make a request to process the childrens. 01563 // 01564 01565 IopRequestDeviceAction( deviceNode->PhysicalDeviceObject, 01566 RestartEnumeration, 01567 NULL, 01568 NULL ); 01569 } else { 01570 deviceNode->Flags &= ~DNF_ENUMERATION_REQUEST_PENDING; 01571 } 01572 } else { 01573 deviceNode->Flags |= DNF_ENUMERATION_REQUEST_PENDING; 01574 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01575 } 01576 01577 IopReleaseEnumerationLockForThread(NULL, LockingThread); 01578 01579 // 01580 // Irp processing is complete, free the irp and then return 01581 // more_processing_required which causes IoCompleteRequest to 01582 // stop "completing" this irp any future. 01583 // 01584 01585 IoFreeIrp (Irp); 01586 ExFreePool(Context); 01587 01588 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 01589 if (deviceNode->Flags & DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING) { 01590 deviceNode->Flags &= ~DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING; 01591 requestEnumeration = TRUE; 01592 } 01593 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01594 if (requestEnumeration) { 01595 IopRequestDeviceAction( DeviceObject, 01596 ReenumerateDeviceTree, 01597 NULL, 01598 NULL ); 01599 } 01600 return STATUS_MORE_PROCESSING_REQUIRED; 01601 }

NTSTATUS IopDeviceStartComplete IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context
 

Definition at line 1370 of file pnpirp.c.

References ASSERT, DNF_NEED_ENUMERATION_ONLY, DNF_START_REQUEST_PENDING, DNF_STARTED, DNF_STOPPED, DOCK_ARRIVING, DOCK_NOTDOCKDEVICE, _DEVICE_NODE::DockInfo, ERESOURCE_THREAD, ExFreePool(), _DEVICE_NODE::Flags, IoFreeIrp(), IopPnPSpinLock, IopReleaseEnumerationLockForThread, IopRequestDeviceAction(), IopRequestDeviceRemoval(), IopSetDevNodeProblem, IoRequestDeviceEject(), _IRP::IoStatus, Irp, IRP_MN_START_DEVICE, NT_SUCCESS, NULL, PDEVICE_COMPLETION_CONTEXT, _DEVICE_NODE::PhysicalDeviceObject, PnpIrpStatusTracking, ReenumerateDeviceTree, and SAVE_FAILURE_INFO.

Referenced by IopStartDevice().

01378 : 01379 01380 Completion function for an Async Start IRP. 01381 01382 Arguments: 01383 01384 DeviceObject - NULL. 01385 Irp - SetPower irp which has completed 01386 Context - a pointer to the DEVICE_CHANGE_COMPLETION_CONTEXT. 01387 01388 Return Value: 01389 01390 STATUS_MORE_PROCESSING_REQUIRED is returned to IoCompleteRequest 01391 to signify that IoCompleteRequest should not continue processing 01392 the IRP. 01393 01394 --*/ 01395 { 01396 PDEVICE_NODE deviceNode = ((PDEVICE_COMPLETION_CONTEXT)Context)->DeviceNode; 01397 ERESOURCE_THREAD LockingThread = ((PDEVICE_COMPLETION_CONTEXT)Context)->Thread; 01398 ULONG oldFlags; 01399 KIRQL oldIrql; 01400 01401 // 01402 // Read state from Irp. 01403 // 01404 01405 #if DBG 01406 if (((PDEVICE_COMPLETION_CONTEXT)Context)->Id != (PVOID)Irp) { 01407 ASSERT(0); 01408 IoFreeIrp (Irp); 01409 ExFreePool(Context); 01410 01411 return STATUS_MORE_PROCESSING_REQUIRED; 01412 } 01413 #endif 01414 01415 PnpIrpStatusTracking(Irp->IoStatus.Status, IRP_MN_START_DEVICE, deviceNode->PhysicalDeviceObject); 01416 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 01417 01418 oldFlags = deviceNode->Flags; 01419 deviceNode->Flags &= ~DNF_START_REQUEST_PENDING; 01420 if (NT_SUCCESS(Irp->IoStatus.Status)) { 01421 01422 if (deviceNode->Flags & DNF_STOPPED) { 01423 01424 // 01425 // If the start is initiated by rebalancing, do NOT do enumeration 01426 // 01427 01428 deviceNode->Flags &= ~DNF_STOPPED; 01429 deviceNode->Flags |= DNF_STARTED; 01430 01431 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01432 } else { 01433 01434 // 01435 // Otherwise, we need to queue a request to enumerate the device if DNF_START_REQUEST_PENDING 01436 // is set. (IopStartDevice sets the flag if status of start irp returns pending.) 01437 // 01438 // 01439 01440 deviceNode->Flags |= DNF_NEED_ENUMERATION_ONLY + DNF_STARTED; 01441 01442 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01443 01444 if (oldFlags & DNF_START_REQUEST_PENDING) { 01445 IopRequestDeviceAction( deviceNode->PhysicalDeviceObject, 01446 ReenumerateDeviceTree, 01447 NULL, 01448 NULL ); 01449 } 01450 } 01451 01452 } else { 01453 01454 // 01455 // The start failed. We will remove the device 01456 // 01457 01458 deviceNode->Flags &= ~(DNF_STOPPED | DNF_STARTED); 01459 01460 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01461 SAVE_FAILURE_INFO(deviceNode, Irp->IoStatus.Status); 01462 01463 IopSetDevNodeProblem(deviceNode, CM_PROB_FAILED_START); 01464 01465 if (deviceNode->DockInfo.DockStatus == DOCK_NOTDOCKDEVICE) { 01466 01467 IopRequestDeviceRemoval(deviceNode->PhysicalDeviceObject, CM_PROB_FAILED_START); 01468 } else { 01469 01470 ASSERT(deviceNode->DockInfo.DockStatus == DOCK_ARRIVING); 01471 01472 // 01473 // ADRIAO BUGBUG 05/12/1999 - 01474 // We never go down this path, but if we fix it a function 01475 // similar to IopRequestDeviceEjectWorker needs to be queued, one 01476 // that passes in "FALSE" for the kernel initiated parameter. 01477 // 01478 ASSERT(0); 01479 IoRequestDeviceEject(deviceNode->PhysicalDeviceObject); 01480 } 01481 } 01482 IopReleaseEnumerationLockForThread(NULL, LockingThread); 01483 01484 // 01485 // Irp processing is complete, free the irp and then return 01486 // more_processing_required which causes IoCompleteRequest to 01487 // stop "completing" this irp any future. 01488 // 01489 01490 IoFreeIrp (Irp); 01491 ExFreePool(Context); 01492 return STATUS_MORE_PROCESSING_REQUIRED; 01493 }

NTSTATUS IopEjectDevice IN PDEVICE_OBJECT  DeviceObject,
IN OUT PPENDING_RELATIONS_LIST_ENTRY  PendingEntry
 

Definition at line 730 of file pnpirp.c.

References DelayedWorkQueue, ExInitializeWorkItem, ExQueueWorkItem(), FALSE, IoAllocateIrp(), IoCallDriver, IoGetAttachedDevice(), IoGetNextIrpStackLocation, IopDeviceEjectComplete(), IopProcessCompletedEject(), IopQueuePendingEject(), IoSetCompletionRoutine, _IRP::IoStatus, IRP_MJ_PNP, IRP_MN_EJECT, IRP_SYSTEM_RESTRICTED, KernelMode, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, PAGED_CODE, PpNotifyUserModeRemovalSafe(), PsGetCurrentThread, _IRP::RequestorMode, SPECIALIRP_WATERMARK_IRP, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserEvent, and _IRP::UserIosb.

00737 : 00738 00739 This function sends an eject device irp to the top level device 00740 object which roots on DeviceObject. 00741 00742 Parameters: 00743 00744 DeviceObject - Supplies a pointer to the device object of the device being 00745 removed. 00746 00747 Return Value: 00748 00749 NTSTATUS code. 00750 00751 --*/ 00752 00753 { 00754 PIO_STACK_LOCATION irpSp; 00755 NTSTATUS status; 00756 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00757 PDEVICE_OBJECT deviceObject; 00758 PIRP irp; 00759 00760 PAGED_CODE(); 00761 00762 if (PendingEntry->LightestSleepState != PowerSystemWorking) { 00763 00764 // 00765 // We have to warm eject. 00766 // 00767 if (PendingEntry->DockInterface) { 00768 00769 PendingEntry->DockInterface->ProfileDepartureSetMode( 00770 PendingEntry->DockInterface->Context, 00771 PDS_UPDATE_ON_EJECT 00772 ); 00773 } 00774 00775 PendingEntry->EjectIrp = NULL; 00776 00777 InitializeListHead( &PendingEntry->Link ); 00778 00779 IopQueuePendingEject(PendingEntry); 00780 00781 ExInitializeWorkItem( &PendingEntry->WorkItem, 00782 IopProcessCompletedEject, 00783 PendingEntry); 00784 00785 ExQueueWorkItem( &PendingEntry->WorkItem, DelayedWorkQueue ); 00786 return STATUS_SUCCESS; 00787 } 00788 00789 if (PendingEntry->DockInterface) { 00790 00791 // 00792 // Notify dock that now is a good time to update it's hardware profile. 00793 // 00794 PendingEntry->DockInterface->ProfileDepartureSetMode( 00795 PendingEntry->DockInterface->Context, 00796 PDS_UPDATE_ON_INTERFACE 00797 ); 00798 00799 PendingEntry->DockInterface->ProfileDepartureUpdate( 00800 PendingEntry->DockInterface->Context 00801 ); 00802 00803 if (PendingEntry->DisplaySafeRemovalDialog) { 00804 00805 PpNotifyUserModeRemovalSafe(DeviceObject); 00806 PendingEntry->DisplaySafeRemovalDialog = FALSE; 00807 } 00808 } 00809 00810 // 00811 // Get a pointer to the topmost device object in the stack of devices, 00812 // beginning with the deviceObject. 00813 // 00814 00815 deviceObject = IoGetAttachedDevice(DeviceObject); 00816 00817 // 00818 // Allocate an I/O Request Packet (IRP) for this device removal operation. 00819 // 00820 00821 irp = IoAllocateIrp( (CCHAR) (deviceObject->StackSize), FALSE ); 00822 if (!irp) { 00823 00824 PendingEntry->EjectIrp = NULL; 00825 00826 InitializeListHead( &PendingEntry->Link ); 00827 00828 IopQueuePendingEject(PendingEntry); 00829 00830 ExInitializeWorkItem( &PendingEntry->WorkItem, 00831 IopProcessCompletedEject, 00832 PendingEntry); 00833 00834 ExQueueWorkItem( &PendingEntry->WorkItem, DelayedWorkQueue ); 00835 00836 return STATUS_INSUFFICIENT_RESOURCES; 00837 } 00838 00839 SPECIALIRP_WATERMARK_IRP(irp, IRP_SYSTEM_RESTRICTED); 00840 00841 // 00842 // Initialize it to failure. 00843 // 00844 00845 irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 00846 irp->IoStatus.Information = 0; 00847 00848 // 00849 // Get a pointer to the next stack location in the packet. This location 00850 // will be used to pass the function codes and parameters to the first 00851 // driver. 00852 // 00853 00854 irpSp = IoGetNextIrpStackLocation(irp); 00855 00856 // 00857 // Initialize the stack location to pass to IopSynchronousCall() 00858 // 00859 00860 RtlZeroMemory(irpSp, sizeof(IO_STACK_LOCATION)); 00861 00862 // 00863 // Set the function codes. 00864 // 00865 00866 irpSp->MajorFunction = IRP_MJ_PNP; 00867 irpSp->MinorFunction = IRP_MN_EJECT; 00868 00869 // 00870 // Fill in the IRP according to this request. 00871 // 00872 00873 irp->Tail.Overlay.Thread = PsGetCurrentThread(); 00874 irp->RequestorMode = KernelMode; 00875 irp->UserIosb = NULL; 00876 irp->UserEvent = NULL; 00877 00878 PendingEntry->EjectIrp = irp; 00879 00880 IopQueuePendingEject(PendingEntry); 00881 00882 IoSetCompletionRoutine(irp, 00883 IopDeviceEjectComplete, 00884 PendingEntry, /* Completion context */ 00885 TRUE, /* Invoke on success */ 00886 TRUE, /* Invoke on error */ 00887 TRUE /* Invoke on cancel */ 00888 ); 00889 00890 status = IoCallDriver( deviceObject, irp ); 00891 00892 return status; 00893 }

NTSTATUS IopFilterResourceRequirementsCall IN PDEVICE_OBJECT  DeviceObject,
IN PIO_RESOURCE_REQUIREMENTS_LIST  ResReqList,
OUT PVOID *  Information
 

Definition at line 3255 of file pnpirp.c.

References Executive, FALSE, IoAllocateIrp(), IoCallDriver, IoGetAttachedDevice(), IoGetNextIrpStackLocation, IopQueueThreadIrp, _IRP::IoStatus, IRP_MJ_PNP, IRP_MN_FILTER_RESOURCE_REQUIREMENTS, IRP_SYSTEM_RESTRICTED, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PnpIrpStatusTracking, PsGetCurrentThread, SPECIALIRP_WATERMARK_IRP, _DEVICE_OBJECT::StackSize, _IRP::Tail, _IRP::UserEvent, _IRP::UserIosb, and VOID().

Referenced by IopQueryDeviceResources().

03263 : 03264 03265 This function sends a synchronous filter resource requirements irp to the 03266 top level device object which roots on DeviceObject. 03267 03268 Parameters: 03269 03270 DeviceObject - Supplies the device object of the device being removed. 03271 03272 ResReqList - Supplies a pointer to the resource requirements requiring 03273 filtering. 03274 03275 Information - Supplies a pointer to a variable that receives the returned 03276 information of the irp. 03277 03278 Return Value: 03279 03280 NTSTATUS code. 03281 03282 --*/ 03283 03284 { 03285 PIRP irp; 03286 PIO_STACK_LOCATION irpSp; 03287 IO_STATUS_BLOCK statusBlock; 03288 KEVENT event; 03289 NTSTATUS status; 03290 PULONG_PTR returnInfo = (PULONG_PTR)Information; 03291 PDEVICE_OBJECT deviceObject; 03292 03293 PAGED_CODE(); 03294 03295 // 03296 // Get a pointer to the topmost device object in the stack of devices, 03297 // beginning with the deviceObject. 03298 // 03299 03300 deviceObject = IoGetAttachedDevice(DeviceObject); 03301 03302 // 03303 // Begin by allocating the IRP for this request. Do not charge quota to 03304 // the current process for this IRP. 03305 // 03306 03307 irp = IoAllocateIrp(deviceObject->StackSize, FALSE); 03308 if (irp == NULL){ 03309 03310 return STATUS_INSUFFICIENT_RESOURCES; 03311 } 03312 03313 SPECIALIRP_WATERMARK_IRP(irp, IRP_SYSTEM_RESTRICTED); 03314 03315 // 03316 // Initialize it to success. This is a special hack for WDM (ie 9x) 03317 // compatibility. The driver verifier is in on this one. 03318 // 03319 03320 if (ResReqList) { 03321 03322 irp->IoStatus.Status = statusBlock.Status = STATUS_SUCCESS; 03323 irp->IoStatus.Information = statusBlock.Information = (ULONG_PTR) ResReqList; 03324 03325 } else { 03326 03327 irp->IoStatus.Status = statusBlock.Status = STATUS_NOT_SUPPORTED; 03328 } 03329 03330 // 03331 // Set the pointer to the status block and initialized event. 03332 // 03333 03334 KeInitializeEvent( &event, 03335 SynchronizationEvent, 03336 FALSE ); 03337 03338 irp->UserIosb = &statusBlock; 03339 irp->UserEvent = &event; 03340 03341 // 03342 // Set the address of the current thread 03343 // 03344 03345 irp->Tail.Overlay.Thread = PsGetCurrentThread(); 03346 03347 // 03348 // Queue this irp onto the current thread 03349 // 03350 03351 IopQueueThreadIrp(irp); 03352 03353 // 03354 // Get a pointer to the stack location of the first driver which will be 03355 // invoked. This is where the function codes and parameters are set. 03356 // 03357 03358 irpSp = IoGetNextIrpStackLocation(irp); 03359 03360 // 03361 // Setup the stack location contents 03362 // 03363 03364 irpSp->MinorFunction = IRP_MN_FILTER_RESOURCE_REQUIREMENTS; 03365 irpSp->MajorFunction = IRP_MJ_PNP; 03366 irpSp->Parameters.FilterResourceRequirements.IoResourceRequirementList = ResReqList; 03367 03368 // 03369 // Call the driver 03370 // 03371 03372 status = IoCallDriver(deviceObject, irp); 03373 03374 PnpIrpStatusTracking(status, IRP_MN_FILTER_RESOURCE_REQUIREMENTS, deviceObject); 03375 03376 // 03377 // If a driver returns STATUS_PENDING, we will wait for it to complete 03378 // 03379 03380 if (status == STATUS_PENDING) { 03381 (VOID) KeWaitForSingleObject( &event, 03382 Executive, 03383 KernelMode, 03384 FALSE, 03385 (PLARGE_INTEGER) NULL ); 03386 status = statusBlock.Status; 03387 } 03388 03389 *returnInfo = (ULONG_PTR) statusBlock.Information; 03390 03391 return status; 03392 }

PDEVICE_OBJECT IopFindMountableDevice IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 1316 of file pnpirp.c.

References _DEVICE_OBJECT::AttachedDevice, DO_DEVICE_HAS_NAME, _DEVICE_OBJECT::Flags, NULL, and _DEVICE_OBJECT::Vpb.

Referenced by IopRemoveDevice().

01321 : 01322 01323 This routine will scan up the device stack and find a device which could 01324 finds with the VPB_REMOVE_PENDING bit (or clear it in the case of cancel) 01325 and increment (or decrement in the case of cancel) the reference count 01326 in the VPB. This is to ensure that no new file system can get mounted on 01327 the device stack while the remove operation is in place. 01328 01329 The search will terminate once all the attached device objects have been 01330 marked, or once a mounted device object has been marked. 01331 01332 Arguments: 01333 01334 DeviceObject - the PDO we are attempting to remove 01335 01336 IrpMinorCode - the remove-type operation we are going to perform 01337 01338 Context - a context block which must be passed in to the unlock operation 01339 01340 Return Value: 01341 01342 A pointer to the device object stack which the remove request should be 01343 sent to. If a mounted file system was found, this will be the lowest 01344 file system device object in the mounted stack. Otherwise this will be 01345 the PDO which was passed in. 01346 01347 --*/ 01348 01349 { 01350 PVPB vpb; 01351 01352 PDEVICE_OBJECT mountableDevice = DeviceObject; 01353 01354 while (mountableDevice != NULL) { 01355 01356 if ((mountableDevice->Flags & DO_DEVICE_HAS_NAME) && 01357 (mountableDevice->Vpb != NULL)) { 01358 01359 return mountableDevice; 01360 } 01361 01362 mountableDevice = mountableDevice->AttachedDevice; 01363 } 01364 01365 return NULL; 01366 }

VOID IopIncDisableableDepends IN OUT PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 3109 of file pnpirp.c.

References NULL.

Referenced by IopQueryDeviceState().

03114 : 03115 03116 Increments the DisableableDepends field of this devicenode 03117 and potentially every parent device node up the tree 03118 A parent devicenode is only incremented if the child in question 03119 is incremented from 0 to 1 03120 03121 Parameters: 03122 03123 DeviceNode - Supplies the device node where the depends is to be incremented 03124 03125 Return Value: 03126 03127 none. 03128 03129 --*/ 03130 { 03131 03132 while (DeviceNode != NULL) { 03133 03134 LONG newval; 03135 03136 newval = InterlockedIncrement(& DeviceNode->DisableableDepends); 03137 if (newval != 1) { 03138 // 03139 // we were already non-disableable, so we don't have to bother parent 03140 // 03141 break; 03142 } 03143 03144 DeviceNode = DeviceNode ->Parent; 03145 03146 } 03147 03148 }

PDEVICE_OBJECT IopLockMountedDeviceForRemove IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  IrpMinorCode,
OUT PLOCK_MOUNTABLE_DEVICE_CONTEXT  Context
 

Definition at line 1080 of file pnpirp.c.

References ASSERT, _DEVICE_OBJECT::AttachedDevice, _DEVICE_OBJECT::DeviceLock, _VPB::DeviceObject, Executive, FALSE, _VPB::Flags, IO_NO_INCREMENT, IoAcquireVpbSpinLock(), IopDatabaseLock, IoReleaseVpbSpinLock(), IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE, IRP_MN_SURPRISE_REMOVAL, KernelMode, KeSetEvent(), KeWaitForSingleObject(), NULL, _DEVICE_OBJECT::Vpb, VPB_MOUNTED, and VPB_REMOVE_PENDING.

Referenced by IopRemoveDevice().

01088 : 01089 01090 This routine will scan up the device stack and mark each unmounted VPB it 01091 finds with the VPB_REMOVE_PENDING bit (or clear it in the case of cancel) 01092 and increment (or decrement in the case of cancel) the reference count 01093 in the VPB. This is to ensure that no new file system can get mounted on 01094 the device stack while the remove operation is in place. 01095 01096 The search will terminate once all the attached device objects have been 01097 marked, or once a mounted device object has been marked. 01098 01099 Arguments: 01100 01101 DeviceObject - the PDO we are attempting to remove 01102 01103 IrpMinorCode - the remove-type operation we are going to perform 01104 01105 Context - a context block which must be passed in to the unlock operation 01106 01107 Return Value: 01108 01109 A pointer to the device object stack which the remove request should be 01110 sent to. If a mounted file system was found, this will be the lowest 01111 file system device object in the mounted stack. Otherwise this will be 01112 the PDO which was passed in. 01113 01114 --*/ 01115 01116 { 01117 PVPB vpb; 01118 01119 PDEVICE_OBJECT device = DeviceObject; 01120 PDEVICE_OBJECT fsDevice = NULL; 01121 01122 BOOLEAN isRemovePendingSet; 01123 KIRQL oldIrql; 01124 01125 RtlZeroMemory(Context, sizeof(LOCK_MOUNTABLE_DEVICE_CONTEXT)); 01126 Context->MountedDevice = DeviceObject; 01127 01128 do { 01129 01130 // 01131 // Walk up each device object in the stack. For each one, if a VPB 01132 // exists, grab the database resource exclusive followed by the 01133 // device lock. Then acquire the Vpb spinlock and perform the 01134 // appropriate magic on the device object. 01135 // 01136 01137 // 01138 // NOTE - Its unfortunate that the locking order includes grabbing 01139 // the device specific lock first followed by the global lock. 01140 // 01141 01142 if(device->Vpb != NULL) { 01143 01144 // 01145 // Grab the device lock. This will ensure that there are no mount 01146 // or verify operations in progress. 01147 // 01148 01149 KeWaitForSingleObject(&(device->DeviceLock), 01150 Executive, 01151 KernelMode, 01152 FALSE, 01153 NULL); 01154 01155 // 01156 // Now set the remove pending flag, which will prevent new mounts 01157 // from occuring on this stack once the current (if existant) 01158 // filesystem dismounts. Filesystems will preserve the flag across 01159 // vpb swaps. 01160 // 01161 01162 IoAcquireVpbSpinLock(&oldIrql); 01163 01164 vpb = device->Vpb; 01165 01166 ASSERT(vpb != NULL); 01167 01168 switch(IrpMinorCode) { 01169 01170 case IRP_MN_QUERY_REMOVE_DEVICE: 01171 case IRP_MN_SURPRISE_REMOVAL: 01172 case IRP_MN_REMOVE_DEVICE: { 01173 01174 vpb->Flags |= VPB_REMOVE_PENDING; 01175 break; 01176 } 01177 01178 case IRP_MN_CANCEL_REMOVE_DEVICE: { 01179 01180 vpb->Flags &= ~VPB_REMOVE_PENDING; 01181 break; 01182 } 01183 01184 default: 01185 break; 01186 } 01187 01188 // 01189 // Note the device object that has the filesystem stack attached. 01190 // We must remember the vpb we referenced that had the fs because 01191 // it may be swapped off of the storage device during a dismount 01192 // operation. 01193 // 01194 01195 if(vpb->Flags & VPB_MOUNTED) { 01196 01197 Context->MountedDevice = device; 01198 fsDevice = vpb->DeviceObject; 01199 } 01200 01201 IoReleaseVpbSpinLock(oldIrql); 01202 KeSetEvent(&(device->DeviceLock), IO_NO_INCREMENT, FALSE); 01203 01204 // 01205 // Stop if we hit a device with a mounted filesystem. 01206 // 01207 01208 if (Context->MountedDevice != NULL) { 01209 01210 // 01211 // We found and setup a mounted device. Time to return. 01212 // 01213 01214 break; 01215 } 01216 } 01217 01218 ExAcquireFastLock( &IopDatabaseLock, &oldIrql ); 01219 device = device->AttachedDevice; 01220 ExReleaseFastLock( &IopDatabaseLock, oldIrql ); 01221 01222 } while (device != NULL); 01223 01224 if(fsDevice != NULL) { 01225 01226 return fsDevice; 01227 } 01228 01229 return Context->MountedDevice; 01230 }

NTSTATUS IopMakeGloballyUniqueId IN PDEVICE_OBJECT  DeviceObject,
IN PWCHAR  UniqueId,
OUT PWCHAR *  GloballyUniqueId
 

Definition at line 1891 of file pnpirp.c.

References ASSERT, CmRegistryMachineSystemCurrentControlSetEnumName, DbgPrint, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), ExReleaseResource, HASH_UNICODE_STRING, _DEVICE_NODE::InstancePath, IopOpenRegistryKeyEx(), KeEnterCriticalRegion, KeLeaveCriticalRegion, L, _DEVICE_NODE::Level, max, MAX_PARENT_PREFIX, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _DEVICE_NODE::Parent, PpRegistryDeviceResource, RtlFreeUnicodeString(), RtlInitUnicodeString(), RtlUpcaseUnicodeString(), TITLE_INDEX_VALUE, and TRUE.

Referenced by IopProcessNewDeviceNode().

01896 { 01897 NTSTATUS status; 01898 ULONG length; 01899 PWSTR id, Prefix = NULL; 01900 HANDLE enumKey; 01901 HANDLE instanceKey; 01902 UCHAR keyBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(ULONG)]; 01903 PKEY_VALUE_PARTIAL_INFORMATION keyValue, stringValueBuffer = NULL; 01904 UNICODE_STRING valueName; 01905 ULONG uniqueIdValue, Hash, hashInstance; 01906 PDEVICE_NODE parentNode; 01907 01908 PAGED_CODE(); 01909 01910 // 01911 // We need to build an instance id to uniquely identify this 01912 // device. We will accomplish this by producing a prefix that will be 01913 // prepended to the non-unique device id supplied. 01914 // 01915 01916 // 01917 // To 'unique-ify' the child's instance ID, we will retrieve 01918 // the unique "UniqueParentID" number that has been assigned 01919 // to the parent and use it to construct a prefix. This is 01920 // the legacy mechanism supported here so that existing device 01921 // settings are not lost on upgrade. 01922 // 01923 01924 KeEnterCriticalRegion(); 01925 ExAcquireResourceShared(&PpRegistryDeviceResource, TRUE); 01926 01927 parentNode = ((PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode)->Parent; 01928 01929 status = IopOpenRegistryKeyEx( &enumKey, 01930 NULL, 01931 &CmRegistryMachineSystemCurrentControlSetEnumName, 01932 KEY_READ | KEY_WRITE 01933 ); 01934 01935 if (!NT_SUCCESS(status)) { 01936 DbgPrint("IopQueryUniqueId:\tUnable to open HKLM\\SYSTEM\\CCS\\ENUM (status %08lx)\n", 01937 status 01938 ); 01939 goto clean0; 01940 } 01941 01942 // 01943 // Open the instance key for this devnode 01944 // 01945 status = IopOpenRegistryKeyEx( &instanceKey, 01946 enumKey, 01947 &parentNode->InstancePath, 01948 KEY_READ | KEY_WRITE 01949 ); 01950 01951 if (!NT_SUCCESS(status)) { 01952 DbgPrint("IopQueryUniqueId:\tUnable to open registry key for %wZ (status %08lx)\n", 01953 &parentNode->InstancePath, 01954 status 01955 ); 01956 goto clean1; 01957 } 01958 01959 // 01960 // Attempt to retrieve the "UniqueParentID" value from the device 01961 // instance key. 01962 // 01963 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)keyBuffer; 01964 PiWstrToUnicodeString(&valueName, REGSTR_VALUE_UNIQUE_PARENT_ID); 01965 01966 status = ZwQueryValueKey(instanceKey, 01967 &valueName, 01968 KeyValuePartialInformation, 01969 keyValue, 01970 sizeof(keyBuffer), 01971 &length 01972 ); 01973 01974 if (NT_SUCCESS(status)) { 01975 ASSERT(keyValue->Type == REG_DWORD); 01976 ASSERT(keyValue->DataLength == sizeof(ULONG)); 01977 if ((keyValue->Type != REG_DWORD) || 01978 (keyValue->DataLength != sizeof(ULONG))) { 01979 status = STATUS_INVALID_PARAMETER; 01980 goto clean2; 01981 } 01982 01983 uniqueIdValue = *(PULONG)(keyValue->Data); 01984 01985 // 01986 // OK, we have a unique parent ID number to prefix to the 01987 // instance ID. 01988 Prefix = (PWSTR)ExAllocatePool(PagedPool, 9 * sizeof(WCHAR)); 01989 if (!Prefix) { 01990 status = STATUS_INSUFFICIENT_RESOURCES; 01991 goto clean2; 01992 } 01993 swprintf(Prefix, L"%x", uniqueIdValue); 01994 } else { 01995 01996 // 01997 // This is the current mechanism for finding existing 01998 // device instance prefixes and calculating new ones if 01999 // required. 02000 // 02001 02002 // 02003 // Attempt to retrieve the "ParentIdPrefix" value from the device 02004 // instance key. 02005 // 02006 02007 PiWstrToUnicodeString(&valueName, REGSTR_VALUE_PARENT_ID_PREFIX); 02008 length = (MAX_PARENT_PREFIX + 1) * sizeof(WCHAR) + 02009 FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); 02010 stringValueBuffer = ExAllocatePool(PagedPool, 02011 length); 02012 if (stringValueBuffer) { 02013 status = ZwQueryValueKey(instanceKey, 02014 &valueName, 02015 KeyValuePartialInformation, 02016 stringValueBuffer, 02017 length, 02018 &length); 02019 } 02020 else { 02021 status = STATUS_INSUFFICIENT_RESOURCES; 02022 goto clean2; 02023 } 02024 02025 if (NT_SUCCESS(status)) { 02026 02027 ASSERT(stringValueBuffer->Type == REG_SZ); 02028 if (stringValueBuffer->Type != REG_SZ) { 02029 status = STATUS_INVALID_PARAMETER; 02030 goto clean2; 02031 } 02032 02033 // 02034 // Parent has already been assigned a "ParentIdPrefix". 02035 // 02036 02037 Prefix = (PWSTR) ExAllocatePool(PagedPool, 02038 stringValueBuffer->DataLength); 02039 if (!Prefix) 02040 { 02041 status = STATUS_INSUFFICIENT_RESOURCES; 02042 goto clean2; 02043 } 02044 wcscpy(Prefix, (PWSTR) stringValueBuffer->Data); 02045 } 02046 else 02047 { 02048 // 02049 // Parent has not been assigned a "ParentIdPrefix". 02050 // Compute the prefix: 02051 // * Compute Hash 02052 // * Look for value of the form: 02053 // NextParentId.<level>.<hash>:REG_DWORD: <NextInstance> 02054 // under CCS\Enum. If not present, create it. 02055 // * Assign the new "ParentIdPrefix" which will be of 02056 // of the form: 02057 // <level>&<hash>&<instance> 02058 // 02059 02060 // Allocate a buffer once for the NextParentId... value 02061 // and for the prefix. 02062 length = max(wcslen(REGSTR_VALUE_NEXT_PARENT_ID) + 2 + 8 + 8, 02063 MAX_PARENT_PREFIX) + 1; 02064 02065 // Device instances are case in-sensitive. Upcase before 02066 // performing hash to ensure that the hash is case-insensitve. 02067 status = RtlUpcaseUnicodeString(&valueName, 02068 &parentNode->InstancePath, 02069 TRUE); 02070 if (!NT_SUCCESS(status)) 02071 { 02072 goto clean2; 02073 } 02074 HASH_UNICODE_STRING(&valueName, &Hash); 02075 RtlFreeUnicodeString(&valueName); 02076 02077 Prefix = (PWSTR) ExAllocatePool(PagedPool, 02078 length * sizeof(WCHAR)); 02079 if (!Prefix) { 02080 status = STATUS_INSUFFICIENT_RESOURCES; 02081 goto clean2; 02082 } 02083 02084 // Check for existence of "NextParentId...." value and update. 02085 swprintf(Prefix, L"%s.%x.%x", REGSTR_VALUE_NEXT_PARENT_ID, 02086 Hash, parentNode->Level); 02087 RtlInitUnicodeString(&valueName, Prefix); 02088 keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)keyBuffer; 02089 status = ZwQueryValueKey(enumKey, 02090 &valueName, 02091 KeyValuePartialInformation, 02092 keyValue, 02093 sizeof(keyBuffer), 02094 &length 02095 ); 02096 if (NT_SUCCESS(status) && (keyValue->Type == REG_DWORD) && 02097 (keyValue->DataLength == sizeof(ULONG))) { 02098 hashInstance = *(PULONG)(keyValue->Data); 02099 } 02100 else { 02101 hashInstance = 0; 02102 } 02103 02104 hashInstance++; 02105 02106 status = ZwSetValueKey(enumKey, 02107 &valueName, 02108 TITLE_INDEX_VALUE, 02109 REG_DWORD, 02110 &hashInstance, 02111 sizeof(hashInstance) 02112 ); 02113 02114 if (!NT_SUCCESS(status)) { 02115 goto clean2; 02116 } 02117 02118 hashInstance--; 02119 02120 // Create actual ParentIdPrefix string 02121 PiWstrToUnicodeString(&valueName, REGSTR_VALUE_PARENT_ID_PREFIX); 02122 length = swprintf(Prefix, L"%x&%x&%x", parentNode->Level, 02123 Hash, hashInstance) + 1; 02124 status = ZwSetValueKey(instanceKey, 02125 &valueName, 02126 TITLE_INDEX_VALUE, 02127 REG_SZ, 02128 Prefix, 02129 length * sizeof(WCHAR) 02130 ); 02131 if (!NT_SUCCESS(status)) 02132 { 02133 goto clean2; 02134 } 02135 } 02136 } 02137 02138 // Construct the instance id from the non-unique id (if any) 02139 // provided by the child and the prefix we've constructed. 02140 length = wcslen(Prefix) + (UniqueId ? wcslen(UniqueId) : 0) + 2; 02141 id = (PWSTR)ExAllocatePool(PagedPool, length * sizeof(WCHAR)); 02142 if (!id) { 02143 status = STATUS_INSUFFICIENT_RESOURCES; 02144 } else if (UniqueId) { 02145 swprintf(id, L"%s&%s", Prefix, UniqueId); 02146 } else { 02147 wcscpy(id, Prefix); 02148 } 02149 02150 clean2: 02151 ZwClose(instanceKey); 02152 02153 clean1: 02154 ZwClose(enumKey); 02155 02156 clean0: 02157 ExReleaseResource(&PpRegistryDeviceResource); 02158 KeLeaveCriticalRegion(); 02159 02160 if (stringValueBuffer) { 02161 ExFreePool(stringValueBuffer); 02162 } 02163 02164 if (Prefix) { 02165 ExFreePool(Prefix); 02166 } 02167 02168 *GloballyUniqueId = id; 02169 return status; 02170 }

NTSTATUS IopQueryCompatibleIds IN PDEVICE_OBJECT  DeviceObject,
IN BUS_QUERY_ID_TYPE  IdType,
OUT PWCHAR *  CompatibleIds,
OUT ULONG *  Length
 

Definition at line 2173 of file pnpirp.c.

References BusQueryCompatibleIDs, BusQueryHardwareIDs, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopProcessNewDeviceNode(), and IopStartAndEnumerateDevice().

02182 : 02183 02184 This routine sends irp to query HardwareIds or CompatibleIds. This rotine 02185 queries MULTISZ Ids. 02186 02187 Parameters: 02188 02189 DeviceObject - Supplies the device object of the device being queried/ 02190 02191 IdType - Specifies the Id type interested. Only HardwareIDs and CompatibleIDs 02192 are supported by this routine. 02193 02194 CompatibleId - Supplies a pointer to a variable to receive the returned Ids. 02195 This must be freed by the caller. 02196 02197 Length - Supplies a pointer to a variable to receive the length of the IDs. 02198 02199 Return Value: 02200 02201 NTSTATUS code. 02202 02203 --*/ 02204 { 02205 IO_STACK_LOCATION irpSp; 02206 NTSTATUS status; 02207 02208 PAGED_CODE(); 02209 02210 *Length = 0; 02211 if ((IdType != BusQueryHardwareIDs) && (IdType != BusQueryCompatibleIDs)) { 02212 return STATUS_INVALID_PARAMETER_2; 02213 } 02214 02215 // 02216 // Initialize the stack location to pass to IopSynchronousCall() 02217 // 02218 02219 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 02220 02221 // 02222 // Set the function codes. 02223 // 02224 02225 irpSp.MajorFunction = IRP_MJ_PNP; 02226 irpSp.MinorFunction = IRP_MN_QUERY_ID; 02227 02228 // 02229 // Set the pointer to the resource list 02230 // 02231 02232 irpSp.Parameters.QueryId.IdType = IdType; 02233 02234 // 02235 // Make the call and return. 02236 // 02237 02238 status = IopSynchronousCall(DeviceObject, &irpSp, CompatibleIds); 02239 02240 if (NT_SUCCESS(status) && *CompatibleIds) { 02241 02242 // 02243 // The Compatible IDs and Hardware IDs are multi_sz, 02244 // try to determine its size. 02245 // 02246 02247 PWCHAR wp; 02248 02249 for (wp = *CompatibleIds; 02250 (*wp != UNICODE_NULL) || (*(wp + 1) != UNICODE_NULL); 02251 wp++) { 02252 02253 *Length += 2; 02254 } 02255 *Length += 4; 02256 } 02257 02258 return status; 02259 }

NTSTATUS IopQueryDeviceId IN PDEVICE_OBJECT  DeviceObject,
OUT PWCHAR *  DeviceId
 

Definition at line 1762 of file pnpirp.c.

References BusQueryDeviceID, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopProcessNewDeviceNode().

01769 : 01770 01771 This routine sends a query device id irp to the specified device object. 01772 01773 Parameters: 01774 01775 DeviceObject - Supplies the device object of the device being queried/ 01776 01777 DeviceId - Supplies a pointer to a variable to receive the returned Id. 01778 This must be freed by the caller. 01779 01780 Return Value: 01781 01782 NTSTATUS code. 01783 01784 --*/ 01785 { 01786 IO_STACK_LOCATION irpSp; 01787 NTSTATUS status; 01788 01789 PAGED_CODE(); 01790 01791 // 01792 // Initialize the stack location to pass to IopSynchronousCall() 01793 // 01794 01795 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 01796 01797 // 01798 // Set the function codes. 01799 // 01800 01801 irpSp.MajorFunction = IRP_MJ_PNP; 01802 irpSp.MinorFunction = IRP_MN_QUERY_ID; 01803 01804 // 01805 // Set the pointer to the resource list 01806 // 01807 01808 irpSp.Parameters.QueryId.IdType = BusQueryDeviceID; 01809 01810 // 01811 // Make the call and return. 01812 // 01813 01814 status = IopSynchronousCall(DeviceObject, &irpSp, DeviceId); 01815 01816 return status; 01817 }

NTSTATUS IopQueryDeviceRelations IN DEVICE_RELATION_TYPE  Relations,
IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  AsyncOk,
OUT PDEVICE_RELATIONS DeviceRelations
 

Definition at line 1604 of file pnpirp.c.

References BusRelations, _DEVICE_COMPLETION_CONTEXT::DeviceNode, DNF_BEING_ENUMERATED, DNF_ENUMERATION_REQUEST_PENDING, DNF_ENUMERATION_REQUEST_QUEUED, DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING, ExAllocatePool, ExGetCurrentResourceThread, FALSE, _DEVICE_NODE::Flags, IopAcquireEnumerationLock, IopAsynchronousCall(), IopDeviceRelationsComplete(), IopPnPSpinLock, IopRequestDeviceAction(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_RELATIONS, _DEVICE_COMPLETION_CONTEXT::IrpMinorCode, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NonPagedPool, NTSTATUS(), NULL, _DEVICE_NODE::OverUsed1, _IO_STACK_LOCATION::Parameters, PDEVICE_COMPLETION_CONTEXT, ReenumerateDeviceTree, _DEVICE_COMPLETION_CONTEXT::Thread, and TRUE.

Referenced by IopEnumerateDevice(), and IopProcessRelation().

01613 : 01614 01615 This routine sends query device relation irp to the specified device object. 01616 01617 Parameters: 01618 01619 Relations - specifies the type of relation interested. 01620 01621 DeviceObjet - Supplies the device object of the device being queried. 01622 01623 AsyncOk - Specifies if we can perform Async QueryDeviceRelations 01624 01625 DeviceRelations - Supplies a pointer to a variable to receive the returned 01626 relation information. This must be freed by the caller. 01627 01628 Return Value: 01629 01630 NTSTATUS code. 01631 01632 --*/ 01633 01634 { 01635 IO_STACK_LOCATION irpSp; 01636 NTSTATUS status; 01637 PDEVICE_RELATIONS deviceRelations; 01638 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 01639 PDEVICE_COMPLETION_CONTEXT completionContext; 01640 BOOLEAN requestEnumeration = FALSE; 01641 KIRQL oldIrql; 01642 01643 // 01644 // Do not allow two bus relations at the same time 01645 // 01646 01647 if (Relations == BusRelations) { 01648 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 01649 if (deviceNode->Flags & DNF_BEING_ENUMERATED) { 01650 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01651 return STATUS_UNSUCCESSFUL; 01652 } 01653 deviceNode->Flags &= ~DNF_ENUMERATION_REQUEST_QUEUED; 01654 deviceNode->Flags |= DNF_BEING_ENUMERATED; 01655 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01656 } 01657 01658 // 01659 // Initialize the stack location to pass to IopSynchronousCall() 01660 // 01661 01662 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 01663 01664 // 01665 // Set the function codes. 01666 // 01667 01668 irpSp.MajorFunction = IRP_MJ_PNP; 01669 irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS; 01670 01671 // 01672 // Set the pointer to the resource list 01673 // 01674 01675 irpSp.Parameters.QueryDeviceRelations.Type = Relations; 01676 01677 // 01678 // Make the call and return. 01679 // 01680 01681 if (AsyncOk && Relations == BusRelations) { 01682 completionContext = (PDEVICE_COMPLETION_CONTEXT) ExAllocatePool( 01683 NonPagedPool, 01684 sizeof(DEVICE_COMPLETION_CONTEXT)); 01685 if (completionContext == NULL) { 01686 return STATUS_INSUFFICIENT_RESOURCES; // BUGBUG - Should try it again. 01687 } 01688 01689 completionContext->DeviceNode = deviceNode; 01690 completionContext->IrpMinorCode = IRP_MN_QUERY_DEVICE_RELATIONS; 01691 completionContext->Thread = ExGetCurrentResourceThread(); 01692 01693 // 01694 // Make the call and return. 01695 // 01696 01697 IopAcquireEnumerationLock(NULL); // To block IopAcquireTreeLock(); 01698 status = IopAsynchronousCall(DeviceObject, &irpSp, completionContext, IopDeviceRelationsComplete); 01699 if (status == STATUS_PENDING) { 01700 KIRQL oldIrql; 01701 01702 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 01703 01704 // 01705 // Check if the completion routine completes before we setting 01706 // the DNF_ENUMERATION_REQUEST_PENDING flags. 01707 // 01708 01709 if (deviceNode->Flags & DNF_ENUMERATION_REQUEST_PENDING) { 01710 deviceNode->Flags &= ~DNF_ENUMERATION_REQUEST_PENDING; 01711 *DeviceRelations = deviceNode->OverUsed1.PendingDeviceRelations; 01712 deviceNode->OverUsed1.PendingDeviceRelations = NULL; 01713 status = STATUS_SUCCESS; 01714 } else { 01715 01716 // 01717 // Set DNF_ENUMERATION_REQUEST_PENDING such that the completion routine knows it 01718 // needs to request enumeration when the Q_bus_relations completed successfully. 01719 // 01720 01721 deviceNode->Flags |= DNF_ENUMERATION_REQUEST_PENDING; 01722 } 01723 01724 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01725 } else { 01726 deviceNode->Flags &= ~DNF_ENUMERATION_REQUEST_PENDING; 01727 *DeviceRelations = deviceNode->OverUsed1.PendingDeviceRelations; 01728 deviceNode->OverUsed1.PendingDeviceRelations = NULL; 01729 } 01730 return status; 01731 } else { 01732 status = IopSynchronousCall(DeviceObject, &irpSp, DeviceRelations); 01733 01734 // 01735 // To prevent the scenario that a driver calls IoInvalidateDeviceRelations while servicing 01736 // an Async Q-D-R irp, and receives another q-d-r irp before first one completed, we will 01737 // set a flag when it calls IoInvalidateDeviceRelations and delay queuing the request till 01738 // the original one is completed. 01739 // 01740 01741 if (Relations == BusRelations) { 01742 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 01743 deviceNode->Flags &= ~DNF_BEING_ENUMERATED; 01744 if (deviceNode->Flags & DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING) { 01745 deviceNode->Flags &= ~DNF_IO_INVALIDATE_DEVICE_RELATIONS_PENDING; 01746 requestEnumeration = TRUE; 01747 } 01748 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 01749 if (requestEnumeration) { 01750 IopRequestDeviceAction( DeviceObject, 01751 ReenumerateDeviceTree, 01752 NULL, 01753 NULL ); 01754 } 01755 } 01756 } 01757 01758 return status; 01759 }

NTSTATUS IopQueryDeviceResources IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  ResourceType,
OUT PVOID *  Resource,
OUT ULONG *  Length
 

Definition at line 2262 of file pnpirp.c.

References ASSERT, DbgPrint, DNF_MADEUP, DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED, ExAllocatePool, ExFreePool(), FALSE, _DEVICE_NODE::Flags, IopCmResourcesToIoResources(), IopDetermineResourceListSize(), IopDeviceObjectToDeviceInstance(), IopFilterResourceRequirementsCall(), IopFilterResourceRequirementsList(), IopGetDeviceResourcesFromRegistry(), IopMergeFilteredResourceRequirementsList(), IopOpenRegistryKeyEx(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_RESOURCE_REQUIREMENTS, IRP_MN_QUERY_RESOURCES, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, QUERY_RESOURCE_LIST, QUERY_RESOURCE_REQUIREMENTS, REGISTRY_ALLOC_CONFIG, REGISTRY_BASIC_CONFIGVECTOR, REGISTRY_BOOT_CONFIG, REGISTRY_FORCED_CONFIG, REGISTRY_OVERRIDE_CONFIGVECTOR, Resource, _DEVICE_NODE::ResourceRequirements, and TITLE_INDEX_VALUE.

Referenced by IopGetResourceRequirementsForAssignTable(), IopProcessNewDeviceNode(), and IopReleaseDeviceResources().

02271 : 02272 02273 This routine sends irp to queries resources or resource requirements list 02274 of the specified device object. 02275 02276 If the device object is a detected device, its resources will be read from 02277 registry. Otherwise, an irp is sent to the bus driver to query its resources. 02278 02279 Parameters: 02280 02281 DeviceObject - Supplies the device object of the device being queries. 02282 02283 ResourceType - 0 for device resources and 1 for resource requirements list. 02284 02285 Resource - Supplies a pointer to a variable to receive the returned resources 02286 02287 Length - Supplies a pointer to a variable to receive the length of the returned 02288 resources or resource requirements list. 02289 02290 Return Value: 02291 02292 NTSTATUS code. 02293 02294 --*/ 02295 { 02296 IO_STACK_LOCATION irpSp; 02297 PDEVICE_NODE deviceNode; 02298 NTSTATUS status; 02299 PIO_RESOURCE_REQUIREMENTS_LIST resReqList, newResources; 02300 ULONG junk; 02301 PCM_RESOURCE_LIST cmList; 02302 PIO_RESOURCE_REQUIREMENTS_LIST filteredList, mergedList; 02303 BOOLEAN exactMatch; 02304 02305 PAGED_CODE(); 02306 02307 #if DBG 02308 02309 if ((ResourceType != QUERY_RESOURCE_LIST) && 02310 (ResourceType != QUERY_RESOURCE_REQUIREMENTS)) { 02311 return STATUS_INVALID_PARAMETER_2; 02312 } 02313 #endif 02314 02315 *Resource = NULL; 02316 *Length = 0; 02317 02318 // 02319 // Initialize the stack location to pass to IopSynchronousCall() 02320 // 02321 02322 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 02323 02324 deviceNode = (PDEVICE_NODE) DeviceObject->DeviceObjectExtension->DeviceNode; 02325 02326 if (ResourceType == QUERY_RESOURCE_LIST) { 02327 02328 // 02329 // caller is asked for RESOURCE_LIST. If this is a madeup device, we will 02330 // read it from registry. Otherwise, we ask drivers. 02331 // 02332 02333 if (deviceNode->Flags & DNF_MADEUP) { 02334 02335 status = IopGetDeviceResourcesFromRegistry( 02336 DeviceObject, 02337 ResourceType, 02338 REGISTRY_ALLOC_CONFIG + REGISTRY_FORCED_CONFIG + REGISTRY_BOOT_CONFIG, 02339 Resource, 02340 Length); 02341 if (status == STATUS_OBJECT_NAME_NOT_FOUND) { 02342 status = STATUS_SUCCESS; 02343 } 02344 return status; 02345 } else { 02346 irpSp.MinorFunction = IRP_MN_QUERY_RESOURCES; 02347 irpSp.MajorFunction = IRP_MJ_PNP; 02348 status = IopSynchronousCall(DeviceObject, &irpSp, Resource); 02349 if (status == STATUS_NOT_SUPPORTED) { 02350 02351 // 02352 // If driver doesn't implement this request, it 02353 // doesn't consume any resources. 02354 // 02355 02356 *Resource = NULL; 02357 status = STATUS_SUCCESS; 02358 } 02359 if (NT_SUCCESS(status)) { 02360 *Length = IopDetermineResourceListSize((PCM_RESOURCE_LIST)*Resource); 02361 } 02362 return status; 02363 } 02364 } else { 02365 02366 // 02367 // Caller is asked for resource requirements list. We will check: 02368 // if there is a ForcedConfig, it will be converted to resource requirements 02369 // list and return. Otherwise, 02370 // If there is an OVerrideConfigVector, we will use it as our 02371 // FilterConfigVector. Otherwise we ask driver for the config vector and 02372 // use it as our FilterConfigVector. 02373 // Finaly, we pass the FilterConfigVector to driver stack to let drivers 02374 // filter the requirements. 02375 // 02376 02377 status = IopGetDeviceResourcesFromRegistry( 02378 DeviceObject, 02379 QUERY_RESOURCE_LIST, 02380 REGISTRY_FORCED_CONFIG, 02381 Resource, 02382 &junk); 02383 if (status == STATUS_OBJECT_NAME_NOT_FOUND) { 02384 status = IopGetDeviceResourcesFromRegistry( 02385 DeviceObject, 02386 QUERY_RESOURCE_REQUIREMENTS, 02387 REGISTRY_OVERRIDE_CONFIGVECTOR, 02388 &resReqList, 02389 &junk); 02390 if (status == STATUS_OBJECT_NAME_NOT_FOUND) { 02391 if (deviceNode->Flags & DNF_MADEUP) { 02392 status = IopGetDeviceResourcesFromRegistry( 02393 DeviceObject, 02394 QUERY_RESOURCE_REQUIREMENTS, 02395 REGISTRY_BASIC_CONFIGVECTOR, 02396 &resReqList, 02397 &junk); 02398 if (status == STATUS_OBJECT_NAME_NOT_FOUND) { 02399 status = STATUS_SUCCESS; 02400 resReqList = NULL; 02401 } 02402 } else { 02403 02404 // 02405 // We are going to ask the bus driver ... 02406 // 02407 02408 if (deviceNode->ResourceRequirements) { 02409 ASSERT(deviceNode->Flags & DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED); 02410 resReqList = ExAllocatePool(PagedPool, deviceNode->ResourceRequirements->ListSize); 02411 if (resReqList) { 02412 RtlMoveMemory(resReqList, 02413 deviceNode->ResourceRequirements, 02414 deviceNode->ResourceRequirements->ListSize 02415 ); 02416 status = STATUS_SUCCESS; 02417 } else { 02418 return STATUS_NO_MEMORY; 02419 } 02420 } else { 02421 irpSp.MinorFunction = IRP_MN_QUERY_RESOURCE_REQUIREMENTS; 02422 irpSp.MajorFunction = IRP_MJ_PNP; 02423 status = IopSynchronousCall(DeviceObject, &irpSp, &resReqList); 02424 if (status == STATUS_NOT_SUPPORTED) { 02425 02426 // 02427 // If driver doesn't implement this request, it 02428 // doesn't require any resources. 02429 // 02430 02431 status = STATUS_SUCCESS; 02432 resReqList = NULL; 02433 02434 } 02435 } 02436 } 02437 if (!NT_SUCCESS(status)) { 02438 return status; 02439 } 02440 } 02441 02442 // 02443 // For devices with boot config, we need to filter the resource requirements 02444 // list against boot config. 02445 // 02446 02447 status = IopGetDeviceResourcesFromRegistry( 02448 DeviceObject, 02449 QUERY_RESOURCE_LIST, 02450 REGISTRY_BOOT_CONFIG, 02451 &cmList, 02452 &junk); 02453 if (NT_SUCCESS(status) && 02454 (!cmList || cmList->Count == 0 || cmList->List[0].InterfaceType != PCIBus)) { 02455 status = IopFilterResourceRequirementsList ( 02456 resReqList, 02457 cmList, 02458 &filteredList, 02459 &exactMatch); 02460 if (cmList) { 02461 ExFreePool(cmList); 02462 } 02463 if (!NT_SUCCESS(status)) { 02464 if (resReqList) { 02465 ExFreePool(resReqList); 02466 } 02467 return status; 02468 } else { 02469 02470 // 02471 // For non-root-enumerated devices, we merge filtered config with basic config 02472 // vectors to form a new res req list. For root-enumerated devices, we don't 02473 // consider Basic config vector. 02474 // 02475 02476 if (!(deviceNode->Flags & DNF_MADEUP) && 02477 (exactMatch == FALSE || resReqList->AlternativeLists > 1)) { 02478 status = IopMergeFilteredResourceRequirementsList ( 02479 filteredList, 02480 resReqList, 02481 &mergedList 02482 ); 02483 if (resReqList) { 02484 ExFreePool(resReqList); 02485 } 02486 if (filteredList) { 02487 ExFreePool(filteredList); 02488 } 02489 if (NT_SUCCESS(status)) { 02490 resReqList = mergedList; 02491 } else { 02492 return status; 02493 } 02494 } else { 02495 if (resReqList) { 02496 ExFreePool(resReqList); 02497 } 02498 resReqList = filteredList; 02499 } 02500 } 02501 } 02502 02503 } else { 02504 ASSERT(NT_SUCCESS(status)); 02505 02506 // 02507 // We have Forced Config. Convert it to resource requirements and return it. 02508 // 02509 02510 if (*Resource) { 02511 resReqList = IopCmResourcesToIoResources (0, (PCM_RESOURCE_LIST)*Resource, LCPRI_FORCECONFIG); 02512 ExFreePool(*Resource); 02513 if (resReqList) { 02514 *Resource = (PVOID)resReqList; 02515 *Length = resReqList->ListSize; 02516 } else { 02517 *Resource = NULL; 02518 *Length = 0; 02519 status = STATUS_INSUFFICIENT_RESOURCES; 02520 return status; 02521 } 02522 } else { 02523 resReqList = NULL; 02524 } 02525 } 02526 02527 // 02528 // If we are here, we have a resource requirements list for drivers to examine ... 02529 // NOTE: Per Lonny's request, we let drivers filter ForcedConfig 02530 // 02531 02532 status = IopFilterResourceRequirementsCall( 02533 DeviceObject, 02534 resReqList, 02535 &newResources 02536 ); 02537 02538 if (NT_SUCCESS(status)) { 02539 UNICODE_STRING unicodeName; 02540 HANDLE handle, handlex; 02541 02542 #if DBG 02543 if (newResources == NULL && resReqList) { 02544 DbgPrint("PnpMgr: Non-NULL resource requirements list filtered to NULL\n"); 02545 } 02546 #endif 02547 if (newResources) { 02548 02549 *Length = newResources->ListSize; 02550 ASSERT(*Length); 02551 02552 // 02553 // Make our own copy of the allocation. We do this so that the 02554 // verifier doesn't believe the driver has leaked memory if 02555 // unloaded. 02556 // 02557 02558 *Resource = (PVOID) ExAllocatePool(PagedPool, *Length); 02559 if (*Resource == NULL) { 02560 02561 ExFreePool(newResources); 02562 return STATUS_INSUFFICIENT_RESOURCES; 02563 } 02564 02565 RtlCopyMemory(*Resource, newResources, *Length); 02566 ExFreePool(newResources); 02567 02568 } else { 02569 *Length = 0; 02570 *Resource = NULL; 02571 } 02572 02573 // 02574 // Write filtered res req to registry 02575 // 02576 02577 status = IopDeviceObjectToDeviceInstance(DeviceObject, &handlex, KEY_ALL_ACCESS); 02578 if (NT_SUCCESS(status)) { 02579 PiWstrToUnicodeString(&unicodeName, REGSTR_KEY_CONTROL); 02580 status = IopOpenRegistryKeyEx( &handle, 02581 handlex, 02582 &unicodeName, 02583 KEY_READ 02584 ); 02585 if (NT_SUCCESS(status)) { 02586 PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_FILTERED_CONFIG_VECTOR); 02587 ZwSetValueKey(handle, 02588 &unicodeName, 02589 TITLE_INDEX_VALUE, 02590 REG_RESOURCE_REQUIREMENTS_LIST, 02591 *Resource, 02592 *Length 02593 ); 02594 ZwClose(handle); 02595 ZwClose(handlex); 02596 } 02597 } 02598 } else { 02599 02600 // 02601 // ADRIAO BUGBUG 05/26/1999 - 02602 // Why do we not bubble up non-STATUS_NOT_SUPPORTED failure 02603 // codes? 02604 // 02605 *Resource = resReqList; 02606 if (resReqList) { 02607 *Length = resReqList->ListSize; 02608 } else { 02609 *Length = 0; 02610 } 02611 } 02612 return STATUS_SUCCESS; 02613 } 02614 }

NTSTATUS IopQueryDeviceSerialNumber IN PDEVICE_OBJECT  DeviceObject,
OUT PWCHAR *  SerialNumber
 

Definition at line 3195 of file pnpirp.c.

References ASSERT, BusQueryDeviceSerialNumber, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopHardwareProfileCommitStartedDock(), and IopHardwareProfileMarkDock().

03202 : 03203 03204 This routine retrieves a hardware serial number for the specified device object. 03205 If the routine fails, SerialNumber is guarenteed to be to NULL. 03206 03207 Parameters: 03208 03209 DeviceObject - Supplies the device object of the device being queried 03210 03211 SerialNumber - Supplies a pointer to a variable to receive the returned Id. 03212 This must be freed by the caller. 03213 03214 Return Value: 03215 03216 NTSTATUS code. 03217 03218 --*/ 03219 { 03220 IO_STACK_LOCATION irpSp; 03221 NTSTATUS status; 03222 03223 PAGED_CODE(); 03224 03225 *SerialNumber = NULL; 03226 03227 // 03228 // Initialize the stack location to pass to IopSynchronousCall() 03229 // 03230 03231 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 03232 03233 // 03234 // Set the function codes. 03235 // 03236 03237 irpSp.MajorFunction = IRP_MJ_PNP; 03238 irpSp.MinorFunction = IRP_MN_QUERY_ID; 03239 irpSp.Parameters.QueryId.IdType = BusQueryDeviceSerialNumber; 03240 03241 // 03242 // Make the call and return. 03243 // 03244 03245 status = IopSynchronousCall(DeviceObject, &irpSp, SerialNumber); 03246 03247 ASSERT(NT_SUCCESS(status) || (*SerialNumber == NULL)); 03248 if (!NT_SUCCESS(status)) { 03249 *SerialNumber = NULL; 03250 } 03251 return status; 03252 }

NTSTATUS IopQueryDeviceState IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 2976 of file pnpirp.c.

References DNF_HAS_PRIVATE_PROBLEM, DNUF_DONT_SHOW_IN_UI, DNUF_NOT_DISABLEABLE, FALSE, _DEVICE_NODE::Flags, IopDecDisableableDepends(), IopIncDisableableDepends(), IopRequestDeviceRemoval(), IopResourceRequirementsChanged(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_PNP_DEVICE_STATE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), PAGED_CODE, PNP_DEVICE_DISABLED, PNP_DEVICE_DONT_DISPLAY_IN_UI, PNP_DEVICE_FAILED, PNP_DEVICE_NOT_DISABLEABLE, PNP_DEVICE_REMOVED, PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED, PNP_DEVICE_STATE, TRUE, and _DEVICE_NODE::UserFlags.

Referenced by IopInvalidateDeviceStateWorker(), and IopStartAndEnumerateDevice().

02982 : 02983 02984 This routine sends query device state irp to the specified device object. 02985 02986 Parameters: 02987 02988 DeviceObjet - Supplies the device object of the device being queried. 02989 02990 Return Value: 02991 02992 NTSTATUS code. 02993 02994 --*/ 02995 02996 { 02997 IO_STACK_LOCATION irpSp; 02998 PDEVICE_NODE deviceNode; 02999 PNP_DEVICE_STATE deviceState; 03000 PDEVICE_RELATIONS deviceRelations; 03001 KEVENT userEvent; 03002 ULONG eventResult; 03003 NTSTATUS status; 03004 03005 PAGED_CODE(); 03006 03007 // 03008 // Initialize the stack location to pass to IopSynchronousCall() 03009 // 03010 03011 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 03012 03013 // 03014 // Set the function codes. 03015 // 03016 03017 irpSp.MajorFunction = IRP_MJ_PNP; 03018 irpSp.MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE; 03019 03020 // 03021 // Make the call. 03022 // 03023 03024 status = IopSynchronousCall(DeviceObject, &irpSp, (PVOID *)&deviceState); 03025 03026 // 03027 // Now perform the appropriate action based on the returned state 03028 // 03029 03030 if (NT_SUCCESS(status)) { 03031 03032 deviceNode = DeviceObject->DeviceObjectExtension->DeviceNode; 03033 03034 if (deviceState != 0) { 03035 03036 // 03037 // everything here can only be turned on (state set) 03038 // 03039 03040 if (deviceState & PNP_DEVICE_DONT_DISPLAY_IN_UI) { 03041 03042 deviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI; 03043 } 03044 03045 if (deviceState & PNP_DEVICE_NOT_DISABLEABLE) { 03046 03047 if ((deviceNode->UserFlags & DNUF_NOT_DISABLEABLE)==0) { 03048 // 03049 // this node itself is not disableable 03050 // 03051 deviceNode->UserFlags |= DNUF_NOT_DISABLEABLE; 03052 // 03053 // propagate up tree 03054 // 03055 IopIncDisableableDepends(deviceNode); 03056 03057 } 03058 } 03059 03060 if (deviceState & (PNP_DEVICE_DISABLED | PNP_DEVICE_REMOVED)) { 03061 03062 IopRequestDeviceRemoval( DeviceObject, 03063 (deviceState & PNP_DEVICE_DISABLED) ? 03064 CM_PROB_HARDWARE_DISABLED : CM_PROB_DEVICE_NOT_THERE 03065 ); 03066 03067 } else if (deviceState & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED) { 03068 03069 if (deviceState & PNP_DEVICE_FAILED) { 03070 03071 IopResourceRequirementsChanged(DeviceObject, TRUE); 03072 03073 } else { 03074 03075 IopResourceRequirementsChanged(DeviceObject, FALSE); 03076 03077 } 03078 } else if (deviceState & PNP_DEVICE_FAILED) { 03079 03080 deviceNode->Flags |= DNF_HAS_PRIVATE_PROBLEM; 03081 03082 IopRequestDeviceRemoval(DeviceObject, 0); 03083 } 03084 } else { 03085 03086 // 03087 // handle things that can be turned off (state cleared) 03088 // 03089 03090 if (deviceNode->UserFlags & DNUF_NOT_DISABLEABLE) { 03091 // 03092 // this node itself is now disableable 03093 // 03094 // 03095 // check tree 03096 // 03097 IopDecDisableableDepends(deviceNode); 03098 } 03099 03100 deviceNode->UserFlags &= ~(DNUF_DONT_SHOW_IN_UI | DNUF_NOT_DISABLEABLE); 03101 } 03102 } 03103 03104 return status; 03105 }

NTSTATUS IopQueryDockRemovalInterface IN PDEVICE_OBJECT  DeviceObject,
IN OUT PDOCK_INTERFACE *  DockInterface
 

Definition at line 3395 of file pnpirp.c.

References dummy(), ExAllocatePool, ExFreePool(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_INTERFACE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, _INTERFACE::Size, USHORT, and _INTERFACE::Version.

03402 : 03403 03404 This routine queries the specified DeviceObject for the dock removal 03405 interface. We use this interface to send pseudo-remove's. We use this 03406 to solve the removal orderings problem. 03407 03408 Parameters: 03409 03410 DeviceObject - Supplies a pointer to the Device object to be queried. 03411 03412 Interface - supplies a variable to receive the desired interface. 03413 03414 Return Value: 03415 03416 Status code that indicates whether or not the function was successful. 03417 03418 --*/ 03419 { 03420 IO_STACK_LOCATION irpSp; 03421 NTSTATUS status; 03422 PVOID dummy; 03423 PINTERFACE interface; 03424 USHORT size; 03425 GUID interfaceType; 03426 03427 PAGED_CODE(); 03428 03429 size = sizeof(DOCK_INTERFACE); 03430 interfaceType = GUID_DOCK_INTERFACE; 03431 interface = (PINTERFACE) ExAllocatePool(PagedPool, size); 03432 if (interface == NULL) { 03433 return STATUS_INSUFFICIENT_RESOURCES; 03434 } 03435 03436 RtlZeroMemory(interface, size); 03437 interface->Size = size; 03438 03439 // 03440 // Initialize the stack location to pass to IopSynchronousCall() 03441 // 03442 03443 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 03444 03445 // 03446 // Set the function codes. 03447 // 03448 03449 irpSp.MajorFunction = IRP_MJ_PNP; 03450 irpSp.MinorFunction = IRP_MN_QUERY_INTERFACE; 03451 03452 // 03453 // Set the pointer to the resource list 03454 // 03455 03456 irpSp.Parameters.QueryInterface.InterfaceType = &interfaceType; 03457 irpSp.Parameters.QueryInterface.Size = interface->Size; 03458 irpSp.Parameters.QueryInterface.Version = interface->Version = 0; 03459 irpSp.Parameters.QueryInterface.Interface = interface; 03460 irpSp.Parameters.QueryInterface.InterfaceSpecificData = NULL; 03461 03462 // 03463 // Make the call and return. 03464 // 03465 03466 status = IopSynchronousCall(DeviceObject, &irpSp, &dummy); 03467 if (NT_SUCCESS(status)) { 03468 *DockInterface = (PDOCK_INTERFACE) interface; 03469 } else { 03470 ExFreePool(interface); 03471 } 03472 return status; 03473 }

NTSTATUS IopQueryLegacyBusInformation IN PDEVICE_OBJECT  DeviceObject,
OUT LPGUID  InterfaceGuid,
OPTIONAL OUT INTERFACE_TYPE *  InterfaceType,
OPTIONAL OUT ULONG *BusNumber  OPTIONAL
 

Definition at line 2793 of file pnpirp.c.

References ASSERT, _LEGACY_BUS_INFORMATION::BusNumber, BusNumber, _LEGACY_BUS_INFORMATION::BusTypeGuid, DbgPrint, ExFreePool(), InterfaceType, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_LEGACY_BUS_INFORMATION, _LEGACY_BUS_INFORMATION::LegacyBusType, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and _DEVICE_NODE::ServiceName.

Referenced by IopCallDriverAddDevice().

02802 : 02803 02804 This routine queries the specified DeviceObject for its legacy bus 02805 information. 02806 02807 Parameters: 02808 02809 DeviceObject - The device object to be queried. 02810 02811 InterfaceGuid = Supplies a pointer to receive the device's interface type 02812 GUID. 02813 02814 Interface = Supplies a pointer to receive the device's interface type. 02815 02816 BusNumber = Supplies a pointer to receive the device's bus number. 02817 02818 Return Value: 02819 02820 Returns NTSTATUS. 02821 02822 --*/ 02823 { 02824 IO_STACK_LOCATION irpSp; 02825 NTSTATUS status; 02826 PLEGACY_BUS_INFORMATION busInfo; 02827 02828 PAGED_CODE(); 02829 02830 // 02831 // Initialize the stack location to pass to IopSynchronousCall() 02832 // 02833 02834 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 02835 02836 // 02837 // Set the function codes. 02838 // 02839 02840 irpSp.MajorFunction = IRP_MJ_PNP; 02841 irpSp.MinorFunction = IRP_MN_QUERY_LEGACY_BUS_INFORMATION; 02842 02843 // 02844 // Make the call and return. 02845 // 02846 02847 status = IopSynchronousCall(DeviceObject, &irpSp, &busInfo); 02848 if (NT_SUCCESS(status)) { 02849 02850 if (busInfo == NULL) { 02851 02852 // 02853 // The device driver LIED to us. Bad, bad, bad device driver. 02854 // 02855 02856 PDEVICE_NODE deviceNode; 02857 02858 deviceNode = DeviceObject->DeviceObjectExtension->DeviceNode; 02859 02860 if (deviceNode && deviceNode->ServiceName.Buffer) { 02861 02862 DbgPrint("*** IopQueryLegacyBusInformation - Driver %wZ returned STATUS_SUCCESS\n", &deviceNode->ServiceName); 02863 DbgPrint(" for IRP_MN_QUERY_LEGACY_BUS_INFORMATION, and a NULL POINTER.\n"); 02864 } 02865 02866 ASSERT(busInfo != NULL); 02867 02868 } else { 02869 if (ARGUMENT_PRESENT(InterfaceGuid)) { 02870 *InterfaceGuid = busInfo->BusTypeGuid; 02871 } 02872 if (ARGUMENT_PRESENT(InterfaceType)) { 02873 *InterfaceType = busInfo->LegacyBusType; 02874 } 02875 if (ARGUMENT_PRESENT(BusNumber)) { 02876 *BusNumber = busInfo->BusNumber; 02877 } 02878 ExFreePool(busInfo); 02879 } 02880 } 02881 return status; 02882 }

NTSTATUS IopQueryPnpBusInformation IN PDEVICE_OBJECT  DeviceObject,
OUT LPGUID  InterfaceGuid,
OPTIONAL OUT INTERFACE_TYPE *  InterfaceType,
OPTIONAL OUT ULONG *BusNumber  OPTIONAL
 

Definition at line 2885 of file pnpirp.c.

References ASSERT, _PNP_BUS_INFORMATION::BusNumber, BusNumber, _PNP_BUS_INFORMATION::BusTypeGuid, DbgPrint, ExFreePool(), InterfaceType, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_BUS_INFORMATION, _PNP_BUS_INFORMATION::LegacyBusType, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and _DEVICE_NODE::ServiceName.

Referenced by IopProcessNewDeviceNode().

02894 : 02895 02896 This routine queries the specified DeviceObject for the specified ResourceType 02897 resource translator. 02898 02899 Parameters: 02900 02901 HandlerType - specifies Arbiter or Translator 02902 02903 DeviceObject - Supplies a pointer to the Device object to be queried. 02904 02905 ResourceType - Specifies the desired type of translator. 02906 02907 Interface - supplies a variable to receive the desired interface. 02908 02909 Return Value: 02910 02911 Status code that indicates whether or not the function was successful. 02912 02913 --*/ 02914 { 02915 IO_STACK_LOCATION irpSp; 02916 NTSTATUS status; 02917 PPNP_BUS_INFORMATION busInfo; 02918 02919 PAGED_CODE(); 02920 02921 // 02922 // Initialize the stack location to pass to IopSynchronousCall() 02923 // 02924 02925 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 02926 02927 // 02928 // Set the function codes. 02929 // 02930 02931 irpSp.MajorFunction = IRP_MJ_PNP; 02932 irpSp.MinorFunction = IRP_MN_QUERY_BUS_INFORMATION; 02933 02934 // 02935 // Make the call and return. 02936 // 02937 02938 status = IopSynchronousCall(DeviceObject, &irpSp, &busInfo); 02939 if (NT_SUCCESS(status)) { 02940 02941 if (busInfo == NULL) { 02942 02943 // 02944 // The device driver LIED to us. Bad, bad, bad device driver. 02945 // 02946 02947 PDEVICE_NODE deviceNode; 02948 02949 deviceNode = DeviceObject->DeviceObjectExtension->DeviceNode; 02950 02951 if (deviceNode && deviceNode->ServiceName.Buffer) { 02952 02953 DbgPrint("*** IopQueryPnpBusInformation - Driver %wZ returned STATUS_SUCCESS\n", &deviceNode->ServiceName); 02954 DbgPrint(" for IRP_MN_QUERY_BUS_INFORMATION, and a NULL POINTER.\n"); 02955 } 02956 02957 ASSERT(busInfo != NULL); 02958 02959 } else { 02960 if (ARGUMENT_PRESENT(InterfaceGuid)) { 02961 *InterfaceGuid = busInfo->BusTypeGuid; 02962 } 02963 if (ARGUMENT_PRESENT(InterfaceType)) { 02964 *InterfaceType = busInfo->LegacyBusType; 02965 } 02966 if (ARGUMENT_PRESENT(BusNumber)) { 02967 *BusNumber = busInfo->BusNumber; 02968 } 02969 ExFreePool(busInfo); 02970 } 02971 } 02972 return status; 02973 }

NTSTATUS IopQueryReconfiguration IN UCHAR  Request,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 2733 of file pnpirp.c.

References ASSERT, dummy(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_QUERY_STOP_DEVICE, IRP_MN_STOP_DEVICE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), PAGED_CODE, and Request().

Referenced by IopRebalance(), and IopTestForReconfiguration().

02740 : 02741 02742 This routine queries the specified DeviceObject for the specified ResourceType 02743 resource translator. 02744 02745 Parameters: 02746 02747 HandlerType - specifies Arbiter or Translator 02748 02749 DeviceObject - Supplies a pointer to the Device object to be queried. 02750 02751 ResourceType - Specifies the desired type of translator. 02752 02753 Interface - supplies a variable to receive the desired interface. 02754 02755 Return Value: 02756 02757 Status code that indicates whether or not the function was successful. 02758 02759 --*/ 02760 { 02761 IO_STACK_LOCATION irpSp; 02762 NTSTATUS status; 02763 PVOID dummy; 02764 02765 PAGED_CODE(); 02766 02767 ASSERT (Request == IRP_MN_QUERY_STOP_DEVICE || 02768 Request == IRP_MN_STOP_DEVICE || 02769 Request == IRP_MN_CANCEL_STOP_DEVICE); 02770 02771 // 02772 // Initialize the stack location to pass to IopSynchronousCall() 02773 // 02774 02775 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 02776 02777 // 02778 // Set the function codes. 02779 // 02780 02781 irpSp.MajorFunction = IRP_MJ_PNP; 02782 irpSp.MinorFunction = Request; 02783 02784 // 02785 // Make the call and return. 02786 // 02787 02788 status = IopSynchronousCall(DeviceObject, &irpSp, &dummy); 02789 return status; 02790 }

NTSTATUS IopQueryResourceHandlerInterface IN RESOURCE_HANDLER_TYPE  HandlerType,
IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  ResourceType,
IN OUT PVOID *  Interface
 

Definition at line 2617 of file pnpirp.c.

References DO_BUS_ENUMERATED_DEVICE, _DEVICE_OBJECT::DriverObject, dummy(), _DEVICE_NODE::DuplicatePDO, ExAllocatePool, ExFreePool(), IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_INTERFACE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, ResourceArbiter, ResourceLegacyDeviceDetection, ResourceTranslator, _INTERFACE::Size, USHORT, and _INTERFACE::Version.

Referenced by IopDuplicateDetection(), and IopSetupArbiterAndTranslators().

02626 : 02627 02628 This routine queries the specified DeviceObject for the specified ResourceType 02629 resource translator. 02630 02631 Parameters: 02632 02633 HandlerType - specifies Arbiter or Translator 02634 02635 DeviceObject - Supplies a pointer to the Device object to be queried. 02636 02637 ResourceType - Specifies the desired type of translator. 02638 02639 Interface - supplies a variable to receive the desired interface. 02640 02641 Return Value: 02642 02643 Status code that indicates whether or not the function was successful. 02644 02645 --*/ 02646 { 02647 IO_STACK_LOCATION irpSp; 02648 NTSTATUS status; 02649 PVOID dummy; 02650 PINTERFACE interface; 02651 USHORT size; 02652 GUID interfaceType; 02653 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 02654 02655 PAGED_CODE(); 02656 02657 // 02658 // If this device object is created by pnp mgr for legacy resource allocation, 02659 // skip it. 02660 // 02661 02662 if ((deviceNode->DuplicatePDO == (PDEVICE_OBJECT) DeviceObject->DriverObject) || 02663 !(DeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE)) { 02664 return STATUS_NOT_SUPPORTED; 02665 } 02666 02667 switch (HandlerType) { 02668 case ResourceTranslator: 02669 size = sizeof(TRANSLATOR_INTERFACE) + 4; // Pnptest 02670 //size = sizeof(TRANSLATOR_INTERFACE); 02671 interfaceType = GUID_TRANSLATOR_INTERFACE_STANDARD; 02672 break; 02673 02674 case ResourceArbiter: 02675 size = sizeof(ARBITER_INTERFACE); 02676 interfaceType = GUID_ARBITER_INTERFACE_STANDARD; 02677 break; 02678 02679 case ResourceLegacyDeviceDetection: 02680 size = sizeof(LEGACY_DEVICE_DETECTION_INTERFACE); 02681 interfaceType = GUID_LEGACY_DEVICE_DETECTION_STANDARD; 02682 break; 02683 02684 default: 02685 return STATUS_INVALID_PARAMETER; 02686 } 02687 02688 interface = (PINTERFACE) ExAllocatePool(PagedPool, size); 02689 if (interface == NULL) { 02690 return STATUS_INSUFFICIENT_RESOURCES; 02691 } 02692 02693 RtlZeroMemory(interface, size); 02694 interface->Size = size; 02695 02696 // 02697 // Initialize the stack location to pass to IopSynchronousCall() 02698 // 02699 02700 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 02701 02702 // 02703 // Set the function codes. 02704 // 02705 02706 irpSp.MajorFunction = IRP_MJ_PNP; 02707 irpSp.MinorFunction = IRP_MN_QUERY_INTERFACE; 02708 02709 // 02710 // Set the pointer to the resource list 02711 // 02712 02713 irpSp.Parameters.QueryInterface.InterfaceType = &interfaceType; 02714 irpSp.Parameters.QueryInterface.Size = interface->Size; 02715 irpSp.Parameters.QueryInterface.Version = interface->Version = 0; 02716 irpSp.Parameters.QueryInterface.Interface = interface; 02717 irpSp.Parameters.QueryInterface.InterfaceSpecificData = (PVOID) ResourceType; 02718 02719 // 02720 // Make the call and return. 02721 // 02722 02723 status = IopSynchronousCall(DeviceObject, &irpSp, &dummy); 02724 if (NT_SUCCESS(status)) { 02725 *Interface = interface; 02726 } else { 02727 ExFreePool(interface); 02728 } 02729 return status; 02730 }

NTSTATUS IopQueryUniqueId IN PDEVICE_OBJECT  DeviceObject,
OUT PWCHAR *  UniqueId
 

Definition at line 1820 of file pnpirp.c.

References BusQueryInstanceID, IopSynchronousCall(), IRP_MJ_PNP, IRP_MN_QUERY_ID, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by IopProcessNewDeviceNode().

01827 : 01828 01829 01830 This routine generates a unique id for the specified device object. 01831 01832 Parameters: 01833 01834 DeviceObject - Supplies the device object of the device being queried 01835 01836 UniqueId - Supplies a pointer to a variable to receive the returned Id. 01837 This must be freed by the caller. 01838 01839 GloballyUnique - Indicates (from a previous call to query capabilities 01840 whether the id is globally unique. 01841 Return Value: 01842 01843 NTSTATUS code. 01844 01845 --*/ 01846 { 01847 IO_STACK_LOCATION irpSp; 01848 NTSTATUS status; 01849 01850 PAGED_CODE(); 01851 01852 *UniqueId = NULL; 01853 01854 // 01855 // First ask for for InstanceId. 01856 // 01857 01858 // Initialize the stack location to pass to IopSynchronousCall() 01859 // 01860 01861 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 01862 01863 // 01864 // Set the function codes. 01865 // 01866 01867 irpSp.MajorFunction = IRP_MJ_PNP; 01868 irpSp.MinorFunction = IRP_MN_QUERY_ID; 01869 01870 // 01871 // Set the pointer to the resource list 01872 // 01873 01874 irpSp.Parameters.QueryId.IdType = BusQueryInstanceID; 01875 01876 // 01877 // Make the call and return. 01878 // 01879 01880 status = IopSynchronousCall(DeviceObject, &irpSp, UniqueId); 01881 01882 if (!NT_SUCCESS(status)) { 01883 *UniqueId = NULL; 01884 } 01885 01886 return status; 01887 01888 }

NTSTATUS IopRemoveDevice IN PDEVICE_OBJECT  TargetDevice,
IN ULONG  IrpMinorCode
 

Definition at line 927 of file pnpirp.c.

References ASSERT, ASSERTMSG, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DNF_ADDED, DNF_LEGACY_DRIVER, DNF_NEED_ENUMERATION_ONLY, DNF_NEED_QUERY_IDS, DNF_STARTED, DNUF_NOT_DISABLEABLE, dummy(), FALSE, IopDecDisableableDepends(), IopFindMountableDevice(), IopInvalidateVolumesForDevice(), IopLockMountedDeviceForRemove(), IopSynchronousCall(), IopUncacheInterfaceInformation(), IopUnlockMountedDeviceForRemove(), IRP_MJ_PNP, IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_EJECT, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE, IRP_MN_SURPRISE_REMOVAL, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, TRUE, and _DEVICE_NODE::UserFlags.

Referenced by IopDeleteLockedDeviceNode(), IopDisableDevice(), and IopProcessNewDeviceNode().

00934 : 00935 00936 This function sends a requested DeviceRemoval related irp to the top level device 00937 object which roots on TargetDevice. If there is a VPB associated with the 00938 TargetDevice, the corresponding filesystem's VDO will be used. Otherwise 00939 the irp will be sent directly to the target device/ or its assocated device 00940 object. 00941 00942 Parameters: 00943 00944 TargetDevice - Supplies the device object of the device being removed. 00945 00946 Operation - Specifies the operation requested. 00947 The following IRP codes are used with IRP_MJ_DEVICE_CHANGE for removing 00948 devices: 00949 IRP_MN_QUERY_REMOVE_DEVICE 00950 IRP_MN_CANCEL_REMOVE_DEVICE 00951 IRP_MN_REMOVE_DEVICE 00952 IRP_MN_EJECT 00953 Return Value: 00954 00955 NTSTATUS code. 00956 00957 --*/ 00958 { 00959 PDEVICE_OBJECT deviceObject; 00960 PIRP irp; 00961 IO_STACK_LOCATION irpSp; 00962 NTSTATUS status; 00963 00964 BOOLEAN isMountable = FALSE; 00965 PDEVICE_OBJECT mountedDevice; 00966 00967 PVOID dummy; 00968 LOCK_MOUNTABLE_DEVICE_CONTEXT lockContext; 00969 00970 PAGED_CODE(); 00971 00972 ASSERT(IrpMinorCode == IRP_MN_QUERY_REMOVE_DEVICE || 00973 IrpMinorCode == IRP_MN_CANCEL_REMOVE_DEVICE || 00974 IrpMinorCode == IRP_MN_REMOVE_DEVICE || 00975 IrpMinorCode == IRP_MN_SURPRISE_REMOVAL || 00976 IrpMinorCode == IRP_MN_EJECT); 00977 00978 if (IrpMinorCode == IRP_MN_REMOVE_DEVICE || 00979 IrpMinorCode == IRP_MN_QUERY_REMOVE_DEVICE) { 00980 IopUncacheInterfaceInformation(TargetDevice); 00981 } 00982 00983 // 00984 // Initialize the stack location to pass to IopSynchronousCall() 00985 // 00986 00987 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 00988 00989 irpSp.MajorFunction = IRP_MJ_PNP; 00990 irpSp.MinorFunction = (UCHAR)IrpMinorCode; 00991 00992 // 00993 // BUGBUG - this should probably go at a higher level but then it goes 00994 // in way too many places. The only thing we do to the VPB is make sure 00995 // that it won't go away while the operation is in the file system and 00996 // that no one new can mount on the device if the FS decides to bail out. 00997 // 00998 00999 // 01000 // Check to see if there's a VPB anywhere in the device stack. If there 01001 // is then we'll have to lock the stack. 01002 // 01003 01004 mountedDevice = IopFindMountableDevice(TargetDevice); 01005 01006 if (mountedDevice != NULL) { 01007 01008 // 01009 // This routine will cause any mount operations on the VPB to fail. 01010 // It will also release the VPB spinlock. 01011 // 01012 01013 mountedDevice = IopLockMountedDeviceForRemove(TargetDevice, 01014 IrpMinorCode, 01015 &lockContext); 01016 01017 isMountable = TRUE; 01018 01019 } else { 01020 ASSERTMSG("Mass storage device does not have VPB - this is odd", 01021 !((TargetDevice->Type == FILE_DEVICE_DISK) || 01022 (TargetDevice->Type == FILE_DEVICE_CD_ROM) || 01023 (TargetDevice->Type == FILE_DEVICE_TAPE) || 01024 (TargetDevice->Type == FILE_DEVICE_VIRTUAL_DISK))); 01025 01026 mountedDevice = TargetDevice; 01027 } 01028 01029 // 01030 // Make the call and return. 01031 // 01032 01033 if (IrpMinorCode == IRP_MN_SURPRISE_REMOVAL || IrpMinorCode == IRP_MN_REMOVE_DEVICE) { 01034 // 01035 // if device was not disableable, we cleanup the tree 01036 // and debug-trace that we surprise-removed a non-disableable device 01037 // 01038 PDEVICE_NODE deviceNode = TargetDevice->DeviceObjectExtension->DeviceNode; 01039 01040 if (deviceNode->UserFlags & DNUF_NOT_DISABLEABLE) { 01041 // 01042 // this device was marked as disableable, update the depends 01043 // before this device disappears 01044 // (by momentarily marking this node as disableable) 01045 // 01046 deviceNode->UserFlags &= ~DNUF_NOT_DISABLEABLE; 01047 IopDecDisableableDepends(deviceNode); 01048 } 01049 } 01050 01051 status = IopSynchronousCall(mountedDevice, &irpSp, &dummy); 01052 01053 if (isMountable) { 01054 01055 IopUnlockMountedDeviceForRemove(TargetDevice, 01056 IrpMinorCode, 01057 &lockContext); 01058 01059 // 01060 // Succesful query should follow up with invalidation of all volumes 01061 // which have been on this device but which are not currently mounted. 01062 // 01063 01064 if (IrpMinorCode == IRP_MN_QUERY_REMOVE_DEVICE && NT_SUCCESS( status )) { 01065 01066 status = IopInvalidateVolumesForDevice( TargetDevice ); 01067 } 01068 } 01069 01070 if (IrpMinorCode == IRP_MN_REMOVE_DEVICE) { 01071 ((PDEVICE_NODE)TargetDevice->DeviceObjectExtension->DeviceNode)->Flags &= 01072 ~(DNF_ADDED | DNF_STARTED | DNF_LEGACY_DRIVER | DNF_NEED_QUERY_IDS | DNF_NEED_ENUMERATION_ONLY); 01073 } 01074 01075 return status; 01076 }

VOID IopStartDevice IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 510 of file pnpirp.c.

References ASSERT, _DEVICE_COMPLETION_CONTEXT::DeviceNode, DNF_NEED_ENUMERATION_ONLY, DNF_RESOURCE_REPORTED, DNF_START_REQUEST_PENDING, DNF_STARTED, DNF_STOPPED, DOCK_ARRIVING, DOCK_NOTDOCKDEVICE, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, dummy(), ExAllocatePool, ExGetCurrentResourceThread, FALSE, _DEVICE_NODE::Flags, IopAcquireEnumerationLock, IopAsynchronousCall(), IopDeviceStartComplete(), IopDoDeferredSetInterfaceState(), IopDoesDevNodeHaveProblem, IopHardwareProfileBeginTransition(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopPnPSpinLock, IopRequestDeviceRemoval(), IopSetDevNodeProblem, IopSynchronousCall(), IopUncacheInterfaceInformation(), IRP_MJ_PNP, IRP_MN_START_DEVICE, _DEVICE_COMPLETION_CONTEXT::IrpMinorCode, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, _IO_STACK_LOCATION::Parameters, PDEVICE_COMPLETION_CONTEXT, _DEVICE_NODE::PhysicalDeviceObject, PnpAsyncOk, PpSetTargetDeviceRemove(), PROFILE_PERHAPS_IN_PNPEVENT, _DEVICE_NODE::ResourceList, _DEVICE_NODE::ResourceListTranslated, SAVE_FAILURE_INFO, _DEVICE_COMPLETION_CONTEXT::Thread, and TRUE.

Referenced by IopReallocateResources(), IopRebalance(), and IopStartAndEnumerateDevice().

00516 : 00517 00518 This function sends a start device irp to the top level device 00519 object which roots on DeviceObject. 00520 00521 Parameters: 00522 00523 DeviceObject - Supplies the pointer to the device object of the device 00524 being removed. 00525 00526 Return Value: 00527 00528 NTSTATUS code. 00529 00530 --*/ 00531 00532 { 00533 IO_STACK_LOCATION irpSp; 00534 PVOID dummy; 00535 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00536 PDEVICE_COMPLETION_CONTEXT completionContext; 00537 NTSTATUS status; 00538 PNP_VETO_TYPE vetoType; 00539 00540 // PAGED_CODE(); 00541 00542 // 00543 // Initialize the stack location to pass to IopSynchronousCall() 00544 // 00545 00546 RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); 00547 00548 // 00549 // Set the function codes. 00550 // 00551 00552 irpSp.MajorFunction = IRP_MJ_PNP; 00553 irpSp.MinorFunction = IRP_MN_START_DEVICE; 00554 00555 // 00556 // Set the pointers for the raw and translated resource lists 00557 // 00558 00559 if (!(deviceNode->Flags & DNF_RESOURCE_REPORTED)) { 00560 irpSp.Parameters.StartDevice.AllocatedResources = deviceNode->ResourceList; 00561 irpSp.Parameters.StartDevice.AllocatedResourcesTranslated = deviceNode->ResourceListTranslated; 00562 } 00563 00564 if (!(deviceNode->Flags & DNF_STOPPED)) { 00565 IopUncacheInterfaceInformation(DeviceObject); 00566 } 00567 00568 if (PnpAsyncOk) { 00569 00570 // 00571 // ADRIAO BUGBUG 11/18/98 - 00572 // The dock code has not been duplicated in the async case, but as 00573 // PnpAsync support is totally broken and disabled anyway, this should 00574 // not matter right now. 00575 // 00576 ASSERT(0); 00577 completionContext = (PDEVICE_COMPLETION_CONTEXT) ExAllocatePool( 00578 NonPagedPool, 00579 sizeof(DEVICE_COMPLETION_CONTEXT)); 00580 if (completionContext == NULL) { 00581 return; // BUGBUG - Should try it again *explicitly* 00582 } 00583 00584 completionContext->DeviceNode = deviceNode; 00585 completionContext->IrpMinorCode = IRP_MN_START_DEVICE; 00586 completionContext->Thread = ExGetCurrentResourceThread(); 00587 00588 // 00589 // Make the call and return. 00590 // 00591 00592 IopAcquireEnumerationLock(NULL); // To block IopAcquireTreeLock(); 00593 status = IopAsynchronousCall(DeviceObject, &irpSp, completionContext, IopDeviceStartComplete); 00594 if (status == STATUS_PENDING) { 00595 00596 KIRQL oldIrql; 00597 00598 // 00599 // Set DNF_START_REQUEST_PENDING flag such that the completion routine knows it 00600 // needs to request enumeration when the start completed successfully. 00601 // 00602 00603 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 00604 00605 if (!(IopDoesDevNodeHaveProblem(deviceNode) || (deviceNode->Flags & DNF_STARTED))) { 00606 deviceNode->Flags |= DNF_START_REQUEST_PENDING; 00607 } 00608 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 00609 } 00610 } else { 00611 00612 if ((deviceNode->Flags & DNF_STOPPED)|| 00613 (deviceNode->DockInfo.DockStatus == DOCK_NOTDOCKDEVICE)) { 00614 00615 00616 // 00617 // This is either the rebalance case in which we are restarting a 00618 // temporarily stopped device, or we are starting a non-dock device, 00619 // and it was previously off. 00620 // 00621 status = IopSynchronousCall(DeviceObject, &irpSp, &dummy); 00622 00623 } else { 00624 00625 // 00626 // This is a dock so we a little bit of work before starting it. 00627 // Take the profile change semaphore. We do this whenever a dock 00628 // is in our list, even if no query is going to occur. 00629 // 00630 IopHardwareProfileBeginTransition(FALSE); 00631 00632 // 00633 // Tell the profile code what dock device object may be bringing the 00634 // new hardware profile online. 00635 // 00636 IopHardwareProfileMarkDock(deviceNode, DOCK_ARRIVING); 00637 00638 // 00639 // Ask everyone if this is really a good idea right now. Note that 00640 // PiProcessStart calls IopNewDevice calls IopStartAndEnumerateDevice 00641 // who calls this function on that thread. Therefore we may indded be 00642 // in an event, although this would probably be a fairly rare event 00643 // for a dock. 00644 // 00645 status = IopHardwareProfileQueryChange( 00646 FALSE, 00647 PROFILE_PERHAPS_IN_PNPEVENT, 00648 &vetoType, 00649 NULL 00650 ); 00651 00652 if (NT_SUCCESS(status)) { 00653 00654 status = IopSynchronousCall(DeviceObject, &irpSp, &dummy); 00655 } 00656 00657 if (NT_SUCCESS(status)) { 00658 00659 // 00660 // Commit the current Hardware Profile as necessary. 00661 // 00662 IopHardwareProfileCommitStartedDock(deviceNode); 00663 00664 } else { 00665 00666 IopHardwareProfileCancelTransition(); 00667 } 00668 } 00669 00670 if (!NT_SUCCESS(status)) { 00671 ULONG Problem = CM_PROB_FAILED_START; 00672 00673 SAVE_FAILURE_INFO(deviceNode, status); 00674 00675 // 00676 // Handle certain problems determined by the status code 00677 // 00678 switch (status) { 00679 case STATUS_PNP_REBOOT_REQUIRED: 00680 Problem = CM_PROB_NEED_RESTART; 00681 break; 00682 00683 default: 00684 Problem = CM_PROB_FAILED_START; 00685 } 00686 IopSetDevNodeProblem(deviceNode, Problem); 00687 00688 if (deviceNode->DockInfo.DockStatus == DOCK_NOTDOCKDEVICE) { 00689 00690 IopRequestDeviceRemoval(deviceNode->PhysicalDeviceObject, CM_PROB_FAILED_START); 00691 } else { 00692 00693 ASSERT(deviceNode->DockInfo.DockStatus == DOCK_QUIESCENT); 00694 00695 PpSetTargetDeviceRemove( deviceNode->PhysicalDeviceObject, 00696 FALSE, 00697 TRUE, 00698 TRUE, 00699 CM_PROB_DEVICE_NOT_THERE, 00700 NULL, 00701 NULL, 00702 NULL, 00703 NULL); 00704 } 00705 00706 } else { 00707 00708 IopDoDeferredSetInterfaceState(deviceNode); 00709 00710 deviceNode->Flags |= DNF_STARTED; 00711 00712 if (deviceNode->Flags & DNF_STOPPED) { 00713 00714 // 00715 // If the start is initiated by rebalancing, do NOT do enumeration 00716 // 00717 00718 deviceNode->Flags &= ~DNF_STOPPED; 00719 00720 } else { 00721 00722 deviceNode->Flags |= DNF_NEED_ENUMERATION_ONLY; 00723 00724 } 00725 } 00726 } 00727 }

NTSTATUS IopSynchronousCall IN PDEVICE_OBJECT  DeviceObject,
IN PIO_STACK_LOCATION  TopStackLocation,
OUT PVOID *  Information
 

Definition at line 381 of file pnpirp.c.

References Executive, FALSE, IoAllocateIrp(), IoCallDriver, IoGetAttachedDevice(), IoGetNextIrpStackLocation, IopQueueThreadIrp, _IRP::IoStatus, IRP_SYSTEM_RESTRICTED, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NTSTATUS(), NULL, PAGED_CODE, PnpIrpStatusTracking, PsGetCurrentThread, SPECIALIRP_WATERMARK_IRP, _DEVICE_OBJECT::StackSize, _IRP::Tail, _IRP::UserEvent, _IRP::UserIosb, and VOID().

Referenced by IoFreeDumpStack(), IopEnumerateDevice(), IopGetDumpStack(), IopGetRelatedTargetDevice(), IopProcessNewDeviceNode(), IopQueryCompatibleIds(), IopQueryDeviceCapabilities(), IopQueryDeviceId(), IopQueryDeviceRelations(), IopQueryDeviceResources(), IopQueryDeviceSerialNumber(), IopQueryDeviceState(), IopQueryDockRemovalInterface(), IopQueryLegacyBusInformation(), IopQueryPnpBusInformation(), IopQueryReconfiguration(), IopQueryResourceHandlerInterface(), IopQueryUniqueId(), IopRemoveDevice(), and IopStartDevice().

00389 : 00390 00391 This function sends a synchronous irp to the top level device 00392 object which roots on DeviceObject. 00393 00394 Parameters: 00395 00396 DeviceObject - Supplies the device object of the device being removed. 00397 00398 TopStackLocation - Supplies a pointer to the parameter block for the irp. 00399 00400 Information - Supplies a pointer to a variable to receive the returned 00401 information of the irp. 00402 00403 Return Value: 00404 00405 NTSTATUS code. 00406 00407 --*/ 00408 00409 { 00410 PIRP irp; 00411 PIO_STACK_LOCATION irpSp; 00412 IO_STATUS_BLOCK statusBlock; 00413 KEVENT event; 00414 NTSTATUS status; 00415 PULONG_PTR returnInfo = (PULONG_PTR)Information; 00416 PDEVICE_OBJECT deviceObject; 00417 00418 PAGED_CODE(); 00419 00420 // 00421 // Get a pointer to the topmost device object in the stack of devices, 00422 // beginning with the deviceObject. 00423 // 00424 00425 deviceObject = IoGetAttachedDevice(DeviceObject); 00426 00427 // 00428 // Begin by allocating the IRP for this request. Do not charge quota to 00429 // the current process for this IRP. 00430 // 00431 00432 irp = IoAllocateIrp(deviceObject->StackSize, FALSE); 00433 if (irp == NULL){ 00434 00435 return STATUS_INSUFFICIENT_RESOURCES; 00436 } 00437 00438 SPECIALIRP_WATERMARK_IRP(irp, IRP_SYSTEM_RESTRICTED); 00439 00440 // 00441 // Initialize it to failure. 00442 // 00443 00444 irp->IoStatus.Status = statusBlock.Status = STATUS_NOT_SUPPORTED; 00445 irp->IoStatus.Information = statusBlock.Information = 0; 00446 00447 // 00448 // Set the pointer to the status block and initialized event. 00449 // 00450 00451 KeInitializeEvent( &event, 00452 SynchronizationEvent, 00453 FALSE ); 00454 00455 irp->UserIosb = &statusBlock; 00456 irp->UserEvent = &event; 00457 00458 // 00459 // Set the address of the current thread 00460 // 00461 00462 irp->Tail.Overlay.Thread = PsGetCurrentThread(); 00463 00464 // 00465 // Queue this irp onto the current thread 00466 // 00467 00468 IopQueueThreadIrp(irp); 00469 00470 // 00471 // Get a pointer to the stack location of the first driver which will be 00472 // invoked. This is where the function codes and parameters are set. 00473 // 00474 00475 irpSp = IoGetNextIrpStackLocation(irp); 00476 00477 // 00478 // Copy in the caller-supplied stack location contents 00479 // 00480 00481 *irpSp = *TopStackLocation; 00482 00483 // 00484 // Call the driver 00485 // 00486 00487 status = IoCallDriver(deviceObject, irp); 00488 00489 PnpIrpStatusTracking(status, TopStackLocation->MinorFunction, deviceObject); 00490 00491 // 00492 // If a driver returns STATUS_PENDING, we will wait for it to complete 00493 // 00494 00495 if (status == STATUS_PENDING) { 00496 (VOID) KeWaitForSingleObject( &event, 00497 Executive, 00498 KernelMode, 00499 FALSE, 00500 (PLARGE_INTEGER) NULL ); 00501 status = statusBlock.Status; 00502 } 00503 00504 *returnInfo = (ULONG_PTR) statusBlock.Information; 00505 00506 return status; 00507 }

VOID IopUncacheInterfaceInformation IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 191 of file pnpirp.c.

References _INTERFACE::Context, _DEVICE_NODE::DeviceArbiterList, _DEVICE_NODE::DeviceTranslatorList, ExFreePool(), _INTERFACE::InterfaceDereference, _DEVICE_NODE::NoArbiterMask, _DEVICE_NODE::NoTranslatorMask, _DEVICE_NODE::QueryArbiterMask, _DEVICE_NODE::QueryTranslatorMask, and _PI_RESOURCE_TRANSLATOR_ENTRY::TranslatorInterface.

Referenced by IopDestroyDeviceNode(), IopInvalidateDeviceStateWorker(), IopRemoveDevice(), and IopStartDevice().

00197 : 00198 00199 This function removes all the cached translators and arbiters information 00200 from the device object. 00201 00202 Parameters: 00203 00204 DeviceObject - Supplies the device object of the device being removed. 00205 00206 Return Value: 00207 00208 NTSTATUS code. 00209 00210 --*/ 00211 00212 { 00213 PDEVICE_NODE deviceNode = (PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode; 00214 PLIST_ENTRY listHead, nextEntry, entry; 00215 PPI_RESOURCE_TRANSLATOR_ENTRY handlerEntry; 00216 PINTERFACE interface; 00217 00218 // 00219 // Dereference all the arbiters on this PDO. 00220 // 00221 00222 listHead = &deviceNode->DeviceArbiterList; 00223 nextEntry = listHead->Flink; 00224 while (nextEntry != listHead) { 00225 entry = nextEntry; 00226 nextEntry = nextEntry->Flink; 00227 handlerEntry = CONTAINING_RECORD(entry, PI_RESOURCE_TRANSLATOR_ENTRY, DeviceTranslatorList); 00228 if (interface = (PINTERFACE)handlerEntry->TranslatorInterface) { 00229 (interface->InterfaceDereference)(interface->Context); 00230 ExFreePool(interface); 00231 } 00232 ExFreePool(entry); 00233 } 00234 InitializeListHead(&deviceNode->DeviceArbiterList); 00235 00236 // 00237 // Dereference all the translators on this PDO. 00238 // 00239 00240 listHead = &deviceNode->DeviceTranslatorList; 00241 nextEntry = listHead->Flink; 00242 while (nextEntry != listHead) { 00243 entry = nextEntry; 00244 nextEntry = nextEntry->Flink; 00245 handlerEntry = CONTAINING_RECORD(entry, PI_RESOURCE_TRANSLATOR_ENTRY, DeviceTranslatorList); 00246 if (interface = (PINTERFACE)handlerEntry->TranslatorInterface) { 00247 (interface->InterfaceDereference)(interface->Context); 00248 ExFreePool(interface); 00249 } 00250 ExFreePool(entry); 00251 } 00252 00253 InitializeListHead(&deviceNode->DeviceTranslatorList); 00254 00255 deviceNode->NoArbiterMask = 0; 00256 deviceNode->QueryArbiterMask = 0; 00257 deviceNode->NoTranslatorMask = 0; 00258 deviceNode->QueryTranslatorMask = 0; 00259 }

VOID IopUnlockMountedDeviceForRemove IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  IrpMinorCode,
IN PLOCK_MOUNTABLE_DEVICE_CONTEXT  Context
 

Definition at line 1233 of file pnpirp.c.

References _DEVICE_OBJECT::AttachedDevice, _DEVICE_OBJECT::DeviceLock, Executive, FALSE, _VPB::Flags, IO_NO_INCREMENT, IoAcquireVpbSpinLock(), IopDatabaseLock, IoReleaseVpbSpinLock(), IRP_MN_REMOVE_DEVICE, KernelMode, KeSetEvent(), KeWaitForSingleObject(), NULL, _DEVICE_OBJECT::Vpb, and VPB_REMOVE_PENDING.

Referenced by IopRemoveDevice().

01238 { 01239 PVPB vpb; 01240 BOOLEAN removePendingSet; 01241 01242 PDEVICE_OBJECT device = DeviceObject; 01243 01244 do { 01245 01246 KIRQL oldIrql; 01247 01248 // 01249 // Walk up each device object in the stack. For each one, if a VPB 01250 // exists, grab the database resource exclusive followed by the 01251 // device lock. Then acquire the Vpb spinlock and perform the 01252 // appropriate magic on the device object. 01253 // 01254 01255 // 01256 // NOTE - It's unfortunate that the locking order includes grabing 01257 // the device specific lock first followed by the global lock. 01258 // 01259 01260 if (device->Vpb != NULL) { 01261 01262 // 01263 // Grab the device lock. This will ensure that there are no mount 01264 // or verify operations in progress, which in turn will ensure 01265 // that any mounted file system won't go away. 01266 // 01267 01268 KeWaitForSingleObject(&(device->DeviceLock), 01269 Executive, 01270 KernelMode, 01271 FALSE, 01272 NULL); 01273 01274 // 01275 // Now decrement the reference count in the VPB. If the remove 01276 // pending flag has been set in the VPB (if this is a QUERY or a 01277 // REMOVE) then even on a dismount no new file system will be 01278 // allowed onto the device. 01279 // 01280 01281 IoAcquireVpbSpinLock(&oldIrql); 01282 01283 if (IrpMinorCode == IRP_MN_REMOVE_DEVICE) { 01284 01285 device->Vpb->Flags &= ~VPB_REMOVE_PENDING; 01286 } 01287 01288 IoReleaseVpbSpinLock(oldIrql); 01289 01290 KeSetEvent(&(device->DeviceLock), IO_NO_INCREMENT, FALSE); 01291 } 01292 01293 // 01294 // Continue up the chain until we know we hit the device the fs 01295 // mounted on, if any. 01296 // 01297 01298 if (Context->MountedDevice == device) { 01299 01300 break; 01301 01302 } else { 01303 01304 ExAcquireFastLock( &IopDatabaseLock, &oldIrql ); 01305 device = device->AttachedDevice; 01306 ExReleaseFastLock( &IopDatabaseLock, oldIrql ); 01307 } 01308 01309 } while (device != NULL); 01310 01311 return; 01312 }


Variable Documentation

PCHAR IrpName[]
 

Initial value:

{ "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 - ", "INVALID_IRP_CODE - ", "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 - ", NULL }

Definition at line 37 of file pnpirp.c.

ULONG PnpIrpMask
 

Definition at line 36 of file pnpirp.c.


Generated on Sat May 15 19:45:14 2004 for test by doxygen 1.3.7