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.

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