Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

215 lines
6.6 KiB

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
pnprlist.h
Abstract:
This file declares the routines and data structures used to manipulate
relations list. Relation lists are used by Plug and Play during the
processing of device removal and ejection.
Author:
Robert Nelson (robertn) Apr, 1998.
Revision History:
--*/
//
// An IRPLOCK allows for safe cancellation. The idea is to protect the IRP
// while the canceller is calling IoCancelIrp. This is done by wrapping the
// call in InterlockedExchange(s). The roles are as follows:
//
// Initiator/completion: Cancelable --> IoCallDriver() --> Completed
// Canceller: CancelStarted --> IoCancelIrp() --> CancelCompleted
//
// No cancellation:
// Cancelable-->Completed
//
// Cancellation, IoCancelIrp returns before completion:
// Cancelable --> CancelStarted --> CancelCompleted --> Completed
//
// Canceled after completion:
// Cancelable --> Completed -> CancelStarted
//
// Cancellation, IRP completed during call to IoCancelIrp():
// Cancelable --> CancelStarted -> Completed --> CancelCompleted
//
// The transition from CancelStarted to Completed tells the completer to block
// postprocessing (IRP ownership is transfered to the canceller). Similarly,
// the canceler learns it owns IRP postprocessing (free, completion, etc)
// during a Completed->CancelCompleted transition.
//
typedef enum {
IRPLOCK_CANCELABLE,
IRPLOCK_CANCEL_STARTED,
IRPLOCK_CANCEL_COMPLETE,
IRPLOCK_COMPLETED
} IRPLOCK;
//
// A RELATION_LIST_ENTRY is an element of a relation list.
//
// It contains all the PDEVICE_OBJECTS which exist at the same level in the
// DEVICE_NODE tree.
//
// Individual PDEVICE_OBJECT entries are tagged by setting their lowest bit.
//
// MaxCount indicates the size of the Devices array. Count indicates the number
// of elements which are currently being used. When a relation list is
// compressed Count will equal MaxCount.
//
typedef struct _RELATION_LIST_ENTRY {
ULONG Count; // Number of current entries
ULONG MaxCount; // Size of Entries list
PDEVICE_OBJECT Devices[1]; // Variable length list of device objects
} RELATION_LIST_ENTRY, *PRELATION_LIST_ENTRY;
//
// A RELATION_LIST contains a number of RELATION_LIST_ENTRY structures.
//
// Each entry in Entries describes all the devices of a given level in the
// DEVICE_NODE tree. In order to conserve memory, space is only allocated for
// the entries between the lowest and highest levels inclusive. The member
// FirstLevel indicates which level is at index 0 of Entries. MaxLevel
// indicates the last level represented in Entries. The number of entries is
// determined by the formula MaxLevel - FirstLevel + 1. The Entries array can
// be sparse. Each element of Entries will either be a PRELATION_LIST_ENTRY or
// NULL.
//
// The total number of PDEVICE_OBJECTs in all PRELATION_LIST_ENTRYs is kept in
// Count. Individual PDEVICE_OBJECTS may be tagged. The tag is maintained in
// Bit 0 of the PDEVICE_OBJECT. The total number of PDEVICE_OBJECTs tagged is
// kept in TagCount. This is used to rapidly determine whether or not all
// objects have been tagged.
//
typedef struct _RELATION_LIST {
ULONG Count; // Count of Devices in all Entries
ULONG TagCount; // Count of Tagged Devices
ULONG FirstLevel; // Level Number of Entries[0]
ULONG MaxLevel; // - FirstLevel + 1 = Number of Entries
PRELATION_LIST_ENTRY Entries[1]; // Variable length list of entries
} RELATION_LIST, *PRELATION_LIST;
//
// A PENDING_RELATIONS_LIST_ENTRY is used to track relation lists for operations
// which may pend. This includes removal when open handles exist and device
// ejection.
//
// The Link field is used to link the PENDING_RELATIONS_LIST_ENTRYs together.
//
// The DeviceObject field is the DEVICE_OBJECT to which the operation was
// originally targetted. It will also exist as a member of the relations list.
//
// The RelationsList is a list of BusRelations, RemovalRelations, (and
// EjectionRelations in the case of eject) which are related to DeviceObject and
// its relations.
//
// The EjectIrp is pointer to the Eject IRP which has been sent to the PDO. If
// this is a pending surprise removal then EjectIrp is not used.
//
typedef struct _PENDING_RELATIONS_LIST_ENTRY {
LIST_ENTRY Link;
WORK_QUEUE_ITEM WorkItem;
PPNP_DEVICE_EVENT_ENTRY DeviceEvent;
PDEVICE_OBJECT DeviceObject;
PRELATION_LIST RelationsList;
PIRP EjectIrp;
IRPLOCK Lock;
ULONG Problem;
BOOLEAN ProfileChangingEject;
BOOLEAN DisplaySafeRemovalDialog;
SYSTEM_POWER_STATE LightestSleepState;
PDOCK_INTERFACE DockInterface;
} PENDING_RELATIONS_LIST_ENTRY, *PPENDING_RELATIONS_LIST_ENTRY;
//
// Functions exported to other kernel modules.
//
NTSTATUS
IopAddRelationToList(
IN PRELATION_LIST List,
IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN DirectDescendant,
IN BOOLEAN Tagged
);
PRELATION_LIST
IopAllocateRelationList(
IN PLUGPLAY_DEVICE_DELETE_TYPE OperationCode
);
NTSTATUS
IopCompressRelationList(
IN OUT PRELATION_LIST *List
);
BOOLEAN
IopEnumerateRelations(
IN PRELATION_LIST List,
IN OUT PULONG Marker,
OUT PDEVICE_OBJECT *PhysicalDevice,
OUT BOOLEAN *DirectDescendant, OPTIONAL
OUT BOOLEAN *Tagged, OPTIONAL
BOOLEAN Reverse
);
VOID
IopFreeRelationList(
IN PRELATION_LIST List
);
ULONG
IopGetRelationsCount(
IN PRELATION_LIST List
);
ULONG
IopGetRelationsTaggedCount(
IN PRELATION_LIST List
);
BOOLEAN
IopIsRelationInList(
IN PRELATION_LIST List,
IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
IopMergeRelationLists(
IN OUT PRELATION_LIST TargetList,
IN PRELATION_LIST SourceList,
IN BOOLEAN Tagged
);
NTSTATUS
IopRemoveIndirectRelationsFromList(
IN PRELATION_LIST List
);
NTSTATUS
IopRemoveRelationFromList(
IN PRELATION_LIST List,
IN PDEVICE_OBJECT DeviceObject
);
VOID
IopSetAllRelationsTags(
IN PRELATION_LIST List,
IN BOOLEAN Tagged
);
NTSTATUS
IopSetRelationsTag(
IN PRELATION_LIST List,
IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN Tagged
);