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.

522 lines
17 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. #define MIN_CONFLICT_LIST_SIZE (sizeof(PLUGPLAY_CONTROL_CONFLICT_LIST) - sizeof(PLUGPLAY_CONTROL_CONFLICT_ENTRY) + sizeof(PLUGPLAY_CONTROL_CONFLICT_STRINGS))
  17. typedef struct _DEVICE_NODE DEVICE_NODE, *PDEVICE_NODE;
  18. //
  19. // Extract DeviceNode from DeviceObject.
  20. //
  21. #define PP_DO_TO_DN(DO) \
  22. ((PDEVICE_NODE)((DO)? (DO)->DeviceObjectExtension->DeviceNode : NULL))
  23. //
  24. // Macros to save useful information into memory dumps.
  25. //
  26. #define PP_SAVE_DEVNODE_TO_TRIAGE_DUMP(dn) { \
  27. if((dn)) { \
  28. IoAddTriageDumpDataBlock(dn, sizeof(DEVICE_NODE)); \
  29. if ((dn)->InstancePath.Length != 0) { \
  30. IoAddTriageDumpDataBlock(&(dn)->InstancePath.Length, sizeof((dn)->InstancePath.Length)); \
  31. IoAddTriageDumpDataBlock((dn)->InstancePath.Buffer, (dn)->InstancePath.Length); \
  32. } \
  33. if ((dn)->ServiceName.Length != 0) { \
  34. IoAddTriageDumpDataBlock(&(dn)->ServiceName.Length, sizeof((dn)->ServiceName.Length)); \
  35. IoAddTriageDumpDataBlock((dn)->ServiceName.Buffer, (dn)->ServiceName.Length); \
  36. } \
  37. if ((dn)->Parent && (dn)->Parent->ServiceName.Length != 0) { \
  38. IoAddTriageDumpDataBlock(&(dn)->Parent->ServiceName.Length, sizeof((dn)->Parent->ServiceName.Length)); \
  39. IoAddTriageDumpDataBlock((dn)->Parent->ServiceName.Buffer, (dn)->Parent->ServiceName.Length); \
  40. } \
  41. } \
  42. }
  43. #define PP_SAVE_DRIVEROBJECT_TO_TRIAGE_DUMP(drvo) { \
  44. if(drvo) { \
  45. IoAddTriageDumpDataBlock(drvo, (drvo)->Size); \
  46. if((drvo)->DriverName.Length != 0) { \
  47. IoAddTriageDumpDataBlock(&(drvo)->DriverName.Length, sizeof((drvo)->DriverName.Length)); \
  48. IoAddTriageDumpDataBlock((drvo)->DriverName.Buffer, (drvo)->DriverName.Length); \
  49. } \
  50. } \
  51. }
  52. #define PP_SAVE_DEVICEOBJECT_TO_TRIAGE_DUMP(do) { \
  53. if((do)) { \
  54. IoAddTriageDumpDataBlock(do, (do)->Size); \
  55. PP_SAVE_DRIVEROBJECT_TO_TRIAGE_DUMP((do)->DriverObject); \
  56. PP_SAVE_DEVNODE_TO_TRIAGE_DUMP(PP_DO_TO_DN(do)); \
  57. } \
  58. }
  59. #define GUID_STRING_LEN 39
  60. #define MAX_DEVICE_ID_LEN 200 // size in chars
  61. #define MAX_SERVICE_NAME_LEN 256 // in characters
  62. //
  63. // PNP_EVENT_LIST
  64. //
  65. // This is the head of the master device event list for both user-mode and
  66. // kernel-mode.
  67. //
  68. typedef struct _PNP_DEVICE_EVENT_LIST {
  69. NTSTATUS Status;
  70. KMUTEX EventQueueMutex;
  71. KGUARDED_MUTEX Lock;
  72. LIST_ENTRY List;
  73. } PNP_DEVICE_EVENT_LIST, *PPNP_DEVICE_EVENT_LIST;
  74. //
  75. // PNP_DEVICE_EVENT_ENTRY
  76. //
  77. // One of these structures is allocated for each dynamic device event and
  78. // is removed after the event has been posted to all waiting recipients.
  79. // The notify block contains a pointer to this list.
  80. //
  81. typedef struct _PNP_DEVICE_EVENT_ENTRY {
  82. LIST_ENTRY ListEntry;
  83. ULONG Argument;
  84. PKEVENT CallerEvent;
  85. PDEVICE_CHANGE_COMPLETE_CALLBACK Callback;
  86. PVOID Context;
  87. PPNP_VETO_TYPE VetoType;
  88. PUNICODE_STRING VetoName;
  89. PLUGPLAY_EVENT_BLOCK Data;
  90. } PNP_DEVICE_EVENT_ENTRY, *PPNP_DEVICE_EVENT_ENTRY;
  91. //
  92. // Defines the enum type to distinguish between REMOVE device
  93. // and EJECT device.
  94. //
  95. typedef enum _PLUGPLAY_DEVICE_DELETE_TYPE {
  96. QueryRemoveDevice,
  97. CancelRemoveDevice,
  98. RemoveDevice,
  99. SurpriseRemoveDevice,
  100. EjectDevice,
  101. RemoveFailedDevice,
  102. RemoveUnstartedFailedDevice,
  103. MaxDeviceDeleteType
  104. } PLUGPLAY_DEVICE_DELETE_TYPE, *PPLUGPLAY_DEVICE_DELETE_TYPE;
  105. //++
  106. //
  107. // VOID
  108. // PiWstrToUnicodeString(
  109. // OUT PUNICODE_STRING u,
  110. // IN PCWSTR p
  111. // )
  112. //
  113. //--
  114. #define PiWstrToUnicodeString(u, p) { \
  115. if (p) { \
  116. (u)->Length = ((u)->MaximumLength = sizeof((p))) - sizeof(WCHAR); \
  117. } else { \
  118. (u)->Length = (u)->MaximumLength = 0; \
  119. } \
  120. (u)->Buffer = (p); \
  121. }
  122. //++
  123. //
  124. // VOID
  125. // PiUlongToUnicodeString(
  126. // OUT PUNICODE_STRING u,
  127. // IN OUT PWCHAR ub,
  128. // IN ULONG ubl,
  129. // IN ULONG i
  130. // )
  131. //
  132. //--
  133. #define PiUlongToUnicodeString(u, ub, ubl, i) \
  134. { \
  135. PWCHAR end; \
  136. LONG len; \
  137. \
  138. StringCchPrintfExW((PWCHAR)(ub), (ubl) / sizeof(WCHAR), &end, NULL, 0, REGSTR_VALUE_STANDARD_ULONG_FORMAT, (i)); \
  139. len = (LONG)(end - (PWCHAR)(ub)); \
  140. (u)->MaximumLength = (USHORT)(ubl); \
  141. (u)->Length = (len == -1) ? (USHORT)(ubl) : (USHORT)len * sizeof(WCHAR); \
  142. (u)->Buffer = (PWSTR)(ub); \
  143. }
  144. //++
  145. //
  146. // VOID
  147. // PiUlongToInstanceKeyUnicodeString(
  148. // OUT PUNICODE_STRING u,
  149. // IN OUT PWCHAR ub,
  150. // IN ULONG ubl,
  151. // IN ULONG i
  152. // )
  153. //
  154. //--
  155. #define PiUlongToInstanceKeyUnicodeString(u, ub, ubl, i) \
  156. { \
  157. PWCHAR end; \
  158. LONG len; \
  159. \
  160. StringCchPrintfExW((PWCHAR)(ub), (ubl) / sizeof(WCHAR), &end, NULL, 0, REGSTR_KEY_INSTANCE_KEY_FORMAT, (i)); \
  161. len = (LONG)(end - (PWCHAR)(ub)); \
  162. (u)->MaximumLength = (USHORT)(ubl); \
  163. (u)->Length = (len == -1) ? (USHORT)(ubl) : (USHORT)len * sizeof(WCHAR); \
  164. (u)->Buffer = (PWSTR)(ub); \
  165. }
  166. //
  167. // The following macros convert between a Count of Wide Characters (CWC) and a Count
  168. // of Bytes (CB).
  169. //
  170. #define CWC_TO_CB(c) ((c) * sizeof(WCHAR))
  171. #define CB_TO_CWC(c) ((c) / sizeof(WCHAR))
  172. //
  173. // Macro to determine the number of elements in a statically
  174. // initialized array.
  175. //
  176. #define ELEMENT_COUNT(x) (sizeof(x)/sizeof((x)[0]))
  177. //
  178. // Enter critical section and acquire a lock on the registry. Both these
  179. // mechanisms are required to prevent deadlock in the case where an APC
  180. // routine calls this routine after the registry resource has been claimed
  181. // in this case it would wait blocking this thread so the registry would
  182. // never be released -> deadlock. Critical sectioning the registry manipulation
  183. // portion solves this problem
  184. //
  185. #define PiLockPnpRegistry(Exclusive) { \
  186. KeEnterCriticalRegion(); \
  187. if (Exclusive) { \
  188. ExAcquireResourceExclusiveLite( \
  189. &PpRegistryDeviceResource, \
  190. TRUE); \
  191. } else { \
  192. ExAcquireResourceSharedLite( \
  193. &PpRegistryDeviceResource, \
  194. TRUE); \
  195. } \
  196. }
  197. //
  198. // Unblock write access to Pnp portion of registry.
  199. //
  200. #define PiUnlockPnpRegistry() { \
  201. ExReleaseResourceLite(&PpRegistryDeviceResource); \
  202. KeLeaveCriticalRegion(); \
  203. }
  204. #define PiIsPnpRegistryLocked(Exclusive) \
  205. ((Exclusive) ? ExIsResourceAcquiredExclusiveLite(&PpRegistryDeviceResource) : \
  206. ((ExIsResourceAcquiredSharedLite(&PpRegistryDeviceResource) > 0) ? TRUE : FALSE))
  207. //
  208. // Function to complete an event asynchronously.
  209. //
  210. VOID
  211. PpCompleteDeviceEvent(
  212. IN OUT PPNP_DEVICE_EVENT_ENTRY DeviceEvent,
  213. IN NTSTATUS FinalStatus
  214. );
  215. //
  216. // Global PnP Manager initialization data.
  217. //
  218. extern PVOID PiScratchBuffer;
  219. //
  220. // Private Entry Points
  221. //
  222. BOOLEAN
  223. PiRegSzToString(
  224. IN PWCHAR RegSzData,
  225. IN ULONG RegSzLength,
  226. OUT PULONG StringLength OPTIONAL,
  227. OUT PWSTR *CopiedString OPTIONAL
  228. );
  229. VOID
  230. PiUserResponse(
  231. IN ULONG Response,
  232. IN PNP_VETO_TYPE VetoType,
  233. IN LPWSTR VetoName,
  234. IN ULONG VetoNameLength
  235. );
  236. NTSTATUS
  237. PiDeviceRegistration(
  238. IN PUNICODE_STRING DeviceInstancePath,
  239. IN BOOLEAN Add,
  240. IN PUNICODE_STRING ServiceKeyName OPTIONAL
  241. );
  242. BOOLEAN
  243. PiCompareGuid(
  244. CONST GUID *Guid1,
  245. CONST GUID *Guid2
  246. );
  247. NTSTATUS
  248. PiGetDeviceRegistryProperty(
  249. IN PDEVICE_OBJECT DeviceObject,
  250. IN ULONG ValueType,
  251. IN PWSTR ValueName,
  252. IN PWSTR KeyName,
  253. OUT PVOID Buffer,
  254. IN OUT PULONG BufferLength
  255. );
  256. VOID
  257. PpInitializeDeviceReferenceTable(
  258. VOID
  259. );
  260. PVOID
  261. NTAPI
  262. PiAllocateGenericTableEntry (
  263. PRTL_GENERIC_TABLE Table,
  264. CLONG ByteSize
  265. );
  266. VOID
  267. NTAPI
  268. PiFreeGenericTableEntry (
  269. PRTL_GENERIC_TABLE Table,
  270. PVOID Buffer
  271. );
  272. VOID
  273. PpRemoveDeviceActionRequests(
  274. IN PDEVICE_OBJECT DeviceObject
  275. );
  276. typedef struct _SYSTEM_HIVE_LIMITS {
  277. ULONG Low;
  278. ULONG High;
  279. } SYSTEM_HIVE_LIMITS, *PSYSTEM_HIVE_LIMITS;
  280. VOID
  281. PpSystemHiveLimitCallback(
  282. PSYSTEM_HIVE_LIMITS HiveLimits,
  283. ULONG Level
  284. );
  285. extern SYSTEM_HIVE_LIMITS PpSystemHiveLimits;
  286. extern BOOLEAN PpSystemHiveTooLarge;
  287. extern BOOLEAN PpCallerInitializesRequestTable;
  288. VOID
  289. PpLogEvent(
  290. IN PUNICODE_STRING InsertionString1,
  291. IN PUNICODE_STRING InsertionString2,
  292. IN NTSTATUS Status,
  293. IN PVOID DumpData,
  294. IN ULONG DumpDataSize
  295. );
  296. NTSTATUS
  297. PpIrpQueryDeviceText(
  298. IN PDEVICE_OBJECT DeviceObject,
  299. IN DEVICE_TEXT_TYPE DeviceTextType,
  300. IN LCID POINTER_ALIGNMENT LocaleId,
  301. OUT PWCHAR *Description
  302. );
  303. #define PpQueryDeviceDescription(dn, desc) PpIrpQueryDeviceText((dn)->PhysicalDeviceObject, DeviceTextDescription, PsDefaultSystemLocaleId, desc)
  304. #define PpQueryDeviceLocationInformation(dn, loc) PpIrpQueryDeviceText((dn)->PhysicalDeviceObject, DeviceTextLocationInformation, PsDefaultSystemLocaleId, loc)
  305. NTSTATUS
  306. PpIrpQueryCapabilities(
  307. IN PDEVICE_OBJECT DeviceObject,
  308. OUT PDEVICE_CAPABILITIES Capabilities
  309. );
  310. NTSTATUS
  311. PpIrpQueryResourceRequirements(
  312. IN PDEVICE_OBJECT DeviceObject,
  313. OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements
  314. );
  315. NTSTATUS
  316. PpIrpQueryID(
  317. IN PDEVICE_OBJECT DeviceObject,
  318. IN BUS_QUERY_ID_TYPE IDType,
  319. OUT PWCHAR *ID
  320. );
  321. NTSTATUS
  322. PpQueryID(
  323. IN PDEVICE_NODE DeviceNode,
  324. IN BUS_QUERY_ID_TYPE IDType,
  325. OUT PWCHAR *ID,
  326. OUT PULONG IDLength
  327. );
  328. NTSTATUS
  329. PpQueryDeviceID(
  330. IN PDEVICE_NODE DeviceNode,
  331. OUT PWCHAR *BusID,
  332. OUT PWCHAR *DeviceID
  333. );
  334. #define PpQueryInstanceID(dn, id, l) PpQueryID(dn, BusQueryInstanceID, id, l)
  335. #define PpQueryHardwareIDs(dn, id, l) PpQueryID(dn, BusQueryHardwareIDs, id, l)
  336. #define PpQueryCompatibleIDs(dn, id, l) PpQueryID(dn, BusQueryCompatibleIDs, id, l)
  337. #define PpQuerySerialNumber(dn, id) PpIrpQueryID((dn)->PhysicalDeviceObject, BusQueryDeviceSerialNumber, id)
  338. NTSTATUS
  339. PpIrpQueryBusInformation(
  340. IN PDEVICE_OBJECT DeviceObject,
  341. OUT PPNP_BUS_INFORMATION *BusInfo
  342. );
  343. NTSTATUS
  344. PpQueryBusInformation(
  345. IN PDEVICE_NODE DeviceNode
  346. );
  347. NTSTATUS
  348. PpSaveDeviceCapabilities (
  349. IN PDEVICE_NODE DeviceNode,
  350. IN PDEVICE_CAPABILITIES Capabilities
  351. );
  352. NTSTATUS
  353. PpBusTypeGuidInitialize(
  354. VOID
  355. );
  356. USHORT
  357. PpBusTypeGuidGetIndex(
  358. IN LPGUID BusTypeGuid
  359. );
  360. NTSTATUS
  361. PpBusTypeGuidGet(
  362. IN USHORT Index,
  363. IN OUT LPGUID BusTypeGuid
  364. );
  365. extern BOOLEAN PpDisableFirmwareMapper;
  366. #if defined(_X86_)
  367. NTSTATUS
  368. PnPBiosMapper(
  369. VOID
  370. );
  371. NTSTATUS
  372. PnPBiosGetBiosInfo(
  373. OUT PVOID *BiosInfo,
  374. OUT ULONG *BiosInfoLength
  375. );
  376. VOID
  377. PnPBiosShutdownSystem(
  378. IN ULONG Phase,
  379. IN OUT PVOID *Context
  380. );
  381. NTSTATUS
  382. PnPBiosInitializePnPBios(
  383. VOID
  384. );
  385. #endif
  386. //
  387. // Firmware mapper external declarations.
  388. //
  389. BOOLEAN
  390. PipIsFirmwareMapperDevicePresent(
  391. IN HANDLE KeyHandle
  392. );
  393. VOID
  394. MapperProcessFirmwareTree(
  395. IN BOOLEAN OnlyProcessSerialPorts
  396. );
  397. VOID
  398. MapperConstructRootEnumTree(
  399. IN BOOLEAN CreatePhantomDevices
  400. );
  401. VOID
  402. MapperFreeList(
  403. VOID
  404. );
  405. VOID
  406. MapperPhantomizeDetectedComPorts(
  407. VOID
  408. );
  409. //
  410. // True iff textmode setup.
  411. //
  412. extern BOOLEAN ExpInTextModeSetup;
  413. VOID
  414. PpMarkDeviceStackStartPending(
  415. IN PDEVICE_OBJECT DeviceObject,
  416. IN BOOLEAN Set
  417. );
  418. NTSTATUS
  419. PiControlMakeUserModeCallersCopy(
  420. PVOID *Destination,
  421. PVOID Src,
  422. ULONG Length,
  423. ULONG Alignment,
  424. KPROCESSOR_MODE CallerMode,
  425. BOOLEAN AllocateDestination
  426. );
  427. #if DBG
  428. LONG
  429. PiControlExceptionFilter(
  430. IN PEXCEPTION_POINTERS ExceptionPointers
  431. );
  432. #else
  433. #define PiControlExceptionFilter(a) EXCEPTION_EXECUTE_HANDLER
  434. #endif
  435. #endif // _KERNEL_PNPI_