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.

711 lines
28 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. vfmessage.c
  5. Abstract:
  6. This module contains the verifier error lists, along with the text and flags
  7. associated with each error.
  8. Author:
  9. Adrian J. Oney (adriao) 20-Apr-1998
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. AdriaO 02/10/2000 - Seperated out from ntos\io\ioassert.c
  14. --*/
  15. #include "vfdef.h"
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGEVRFY, VfMessageRetrieveInternalTable)
  18. #pragma alloc_text(PAGEVRFY, VfMessageRetrieveErrorData)
  19. #endif
  20. #ifdef ALLOC_DATA_PRAGMA
  21. #pragma const_seg("PAGEVRFC")
  22. #endif
  23. //
  24. // These are the general "classifications" of driver errors, along with the
  25. // default flags that will be applied the first time this is hit.
  26. //
  27. // ViMessageClassFailDriverInField -
  28. // Bugs in this class are severe enough that the driver should be
  29. // immediately removed from a running production machine.
  30. //
  31. // ViMessageClassFailDriverLogo -
  32. // Bugs of this class are severe enough for WHQL to deny a logo for the
  33. // failing whateverware.
  34. //
  35. // ViMessageClassFailDriverUnderDebugger -
  36. // Bugs of this class stop the machine only if it is running under a
  37. // kernel debugger.
  38. //
  39. // ViMessageClassDriverWarning -
  40. // Anything in this class will beep but continue without breaking in.
  41. //
  42. // ViMessageClassPostponedDriverIssue -
  43. // Anything in this class will merely print and continue.
  44. //
  45. // ViMessageClassCoreError -
  46. // Issue in a core component (kernel or hal)
  47. //
  48. const VFMESSAGE_CLASS ViMessageClassFailDriverInField = {
  49. VFM_FLAG_BEEP | VFM_LOGO_FAILURE | VFM_DEPLOYMENT_FAILURE,
  50. "WDM DRIVER ERROR"
  51. };
  52. // VFM_DEPLOYMENT_FAILURE is set here because we don't yet have a "logo" mode
  53. const VFMESSAGE_CLASS ViMessageClassFailDriverLogo = {
  54. VFM_FLAG_BEEP | VFM_LOGO_FAILURE | VFM_DEPLOYMENT_FAILURE,
  55. "WDM DRIVER ERROR"
  56. };
  57. const VFMESSAGE_CLASS ViMessageClassFailDriverUnderDebugger = {
  58. VFM_FLAG_BEEP,
  59. "WDM DRIVER ERROR"
  60. };
  61. const VFMESSAGE_CLASS ViMessageClassDriverWarning = {
  62. VFM_FLAG_BEEP | VFM_FLAG_ZAPPED,
  63. "WDM DRIVER WARNING"
  64. };
  65. const VFMESSAGE_CLASS ViMessageClassPostponedDriverIssue = {
  66. VFM_FLAG_ZAPPED,
  67. "POSTPONED WDM DRIVER BUG"
  68. };
  69. const VFMESSAGE_CLASS ViMessageClassCoreError = {
  70. VFM_FLAG_BEEP,
  71. "CORE DRIVER ERROR"
  72. };
  73. //
  74. // This table contains things we've postponed.
  75. //
  76. const VFMESSAGE_OVERRIDE ViMessageIoVerifierOverrides[] = {
  77. //
  78. // These exist because verifier.exe cannot specify kernels or hals. We still
  79. // want a mechanism to allow complaints.
  80. //
  81. { VIMESSAGE_ALL_IDS, "HAL.DLL", &ViMessageClassCoreError },
  82. { VIMESSAGE_ALL_IDS, "NTOSKRNL.EXE", &ViMessageClassCoreError },
  83. { VIMESSAGE_ALL_IDS, "NTKRNLMP.EXE", &ViMessageClassCoreError },
  84. { VIMESSAGE_ALL_IDS, "NTKRNLPA.EXE", &ViMessageClassCoreError },
  85. { VIMESSAGE_ALL_IDS, "NTKRPAMP.EXE", &ViMessageClassCoreError },
  86. //
  87. // ADRIAO BUGBUG 08/10/1999 -
  88. // NDIS doesn't call the shutdown handlers at power-off because many are
  89. // unstable and that adds seconds to shutdown. This is an unsafe design as
  90. // the miniport, which owns an IRQ, may find it's ports drop out from under
  91. // it when the *parent* powers off.
  92. //
  93. { DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED, "NDIS.SYS",
  94. &ViMessageClassPostponedDriverIssue },
  95. //
  96. // ADRIAO BUGBUG 08/10/1999 -
  97. // ACPI and PCI have to work together to handle wait-wake. In the
  98. // current design, ACPI.SYS gets an interface and does all the work itself.
  99. // The proper design should move the queueing to PCI, or tell PCI to leave
  100. // wait-wake IRPs alone for the given device. Cutting off any other bus
  101. // filters is a bad design.
  102. //
  103. { DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED, "ACPI.SYS",
  104. &ViMessageClassPostponedDriverIssue },
  105. //
  106. // ADRIAO BUGBUG 08/21/1999 -
  107. // SCSIPORT doesn't forward S0 Irps if the system is already in S0.
  108. // Consider if a PDO succeeds a Query-S1 IRP and then waits for either a
  109. // Set to S1, a new Query, or a Set to S0 meaning no transition will take
  110. // place after all. A filter between SCSIPORT and the PDO could fail the
  111. // Query-S1 on the way up. SCSIPORT knows the system has decided to stay in
  112. // S0, but it cuts such knowledge off from the PDO. Luckily today's list of
  113. // likely PDO's don't have such logic though. PeterWie has postponed this
  114. // one till NT 5.1
  115. //
  116. { DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED, "SCSIPORT.SYS",
  117. &ViMessageClassPostponedDriverIssue }
  118. };
  119. #ifdef ALLOC_DATA_PRAGMA
  120. #pragma data_seg("PAGEVRFD")
  121. #endif
  122. //
  123. // This message is used if someone provides bad data for a verifier assert. The
  124. // message Id is VIMESSAGE_ALL_IDS - a nice reserved Id that'll match with
  125. // nothing except possibly a generic class override.
  126. //
  127. VFMESSAGE_TEMPLATE ViMessageBogusTemplate = { VIMESSAGE_ALL_IDS, NULL, 0, NULL, NULL };
  128. //
  129. // Here begins internal verifier error tables. The current algorithm for
  130. // identifying errors expects all messages in a table to be numbered
  131. // consecutively. If a check is later removed the algorithm may need to be
  132. // replaced with something akin to a binary search.
  133. //
  134. //
  135. // This is the table of IO verifier error messages.
  136. //
  137. VFMESSAGE_TEMPLATE ViMessageIoVerifierTemplates[DCERROR_MAXIMUM - DCERROR_UNSPECIFIED] = {
  138. { DCERROR_UNSPECIFIED, NULL, 0, NULL, NULL },
  139. { DCERROR_DELETE_WHILE_ATTACHED, &ViMessageClassFailDriverInField, 0,
  140. NULL,
  141. "A device is deleting itself while there is another device beneath it in "
  142. "the driver stack. This may be because the caller has forgotten to call "
  143. "IoDetachDevice first, or the lower driver may have incorrectly deleted "
  144. "itself." },
  145. { DCERROR_DETACH_NOT_ATTACHED, &ViMessageClassFailDriverInField, 0,
  146. NULL,
  147. "Driver has attempted to detach from device object %DevObj, which is not "
  148. "attached to anything. This may occur if detach was called twice on the "
  149. "same device object." },
  150. { DCERROR_CANCELROUTINE_FORWARDED, &ViMessageClassFailDriverInField, 0,
  151. NULL,
  152. "A driver has called IoCallDriver without setting the CancelRoutine in "
  153. "the Irp to NULL (Irp = %Irp )." },
  154. { DCERROR_NULL_DEVOBJ_FORWARDED, &ViMessageClassFailDriverInField, 0,
  155. NULL,
  156. "Caller has passed in NULL as a DeviceObject. This is fatal (Irp = %Irp )."
  157. },
  158. { DCERROR_QUEUED_IRP_FORWARDED, &ViMessageClassFailDriverInField, 0,
  159. NULL,
  160. "Caller is forwarding an IRP that is currently queued beneath it! The "
  161. "code handling IRPs returning STATUS_PENDING in this driver appears to "
  162. "be broken (Irp = %Irp )." },
  163. { DCERROR_NEXTIRPSP_DIRTY, &ViMessageClassFailDriverInField, 0,
  164. NULL,
  165. "Caller has incorrectly forwarded an IRP (control field not zerod). The "
  166. "driver should use IoCopyCurrentIrpStackLocationToNext or "
  167. "IoSkipCurrentIrpStackLocation. (Irp = %Irp )" },
  168. { DCERROR_IRPSP_COPIED, &ViMessageClassFailDriverInField, 0,
  169. NULL,
  170. "Caller has manually copied the stack and has inadvertantly copied the "
  171. "upper layer's completion routine. Please use "
  172. "IoCopyCurrentIrpStackLocationToNext. (Irp = %Irp )." },
  173. { DCERROR_INSUFFICIENT_STACK_LOCATIONS, &ViMessageClassFailDriverInField, 0,
  174. NULL,
  175. "This IRP is about to run out of stack locations. Someone may have "
  176. "forwarded this IRP from another stack (Irp = %Irp )." },
  177. { DCERROR_QUEUED_IRP_COMPLETED, &ViMessageClassFailDriverInField, 0,
  178. NULL,
  179. "Caller is completing an IRP that is currently queued beneath it! The "
  180. "code handling IRPs returning STATUS_PENDING in this driver appears to be "
  181. "broken. (Irp = %Irp )" },
  182. { DCERROR_FREE_OF_INUSE_TRACKED_IRP, &ViMessageClassFailDriverInField, 0,
  183. NULL,
  184. "Caller of IoFreeIrp is freeing an IRP that is still in use! (Original "
  185. "Irp = %Irp1, Irp in usage is %Irp2 )" },
  186. { DCERROR_FREE_OF_INUSE_IRP, &ViMessageClassFailDriverInField, 0,
  187. NULL,
  188. "Caller of IoFreeIrp is freeing an IRP that is still in use! (Irp = %Irp )"
  189. },
  190. { DCERROR_FREE_OF_THREADED_IRP, &ViMessageClassFailDriverInField, 0,
  191. NULL,
  192. "Caller of IoFreeIrp is freeing an IRP that is still enqueued against a "
  193. "thread! (Irp = %Irp )" },
  194. { DCERROR_REINIT_OF_ALLOCATED_IRP_WITH_QUOTA, &ViMessageClassFailDriverInField, 0,
  195. NULL,
  196. "Caller of IoInitializeIrp has passed an IRP that was allocated with "
  197. "IoAllocateIrp. This is illegal and unneccessary, and has caused a quota "
  198. "leak. Check the documentation for IoReuseIrp if this IRP is being "
  199. "recycled." },
  200. { DCERROR_PNP_IRP_BAD_INITIAL_STATUS, &ViMessageClassFailDriverLogo, 0,
  201. NULL,
  202. "Any PNP IRP must have status initialized to STATUS_NOT_SUPPORTED "
  203. "(Irp = %Irp )." },
  204. { DCERROR_POWER_IRP_BAD_INITIAL_STATUS, &ViMessageClassFailDriverLogo, 0,
  205. NULL,
  206. "Any Power IRP must have status initialized to STATUS_NOT_SUPPORTED "
  207. "(Irp = %Irp )." },
  208. { DCERROR_WMI_IRP_BAD_INITIAL_STATUS, &ViMessageClassFailDriverLogo, 0,
  209. NULL,
  210. "Any WMI IRP must have status initialized to STATUS_NOT_SUPPORTED "
  211. "(Irp = %Irp )." },
  212. { DCERROR_SKIPPED_DEVICE_OBJECT, &ViMessageClassFailDriverLogo, 0,
  213. NULL,
  214. "Caller has forwarded an Irp while skipping a device object in the stack. "
  215. "The caller is probably sending IRPs to the PDO instead of to the device "
  216. "returned by IoAttachDeviceToDeviceStack (Irp = %Irp )." },
  217. { DCERROR_BOGUS_FUNC_TRASHED, &ViMessageClassFailDriverLogo, 0,
  218. NULL,
  219. "Caller has trashed or has not properly copied IRP's stack (Irp = %Irp )."
  220. },
  221. { DCERROR_BOGUS_STATUS_TRASHED, &ViMessageClassFailDriverLogo, 0,
  222. NULL,
  223. "Caller has changed the status field of an IRP it does not understand "
  224. "(Irp = %Irp )." },
  225. { DCERROR_BOGUS_INFO_TRASHED, &ViMessageClassFailDriverLogo, 0,
  226. NULL,
  227. "Caller has changed the information field of an IRP it does not "
  228. "understand (Irp = %Irp )." },
  229. { DCERROR_PNP_FAILURE_FORWARDED, &ViMessageClassFailDriverLogo, 0,
  230. NULL,
  231. "Non-successful non-STATUS_NOT_SUPPORTED IRP status for IRP_MJ_PNP is "
  232. "being passed down stack (Irp = %Irp ). Failed PNP IRPs must be completed."
  233. },
  234. { DCERROR_PNP_IRP_STATUS_RESET, &ViMessageClassFailDriverLogo, 0,
  235. NULL,
  236. "Previously set IRP_MJ_PNP status has been converted to "
  237. "STATUS_NOT_SUPPORTED. This failure status is reserved for use of the OS "
  238. "- drivers cannot fail a PnP IRP with this value. (Irp = %Irp )." },
  239. { DCERROR_PNP_IRP_NEEDS_HANDLING, &ViMessageClassFailDriverUnderDebugger, 0,
  240. NULL,
  241. "The driver has not handled a required IRP. The driver must update the "
  242. "status of the IRP to indicate whether it's been handled or not. "
  243. "(Irp = %Irp )." },
  244. { DCERROR_PNP_IRP_HANDS_OFF, &ViMessageClassFailDriverUnderDebugger, 0,
  245. NULL,
  246. "The driver has responded to an IRP that is that is reserved for other "
  247. "device objects elsewhere in the stack. (Irp = %Irp )" },
  248. { DCERROR_POWER_FAILURE_FORWARDED, &ViMessageClassFailDriverLogo, 0,
  249. NULL,
  250. "Non-successful non-STATUS_NOT_SUPPORTED IRP status for IRP_MJ_POWER is "
  251. "being passed down stack (Irp = %Irp ). Failed POWER IRPs must be "
  252. "completed." },
  253. { DCERROR_POWER_IRP_STATUS_RESET, &ViMessageClassFailDriverUnderDebugger, 0,
  254. NULL,
  255. "Previously set IRP_MJ_POWER status has been converted to "
  256. "STATUS_NOT_SUPPORTED. This failure status is reserved for use of the OS "
  257. "- drivers cannot fail a Power IRP with this value (Irp = %Irp )." },
  258. { DCERROR_INVALID_STATUS, &ViMessageClassFailDriverUnderDebugger, 0,
  259. NULL,
  260. "Driver has returned a suspicious status. This is probably due to an "
  261. "uninitiaized variable bug in the driver. (Irp = %Irp )" },
  262. { DCERROR_UNNECCESSARY_COPY, &ViMessageClassDriverWarning, 0,
  263. NULL,
  264. "Caller has copied the Irp stack but not set a completion routine. "
  265. "This is inefficient, use IoSkipCurrentIrpStackLocation instead "
  266. "(Irp = %Irp )." },
  267. { DCERROR_SHOULDVE_DETACHED, &ViMessageClassFailDriverInField, 0,
  268. NULL,
  269. "An IRP dispatch handler has not properly detached from the stack below "
  270. "it upon receiving a remove IRP. DeviceObject = %DevObj - Dispatch = "
  271. "%Routine - Irp = %Snapshot" },
  272. { DCERROR_SHOULDVE_DELETED, &ViMessageClassFailDriverInField, 0,
  273. NULL,
  274. "An IRP dispatch handler has not properly deleted it's device object upon "
  275. "receiving a remove IRP. DeviceObject = %DevObj - Dispatch = %Routine - "
  276. "Irp = %Snapshot" },
  277. { DCERROR_MISSING_DISPATCH_FUNCTION, &ViMessageClassFailDriverLogo, 0,
  278. NULL,
  279. "This driver has not filled out a dispatch routine for a required IRP "
  280. "major function (Irp = %Irp )." },
  281. { DCERROR_WMI_IRP_NOT_FORWARDED, &ViMessageClassFailDriverLogo, 0,
  282. NULL,
  283. "IRP_MJ_SYSTEM_CONTROL has been completed by someone other than the "
  284. "ProviderId. This IRP should either have been completed earlier or "
  285. "should have been passed down (Irp = %Irp ). The IRP was targetted at "
  286. "DeviceObject %DevObj" },
  287. { DCERROR_DELETED_PRESENT_PDO, &ViMessageClassFailDriverInField, 0,
  288. NULL,
  289. "An IRP dispatch handler for a PDO has deleted it's device object, but "
  290. "the hardware has not been reported as missing in a bus relations query. "
  291. "DeviceObject = %DevObj - Dispatch = %Routine - Irp = %Snapshot " },
  292. { DCERROR_BUS_FILTER_ERRONEOUSLY_DETACHED, &ViMessageClassFailDriverInField, 0,
  293. NULL,
  294. "A Bus Filter's IRP dispatch handler has detached upon receiving a remove "
  295. "IRP when the PDO is still alive. Bus Filters must clean up in "
  296. "FastIoDetach callbacks. DeviceObject = %DevObj - Dispatch = %Routine - "
  297. "Irp = %Snapshot" },
  298. { DCERROR_BUS_FILTER_ERRONEOUSLY_DELETED, &ViMessageClassFailDriverInField, 0,
  299. NULL,
  300. "An IRP dispatch handler for a bus filter has deleted it's device object, "
  301. "but the PDO is still present! Bus filters must clean up in FastIoDetach "
  302. "callbacks. DeviceObject = %DevObj - Dispatch = %Routine - Irp = %Snapshot" },
  303. { DCERROR_INCONSISTANT_STATUS, &ViMessageClassFailDriverInField, 0,
  304. NULL,
  305. "An IRP dispatch handler ( %Routine ) has returned a status that is "
  306. "inconsistent with the Irp's IoStatus.Status field. ( Irp = %Snapshot - "
  307. "Irp->IoStatus.Status = %Status1 - returned = %Status2 )" },
  308. { DCERROR_UNINITIALIZED_STATUS, &ViMessageClassFailDriverLogo, 0,
  309. NULL,
  310. "An IRP dispatch handler has returned a status that is illegal "
  311. "(0xFFFFFFFF). This is probably due to an uninitialized stack variable. "
  312. "Please do an ln on address %lx and file a bug. (Irp = %Snapshot )" },
  313. { DCERROR_IRP_RETURNED_WITHOUT_COMPLETION, &ViMessageClassFailDriverInField, 0,
  314. NULL,
  315. "An IRP dispatch handler has returned without passing down or completing "
  316. "this Irp or someone forgot to return STATUS_PENDING. (Irp = %Snapshot )." },
  317. { DCERROR_COMPLETION_ROUTINE_PAGABLE, &ViMessageClassFailDriverInField, 0,
  318. NULL,
  319. "IRP completion routines must be in nonpagable code, and this one is not: "
  320. "%Routine. (Irp = %Irp )" },
  321. { DCERROR_PENDING_BIT_NOT_MIGRATED, &ViMessageClassFailDriverUnderDebugger, 0,
  322. NULL,
  323. "A driver's completion routine ( %Routine ) has not marked the IRP "
  324. "pending if the PendingReturned field was set in the IRP passed to it. "
  325. "This may cause the OS to hang, especially if an error is returned by the "
  326. " stack. (Irp = %Irp )" },
  327. { DCERROR_CANCELROUTINE_ON_FORWARDED_IRP, &ViMessageClassFailDriverInField, 0,
  328. NULL,
  329. "A cancel routine has been set for an IRP that is currently being "
  330. "processed by drivers lower in the stack, possibly stomping their cancel "
  331. "routine (Irp = %Irp, Routine=%Routine )." },
  332. { DCERROR_PNP_IRP_NEEDS_PDO_HANDLING, &ViMessageClassFailDriverUnderDebugger, 0,
  333. NULL,
  334. "PDO has not responded to a required IRP (Irp = %Irp )" },
  335. { DCERROR_TARGET_RELATION_LIST_EMPTY, &ViMessageClassFailDriverLogo, 0,
  336. NULL,
  337. "PDO has forgotten to fill out the device relation list with the PDO for "
  338. "the TargetDeviceRelation query (Irp = %Irp )" },
  339. { DCERROR_TARGET_RELATION_NEEDS_REF, &ViMessageClassFailDriverInField, 0,
  340. NULL,
  341. "The code implementing the TargetDeviceRelation query has not called "
  342. "ObReferenceObject on the PDO (Irp = %Irp )." },
  343. { DCERROR_BOGUS_PNP_IRP_COMPLETED, &ViMessageClassFailDriverLogo, 0,
  344. NULL,
  345. "Caller has completed a IRP_MJ_PNP it didn't understand instead of "
  346. "passing it down (Irp = %Irp )." },
  347. { DCERROR_SUCCESSFUL_PNP_IRP_NOT_FORWARDED, &ViMessageClassFailDriverLogo, 0,
  348. NULL,
  349. "Caller has completed successful IRP_MJ_PNP instead of passing it down "
  350. "(Irp = %Irp )." },
  351. { DCERROR_UNTOUCHED_PNP_IRP_NOT_FORWARDED, &ViMessageClassFailDriverLogo, 0,
  352. NULL,
  353. "Caller has completed untouched IRP_MJ_PNP (instead of passing the irp "
  354. "down) or non-PDO has failed the irp using illegal value of "
  355. "STATUS_NOT_SUPPORTED. (Irp = %Irp )." },
  356. { DCERROR_BOGUS_POWER_IRP_COMPLETED, &ViMessageClassFailDriverLogo, 0,
  357. NULL,
  358. "Caller has completed a IRP_MJ_POWER it didn't understand instead of "
  359. "passing it down (Irp = %Irp )." },
  360. { DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED, &ViMessageClassFailDriverInField, 0,
  361. NULL,
  362. "Caller has completed successful IRP_MJ_POWER instead of passing it down "
  363. "(Irp = %Irp )." },
  364. { DCERROR_UNTOUCHED_POWER_IRP_NOT_FORWARDED, &ViMessageClassFailDriverLogo, 0,
  365. NULL,
  366. "Caller has completed untouched IRP_MJ_POWER (instead of passing the irp "
  367. "down) or non-PDO has failed the irp using illegal value of "
  368. "STATUS_NOT_SUPPORTED. (Irp = %Irp )." },
  369. { DCERROR_PNP_QUERY_CAP_BAD_VERSION, &ViMessageClassFailDriverLogo, 0,
  370. NULL,
  371. "The version field of the query capabilities structure in a query "
  372. "capabilities IRP was not properly initialized. (Irp = %Irp )." },
  373. { DCERROR_PNP_QUERY_CAP_BAD_SIZE, &ViMessageClassFailDriverLogo, 0,
  374. NULL,
  375. "The size field of the query capabilities structure in a query "
  376. "capabilities IRP was not properly initialized. (Irp = %Irp )." },
  377. { DCERROR_PNP_QUERY_CAP_BAD_ADDRESS, &ViMessageClassFailDriverLogo, 0,
  378. NULL,
  379. "The address field of the query capabilities structure in a query "
  380. "capabilities IRP was not properly initialized to -1. (Irp = %Irp )." },
  381. { DCERROR_PNP_QUERY_CAP_BAD_UI_NUM, &ViMessageClassFailDriverLogo, 0,
  382. NULL,
  383. "The UI Number field of the query capabilities structure in a query "
  384. "capabilities IRP was not properly initialized to -1. (Irp = %Irp )." },
  385. { DCERROR_RESTRICTED_IRP, &ViMessageClassFailDriverInField, 0,
  386. NULL,
  387. "A driver has sent an IRP that is restricted for system use only. "
  388. "(Irp = %Irp )." },
  389. { DCERROR_REINIT_OF_ALLOCATED_IRP_WITHOUT_QUOTA, &ViMessageClassDriverWarning, 0,
  390. NULL,
  391. "Caller of IoInitializeIrp has passed an IRP that was allocated with "
  392. "IoAllocateIrp. This is illegal, unneccessary, and negatively impacts "
  393. "performace in normal use. Check the documentation for IoReuseIrp if "
  394. "this IRP is being recycled." },
  395. { DCERROR_UNFORWARDED_IRP_COMPLETED, &ViMessageClassDriverWarning, 0,
  396. NULL,
  397. "The caller of IoCompleteRequest is completing an IRP that has never "
  398. "been forwarded via a call to IoCallDriver or PoCallDriver. This may "
  399. "be a bug. (Irp = %Irp )." },
  400. { DCERROR_DISPATCH_CALLED_AT_BAD_IRQL, &ViMessageClassFailDriverInField, 0,
  401. NULL,
  402. "A driver has forwarded an IRP at an IRQL that is illegal for this major"
  403. " code. "
  404. "(Irp = %Irp )." },
  405. { DCERROR_BOGUS_MINOR_STATUS_TRASHED, &ViMessageClassFailDriverLogo, 0,
  406. NULL,
  407. "Caller has changed the status field of an IRP it does not understand "
  408. "(Irp = %Irp )." },
  409. { DCERROR_CANCELROUTINE_AFTER_COMPLETION, &ViMessageClassFailDriverInField, 0,
  410. NULL,
  411. "A driver has completed an IRP without setting the CancelRoutine in "
  412. "the Irp to NULL (Irp = %Irp )." },
  413. { DCERROR_PENDING_RETURNED_NOT_MARKED, &ViMessageClassFailDriverUnderDebugger, 0,
  414. NULL,
  415. "A driver has returned STATUS_PENDING but did not mark the IRP pending "
  416. "via a call to IoMarkIrpPending (Irp = %Irp)." },
  417. { DCERROR_PENDING_MARKED_NOT_RETURNED, &ViMessageClassFailDriverUnderDebugger, 0,
  418. NULL,
  419. "A driver has marked an IRP pending but didn't return STATUS_PENDING. "
  420. "(Irp = %Snapshot)." },
  421. { DCERROR_POWER_PAGABLE_NOT_INHERITED, &ViMessageClassFailDriverInField, 0,
  422. NULL,
  423. "A driver has not inherited the DO_POWER_PAGABLE bit from the stack it "
  424. "has attached to (DevObj = %DevObj)." },
  425. { DCERROR_DOUBLE_DELETION, &ViMessageClassFailDriverInField, 0,
  426. NULL,
  427. "A driver is attempting to delete a device object that has already been "
  428. "deleted via a prior call to IoDeleteDevice." },
  429. { DCERROR_DETACHED_IN_SURPRISE_REMOVAL, &ViMessageClassFailDriverInField, 0,
  430. NULL,
  431. "A driver has detached it's device object during a surprise remove IRP "
  432. "(Irp = %Irp DevObj = %DevObj)." },
  433. { DCERROR_DELETED_IN_SURPRISE_REMOVAL, &ViMessageClassFailDriverInField, 0,
  434. NULL,
  435. "A driver has deleted it's device object during a surprise remove IRP "
  436. "(Irp = %Irp DevObj = %DevObj)." },
  437. { DCERROR_DO_INITIALIZING_NOT_CLEARED, &ViMessageClassFailDriverInField, 0,
  438. NULL,
  439. "A driver has failed to clear the DO_DEVICE_INITIALIZING flag at the "
  440. "end of AddDevice (DevObj = %DevObj)." },
  441. { DCERROR_DO_FLAG_NOT_COPIED, &ViMessageClassFailDriverInField, 0,
  442. NULL,
  443. "A driver has not copied either the DO_BUFFERED_IO or the DO_DIRECT_IO "
  444. "flag from the device object it is attaching to (DevObj = %DevObj)." },
  445. { DCERROR_INCONSISTANT_DO_FLAGS, &ViMessageClassFailDriverInField, 0,
  446. NULL,
  447. "A driver has set both the DO_BUFFERED_IO and the DO_DIRECT_IO flags. "
  448. "These flags are mutually exclusive (DevObj = %DevObj)." },
  449. { DCERROR_DEVICE_TYPE_NOT_COPIED, &ViMessageClassFailDriverInField, 0,
  450. NULL,
  451. "A driver has failed to copy the DeviceType field from the device object "
  452. "it is attaching to (DevObj = %DevObj)." },
  453. { DCERROR_NON_FAILABLE_IRP, &ViMessageClassFailDriverInField, 0,
  454. NULL,
  455. "A driver has failed an IRP that cannot legally be failed IRP "
  456. "(Irp = %Irp)." },
  457. { DCERROR_NON_PDO_RETURNED_IN_RELATION, &ViMessageClassFailDriverInField, 0,
  458. NULL,
  459. "A driver has added a device object that is not a PDO to a device "
  460. "relations query (Irp = %Irp, DevObj = %DevObj)." },
  461. { DCERROR_DUPLICATE_ENUMERATION, &ViMessageClassFailDriverLogo, 0,
  462. NULL,
  463. "A driver has enumerated two child PDO's that returned identical Device "
  464. "ID's (DevObj1 = %DevObj1 , DevObj2 = %DevObj2 )." },
  465. { DCERROR_FILE_IO_AT_BAD_IRQL, &ViMessageClassFailDriverInField, 0,
  466. NULL,
  467. "A driver has mistakenly called a file I/O function at an IRQL other "
  468. "than PASSIVE_LEVEL." },
  469. { DCERROR_MISHANDLED_TARGET_DEVICE_RELATIONS, &ViMessageClassFailDriverInField, 0,
  470. NULL,
  471. "A driver has succeeded IRP_MJ_PNP.IRP_MN_QUERY_DEVICE_RELATIONS(TargetRelations) "
  472. "but didn't properly fill out the request or forward the IRP to the "
  473. "underlying hardware stack (DevObj = %DevObj)." },
  474. { DCERROR_PENDING_RETURNED_NOT_MARKED_2, &ViMessageClassFailDriverUnderDebugger, 0,
  475. NULL,
  476. "A driver has returned STATUS_PENDING but did not mark the IRP pending "
  477. "via a call to IoMarkIrpPending (Irp = %Snapshot)." },
  478. { DCERROR_DDI_REQUIRES_PDO, &ViMessageClassFailDriverInField, 0,
  479. NULL,
  480. "A driver has passed an invalid device object to a function that requires "
  481. "a PDO (DevObj = %DevObj)." }
  482. };
  483. //
  484. // Here is the table collecting together all internal tables.
  485. //
  486. VFMESSAGE_TEMPLATE_TABLE ViMessageBuiltInTables[] = {
  487. { VFMESSAGE_TABLE_IOVERIFIER,
  488. DRIVER_VERIFIER_IOMANAGER_VIOLATION,
  489. ViMessageIoVerifierTemplates,
  490. ARRAY_COUNT(ViMessageIoVerifierTemplates),
  491. ViMessageIoVerifierOverrides,
  492. ARRAY_COUNT(ViMessageIoVerifierOverrides) }
  493. };
  494. VOID
  495. VfMessageRetrieveInternalTable(
  496. IN VFMESSAGE_TABLEID TableID,
  497. OUT PVFMESSAGE_TEMPLATE_TABLE *MessageTable
  498. )
  499. /*++
  500. Routine Description:
  501. This routine retrieves the appropriate error table using the passed in
  502. TableID.
  503. Arguments:
  504. TableID - Name of error table to use.
  505. MessageTable - Receives Table, NULL if no match is found.
  506. Return Value:
  507. None.
  508. --*/
  509. {
  510. PVFMESSAGE_TEMPLATE_TABLE errorTable;
  511. ULONG i;
  512. //
  513. // Assert we have valid Table IDs (0 is reserved)
  514. //
  515. ASSERT(TableID);
  516. //
  517. // Preinit for error.
  518. //
  519. errorTable = NULL;
  520. //
  521. // Find the appropriate template by searching the built-in tables
  522. //
  523. for (i=0; i<ARRAY_COUNT(ViMessageBuiltInTables); i++) {
  524. if (ViMessageBuiltInTables[i].TableID == TableID) {
  525. //
  526. // We found the appropriate table. Get out now.
  527. //
  528. errorTable = &ViMessageBuiltInTables[i];
  529. break;
  530. }
  531. }
  532. *MessageTable = errorTable;
  533. }
  534. VOID
  535. VfMessageRetrieveErrorData(
  536. IN PVFMESSAGE_TEMPLATE_TABLE MessageTable OPTIONAL,
  537. IN VFMESSAGE_ERRORID MessageID,
  538. IN PSTR AnsiDriverName,
  539. OUT ULONG *BugCheckMajor,
  540. OUT PCVFMESSAGE_CLASS *MessageClass,
  541. OUT PCSTR *MessageTextTemplate,
  542. OUT PULONG *TemplateFlags
  543. )
  544. /*++
  545. Routine Description:
  546. This routine takes a failure ID and retrieves the text template and the
  547. error class associated with it.
  548. Arguments:
  549. MessageTable - Message table to use.
  550. MessageID - Failure code (doubles as bugcheck minor).
  551. AnsiDriverName - Name of the driver that failed verification.
  552. BugCheckMajor - Receives bugcheck major code if applicable.
  553. MessageClass - Receives a pointer to a VFMESSAGE_CLASS structure
  554. that contains information on how to handle the error.
  555. MessageTextTemplate - Receives a pointer to the text associated with the
  556. failure code.
  557. TemplateFlags - Receives address of the assertion's control field,
  558. which can be used to suppress the assertion.
  559. Return Value:
  560. None.
  561. --*/
  562. {
  563. PVFMESSAGE_TEMPLATE errorTemplate;
  564. ULONG tableIndex, i;
  565. //
  566. // Assert we have a valid Message ID (0 is reserved)
  567. //
  568. ASSERT(MessageID);
  569. //
  570. // Preinit for error.
  571. //
  572. errorTemplate = NULL;
  573. //
  574. // If we have an error table, look for the specific error message.
  575. //
  576. if (ARGUMENT_PRESENT(MessageTable)) {
  577. //
  578. // Convert the ID to a table index.
  579. //
  580. tableIndex = MessageID - MessageTable->TemplateArray[0].MessageID;
  581. //
  582. // Retrieve the appropriate entry if it exists.
  583. //
  584. if (tableIndex < MessageTable->TemplateCount) {
  585. errorTemplate = &MessageTable->TemplateArray[tableIndex];
  586. //
  587. // Our "algorithm" currently expects table numbers to be sequential.
  588. //
  589. ASSERT(errorTemplate->MessageID == MessageID);
  590. }
  591. }
  592. if (!errorTemplate) {
  593. //
  594. // Bogus message or table index!
  595. //
  596. ASSERT(0);
  597. //
  598. // Give the engine something to chew on.
  599. //
  600. errorTemplate = &ViMessageBogusTemplate;
  601. }
  602. //
  603. // Return the appropriate data.
  604. //
  605. *MessageTextTemplate = errorTemplate->MessageText;
  606. *MessageClass = errorTemplate->MessageClass;
  607. *TemplateFlags = &errorTemplate->Flags;
  608. if (ARGUMENT_PRESENT(MessageTable)) {
  609. *BugCheckMajor = MessageTable->BugCheckMajor;
  610. //
  611. // Let the override table make any modifications to the error.
  612. //
  613. for(i=0; i<MessageTable->OverrideCount; i++) {
  614. if ((MessageTable->OverrideArray[i].MessageID == MessageID) ||
  615. (MessageTable->OverrideArray[i].MessageID == VIMESSAGE_ALL_IDS)) {
  616. if (!_stricmp(AnsiDriverName,
  617. MessageTable->OverrideArray[i].DriverName)) {
  618. *MessageClass = MessageTable->OverrideArray[i].ReplacementClass;
  619. }
  620. }
  621. }
  622. } else {
  623. //
  624. // Bleagh.
  625. //
  626. *BugCheckMajor = 0;
  627. }
  628. }