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.

388 lines
12 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. pnpi.h
  5. Abstract:
  6. This module contains the internal structure definitions and APIs used by
  7. the kernel-mode Plug and Play manager.
  8. Author:
  9. Lonny McMichael (lonnym) 02/08/1995
  10. Revision History:
  11. --*/
  12. #ifndef _KERNEL_PNPI_
  13. #define _KERNEL_PNPI_
  14. #include <wdmguid.h>
  15. #include "regstrp.h"
  16. typedef struct _DEVICE_NODE DEVICE_NODE, *PDEVICE_NODE;
  17. //
  18. // Extract DeviceNode from DeviceObject.
  19. //
  20. #define PP_DO_TO_DN(DO) \
  21. ((PDEVICE_NODE)((DO)? (DO)->DeviceObjectExtension->DeviceNode : NULL))
  22. //
  23. // Macros to save useful information into memory dumps.
  24. //
  25. #define PP_SAVE_DEVNODE_TO_TRIAGE_DUMP(dn) { \
  26. if((dn)) { \
  27. IoAddTriageDumpDataBlock(dn, sizeof(DEVICE_NODE)); \
  28. if ((dn)->InstancePath.Length != 0) { \
  29. IoAddTriageDumpDataBlock(&(dn)->InstancePath.Length, sizeof((dn)->InstancePath.Length)); \
  30. IoAddTriageDumpDataBlock((dn)->InstancePath.Buffer, (dn)->InstancePath.Length); \
  31. } \
  32. if ((dn)->ServiceName.Length != 0) { \
  33. IoAddTriageDumpDataBlock(&(dn)->ServiceName.Length, sizeof((dn)->ServiceName.Length)); \
  34. IoAddTriageDumpDataBlock((dn)->ServiceName.Buffer, (dn)->ServiceName.Length); \
  35. } \
  36. if ((dn)->Parent && (dn)->Parent->ServiceName.Length != 0) { \
  37. IoAddTriageDumpDataBlock(&(dn)->Parent->ServiceName.Length, sizeof((dn)->Parent->ServiceName.Length)); \
  38. IoAddTriageDumpDataBlock((dn)->Parent->ServiceName.Buffer, (dn)->Parent->ServiceName.Length); \
  39. } \
  40. } \
  41. }
  42. #define PP_SAVE_DRIVEROBJECT_TO_TRIAGE_DUMP(drvo) { \
  43. if(drvo) { \
  44. IoAddTriageDumpDataBlock(drvo, (drvo)->Size); \
  45. if((drvo)->DriverName.Length != 0) { \
  46. IoAddTriageDumpDataBlock(&(drvo)->DriverName.Length, sizeof((drvo)->DriverName.Length)); \
  47. IoAddTriageDumpDataBlock((drvo)->DriverName.Buffer, (drvo)->DriverName.Length); \
  48. } \
  49. } \
  50. }
  51. #define PP_SAVE_DEVICEOBJECT_TO_TRIAGE_DUMP(do) { \
  52. if((do)) { \
  53. IoAddTriageDumpDataBlock(do, (do)->Size); \
  54. PP_SAVE_DRIVEROBJECT_TO_TRIAGE_DUMP((do)->DriverObject); \
  55. PP_SAVE_DEVNODE_TO_TRIAGE_DUMP(PP_DO_TO_DN(do)); \
  56. } \
  57. }
  58. #define GUID_STRING_LEN 39
  59. #define MAX_DEVICE_ID_LEN 200 // size in chars
  60. #define MAX_SERVICE_NAME_LEN 256 // in characters
  61. //
  62. // PNP_EVENT_LIST
  63. //
  64. // This is the head of the master device event list for both user-mode and
  65. // kernel-mode.
  66. //
  67. typedef struct _PNP_DEVICE_EVENT_LIST {
  68. NTSTATUS Status;
  69. KMUTEX EventQueueMutex;
  70. FAST_MUTEX Lock;
  71. LIST_ENTRY List;
  72. } PNP_DEVICE_EVENT_LIST, *PPNP_DEVICE_EVENT_LIST;
  73. //
  74. // PNP_DEVICE_EVENT_ENTRY
  75. //
  76. // One of these structures is allocated for each dynamic device event and
  77. // is removed after the event has been posted to all waiting recipients.
  78. // The notify block contains a pointer to this list.
  79. //
  80. typedef struct _PNP_DEVICE_EVENT_ENTRY {
  81. LIST_ENTRY ListEntry;
  82. ULONG Argument;
  83. PKEVENT CallerEvent;
  84. PDEVICE_CHANGE_COMPLETE_CALLBACK Callback;
  85. PVOID Context;
  86. PPNP_VETO_TYPE VetoType;
  87. PUNICODE_STRING VetoName;
  88. PLUGPLAY_EVENT_BLOCK Data;
  89. } PNP_DEVICE_EVENT_ENTRY, *PPNP_DEVICE_EVENT_ENTRY;
  90. //
  91. // Defines the enum type to distinguish between REMOVE device
  92. // and EJECT device.
  93. //
  94. typedef enum _PLUGPLAY_DEVICE_DELETE_TYPE {
  95. QueryRemoveDevice,
  96. CancelRemoveDevice,
  97. RemoveDevice,
  98. SurpriseRemoveDevice,
  99. EjectDevice,
  100. RemoveFailedDevice,
  101. RemoveUnstartedFailedDevice,
  102. MaxDeviceDeleteType
  103. } PLUGPLAY_DEVICE_DELETE_TYPE, *PPLUGPLAY_DEVICE_DELETE_TYPE;
  104. //++
  105. //
  106. // VOID
  107. // PiWstrToUnicodeString(
  108. // OUT PUNICODE_STRING u,
  109. // IN PCWSTR p
  110. // )
  111. //
  112. //--
  113. #define PiWstrToUnicodeString(u, p) { \
  114. if (p) { \
  115. (u)->Length = ((u)->MaximumLength = sizeof((p))) - sizeof(WCHAR); \
  116. } else { \
  117. (u)->Length = (u)->MaximumLength = 0; \
  118. } \
  119. (u)->Buffer = (p); \
  120. }
  121. //++
  122. //
  123. // VOID
  124. // PiUlongToUnicodeString(
  125. // OUT PUNICODE_STRING u,
  126. // IN OUT PWCHAR ub,
  127. // IN ULONG ubl,
  128. // IN ULONG i
  129. // )
  130. //
  131. //--
  132. #define PiUlongToUnicodeString(u, ub, ubl, i) \
  133. { \
  134. LONG len; \
  135. \
  136. len = _snwprintf((PWCHAR)(ub), (ubl) / sizeof(WCHAR), REGSTR_VALUE_STANDARD_ULONG_FORMAT, (i)); \
  137. (u)->MaximumLength = (USHORT)(ubl); \
  138. (u)->Length = (len == -1) ? (USHORT)(ubl) : (USHORT)len * sizeof(WCHAR); \
  139. (u)->Buffer = (PWSTR)(ub); \
  140. }
  141. //++
  142. //
  143. // VOID
  144. // PiUlongToInstanceKeyUnicodeString(
  145. // OUT PUNICODE_STRING u,
  146. // IN OUT PWCHAR ub,
  147. // IN ULONG ubl,
  148. // IN ULONG i
  149. // )
  150. //
  151. //--
  152. #define PiUlongToInstanceKeyUnicodeString(u, ub, ubl, i) \
  153. { \
  154. LONG len; \
  155. \
  156. len = _snwprintf((PWCHAR)(ub), (ubl) / sizeof(WCHAR), REGSTR_KEY_INSTANCE_KEY_FORMAT, (i)); \
  157. (u)->MaximumLength = (USHORT)(ubl); \
  158. (u)->Length = (len == -1) ? (USHORT)(ubl) : (USHORT)len * sizeof(WCHAR); \
  159. (u)->Buffer = (PWSTR)(ub); \
  160. }
  161. //
  162. // The following macros convert between a Count of Wide Characters (CWC) and a Count
  163. // of Bytes (CB).
  164. //
  165. #define CWC_TO_CB(c) ((c) * sizeof(WCHAR))
  166. #define CB_TO_CWC(c) ((c) / sizeof(WCHAR))
  167. //
  168. // Macro to determine the number of elements in a statically
  169. // initialized array.
  170. //
  171. #define ELEMENT_COUNT(x) (sizeof(x)/sizeof((x)[0]))
  172. //
  173. // Block write access to Pnp portion of registry.
  174. //
  175. #define PiLockPnpRegistry(Exclusive) { \
  176. KeEnterCriticalRegion(); \
  177. if (Exclusive) { \
  178. ExAcquireResourceExclusiveLite( \
  179. &PpRegistryDeviceResource, \
  180. TRUE); \
  181. } else { \
  182. ExAcquireResourceSharedLite( \
  183. &PpRegistryDeviceResource, \
  184. TRUE); \
  185. } \
  186. }
  187. //
  188. // Unblock write access to Pnp portion of registry.
  189. //
  190. #define PiUnlockPnpRegistry() { \
  191. ExReleaseResourceLite(&PpRegistryDeviceResource); \
  192. KeLeaveCriticalRegion(); \
  193. }
  194. //
  195. // Function to complete an event asynchronously.
  196. //
  197. VOID
  198. PpCompleteDeviceEvent(
  199. IN OUT PPNP_DEVICE_EVENT_ENTRY DeviceEvent,
  200. IN NTSTATUS FinalStatus
  201. );
  202. //
  203. // Global PnP Manager initialization data.
  204. //
  205. extern PVOID PiScratchBuffer;
  206. //
  207. // Private Entry Points
  208. //
  209. BOOLEAN
  210. PiRegSzToString(
  211. IN PWCHAR RegSzData,
  212. IN ULONG RegSzLength,
  213. OUT PULONG StringLength OPTIONAL,
  214. OUT PWSTR *CopiedString OPTIONAL
  215. );
  216. VOID
  217. PiUserResponse(
  218. IN ULONG Response,
  219. IN PNP_VETO_TYPE VetoType,
  220. IN LPWSTR VetoName,
  221. IN ULONG VetoNameLength
  222. );
  223. NTSTATUS
  224. PiDeviceRegistration(
  225. IN PUNICODE_STRING DeviceInstancePath,
  226. IN BOOLEAN Add,
  227. IN PUNICODE_STRING ServiceKeyName OPTIONAL
  228. );
  229. BOOLEAN
  230. PiCompareGuid(
  231. CONST GUID *Guid1,
  232. CONST GUID *Guid2
  233. );
  234. VOID
  235. PnPBiosShutdownSystem (
  236. IN ULONG Phase,
  237. IN OUT PVOID *Context
  238. );
  239. NTSTATUS
  240. PnPBiosInitializePnPBios (
  241. VOID
  242. );
  243. NTSTATUS
  244. PiGetDeviceRegistryProperty(
  245. IN PDEVICE_OBJECT DeviceObject,
  246. IN ULONG ValueType,
  247. IN PWSTR ValueName,
  248. IN PWSTR KeyName,
  249. OUT PVOID Buffer,
  250. IN OUT PULONG BufferLength
  251. );
  252. VOID
  253. PpInitializeDeviceReferenceTable(
  254. VOID
  255. );
  256. PVOID
  257. NTAPI
  258. PiAllocateGenericTableEntry (
  259. PRTL_GENERIC_TABLE Table,
  260. CLONG ByteSize
  261. );
  262. VOID
  263. NTAPI
  264. PiFreeGenericTableEntry (
  265. PRTL_GENERIC_TABLE Table,
  266. PVOID Buffer
  267. );
  268. VOID
  269. PpRemoveDeviceActionRequests(
  270. IN PDEVICE_OBJECT DeviceObject
  271. );
  272. typedef struct _SYSTEM_HIVE_LIMITS {
  273. ULONG Low;
  274. ULONG High;
  275. } SYSTEM_HIVE_LIMITS, *PSYSTEM_HIVE_LIMITS;
  276. VOID
  277. PpSystemHiveLimitCallback(
  278. PSYSTEM_HIVE_LIMITS HiveLimits,
  279. ULONG Level
  280. );
  281. extern SYSTEM_HIVE_LIMITS PpSystemHiveLimits;
  282. extern BOOLEAN PpSystemHiveTooLarge;
  283. extern BOOLEAN PpCallerInitializesRequestTable;
  284. NTSTATUS
  285. PpBusTypeGuidInitialize(
  286. VOID
  287. );
  288. USHORT
  289. PpBusTypeGuidGetIndex(
  290. IN LPGUID BusTypeGuid
  291. );
  292. NTSTATUS
  293. PpBusTypeGuidGet(
  294. IN USHORT Index,
  295. IN OUT LPGUID BusTypeGuid
  296. );
  297. VOID
  298. PiMarkDeviceStackStartPending(
  299. IN PDEVICE_OBJECT DeviceObject,
  300. IN BOOLEAN Set
  301. );
  302. NTSTATUS
  303. PpIrpQueryResourceRequirements(
  304. IN PDEVICE_OBJECT DeviceObject,
  305. OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements
  306. );
  307. NTSTATUS
  308. PpQueryDeviceID(
  309. IN PDEVICE_NODE DeviceNode,
  310. OUT PWCHAR *BusID,
  311. OUT PWCHAR *DeviceID
  312. );
  313. NTSTATUS
  314. PpQueryID(
  315. IN PDEVICE_NODE DeviceNode,
  316. IN BUS_QUERY_ID_TYPE IDType,
  317. OUT PWCHAR *ID,
  318. OUT PULONG IDLength
  319. );
  320. NTSTATUS
  321. PpIrpQueryID(
  322. IN PDEVICE_OBJECT DeviceObject,
  323. IN BUS_QUERY_ID_TYPE IDType,
  324. OUT PWCHAR *ID
  325. );
  326. #define PpQueryInstanceID(dn, id, l) PpQueryID(dn, BusQueryInstanceID, id, l)
  327. #define PpQueryHardwareIDs(dn, id, l) PpQueryID(dn, BusQueryHardwareIDs, id, l)
  328. #define PpQueryCompatibleIDs(dn, id, l) PpQueryID(dn, BusQueryCompatibleIDs, id, l)
  329. #define IopQueryDeviceSerialNumber(do, id) PpIrpQueryID(do, BusQueryDeviceSerialNumber, id)
  330. #endif // _KERNEL_PNPI_