Source code of Windows XP (NT5)
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.

658 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. local.h
  5. Abstract:
  6. This header declares the stuctures and function prototypes shared between
  7. the various modules.
  8. Author:
  9. Andy Thornton (andrewth) 20-Oct-97
  10. Revision History:
  11. --*/
  12. #if !defined(_LOCAL_)
  13. #define _LOCAL_
  14. #include <ntddk.h>
  15. #include <arbiter.h>
  16. #include <wdmguid.h>
  17. //#include <initguid.h>
  18. #include <mf.h>
  19. #include "msg.h"
  20. #include "debug.h"
  21. //
  22. // --- Constants ---
  23. //
  24. #define MF_CM_RESOURCE_VERSION 1
  25. #define MF_CM_RESOURCE_REVISION 1
  26. #define MF_ARBITER_INTERFACE_VERSION 1
  27. #define MF_TRANSLATOR_INTERFACE_VERSION 1
  28. //
  29. // These must be updated if any new PNP or PO irps are added
  30. //
  31. #define IRP_MN_PNP_MAXIMUM_FUNCTION IRP_MN_QUERY_LEGACY_BUS_INFORMATION
  32. #define IRP_MN_PO_MAXIMUM_FUNCTION IRP_MN_QUERY_POWER
  33. //
  34. // Pool Tags
  35. //
  36. #define MF_POOL_TAG ' fM'
  37. #define MF_RESOURCE_MAP_TAG 'MRfM'
  38. #define MF_VARYING_MAP_TAG 'MVfM'
  39. #define MF_CHILD_LIST_TAG 'LCfM'
  40. #define MF_DEVICE_ID_TAG 'IDfM'
  41. #define MF_INSTANCE_ID_TAG 'IIfM'
  42. #define MF_CHILD_REQUIREMENTS_TAG 'QCfM'
  43. #define MF_CHILD_RESOURCE_TAG 'RCfM'
  44. #define MF_HARDWARE_COMPATIBLE_ID_TAG 'IHfM'
  45. #define MF_PARENTS_RESOURCE_TAG 'RPfM'
  46. #define MF_PARENTS_REQUIREMENTS_TAG 'QPfM'
  47. #define MF_BUS_RELATIONS_TAG 'RBfM'
  48. #define MF_TARGET_RELATIONS_TAG 'RTfM'
  49. #define MF_REQUIREMENTS_INDEX_TAG 'IRfM'
  50. #define MF_ARBITER_TAG 'rAfM'
  51. //
  52. // Device state flags
  53. //
  54. #define MF_DEVICE_STARTED 0x00000001
  55. #define MF_DEVICE_REMOVED 0x00000002
  56. #define MF_DEVICE_ENUMERATED 0x00000004
  57. #define MF_DEVICE_REMOVE_PENDING 0x00000008 /* DEPRECATED */
  58. #define MF_DEVICE_STOP_PENDING 0x00000010 /* DEPRECATED */
  59. #define MF_DEVICE_CAPABILITIES_CAPTURED 0x00000020 /* DEPRECATED */
  60. #define MF_DEVICE_REQUIREMENTS_CAPTURED 0x00000040 /* DEPRECATED */
  61. #define MF_DEVICE_DELETED 0x00000080
  62. #define MF_DEVICE_SURPRISE_REMOVED 0x00000100
  63. //
  64. // Flags to MfGetRegistryValue
  65. //
  66. #define MF_GETREG_SZ_TO_MULTI_SZ 0x00000001
  67. //
  68. // --- Type definitions ---
  69. //
  70. typedef enum _MF_OBJECT_TYPE {
  71. MfPhysicalDeviceObject = 'dPfM',
  72. MfFunctionalDeviceObject = 'dFfM'
  73. } MF_OBJECT_TYPE;
  74. typedef
  75. NTSTATUS
  76. (*PMF_DISPATCH)(
  77. IN PIRP Irp,
  78. IN PVOID Extension,
  79. IN PIO_STACK_LOCATION IrpStack
  80. );
  81. typedef ULONG Mf_MSG_ID;
  82. //
  83. // Structures for storing the resource distributions
  84. //
  85. typedef struct _MF_ARBITER {
  86. //
  87. // List of arbiters
  88. //
  89. LIST_ENTRY ListEntry;
  90. //
  91. // The resource this arbiter arbitrates
  92. //
  93. CM_RESOURCE_TYPE Type;
  94. //
  95. // The arbiter instance
  96. //
  97. ARBITER_INSTANCE Instance;
  98. } MF_ARBITER, *PMF_ARBITER;
  99. typedef struct _MF_COMMON_EXTENSION {
  100. //
  101. // Type of device this is
  102. //
  103. MF_OBJECT_TYPE Type;
  104. //
  105. // Dispatch tables for Pnp and Power Irps.
  106. //
  107. PMF_DISPATCH *PnpDispatchTable;
  108. PMF_DISPATCH *PoDispatchTable;
  109. //
  110. // Flags to indicate the device's current state (use MF_DEVICE_*)
  111. //
  112. ULONG DeviceState;
  113. ULONG PagingCount;
  114. ULONG HibernationCount;
  115. ULONG DumpCount;
  116. //
  117. // The power state of the device
  118. //
  119. DEVICE_POWER_STATE PowerState;
  120. } MF_COMMON_EXTENSION, *PMF_COMMON_EXTENSION;
  121. typedef struct _MF_CHILD_EXTENSION *PMF_CHILD_EXTENSION;
  122. typedef struct _MF_PARENT_EXTENSION *PMF_PARENT_EXTENSION;
  123. typedef struct _MF_CHILD_EXTENSION {
  124. //
  125. // The common extension
  126. //
  127. MF_COMMON_EXTENSION Common;
  128. //
  129. // Various Flags
  130. //
  131. ULONG Flags;
  132. //
  133. // Backpointer to the device object we are are the extension of
  134. //
  135. PDEVICE_OBJECT Self;
  136. //
  137. // The FDO who enumerated us
  138. //
  139. PMF_PARENT_EXTENSION Parent;
  140. //
  141. // Other children enumerated by the same FDO
  142. //
  143. LIST_ENTRY ListEntry;
  144. //
  145. // The pnp device state of the device
  146. //
  147. PNP_DEVICE_STATE PnpDeviceState;
  148. //
  149. // The information about this device
  150. //
  151. MF_DEVICE_INFO Info;
  152. } MF_CHILD_EXTENSION, *PMF_CHILD_EXTENSION;
  153. typedef struct _MF_PARENT_EXTENSION {
  154. //
  155. // The common extension
  156. //
  157. MF_COMMON_EXTENSION Common;
  158. //
  159. // Backpointer to the device object of whom we are the extension
  160. //
  161. PDEVICE_OBJECT Self;
  162. //
  163. // The PDO for the multi-function device
  164. //
  165. PDEVICE_OBJECT PhysicalDeviceObject;
  166. //
  167. // Lock for the children database
  168. //
  169. KEVENT ChildrenLock;
  170. //
  171. // List of children enumerated by this device
  172. //
  173. LIST_ENTRY Children;
  174. //
  175. // The next device in the stack who we should send our IRPs down to
  176. //
  177. PDEVICE_OBJECT AttachedDevice;
  178. //
  179. // The resources with which the parent was stated
  180. //
  181. PCM_RESOURCE_LIST ResourceList;
  182. PCM_RESOURCE_LIST TranslatedResourceList;
  183. //
  184. // The device and instance ID's of our parent
  185. //
  186. UNICODE_STRING DeviceID;
  187. UNICODE_STRING InstanceID;
  188. //
  189. // The already instantiated arbiters for this device
  190. //
  191. LIST_ENTRY Arbiters;
  192. //
  193. // If we had to traverse the children in order to determine what
  194. // the lowest power state the parent can go to, then the
  195. // synchronization of the children list would become extremely
  196. // complicated.
  197. //
  198. // Instead, have a spinlock protected data structure consisting of
  199. // an array of device power states. Each element of the array is
  200. // a count of how many children are in that power state.
  201. //
  202. KSPIN_LOCK PowerLock;
  203. LONG ChildrenPowerReferences[PowerDeviceMaximum];
  204. //
  205. // Remove lock. Used to prevent the FDO from being removed while
  206. // other operations are digging around in the extension.
  207. //
  208. IO_REMOVE_LOCK RemoveLock;
  209. } MF_PARENT_EXTENSION, *PMF_PARENT_EXTENSION;
  210. //
  211. // A list of MF_CHILD_LIST_ENTRYs is returned by MfEnumerate
  212. //
  213. typedef struct _MF_CHILD_LIST_ENTRY {
  214. LIST_ENTRY ListEntry;
  215. MF_DEVICE_INFO Info;
  216. } MF_CHILD_LIST_ENTRY, *PMF_CHILD_LIST_ENTRY;
  217. //
  218. // Registry structure - from our friends in Win9x so it must be byte aligned
  219. //
  220. #include <pshpack1.h>
  221. typedef struct _MF_REGISTRY_VARYING_RESOURCE_MAP {
  222. UCHAR ResourceIndex; // Win9x BYTE
  223. ULONG Offset;
  224. ULONG Size;
  225. } MF_REGISTRY_VARYING_RESOURCE_MAP, *PMF_REGISTRY_VARYING_RESOURCE_MAP;
  226. #include <poppack.h>
  227. typedef
  228. NTSTATUS
  229. (*PMF_REQUIREMENT_FROM_RESOURCE)(
  230. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource,
  231. OUT PIO_RESOURCE_DESCRIPTOR Requirement
  232. );
  233. typedef
  234. NTSTATUS
  235. (*PMF_UPDATE_RESOURCE)(
  236. IN OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource,
  237. IN ULONGLONG Start,
  238. IN ULONG Length
  239. );
  240. typedef struct _MF_RESOURCE_TYPE {
  241. CM_RESOURCE_TYPE Type;
  242. PARBITER_UNPACK_REQUIREMENT UnpackRequirement;
  243. PARBITER_PACK_RESOURCE PackResource;
  244. PARBITER_UNPACK_RESOURCE UnpackResource;
  245. PMF_REQUIREMENT_FROM_RESOURCE RequirementFromResource;
  246. PMF_UPDATE_RESOURCE UpdateResource;
  247. } MF_RESOURCE_TYPE, *PMF_RESOURCE_TYPE;
  248. typedef struct _MF_POWER_COMPLETION_CONTEXT {
  249. //
  250. // Event that will be set when the operation is complete
  251. //
  252. KEVENT Event;
  253. //
  254. // The status of the completed operation
  255. //
  256. NTSTATUS Status;
  257. } MF_POWER_COMPLETION_CONTEXT, *PMF_POWER_COMPLETION_CONTEXT;
  258. //
  259. // --- Globals ---
  260. //
  261. extern PDRIVER_OBJECT MfDriverObject;
  262. //
  263. // --- Function prototypes ---
  264. //
  265. //
  266. // arbiter.c
  267. //
  268. NTSTATUS
  269. MfInitializeArbiters(
  270. IN PMF_PARENT_EXTENSION Parent
  271. );
  272. //
  273. // common.c
  274. //
  275. NTSTATUS
  276. MfDeviceUsageNotificationCommon(
  277. IN PIRP Irp,
  278. IN PMF_COMMON_EXTENSION Common,
  279. IN PIO_STACK_LOCATION IrpStack
  280. );
  281. //
  282. // dispatch.c
  283. //
  284. NTSTATUS
  285. MfAddDevice(
  286. IN PDRIVER_OBJECT DriverObject,
  287. IN PDEVICE_OBJECT PhysicalDeviceObject
  288. );
  289. NTSTATUS
  290. MfDispatchPnp(
  291. IN PDEVICE_OBJECT DeviceObject,
  292. IN PIRP Irp
  293. );
  294. NTSTATUS
  295. MfDispatchPower(
  296. IN PDEVICE_OBJECT DeviceObject,
  297. IN PIRP Irp
  298. );
  299. NTSTATUS
  300. MfIrpNotSupported(
  301. IN PIRP Irp,
  302. IN PVOID Extension,
  303. IN PIO_STACK_LOCATION IrpStack
  304. );
  305. NTSTATUS
  306. MfForwardIrpToParent(
  307. IN PIRP Irp,
  308. IN PMF_CHILD_EXTENSION Extension,
  309. IN PIO_STACK_LOCATION IrpStack
  310. );
  311. NTSTATUS
  312. MfDispatchNop(
  313. IN PDEVICE_OBJECT DeviceObject,
  314. IN PIRP Irp
  315. );
  316. //
  317. // enum.c
  318. //
  319. NTSTATUS
  320. MfEnumerate(
  321. IN PMF_PARENT_EXTENSION Parent
  322. );
  323. NTSTATUS
  324. MfBuildDeviceID(
  325. IN PMF_PARENT_EXTENSION Parent,
  326. OUT PWSTR *DeviceID
  327. );
  328. NTSTATUS
  329. MfBuildInstanceID(
  330. IN PMF_CHILD_EXTENSION Child,
  331. OUT PWSTR *InstanceID
  332. );
  333. NTSTATUS
  334. MfBuildChildRequirements(
  335. IN PMF_CHILD_EXTENSION Child,
  336. OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList
  337. );
  338. //
  339. // fdo.c
  340. //
  341. NTSTATUS
  342. MfDispatchPnpFdo(
  343. IN PDEVICE_OBJECT DeviceObject,
  344. IN PMF_PARENT_EXTENSION Parent,
  345. IN PIO_STACK_LOCATION IrpStack,
  346. IN OUT PIRP Irp
  347. );
  348. NTSTATUS
  349. MfDispatchPowerFdo(
  350. IN PDEVICE_OBJECT DeviceObject,
  351. IN PMF_PARENT_EXTENSION Parent,
  352. IN PIO_STACK_LOCATION IrpStack,
  353. IN OUT PIRP Irp
  354. );
  355. NTSTATUS
  356. MfCreateFdo(
  357. PDEVICE_OBJECT *Fdo
  358. );
  359. VOID
  360. MfAcquireChildrenLock(
  361. IN PMF_PARENT_EXTENSION Parent
  362. );
  363. VOID
  364. MfReleaseChildrenLock(
  365. IN PMF_PARENT_EXTENSION Parent
  366. );
  367. //
  368. // init.c
  369. //
  370. //
  371. // pdo.c
  372. //
  373. NTSTATUS
  374. MfDispatchPnpPdo(
  375. IN PDEVICE_OBJECT DeviceObject,
  376. IN PMF_CHILD_EXTENSION Parent,
  377. IN PIO_STACK_LOCATION IrpStack,
  378. IN OUT PIRP Irp
  379. );
  380. NTSTATUS
  381. MfDispatchPowerPdo(
  382. IN PDEVICE_OBJECT DeviceObject,
  383. IN PMF_CHILD_EXTENSION Parent,
  384. IN PIO_STACK_LOCATION IrpStack,
  385. IN OUT PIRP Irp
  386. );
  387. NTSTATUS
  388. MfCreatePdo(
  389. IN PMF_PARENT_EXTENSION Parent,
  390. OUT PDEVICE_OBJECT *PhysicalDeviceObject
  391. );
  392. VOID
  393. MfDeletePdo(
  394. IN PMF_CHILD_EXTENSION Child
  395. );
  396. //
  397. // resource.c
  398. //
  399. PMF_RESOURCE_TYPE
  400. MfFindResourceType(
  401. IN CM_RESOURCE_TYPE Type
  402. );
  403. //
  404. // utils.c
  405. //
  406. NTSTATUS
  407. MfGetSubkeyByIndex(
  408. IN HANDLE ParentHandle,
  409. IN ULONG Index,
  410. IN ACCESS_MASK Access,
  411. OUT PHANDLE ChildHandle,
  412. OUT PUNICODE_STRING Name
  413. );
  414. VOID
  415. MfInitCommonExtension(
  416. IN OUT PMF_COMMON_EXTENSION Common,
  417. IN MF_OBJECT_TYPE Type
  418. );
  419. VOID
  420. MfFreeDeviceInfo(
  421. PMF_DEVICE_INFO Info
  422. );
  423. NTSTATUS
  424. MfGetRegistryValue(
  425. IN HANDLE Handle,
  426. IN PWSTR Name,
  427. IN ULONG Type,
  428. IN ULONG Flags,
  429. IN OUT PULONG DataLength,
  430. IN OUT PVOID *Data OPTIONAL
  431. );
  432. NTSTATUS
  433. MfSendPnpIrp(
  434. IN PDEVICE_OBJECT DeviceObject,
  435. IN PIO_STACK_LOCATION Location,
  436. OUT PULONG_PTR Information OPTIONAL
  437. );
  438. NTSTATUS
  439. MfSendSetPowerIrp(
  440. IN PDEVICE_OBJECT Target,
  441. IN POWER_STATE State
  442. );
  443. DEVICE_POWER_STATE
  444. MfUpdateChildrenPowerReferences(
  445. IN PMF_PARENT_EXTENSION Parent,
  446. IN DEVICE_POWER_STATE PreviousPowerState,
  447. IN DEVICE_POWER_STATE NewPowerState
  448. );
  449. NTSTATUS
  450. MfUpdateParentPowerState(
  451. IN PMF_PARENT_EXTENSION Parent,
  452. IN DEVICE_POWER_STATE TargetPowerState
  453. );
  454. //
  455. // --- Macros ---
  456. //
  457. #define IS_FDO(Extension) \
  458. (((PMF_COMMON_EXTENSION)Extension)->Type == MfFunctionalDeviceObject)
  459. #define MfCompareGuid(a,b) \
  460. (RtlEqualMemory((PVOID)(a), (PVOID)(b), sizeof(GUID)))
  461. //
  462. // Control macro (used like a for loop) which iterates over all entries in
  463. // a standard doubly linked list. Head is the list head and the entries are of
  464. // type Type. A member called ListEntry is assumed to be the LIST_ENTRY
  465. // structure linking the entries together. Current contains a pointer to each
  466. // entry in turn.
  467. //
  468. #define FOR_ALL_IN_LIST(Type, Head, Current) \
  469. for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \
  470. (Head) != &(Current)->ListEntry; \
  471. (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  472. Type, \
  473. ListEntry) \
  474. )
  475. #define FOR_ALL_IN_LIST_SAFE(Type, Head, Current, Next) \
  476. for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry), \
  477. (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  478. Type, ListEntry); \
  479. (Head) != &(Current)->ListEntry; \
  480. (Current) = (Next), \
  481. (Next) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  482. Type, ListEntry) \
  483. )
  484. //
  485. // Similar to the above only iteration is over an array of length _Size.
  486. //
  487. #define FOR_ALL_IN_ARRAY(_Array, _Size, _Current) \
  488. for ( (_Current) = (_Array); \
  489. (_Current) < (_Array) + (_Size); \
  490. (_Current)++ )
  491. //
  492. // FOR_ALL_CM_DESCRIPTORS(
  493. // IN PCM_RESOURCE_LIST _ResList,
  494. // OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR _Descriptor
  495. // )
  496. //
  497. // Iterates over the resource descriptors in a CM_RESOURCE_LIST of Count 1
  498. //
  499. #define FOR_ALL_CM_DESCRIPTORS(_ResList, _Descriptor) \
  500. ASSERT((_ResList)->Count == 1); \
  501. FOR_ALL_IN_ARRAY( \
  502. (_ResList)->List[0].PartialResourceList.PartialDescriptors, \
  503. (_ResList)->List[0].PartialResourceList.Count, \
  504. (_Descriptor) \
  505. )
  506. //
  507. // BOOLEAN
  508. // IS_ARBITRATED_RESOURCE(
  509. // IN CM_RESOURCE_TYPE _Resource
  510. // )
  511. //
  512. // If the top bit of the resource type (when viewed as a UCHAR) is set
  513. // then the resource is nonarbitrated.
  514. //
  515. #define IS_ARBITRATED_RESOURCE(_Resource) \
  516. (!(((UCHAR)(_Resource)) & 0x80) && \
  517. !(((UCHAR)(_Resource)) == 0x00))
  518. #define END_OF_RANGE(_Start, _Length) \
  519. ((_Start)+(_Length)-1)
  520. #endif // !defined(_LOCAL_)