00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#include "iop.h"
00029
00030
#if (( defined(_X86_) ) && ( FPO ))
00031
#pragma optimize( "y", off ) // disable FPO for consistent stack traces
00032
#endif
00033
00034
#ifndef NO_SPECIAL_IRP
00035
00036
#ifdef ALLOC_PRAGMA
00037
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessTakeLock)
00038
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessReleaseLock)
00039
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessCheckUnderLock)
00040
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessProcessParams)
00041
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessProcessMessageText)
00042
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessApplyControl)
00043
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessThrowBugCheck)
00044
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessPrintBuffer)
00045
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessPrintParamData)
00046
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessPrompt)
00047
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessAddressToFileHeader)
00048
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessPrintIrp)
00049
#pragma alloc_text(PAGEVRFY, IopDriverCorrectnessPrintIrpStack)
00050
#endif // ALLOC_PRAGMA
00051
00052 PULONG
IopDcControlCurrent =
NULL;
00053 LONG
IopDcCurrentFrameSkips = -1;
00054 KIRQL
IopDcControlIrql;
00055 KSPIN_LOCK
IopDcControlLock;
00056 ULONG
IopDcControlInitial = (ULONG) -1;
00057 ULONG
IopDcControlOverride = (ULONG) -1;
00058
00059
#ifdef ALLOC_DATA_PRAGMA
00060
#pragma data_seg("PAGEVRFY$data")
00061
#endif
00062
00063
00064
00065
00066
00067 DCPARAM_TYPE_ENTRY DcParamTable[] = {
00068 {
DCPARAM_IRP,
"Irp" },
00069 {
DCPARAM_ROUTINE,
"Routine" },
00070 {
DCPARAM_DEVOBJ,
"DevObj" },
00071 {
DCPARAM_STATUS,
"Status" }
00072 };
00073
00074 typedef struct _DCERROR_MESSAGE {
00075
00076 DCERROR_ID MessageID;
00077 PCDCERROR_CLASS MessageClass;
00078 PSTR
MessageText;
00079
00080 }
DCERROR_MESSAGE, *
PDCERROR_MESSAGE;
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 DCERROR_CLASS IopDcWdmDriverErrorFatal =
00104 {
DIAG_BEEP |
DIAG_FATAL_ERROR |
DIAG_WDM_ERROR,
"WDM DRIVER ERROR" };
00105
00106 DCERROR_CLASS IopDcWdmDriverErrorNonFatal =
00107 {
DIAG_BEEP |
DIAG_WDM_ERROR,
"WDM DRIVER ERROR" };
00108
00109 DCERROR_CLASS IopDcWdmDriverWarning =
00110 {
DIAG_BEEP |
DIAG_ZAPPED,
"WDM DRIVER WARNING" };
00111
00112 DCERROR_CLASS IopDcWdmDriverPostponed = {
DIAG_ZAPPED,
"POSTPONED WDM DRIVER BUG" };
00113
00114 DCERROR_CLASS IopDcWdmCoreError = {
DIAG_BEEP,
"CORE DRIVER ERROR" };
00115
00116
00117
00118
00119
00120
00121
00122
00123 DCERROR_MESSAGE IopDcMessageTable[
DCERROR_MAXIMUM -
DCERROR_UNSPECIFIED] = {
00124 {
DCERROR_UNSPECIFIED,
NULL,
NULL },
00125 {
DCERROR_DELETE_WHILE_ATTACHED, &
IopDcWdmDriverErrorFatal,
00126
"A device is deleting itself while there is another device beneath it in "
00127
"the driver stack. This may be because the caller has forgotten to call "
00128
"IoDetachDevice first, or the lower driver may have incorrectly deleted "
00129
"itself." },
00130 {
DCERROR_DETACH_NOT_ATTACHED, &
IopDcWdmDriverErrorFatal,
00131
"Driver has attempted to detach from device object %DevObj, which is not "
00132
"attached to anything. This may occur if detach was called twice on the "
00133
"same device object." },
00134 {
DCERROR_CANCELROUTINE_FORWARDED, &
IopDcWdmDriverErrorFatal,
00135
"A driver has called IoCallDriver without setting the CancelRoutine in "
00136
"the Irp to NULL (Irp = %Irp )." },
00137 {
DCERROR_NULL_DEVOBJ_FORWARDED, &
IopDcWdmDriverErrorFatal,
00138
"Caller has passed in NULL as a DeviceObject. This is fatal (Irp = %Irp )."
00139 },
00140 {
DCERROR_QUEUED_IRP_FORWARDED, &
IopDcWdmDriverErrorFatal,
00141
"Caller is forwarding an IRP that is currently queued beneath it! The "
00142
"code handling IRPs returning STATUS_PENDING in this driver appears to "
00143
"be broken (Irp = %Irp )." },
00144 {
DCERROR_NEXTIRPSP_DIRTY, &
IopDcWdmDriverErrorFatal,
00145
"Caller has incorrectly forwarded an IRP (control field not zerod). The "
00146
"driver should use IoCopyCurrentIrpStackLocationToNext or "
00147
"IoSkipCurrentIrpStackLocation. (Irp = %Irp )" },
00148 {
DCERROR_IRPSP_COPIED, &
IopDcWdmDriverErrorFatal,
00149
"Caller has manually copied the stack and has inadvertantly copied the "
00150
"upper layer's completion routine. Please use "
00151
"IoCopyCurrentIrpStackLocationToNext. (Irp = %Irp )." },
00152 {
DCERROR_INSUFFICIENT_STACK_LOCATIONS, &
IopDcWdmDriverErrorFatal,
00153
"This IRP is about to run out of stack locations. Someone may have "
00154
"forwarded this IRP from another stack (Irp = %Irp )." },
00155 {
DCERROR_QUEUED_IRP_COMPLETED, &
IopDcWdmDriverErrorFatal,
00156
"Caller is completing an IRP that is currently queued beneath it! The "
00157
"code handling IRPs returning STATUS_PENDING in this driver appears to be "
00158
"broken. (Irp = %Irp )" },
00159 {
DCERROR_FREE_OF_INUSE_TRACKED_IRP, &
IopDcWdmDriverErrorFatal,
00160
"Caller of IoFreeIrp is freeing an IRP that is still in use! (Original "
00161
"Irp = %Irp1, Irp in usage is %Irp2 )" },
00162 {
DCERROR_FREE_OF_INUSE_IRP, &
IopDcWdmDriverErrorFatal,
00163
"Caller of IoFreeIrp is freeing an IRP that is still in use! (Irp = %Irp )"
00164 },
00165 {
DCERROR_FREE_OF_THREADED_IRP, &
IopDcWdmDriverErrorFatal,
00166
"Caller of IoFreeIrp is freeing an IRP that is still enqueued against a "
00167
"thread! (Irp = %Irp )" },
00168 {
DCERROR_REINIT_OF_ALLOCATED_IRP_WITH_QUOTA, &
IopDcWdmDriverErrorFatal,
00169
"Caller of IoInitializeIrp has passed an IRP that was allocated with "
00170
"IoAllocateIrp. This is illegal and unneccessary, and has caused a quota "
00171
"leak. Check the documentation for IoReuseIrp if this IRP is being "
00172
"recycled." },
00173 {
DCERROR_PNP_IRP_BAD_INITIAL_STATUS, &
IopDcWdmDriverErrorNonFatal,
00174
"Any PNP IRP must have status initialized to STATUS_NOT_SUPPORTED "
00175
"(Irp = %Irp )." },
00176 {
DCERROR_POWER_IRP_BAD_INITIAL_STATUS, &
IopDcWdmDriverErrorNonFatal,
00177
"Any Power IRP must have status initialized to STATUS_NOT_SUPPORTED "
00178
"(Irp = %Irp )." },
00179 {
DCERROR_WMI_IRP_BAD_INITIAL_STATUS, &
IopDcWdmDriverErrorNonFatal,
00180
"Any WMI IRP must have status initialized to STATUS_NOT_SUPPORTED "
00181
"(Irp = %Irp )." },
00182 {
DCERROR_SKIPPED_DEVICE_OBJECT, &
IopDcWdmDriverErrorNonFatal,
00183
"Caller has forwarded an Irp while skipping a device object in the stack. "
00184
"The caller is probably sending IRPs to the PDO instead of to the device "
00185
"returned by IoAttachDeviceToDeviceStack (Irp = %Irp )." },
00186 {
DCERROR_BOGUS_FUNC_TRASHED, &
IopDcWdmDriverErrorNonFatal,
00187
"Caller has trashed or has not properly copied IRP's stack (Irp = %Irp )."
00188 },
00189 {
DCERROR_BOGUS_STATUS_TRASHED, &
IopDcWdmDriverErrorNonFatal,
00190
"Caller has changed the status field of an IRP it does not understand "
00191
"(Irp = %Irp )." },
00192 {
DCERROR_BOGUS_INFO_TRASHED, &
IopDcWdmDriverErrorNonFatal,
00193
"Caller has changed the information field of an IRP it does not "
00194
"understand (Irp = %Irp )." },
00195 {
DCERROR_PNP_FAILURE_FORWARDED, &
IopDcWdmDriverErrorNonFatal,
00196
"Non-successful non-STATUS_NOT_SUPPORTED IRP status for IRP_MJ_PNP is "
00197
"being passed down stack (Irp = %Irp ). Failed PNP IRPs must be completed."
00198 },
00199 {
DCERROR_PNP_IRP_STATUS_RESET, &
IopDcWdmDriverErrorNonFatal,
00200
"Previously set IRP_MJ_PNP status has been converted to "
00201
"STATUS_NOT_SUPPORTED. (Irp = %Irp )." },
00202 {
DCERROR_PNP_IRP_NEEDS_FDO_HANDLING, &
IopDcWdmDriverErrorNonFatal,
00203
"FDO caller has not handled a required IRP. The FDO must either fail the "
00204
"IRP or set the IRP's status if it is not going change the IRP's status "
00205
"using a completion routine. (Irp = %Irp )." },
00206 {
DCERROR_PNP_IRP_FDO_HANDS_OFF, &
IopDcWdmDriverErrorNonFatal,
00207
"FDO caller has responded to an IRP that is reserved for PDO use only. "
00208
"Stop it. (Irp = %Irp )" },
00209 {
DCERROR_POWER_FAILURE_FORWARDED, &
IopDcWdmDriverErrorNonFatal,
00210
"Non-successful non-STATUS_NOT_SUPPORTED IRP status for IRP_MJ_POWER is "
00211
"being passed down stack (Irp = %Irp ). Failed POWER IRPs must be "
00212
"completed." },
00213 {
DCERROR_POWER_IRP_STATUS_RESET, &
IopDcWdmDriverErrorNonFatal,
00214
"Previously set IRP_MJ_POWER status has been converted to "
00215
"STATUS_NOT_SUPPORTED. (Irp = %Irp )." },
00216 {
DCERROR_INVALID_STATUS, &
IopDcWdmDriverErrorNonFatal,
00217
"Driver has returned a suspicious status. This is probably due to an "
00218
"uninitiaized variable bug in the driver. (Irp = %Irp )" },
00219 {
DCERROR_UNNECCESSARY_COPY, &
IopDcWdmDriverWarning,
00220
"Caller has copied the Irp stack but not set a completion routine. "
00221
"This is inefficient, use IoSkipCurrentIrpStackLocation instead "
00222
"(Irp = %Irp )." },
00223 {
DCERROR_SHOULDVE_DETACHED, &
IopDcWdmDriverErrorFatal,
00224
"An IRP dispatch handler has not properly detached from the stack below "
00225
"it upon receiving a remove IRP. DeviceObject = %DevObj - Dispatch = "
00226
"%Routine - Irp = %Irp" },
00227 {
DCERROR_SHOULDVE_DELETED, &
IopDcWdmDriverErrorFatal,
00228
"An IRP dispatch handler has not properly deleted it's device object upon "
00229
"receiving a remove IRP. DeviceObject = %DevObj - Dispatch = %Routine - "
00230
"Irp = %Irp" },
00231 {
DCERROR_MISSING_DISPATCH_FUNCTION, &
IopDcWdmDriverErrorNonFatal,
00232
"This driver has not filled out a dispatch routine for a required IRP "
00233
"major function (Irp = %Irp )." },
00234 {
DCERROR_WMI_IRP_NOT_FORWARDED, &
IopDcWdmDriverErrorNonFatal,
00235
"IRP_MJ_SYSTEM_CONTROL has been completed by someone other than the "
00236
"ProviderId. This IRP should either have been completed earlier or "
00237
"should have been passed down (Irp = %Irp ). The IRP was targetted at "
00238
"DeviceObject %DevObj" },
00239 {
DCERROR_DELETED_PRESENT_PDO, &
IopDcWdmDriverErrorFatal,
00240
"An IRP dispatch handler for a PDO has deleted it's device object, but "
00241
"the hardware has not been reported as missing in a bus relations query. "
00242
"DeviceObject = %DevObj - Dispatch = %Routine - Irp = %Irp " },
00243 {
DCERROR_BUS_FILTER_ERRONEOUSLY_DETACHED, &
IopDcWdmDriverErrorFatal,
00244
"A Bus Filter's IRP dispatch handler has detached upon receiving a remove "
00245
"IRP when the PDO is still alive. Bus Filters must clean up in "
00246
"FastIoDetach callbacks. DeviceObject = %DevObj - Dispatch = %Routine - "
00247
"Irp = %Irp" },
00248 {
DCERROR_BUS_FILTER_ERRONEOUSLY_DELETED, &
IopDcWdmDriverErrorFatal,
00249
"An IRP dispatch handler for a bus filter has deleted it's device object, "
00250
"but the PDO is still present! Bus filters must clean up in FastIoDetach "
00251
"callbacks. DeviceObject = %DevObj - Dispatch = %Routine - Irp = %Irp" },
00252 {
DCERROR_INCONSISTANT_STATUS, &
IopDcWdmDriverErrorFatal,
00253
"An IRP dispatch handler ( %Routine ) has returned a status that is "
00254
"inconsistent with the Irp's IoStatus.Status field. ( Irp = %Irp - "
00255
"Irp->IoStatus.Status = %Status1 - returned = %Status2 )" },
00256 {
DCERROR_UNINITIALIZED_STATUS, &
IopDcWdmDriverErrorNonFatal,
00257
"An IRP dispatch handler has returned a status that is illegal "
00258
"(0xFFFFFFFF). This is probably due to an uninitialized stack variable. "
00259
"Please do an ln on address %lx and file a bug. (Irp = %Irp )" },
00260 {
DCERROR_IRP_RETURNED_WITHOUT_COMPLETION, &
IopDcWdmDriverErrorFatal,
00261
"An IRP dispatch handler has returned without passing down or completing "
00262
"this Irp or someone forgot to return STATUS_PENDING. (Irp = %Irp )." },
00263 {
DCERROR_COMPLETION_ROUTINE_PAGABLE, &
IopDcWdmDriverErrorFatal,
00264
"IRP completion routines must be in nonpagable code, and this one is not: "
00265
"%Routine. (Irp = %Irp )" },
00266 {
DCERROR_PENDING_BIT_NOT_MIGRATED, &
IopDcWdmDriverErrorNonFatal,
00267
"A driver's completion routine ( %Routine ) has not marked the IRP "
00268
"pending if the PendingReturned field was set in the IRP passed to it. "
00269
"This may cause the OS to hang, especially if an error is returned by the "
00270
" stack. (Irp = %Irp )" },
00271 {
DCERROR_CANCELROUTINE_ON_FORWARDED_IRP, &
IopDcWdmDriverErrorFatal,
00272
"A cancel routine has been set for an IRP that is currently being "
00273
"processed by drivers lower in the stack, possibly stomping their cancel "
00274
"routine (Irp = %Irp, Routine=%Routine )." },
00275 {
DCERROR_PNP_IRP_NEEDS_PDO_HANDLING, &
IopDcWdmDriverErrorNonFatal,
00276
"PDO has not responded to a required IRP (Irp = %Irp )" },
00277 {
DCERROR_TARGET_RELATION_LIST_EMPTY, &
IopDcWdmDriverErrorNonFatal,
00278
"PDO has forgotten to fill out the device relation list with the PDO for "
00279
"the TargetDeviceRelation query (Irp = %Irp )" },
00280 {
DCERROR_TARGET_RELATION_NEEDS_REF, &
IopDcWdmDriverErrorFatal,
00281
"The code implementing the TargetDeviceRelation query has not called "
00282
"ObReferenceObject on the PDO (Irp = %Irp )." },
00283 {
DCERROR_BOGUS_PNP_IRP_COMPLETED, &
IopDcWdmDriverErrorNonFatal,
00284
"Caller has completed a IRP_MJ_PNP it didn't understand instead of "
00285
"passing it down (Irp = %Irp )." },
00286 {
DCERROR_SUCCESSFUL_PNP_IRP_NOT_FORWARDED, &
IopDcWdmDriverErrorNonFatal,
00287
"Caller has completed successful IRP_MJ_PNP instead of passing it down "
00288
"(Irp = %Irp )." },
00289 {
DCERROR_UNTOUCHED_PNP_IRP_NOT_FORWARDED, &
IopDcWdmDriverErrorNonFatal,
00290
"Caller has completed untouched IRP_MJ_PNP (instead of passing the irp "
00291
"down) or non-PDO has failed the irp using illegal value of "
00292
"STATUS_NOT_SUPPORTED. (Irp = %Irp )." },
00293 {
DCERROR_BOGUS_POWER_IRP_COMPLETED, &
IopDcWdmDriverErrorNonFatal,
00294
"Caller has completed a IRP_MJ_POWER it didn't understand instead of "
00295
"passing it down (Irp = %Irp )." },
00296 {
DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED, &
IopDcWdmDriverErrorFatal,
00297
"Caller has completed successful IRP_MJ_POWER instead of passing it down "
00298
"(Irp = %Irp )." },
00299 {
DCERROR_UNTOUCHED_POWER_IRP_NOT_FORWARDED, &
IopDcWdmDriverErrorNonFatal,
00300
"Caller has completed untouched IRP_MJ_POWER (instead of passing the irp "
00301
"down) or non-PDO has failed the irp using illegal value of "
00302
"STATUS_NOT_SUPPORTED. (Irp = %Irp )." },
00303 {
DCERROR_PNP_QUERY_CAP_BAD_VERSION, &
IopDcWdmDriverErrorFatal,
00304
"The version field of the query capabilities structure in a query "
00305
"capabilities IRP was not properly initialized. (Irp = %Irp )." },
00306 {
DCERROR_PNP_QUERY_CAP_BAD_SIZE, &
IopDcWdmDriverErrorFatal,
00307
"The size field of the query capabilities structure in a query "
00308
"capabilities IRP was not properly initialized. (Irp = %Irp )." },
00309 {
DCERROR_PNP_QUERY_CAP_BAD_ADDRESS, &
IopDcWdmDriverErrorNonFatal,
00310
"The address field of the query capabilities structure in a query "
00311
"capabilities IRP was not properly initialized to -1. (Irp = %Irp )." },
00312 {
DCERROR_PNP_QUERY_CAP_BAD_UI_NUM, &
IopDcWdmDriverErrorNonFatal,
00313
"The UI Number field of the query capabilities structure in a query "
00314
"capabilities IRP was not properly initialized to -1. (Irp = %Irp )." },
00315 {
DCERROR_RESTRICTED_IRP, &
IopDcWdmDriverErrorFatal,
00316
"A driver has sent an IRP that is restricted for system use only. "
00317
"(Irp = %Irp )." },
00318 {
DCERROR_REINIT_OF_ALLOCATED_IRP_WITHOUT_QUOTA, &
IopDcWdmDriverWarning,
00319
"Caller of IoInitializeIrp has passed an IRP that was allocated with "
00320
"IoAllocateIrp. This is illegal, unneccessary, and negatively impacts "
00321
"performace in normal use. Check the documentation for IoReuseIrp if "
00322
"this IRP is being recycled." },
00323 {
DCERROR_UNFORWARDED_IRP_COMPLETED, &
IopDcWdmDriverWarning,
00324
"The caller of IoCompleteRequest is completing an IRP that has never "
00325
"been forwarded via a call to IoCallDriver or PoCallDriver. This may "
00326
"be a bug. (Irp = %Irp )." },
00327 {
DCERROR_DISPATCH_CALLED_AT_BAD_IRQL, &
IopDcWdmDriverErrorFatal,
00328
"A driver has forwarded an IRP at an IRQL that is illegal for this major"
00329
" code. "
00330
"(Irp = %Irp )." },
00331 {
DCERROR_BOGUS_MINOR_STATUS_TRASHED, &
IopDcWdmDriverErrorFatal,
00332
"Caller has changed the status field of an IRP it does not understand "
00333
"(Irp = %Irp )." }
00334 };
00335
00336 typedef struct _DC_OVERRIDE_TABLE {
00337
00338 DCERROR_ID MessageID;
00339 PSTR
DriverName;
00340 PDCERROR_CLASS ReplacementClass;
00341
00342 }
DC_OVERRIDE_TABLE, *
PDC_OVERRIDE_TABLE;
00343
00344
00345
00346
00347 DC_OVERRIDE_TABLE IopDcOverrideTable[] = {
00348
00349
00350
00351
00352
00353 {
DCERROR_UNSPECIFIED,
"HAL.DLL", &
IopDcWdmCoreError },
00354 {
DCERROR_UNSPECIFIED,
"NTOSKRNL.EXE", &
IopDcWdmCoreError },
00355 {
DCERROR_UNSPECIFIED,
"NTKRNLMP.EXE", &
IopDcWdmCoreError },
00356 {
DCERROR_UNSPECIFIED,
"NTKRNLPA.EXE", &
IopDcWdmCoreError },
00357 {
DCERROR_UNSPECIFIED,
"NTKRPAMP.EXE", &
IopDcWdmCoreError },
00358
00359
00360
00361
00362
00363
00364
00365
00366 {
DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED,
"NDIS.SYS",
00367 &
IopDcWdmDriverPostponed },
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 {
DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED,
"ACPI.SYS",
00378 &
IopDcWdmDriverPostponed },
00379
00380
00381
00382
00383
00384
00385 {
DCERROR_SUCCESSFUL_PNP_IRP_NOT_FORWARDED,
"PCMCIA.SYS",
00386 &
IopDcWdmDriverPostponed },
00387
00388
00389
00390
00391
00392
00393 {
DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED,
"PCMCIA.SYS",
00394 &
IopDcWdmDriverPostponed },
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 {
DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED,
"SCSIPORT.SYS",
00408 &
IopDcWdmDriverPostponed }
00409 };
00410
00411
#ifdef ALLOC_DATA_PRAGMA
00412
#pragma data_seg()
00413
#endif
00414
00415 PCHAR
00416
KeBugCheckUnicodeToAnsi(
00417 IN PUNICODE_STRING UnicodeString,
00418 OUT PCHAR AnsiBuffer,
00419 IN ULONG MaxAnsiLength
00420 );
00421
00422
VOID
00423 IopDriverCorrectnessTakeLock(
00424 IN PULONG ControlNew,
00425 IN LONG StackFramesToSkip
00426 )
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 {
00438
ASSERT(
IovpInitCalled);
00439 ExAcquireSpinLock( &
IopDcControlLock, &
IopDcControlIrql );
00440
ASSERT(
IopDcControlCurrent ==
NULL) ;
00441
IopDcControlCurrent = ControlNew ;
00442
IopDcCurrentFrameSkips = StackFramesToSkip ;
00443 }
00444
00445
VOID
00446 IopDriverCorrectnessReleaseLock(
00447 VOID
00448 )
00449
00450
00451
00452
00453
00454
00455
00456 {
00457
IopDcControlCurrent =
NULL ;
00458
IopDcCurrentFrameSkips = -1 ;
00459 ExReleaseSpinLock( &
IopDcControlLock,
IopDcControlIrql );
00460 }
00461
00462
NTSTATUS
00463 IopDriverCorrectnessCheckUnderLock(
00464 IN
DCERROR_ID MessageID,
00465 IN ULONG MessageParameterMask,
00466 ...
00467 )
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 {
00533 va_list arglist;
00534 UCHAR finalBuffer[512];
00535
NTSTATUS status;
00536
DC_CHECK_DATA dcCheckData;
00537 PVOID dcParamArray[3*
sizeof(
DcParamTable)/
sizeof(
DCPARAM_TYPE_ENTRY)];
00538 BOOLEAN exitAssertion;
00539
00540 va_start(arglist, MessageParameterMask);
00541
00542
00543
00544
00545
00546
IopDriverCorrectnessProcessParams(
00547
IopDcControlCurrent,
00548
IopDcCurrentFrameSkips,
00549 MessageID,
00550 MessageParameterMask,
00551 &arglist,
00552 dcParamArray,
00553 &dcCheckData
00554 );
00555
00556 va_end(arglist);
00557
00558
if (!
IopDriverCorrectnessApplyControl(&dcCheckData)) {
00559
00560
00561
00562
00563
return STATUS_SUCCESS;
00564 }
00565
00566
00567
00568
00569
00570 status =
IopDriverCorrectnessProcessMessageText(
00571
sizeof(finalBuffer),
00572 finalBuffer,
00573 &dcCheckData
00574 );
00575
00576
if (!
NT_SUCCESS(status)) {
00577
00578
ASSERT(0);
00579
00580
00581
00582
00583
return status;
00584 }
00585
00586
do {
00587
00588
IopDriverCorrectnessPrintBuffer(&dcCheckData);
00589
IopDriverCorrectnessPrintParamData(&dcCheckData);
00590
IopDriverCorrectnessThrowBugCheck(&dcCheckData);
00591
IopDriverCorrectnessPrompt(&dcCheckData, &exitAssertion);
00592
00593 }
while (!exitAssertion);
00594
00595
return status;
00596 }
00597
00598
VOID
00599 IopDriverCorrectnessProcessParams(
00600 IN OUT PULONG Control OPTIONAL,
00601 IN LONG StackFramesToSkip,
00602 IN DCERROR_ID MessageID,
00603 IN ULONG MessageParameterMask,
00604 IN va_list * MessageParameters,
00605 IN PVOID * DcParamArray,
00606 OUT
PDC_CHECK_DATA DcCheckData
00607 )
00608 {
00609 PVOID returnAddress[1];
00610 PVOID baseOfImage, culpritAddress;
00611 ULONG stackHash;
00612 PLDR_DATA_TABLE_ENTRY dataTableEntry;
00613 PIMAGE_NT_HEADERS ntHeaders;
00614 ULONG i, currentMessageMask, paramType, maxParameterTypes, paramMask;
00615 ULONG tableIndex;
00616
char ansiDriverName[81];
00617
00618 tableIndex = MessageID -
DCERROR_UNSPECIFIED;
00619
00620
00621
00622
00623
if (tableIndex >=
sizeof(
IopDcMessageTable)/
sizeof(
DCERROR_MESSAGE)) {
00624
00625
00626
00627
00628
ASSERT(0);
00629 tableIndex = 0;
00630 }
00631
00632
ASSERT(
IopDcMessageTable[tableIndex].MessageID == MessageID);
00633
00634
00635
00636
00637 maxParameterTypes =
sizeof(
DcParamTable)/
sizeof(
DCPARAM_TYPE_ENTRY);
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 currentMessageMask = MessageParameterMask;
00648
00649
for(paramType = 0; paramType < maxParameterTypes; paramType++) {
00650
00651 paramMask =
DcParamTable[paramType].
DcParamMask ;
00652
for(i=0; i<3; i++) {
00653
00654
if (currentMessageMask&(paramMask*3)) {
00655
00656 currentMessageMask -= paramMask;
00657 DcParamArray[paramType*3+i] = va_arg(*MessageParameters, PVOID);
00658
00659 }
else {
00660
00661 DcParamArray[paramType*3+i] =
NULL;
00662 }
00663 }
00664 }
00665
00666
00667
00668
00669
00670
ASSERT(currentMessageMask == 0);
00671
00672
00673
00674
00675 culpritAddress =
NULL;
00676 DcCheckData->OffsetIntoImage = 0;
00677 DcCheckData->InVerifierList =
TRUE;
00678
RtlInitUnicodeString(&DcCheckData->DriverName,
NULL);
00679
00680
00681
00682
00683
if (StackFramesToSkip != -1) {
00684
00685
if (
RtlCaptureStackBackTrace(StackFramesToSkip+2, 1, returnAddress,
00686 &stackHash)==1) {
00687
00688 culpritAddress = returnAddress[0];
00689 }
00690
00691 }
else {
00692
00693
00694
00695
00696 culpritAddress = DcParamArray[3];
00697 }
00698
00699
00700
00701
00702
if (culpritAddress) {
00703
00704 baseOfImage =
IopDriverCorrectnessAddressToFileHeader(
00705 (PVOID) culpritAddress,
00706 &dataTableEntry
00707 );
00708
00709
if (baseOfImage !=
NULL) {
00710
00711
00712
00713
00714
00715
if (
MmIsAddressValid(dataTableEntry->DllBase) !=
FALSE) {
00716
00717 ntHeaders =
RtlImageNtHeader(dataTableEntry->DllBase);
00718
00719 RtlCopyMemory(
00720 &DcCheckData->DriverName,
00721 &dataTableEntry->BaseDllName,
00722
sizeof(UNICODE_STRING)
00723 );
00724
00725 DcCheckData->OffsetIntoImage = (PUCHAR) culpritAddress - (PUCHAR) baseOfImage;
00726 }
00727
00728
00729
00730
00731
if (!(dataTableEntry->Flags & LDRP_IMAGE_VERIFYING)) {
00732
00733 DcCheckData->InVerifierList =
FALSE;
00734 }
00735 }
00736 }
00737
00738 DcCheckData->CulpritAddress = culpritAddress;
00739 DcCheckData->DcParamArray = DcParamArray;
00740 DcCheckData->TableIndex = tableIndex;
00741 DcCheckData->MessageID = MessageID;
00742 DcCheckData->Control = Control;
00743 DcCheckData->AssertionClass =
IopDcMessageTable[DcCheckData->TableIndex].
MessageClass;
00744
00745
00746
00747
00748
00749
KeBugCheckUnicodeToAnsi(
00750 &DcCheckData->DriverName,
00751 ansiDriverName,
00752
sizeof(ansiDriverName)
00753 );
00754
00755
for(i=0; i<
sizeof(
IopDcOverrideTable)/
sizeof(
DC_OVERRIDE_TABLE); i++) {
00756
00757
if ((
IopDcOverrideTable[i].
MessageID == MessageID) ||
00758 (
IopDcOverrideTable[i].
MessageID ==
DCERROR_UNSPECIFIED)) {
00759
00760
if (!_stricmp(ansiDriverName,
IopDcOverrideTable[i].DriverName)) {
00761
00762
00763
00764
00765
00766
00767
00768 DcCheckData->Control =
NULL;
00769 DcCheckData->AssertionClass =
IopDcOverrideTable[i].
ReplacementClass;
00770 }
00771 }
00772 }
00773 }
00774
00775 BOOLEAN
00776 IopDriverCorrectnessApplyControl(
00777 IN OUT
PDC_CHECK_DATA DcCheckData
00778 )
00779 {
00780 ULONG assertionControl;
00781
00782
if (
IopDcControlOverride) {
00783
00784 assertionControl =
IopDcControlOverride;
00785
00786 }
else if (DcCheckData->Control) {
00787
00788
00789
00790
00791
if (!((*DcCheckData->Control)&
DIAG_INITIALIZED)) {
00792
00793 *DcCheckData->Control |= (
00794
DIAG_INITIALIZED |
IopDcControlInitial |
00795 DcCheckData->AssertionClass->ClassFlags );
00796 }
00797
00798 assertionControl = *DcCheckData->Control;
00799
00800 }
else {
00801
00802 assertionControl =
00803 (
IopDcControlInitial | DcCheckData->AssertionClass->ClassFlags );
00804 }
00805
00806
if (assertionControl&
DIAG_CLEARED) {
00807
00808
00809
00810
00811
return FALSE;
00812 }
00813
00814
if ((!(assertionControl&
DIAG_IGNORE_DRIVER_LIST)) &&
00815 (!DcCheckData->InVerifierList)) {
00816
00817
00818
00819
00820
return FALSE;
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
if ((!
KdDebuggerEnabled) && (!(assertionControl&
DIAG_FATAL_ERROR))) {
00830
00831
return FALSE;
00832 }
00833
00834
00835
00836
00837 DcCheckData->AssertionControl = assertionControl;
00838
return TRUE;
00839 }
00840
00841
NTSTATUS
00842 IopDriverCorrectnessProcessMessageText(
00843 IN ULONG MaxOutputBufferSize,
00844 OUT PSTR OutputBuffer,
00845 IN OUT
PDC_CHECK_DATA DcCheckData
00846 )
00847 {
00848 ULONG paramType, maxParameterTypes;
00849 ULONG arrayIndex, paramLength;
00850 PSTR messageHead, newMessage;
00851 LONG charsRemaining, length;
00852
00853
00854
00855
00856 messageHead =
IopDcMessageTable[DcCheckData->TableIndex].
MessageText;
00857
00858
00859
00860
00861 newMessage = OutputBuffer;
00862 charsRemaining = (MaxOutputBufferSize/
sizeof(UCHAR))-1;
00863 maxParameterTypes =
sizeof(
DcParamTable)/
sizeof(
DCPARAM_TYPE_ENTRY);
00864
00865
while(*messageHead !=
'\0') {
00866
00867
if (charsRemaining <= 0) {
00868
00869
return STATUS_BUFFER_OVERFLOW;
00870 }
00871
00872
if (*messageHead !=
'%') {
00873
00874 *newMessage = *messageHead;
00875 newMessage++;
00876 messageHead++;
00877 charsRemaining--;
00878
00879 }
else {
00880
00881
for(paramType = 0; paramType < maxParameterTypes; paramType++) {
00882
00883 paramLength =
strlen(
DcParamTable[paramType].DcParamName);
00884
00885
00886
00887
00888
00889
00890
00891
if (RtlCompareMemory(
00892 messageHead+1,
00893
DcParamTable[paramType].DcParamName,
00894 paramLength*
sizeof(UCHAR)) == paramLength*
sizeof(UCHAR)) {
00895
00896 arrayIndex = paramType*3;
00897 messageHead += (paramLength+1);
00898
00899
00900
00901
00902
if ((*messageHead >=
'1') && (*messageHead <=
'3')) {
00903
00904
00905
00906
00907 arrayIndex += (*messageHead -
'1') ;
00908 messageHead++;
00909 }
00910
00911 length = _snprintf(
00912 newMessage,
00913 charsRemaining+1,
00914
"%p",
00915 DcCheckData->DcParamArray[arrayIndex]
00916 );
00917
00918
if (length == -1) {
00919
00920
return STATUS_BUFFER_OVERFLOW;
00921 }
00922
00923 charsRemaining -= length;
00924 newMessage += length;
00925
break;
00926 }
00927 }
00928
00929
if (paramType == maxParameterTypes) {
00930
00931
00932
00933
00934
00935 *newMessage = *messageHead;
00936 messageHead++;
00937 newMessage++;
00938 charsRemaining--;
00939
00940
if (*messageHead ==
'%') {
00941
00942 messageHead++;
00943 }
00944 }
00945 }
00946 }
00947
00948
00949
00950
00951
00952 *newMessage =
'\0';
00953
00954 DcCheckData->ClassText = DcCheckData->AssertionClass->MessageClassText;
00955 DcCheckData->AssertionText = OutputBuffer;
00956
return STATUS_SUCCESS;
00957 }
00958
00959
VOID
00960 IopDriverCorrectnessThrowBugCheck(
00961 IN
PDC_CHECK_DATA DcCheckData
00962 )
00963 {
00964 PVOID parameterArray[4];
00965
char captionBuffer[256];
00966
char ansiDriverName[81];
00967 UNICODE_STRING unicodeString;
00968
00969
00970
00971
00972
00973
if (
KdDebuggerEnabled || (!(DcCheckData->AssertionControl&
DIAG_FATAL_ERROR))) {
00974
00975
return;
00976 }
00977
00978
00979
00980
00981
00982
00983 parameterArray[0] = (PVOID) DcCheckData->MessageID;
00984 parameterArray[1] = DcCheckData->CulpritAddress;
00985 parameterArray[2] = DcCheckData->DcParamArray[0];
00986 parameterArray[3] = DcCheckData->DcParamArray[6];
00987
00988
KeBugCheckUnicodeToAnsi(
00989 &DcCheckData->DriverName,
00990 ansiDriverName,
00991
sizeof(ansiDriverName)
00992 );
00993
00994 _snprintf(
00995 captionBuffer,
00996
sizeof(captionBuffer),
00997
"IO SYSTEM VERIFICATION ERROR in %s (%s %x)\n[%s+%x at %p]\n",
00998 ansiDriverName,
00999 DcCheckData->ClassText,
01000 DcCheckData->MessageID,
01001 ansiDriverName,
01002 DcCheckData->OffsetIntoImage,
01003 DcCheckData->CulpritAddress
01004 );
01005
01006
KeBugCheckEx(
01007 FATAL_UNHANDLED_HARD_ERROR,
01008 DRIVER_VERIFIER_IOMANAGER_VIOLATION,
01009 (ULONG_PTR) parameterArray,
01010 (ULONG_PTR) captionBuffer,
01011 (ULONG_PTR)
""
01012 );
01013 }
01014
01015
VOID
01016 IopDriverCorrectnessPrintBuffer(
01017 IN
PDC_CHECK_DATA DcCheckData
01018 )
01019 {
01020 UCHAR buffer[82];
01021 UCHAR classBuf[81];
01022 UCHAR callerBuf[81+40];
01023 UCHAR ansiDriverName[81];
01024 LONG lMargin, i, lMarginCur, rMargin=78;
01025 PSTR lineStart, lastWord, current, lMarginText;
01026
01027
01028
01029
01030
DbgPrint(
"\n") ;
01031
01032
01033
01034
01035
if (DcCheckData->AssertionControl&
DIAG_FATAL_ERROR) {
01036
01037
DbgPrint(
01038
"***********************************************************************\n"
01039
"* THIS DRIVER BUG IS FATAL AND WILL CAUSE THE VERIFIER TO HALT *\n"
01040
"* WINDOWS (BUGCHECK) WHEN THE MACHINE IS NOT UNDER A KERNEL DEBUGGER! *\n"
01041
"***********************************************************************\n"
01042
"\n"
01043 );
01044 }
01045
01046
01047
01048
01049
if (DcCheckData->ClassText !=
NULL) {
01050
01051 lMargin =
strlen(DcCheckData->ClassText)+2;
01052
01053
DbgPrint(
"%s: ", DcCheckData->ClassText);
01054
01055 }
else {
01056
01057 lMargin = 0;
01058 }
01059
01060
if (lMargin+1>=rMargin) {
01061
01062 lMargin=0;
01063 }
01064
01065
for(i=0; i<lMargin; i++) classBuf[i] =
' ';
01066 classBuf[lMargin] =
'\0';
01067 lMarginText = classBuf+lMargin;
01068 lMarginCur = lMargin;
01069
01070 lineStart = lastWord = current = DcCheckData->AssertionText;
01071
01072
01073
01074
01075
if (DcCheckData->CulpritAddress) {
01076
01077
if (DcCheckData->DriverName.Length) {
01078
01079
KeBugCheckUnicodeToAnsi(
01080 &DcCheckData->DriverName,
01081 ansiDriverName,
01082
sizeof(ansiDriverName)
01083 );
01084
01085
sprintf(callerBuf,
"[%s @ 0x%p] ",
01086 ansiDriverName,
01087 DcCheckData->CulpritAddress
01088 );
01089
01090 }
else {
01091
01092
sprintf(callerBuf,
"[0x%p] ", DcCheckData->CulpritAddress);
01093 }
01094
01095
DbgPrint(
"%s", callerBuf);
01096 lMarginCur +=
strlen(callerBuf);
01097 }
01098
01099
01100
01101
01102
while(*current) {
01103
01104
if (*current ==
' ') {
01105
01106
if ((current - lineStart) >= (rMargin-lMarginCur-1)) {
01107
01108
DbgPrint(
"%s", lMarginText);
01109 lMarginText = classBuf;
01110 lMarginCur = lMargin;
01111
01112
if ((lastWord-lineStart)<rMargin) {
01113
01114 memcpy(buffer, lineStart, (ULONG)(lastWord-lineStart)*
sizeof(UCHAR));
01115 buffer[lastWord-lineStart] =
'\0';
01116
DbgPrint(
"%s\n", buffer);
01117
01118 }
01119
01120 lineStart = lastWord+1;
01121 }
01122
01123 lastWord = current;
01124 }
01125
01126 current++;
01127 }
01128
01129
if ((current - lineStart) >= (rMargin-lMarginCur-1)) {
01130
01131
DbgPrint(
"%s", lMarginText);
01132 lMarginText = classBuf;
01133
01134
if ((lastWord-lineStart)<rMargin) {
01135
01136 memcpy(buffer, lineStart, (ULONG)(lastWord-lineStart)*
sizeof(UCHAR));
01137 buffer[lastWord-lineStart] =
'\0';
01138
DbgPrint(
"%s\n", buffer);
01139 }
01140
01141 lineStart = lastWord+1;
01142 }
01143
01144
if (lineStart<current) {
01145
01146
DbgPrint(
"%s%s\n", lMarginText, lineStart);
01147 }
01148 }
01149
01150
VOID
01151 IopDriverCorrectnessPrintParamData(
01152 IN
PDC_CHECK_DATA DcCheckData
01153 )
01154 {
01155
if (DcCheckData->DcParamArray[0]) {
01156
01157
IopDriverCorrectnessPrintIrp((
PIRP) DcCheckData->DcParamArray[0]);
01158 }
01159 }
01160
01161
VOID
01162 IopDriverCorrectnessPrompt(
01163 IN
PDC_CHECK_DATA DcCheckData,
01164 OUT PBOOLEAN ExitAssertion
01165 )
01166 {
01167
char response[2];
01168 ULONG assertionControl;
01169 BOOLEAN waitForInput;
01170
01171 assertionControl = DcCheckData->AssertionControl;
01172
01173 *ExitAssertion =
TRUE;
01174
01175
01176
01177
01178
if (assertionControl&
DIAG_BEEP) {
01179
01180
DbgPrint(
"%c", 7);
01181 }
01182
01183
if (assertionControl&
DIAG_ZAPPED) {
01184
01185
return;
01186 }
01187
01188
01189
01190
01191 waitForInput =
TRUE;
01192
while(waitForInput) {
01193
01194
if (DcCheckData->Control) {
01195
01196
DbgPrompt(
"Break, Ignore, Zap, Remove, Disable all (bizrd)? ", response,
sizeof( response ));
01197 }
else {
01198
01199
DbgPrompt(
"Break, Ignore, Disable all (bid)? ", response,
sizeof( response ));
01200 }
01201
01202
switch (response[0]) {
01203
01204
case 'B':
01205
case 'b':
01206
DbgPrint(
"Breaking in... (press g<enter> to return to assert menu)\n");
01207 DbgBreakPoint();
01208 waitForInput =
FALSE;
01209 *ExitAssertion =
FALSE;
01210
break;
01211
01212
case 'I':
01213
case 'i':
01214 waitForInput =
FALSE;
01215
break;
01216
01217
case 'Z':
01218
case 'z':
01219
if (DcCheckData->Control) {
01220
01221
DbgPrint(
"Breakpoint zapped (OS will print text and return)\n");
01222 assertionControl |=
DIAG_ZAPPED;
01223 assertionControl &=~ DIAG_BEEP;
01224 waitForInput =
FALSE;
01225 }
01226
break;
01227
01228
case 'D':
01229
case 'd':
01230
IopDcControlOverride =
DIAG_CLEARED;
01231
DbgPrint(
"Verification asserts disabled.\n");
01232
01233 waitForInput =
FALSE;
01234
break;
01235
01236
case 'R':
01237
case 'r':
01238
if (DcCheckData->Control) {
01239
01240
DbgPrint(
"Breakpoint removed\n") ;
01241 assertionControl |=
DIAG_CLEARED;
01242 waitForInput =
FALSE;
01243 }
01244
break;
01245 }
01246 }
01247
01248
if (DcCheckData->Control) {
01249 *DcCheckData->Control = assertionControl;
01250 }
01251 }
01252
01253 PVOID
01254 IopDriverCorrectnessAddressToFileHeader(
01255 IN PVOID Address,
01256 OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry
01257 )
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 {
01285
01286 PLIST_ENTRY ModuleListHead;
01287 PLDR_DATA_TABLE_ENTRY Entry;
01288 PLIST_ENTRY Next;
01289 UINT_PTR Bounds;
01290 PVOID ReturnBase=
NULL, Base;
01291
01292 ModuleListHead = &
PsLoadedModuleList;
01293
01294
01295
01296
01297
01298 Next = ModuleListHead->Flink;
01299
if (Next !=
NULL) {
01300
while (Next != ModuleListHead) {
01301 Entry = CONTAINING_RECORD(Next,
01302 LDR_DATA_TABLE_ENTRY,
01303 InLoadOrderLinks);
01304
01305 Next = Next->Flink;
01306 Base = Entry->DllBase;
01307 Bounds = (UINT_PTR)Base + Entry->SizeOfImage;
01308
if ((UINT_PTR)Address >= (UINT_PTR)Base && (UINT_PTR)Address < Bounds) {
01309 *DataTableEntry = Entry;
01310 ReturnBase = Base;
01311
break;
01312 }
01313 }
01314 }
01315
01316
return ReturnBase;
01317 }
01318
01319 BOOLEAN
01320 IopIsMemoryRangeReadable(
01321 IN PVOID Location,
01322 IN size_t Length
01323 )
01324 {
01325
while (((ULONG_PTR)Location & (
sizeof(ULONG_PTR)-1)) && (Length > 0)) {
01326
01327
01328
01329
01330
01331
if (
MmIsAddressValid(Location)==
FALSE) {
01332
return FALSE ;
01333 }
01334
01335 ((PCHAR) Location)++ ;
01336 Length-- ;
01337 }
01338
01339
while (Length > (
sizeof(ULONG_PTR)-1)) {
01340
01341
01342
01343
01344
01345
if (
MmIsAddressValid(Location)==
FALSE) {
01346
return FALSE ;
01347 }
01348 ((PCHAR) Location) +=
sizeof(ULONG_PTR);
01349 Length -=
sizeof(ULONG_PTR);
01350
01351 }
01352
01353
while (Length > 0) {
01354
01355
01356
01357
01358
01359
if (
MmIsAddressValid(Location)==
FALSE) {
01360
return FALSE;
01361 }
01362
01363 ((PCHAR) Location)++ ;
01364 Length-- ;
01365 }
01366
return TRUE ;
01367 }
01368
01369
VOID
01370 IopDriverCorrectnessPrintIrp(
01371 IN
PIRP IrpToFlag
01372 )
01373 {
01374
PIO_STACK_LOCATION irpSpCur ;
01375
PIO_STACK_LOCATION irpSpNxt ;
01376
01377
01378
01379
01380
if(!
IopIsMemoryRangeReadable(IrpToFlag,
sizeof(
IRP))) {
01381
return ;
01382 }
01383
01384
01385
01386
01387 irpSpNxt =
IoGetNextIrpStackLocation( IrpToFlag );
01388 irpSpCur =
IoGetCurrentIrpStackLocation( IrpToFlag );
01389
01390
if (
IopIsMemoryRangeReadable(irpSpNxt, 2*
sizeof(
IO_STACK_LOCATION))) {
01391
01392
01393
01394
01395
if (irpSpNxt->
MinorFunction == irpSpCur->
MinorFunction) {
01396
01397
01398
01399
01400
IopDriverCorrectnessPrintIrpStack(irpSpNxt) ;
01401 }
else if (irpSpNxt->
MinorFunction == 0) {
01402
01403
01404
01405
01406
IopDriverCorrectnessPrintIrpStack(irpSpCur) ;
01407 }
else {
01408
DbgPrint(
"Next: >") ;
01409
IopDriverCorrectnessPrintIrpStack(irpSpNxt) ;
01410
DbgPrint(
"Current: ") ;
01411
IopDriverCorrectnessPrintIrpStack(irpSpCur) ;
01412 }
01413 }
else if (
IopIsMemoryRangeReadable(irpSpCur,
sizeof(
IO_STACK_LOCATION))) {
01414
01415
IopDriverCorrectnessPrintIrpStack(irpSpCur) ;
01416 }
else if (
IopIsMemoryRangeReadable(irpSpNxt,
sizeof(
IO_STACK_LOCATION))) {
01417
01418
IopDriverCorrectnessPrintIrpStack(irpSpNxt) ;
01419 }
01420 }
01421
01422 PCHAR
IrpMajorNames[] = {
01423
"IRP_MJ_CREATE",
01424
"IRP_MJ_CREATE_NAMED_PIPE",
01425
"IRP_MJ_CLOSE",
01426
"IRP_MJ_READ",
01427
"IRP_MJ_WRITE",
01428
"IRP_MJ_QUERY_INFORMATION",
01429
"IRP_MJ_SET_INFORMATION",
01430
"IRP_MJ_QUERY_EA",
01431
"IRP_MJ_SET_EA",
01432
"IRP_MJ_FLUSH_BUFFERS",
01433
"IRP_MJ_QUERY_VOLUME_INFORMATION",
01434
"IRP_MJ_SET_VOLUME_INFORMATION",
01435
"IRP_MJ_DIRECTORY_CONTROL",
01436
"IRP_MJ_FILE_SYSTEM_CONTROL",
01437
"IRP_MJ_DEVICE_CONTROL",
01438
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
01439
"IRP_MJ_SHUTDOWN",
01440
"IRP_MJ_LOCK_CONTROL",
01441
"IRP_MJ_CLEANUP",
01442
"IRP_MJ_CREATE_MAILSLOT",
01443
"IRP_MJ_QUERY_SECURITY",
01444
"IRP_MJ_SET_SECURITY",
01445
"IRP_MJ_POWER",
01446
"IRP_MJ_SYSTEM_CONTROL",
01447
"IRP_MJ_DEVICE_CHANGE",
01448
"IRP_MJ_QUERY_QUOTA",
01449
"IRP_MJ_SET_QUOTA",
01450
"IRP_MJ_PNP",
01451
NULL
01452 } ;
01453
01454 #define MAX_NAMED_MAJOR_IRPS 0x1b
01455
01456
01457 PCHAR
PnPIrpNames[] = {
01458
"IRP_MN_START_DEVICE",
01459
"IRP_MN_QUERY_REMOVE_DEVICE",
01460
"IRP_MN_REMOVE_DEVICE - ",
01461
"IRP_MN_CANCEL_REMOVE_DEVICE",
01462
"IRP_MN_STOP_DEVICE",
01463
"IRP_MN_QUERY_STOP_DEVICE",
01464
"IRP_MN_CANCEL_STOP_DEVICE",
01465
"IRP_MN_QUERY_DEVICE_RELATIONS",
01466
"IRP_MN_QUERY_INTERFACE",
01467
"IRP_MN_QUERY_CAPABILITIES",
01468
"IRP_MN_QUERY_RESOURCES",
01469
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
01470
"IRP_MN_QUERY_DEVICE_TEXT",
01471
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
01472
"INVALID_IRP_CODE",
01473
"IRP_MN_READ_CONFIG",
01474
"IRP_MN_WRITE_CONFIG",
01475
"IRP_MN_EJECT",
01476
"IRP_MN_SET_LOCK",
01477
"IRP_MN_QUERY_ID",
01478
"IRP_MN_QUERY_PNP_DEVICE_STATE",
01479
"IRP_MN_QUERY_BUS_INFORMATION",
01480
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
01481
"IRP_MN_SURPRISE_REMOVAL",
01482
"IRP_MN_QUERY_LEGACY_BUS_INFORMATION",
01483
NULL
01484 } ;
01485
01486 #define MAX_NAMED_PNP_IRP 0x18
01487
01488 PCHAR
WmiIrpNames[] = {
01489
"IRP_MN_QUERY_ALL_DATA",
01490
"IRP_MN_QUERY_SINGLE_INSTANCE",
01491
"IRP_MN_CHANGE_SINGLE_INSTANCE",
01492
"IRP_MN_CHANGE_SINGLE_ITEM",
01493
"IRP_MN_ENABLE_EVENTS",
01494
"IRP_MN_DISABLE_EVENTS",
01495
"IRP_MN_ENABLE_COLLECTION",
01496
"IRP_MN_DISABLE_COLLECTION",
01497
"IRP_MN_REGINFO",
01498
"IRP_MN_EXECUTE_METHOD",
01499
NULL
01500 } ;
01501
01502 #define MAX_NAMED_WMI_IRP 0x9
01503
01504 PCHAR
PowerIrpNames[] = {
01505
"IRP_MN_WAIT_WAKE",
01506
"IRP_MN_POWER_SEQUENCE",
01507
"IRP_MN_SET_POWER",
01508
"IRP_MN_QUERY_POWER",
01509
NULL
01510 } ;
01511
01512 #define MAX_NAMED_POWER_IRP 0x3
01513
01514
01515
VOID
01516 IopDriverCorrectnessPrintIrpStack(
01517 IN
PIO_STACK_LOCATION IrpSp
01518 )
01519 {
01520
if ((IrpSp->MajorFunction==
IRP_MJ_INTERNAL_DEVICE_CONTROL)&&(IrpSp->MinorFunction ==
IRP_MN_SCSI_CLASS)) {
01521
01522
DbgPrint(
"IRP_MJ_SCSI") ;
01523
01524 }
else if (IrpSp->MajorFunction<=
MAX_NAMED_MAJOR_IRPS) {
01525
01526
DbgPrint(
IrpMajorNames[IrpSp->MajorFunction]) ;
01527
01528 }
else if (IrpSp->MajorFunction==0xFF) {
01529
01530
DbgPrint(
"IRP_MJ_BOGUS") ;
01531
01532 }
else {
01533
01534
DbgPrint(
"IRP_MJ_??") ;
01535 }
01536
01537
switch(IrpSp->MajorFunction) {
01538
01539
case IRP_MJ_SYSTEM_CONTROL:
01540
DbgPrint(
".") ;
01541
if (IrpSp->MinorFunction<=
MAX_NAMED_WMI_IRP) {
01542
01543
DbgPrint(
WmiIrpNames[IrpSp->MinorFunction]) ;
01544 }
else if (IrpSp->MinorFunction==0xFF) {
01545
01546
DbgPrint(
"IRP_MN_BOGUS") ;
01547 }
else {
01548
DbgPrint(
"(Bogus)\n") ;
01549 }
01550
DbgPrint(
"\n") ;
01551
break ;
01552
case IRP_MJ_PNP:
01553
DbgPrint(
".") ;
01554
if (IrpSp->MinorFunction<=
MAX_NAMED_PNP_IRP) {
01555
01556
DbgPrint(
PnPIrpNames[IrpSp->MinorFunction]) ;
01557 }
else if (IrpSp->MinorFunction==0xFF) {
01558
01559
DbgPrint(
"IRP_MN_BOGUS") ;
01560 }
else {
01561
01562
DbgPrint(
"(Bogus)\n") ;
01563 }
01564
switch(IrpSp->MinorFunction) {
01565
case IRP_MN_QUERY_DEVICE_RELATIONS:
01566
01567
switch(IrpSp->Parameters.QueryDeviceRelations.Type) {
01568
case BusRelations:
01569
DbgPrint(
"(BusRelations)") ;
01570
break ;
01571
case EjectionRelations:
01572
DbgPrint(
"(EjectionRelations)") ;
01573
break ;
01574
case PowerRelations:
01575
DbgPrint(
"(PowerRelations)") ;
01576
break ;
01577
case RemovalRelations:
01578
DbgPrint(
"(RemovalRelations)") ;
01579
break ;
01580
case TargetDeviceRelation:
01581
DbgPrint(
"(TargetDeviceRelation)") ;
01582
break ;
01583
default:
01584
DbgPrint(
"(Bogus)\n") ;
01585
break ;
01586 }
01587
break ;
01588
case IRP_MN_QUERY_INTERFACE:
01589
break ;
01590
case IRP_MN_QUERY_DEVICE_TEXT:
01591
switch(IrpSp->Parameters.QueryId.IdType) {
01592
case DeviceTextDescription:
01593
DbgPrint(
"(DeviceTextDescription)") ;
01594
break ;
01595
case DeviceTextLocationInformation:
01596
DbgPrint(
"(DeviceTextLocationInformation)") ;
01597
break ;
01598
default:
01599
DbgPrint(
"(Bogus)\n") ;
01600
break ;
01601 }
01602
break ;
01603
case IRP_MN_WRITE_CONFIG:
01604
case IRP_MN_READ_CONFIG:
01605
DbgPrint(
"(WhichSpace=%x, Buffer=%x, Offset=%x, Length=%x)",
01606 IrpSp->Parameters.ReadWriteConfig.WhichSpace,
01607 IrpSp->Parameters.ReadWriteConfig.Buffer,
01608 IrpSp->Parameters.ReadWriteConfig.Offset,
01609 IrpSp->Parameters.ReadWriteConfig.Length
01610 ) ;
01611
break ;
01612
case IRP_MN_SET_LOCK:
01613
if (IrpSp->Parameters.SetLock.Lock)
DbgPrint(
"(True)") ;
01614
else DbgPrint(
"(False)") ;
01615
break ;
01616
case IRP_MN_QUERY_ID:
01617
switch(IrpSp->Parameters.QueryId.IdType) {
01618
case BusQueryDeviceID:
01619
DbgPrint(
"(BusQueryDeviceID)") ;
01620
break ;
01621
case BusQueryHardwareIDs:
01622
DbgPrint(
"(BusQueryHardwareIDs)") ;
01623
break ;
01624
case BusQueryCompatibleIDs:
01625
DbgPrint(
"(BusQueryCompatibleIDs)") ;
01626
break ;
01627
case BusQueryInstanceID:
01628
DbgPrint(
"(BusQueryInstanceID)") ;
01629
break ;
01630
default:
01631
DbgPrint(
"(Bogus)\n") ;
01632
break ;
01633 }
01634
break ;
01635
case IRP_MN_QUERY_BUS_INFORMATION:
01636
01637
break ;
01638
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
01639
switch(IrpSp->Parameters.UsageNotification.Type) {
01640
case DeviceUsageTypeUndefined:
01641
DbgPrint(
"(DeviceUsageTypeUndefined") ;
01642
break ;
01643
case DeviceUsageTypePaging:
01644
DbgPrint(
"(DeviceUsageTypePaging") ;
01645
break ;
01646
case DeviceUsageTypeHibernation:
01647
DbgPrint(
"(DeviceUsageTypeHibernation") ;
01648
break ;
01649
case DeviceUsageTypeDumpFile:
01650
DbgPrint(
"(DeviceUsageTypeDumpFile") ;
01651
break ;
01652
default:
01653
DbgPrint(
"(Bogus)\n") ;
01654
break ;
01655 }
01656
if (IrpSp->Parameters.UsageNotification.InPath) {
01657
DbgPrint(
", InPath=TRUE)") ;
01658 }
else {
01659
DbgPrint(
", InPath=FALSE)") ;
01660 }
01661
break ;
01662
case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
01663
01664
break ;
01665
default:
01666
break ;
01667 }
01668
DbgPrint(
"\n") ;
01669
break ;
01670
01671
case IRP_MJ_POWER:
01672
DbgPrint(
".") ;
01673
if (IrpSp->MinorFunction<=
MAX_NAMED_POWER_IRP) {
01674
01675
DbgPrint(
PowerIrpNames[IrpSp->MinorFunction]) ;
01676 }
else if (IrpSp->MinorFunction==0xFF) {
01677
01678
DbgPrint(
"IRP_MN_BOGUS") ;
01679 }
else {
01680
DbgPrint(
"(Bogus)\n") ;
01681 }
01682
DbgPrint(
"\n") ;
01683
break ;
01684
01685
default:
01686
DbgPrint(
"\n") ;
01687
break ;
01688 }
01689 }
01690
#endif // NO_SPECIAL_IRP
01691