test: flunkirp.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# flunkirp.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1998  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     flunkirp.c
    00008
    00009 Abstract:
    00010
    00011     Note to people hitting bugs in these code paths due to core changes:
    00012
    00013     -   "This file is NOT vital to operation of the OS, and could easily be
    00014          disabled while a redesign to compensate for the core change is
    00015          implemented." - the author
    00016
    00017     This module asserts Irps are handled correctly by drivers.
    00018
    00019 To Do:
    00020
    00021       **. Fail non-OS initiators of certain IRPs
    00022
    00023 Author:
    00024
    00025     Adrian J. Oney (adriao) 20-Apr-1998
    00026
    00027 Environment:
    00028
    00029     Kernel mode
    00030
    00031 Revision History:
    00032
    00033 Known BUGBUGs:
    00034
    00035    >ADRIAO BUGBUG   #07 05/11/98 - Add a pass-through filter at every attach.
    00036    ADRIAO BUGBUG   #03 06/05/98 - Need more chaff. Very much more.
    00037    ADRIAO BUGBUG   #06 06/11/98 - Figure out when (Internal_)Device_Control
    00038                                   IRPs must be sent at IRQL<DISPATCH_LEVEL...
    00039 Known HACKHACKs:
    00040
    00041    ADRIAO HACKHACK 08/16/1999 - Fix ACPI to enable more chaff.
    00042                                 (HACKHACK_FOR_ACPI)
    00043
    00044 --*/
    00045
    00046 #include "iop.h"
    00047 #include "ob.h"
    00048
    00049 #if (( defined(_X86_) ) && ( FPO ))
    00050 #pragma optimize( "y", off )    // disable FPO for consistent stack traces
    00051 #endif
    00052
    00053 //
    00054 // This entire file is only present if NO_SPECIAL_IRP isn't defined
    00055 //
    00056 #ifndef NO_SPECIAL_IRP
    00057
    00058 //
    00059 // When enabled, everything is locked down on demand...
    00060 //
    00061 #ifdef ALLOC_PRAGMA
    00062 #pragma alloc_text(PAGEVRFY, IovpAssertIsNewRequest)
    00063 #pragma alloc_text(PAGEVRFY, IovpAssertNewIrps)
    00064 #pragma alloc_text(PAGEVRFY, IovpAssertFinalIrpStack)
    00065 #pragma alloc_text(PAGEVRFY, IovpAssertNewRequest)
    00066 #pragma alloc_text(PAGEVRFY, IovpAssertIrpStackDownward)
    00067 #pragma alloc_text(PAGEVRFY, IovpAssertIrpStackUpward)
    00068 #pragma alloc_text(PAGEVRFY, IovpThrowChaffAtStartedPdoStack)
    00069 #pragma alloc_text(PAGEVRFY, IovpThrowBogusSynchronousIrp)
    00070 #pragma alloc_text(PAGEVRFY, IovpStartObRefMonitoring)
    00071 #pragma alloc_text(PAGEVRFY, IovpStopObRefMonitoring)
    00072 #pragma alloc_text(PAGEVRFY, IovpIsSystemRestrictedIrp)
    00073 #endif
    00074
    00075 extern PUCHAR PnPIrpNames[];
    00076
    00077 #include <initguid.h>
    00078 DEFINE_GUID( GUID_BOGUS_INTERFACE, 0x00000000L, 0x0000, 0x0000,
    00079 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
    00080
    00081 PCHAR
    00082 KeBugCheckUnicodeToAnsi(
    00083     IN PUNICODE_STRING UnicodeString,
    00084     OUT PCHAR AnsiBuffer,
    00085     IN ULONG MaxAnsiLength
    00086     );
    00087
    00088 BOOLEAN
    00089 IovpAssertIsNewRequest(
    00090     IN PIO_STACK_LOCATION   IrpLastSp OPTIONAL,
    00091     IN PIO_STACK_LOCATION   IrpSp
    00092     )
    00093 /*++
    00094
    00095   Description:
    00096
    00097      Determines whether the two Irp stacks refer to the same "request",
    00098      ie starting the same device, etc. This is used to detect whether an IRP
    00099      has been simply forwarded or rather the IRP has been reused to initiate
    00100      a new request.
    00101
    00102   Arguments:
    00103
    00104      The two IRP stacks to compare.
    00105
    00106      N.B. - the device object is not currently part of those IRP stacks.
    00107
    00108   Return Value:
    00109
    00110      TRUE if the stacks represent the same request, FALSE otherwise.
    00111
    00112 --*/
    00113 {
    00114     return ((IrpLastSp==NULL)||
    00115         (IrpSp->MajorFunction != IrpLastSp->MajorFunction) ||
    00116         (IrpSp->MinorFunction != IrpLastSp->MinorFunction));
    00117 }
    00118
    00119 BOOLEAN
    00120 IovpAssertDoAdvanceStatus(
    00121     IN     PIO_STACK_LOCATION   IrpSp,
    00122     IN     NTSTATUS             OriginalStatus,
    00123     IN OUT NTSTATUS             *StatusToAdvance
    00124     )
    00125 /*++
    00126
    00127   Description:
    00128
    00129      Given an IRP stack pointer, is it legal to change the status for
    00130      debug-ability? If so, this function determines what the new status
    00131      should be. Note that for each stack location, this function is iterated
    00132      over n times where n is equal to the number of drivers who IoSkip'd this
    00133      location.
    00134
    00135   Arguments:
    00136
    00137      IrpSp           - Current stack right after complete for the given stack
    00138                        location, but before the completion routine for the
    00139                        stack location above has been called.
    00140
    00141      OriginalStatus  - The status of the IRP at the time listed above. Does
    00142                        not change over iteration per skipping driver.
    00143
    00144      StatusToAdvance - Pointer to the current status that should be updated.
    00145
    00146   Return Value:
    00147
    00148      TRUE if the status has been adjusted, FALSE otherwise.
    00149
    00150 --*/
    00151 {
    00152     switch(IrpSp->MajorFunction) {
    00153
    00154         case IRP_MJ_PNP:
    00155         case IRP_MJ_POWER:
    00156             if (((ULONG) OriginalStatus) < 256) {
    00157
    00158                 (*StatusToAdvance)++;
    00159                 if ((*StatusToAdvance) == STATUS_PENDING) {
    00160                     (*StatusToAdvance)++;
    00161                 }
    00162                 return TRUE;
    00163             }
    00164             break;
    00165
    00166         default:
    00167             break;
    00168     }
    00169     return FALSE;
    00170 }
    00171
    00172 VOID
    00173 IovpAssertNewIrps(
    00174     IN PIOV_REQUEST_PACKET  IrpTrackingData,
    00175     IN PIO_STACK_LOCATION   IrpSp,
    00176     IN PIOV_STACK_LOCATION  StackLocationData
    00177     )
    00178 {
    00179 }
    00180
    00181 VOID
    00182 IovpAssertFinalIrpStack(
    00183     IN PIOV_REQUEST_PACKET  IrpTrackingData,
    00184     IN PIO_STACK_LOCATION   IrpSp
    00185     )
    00186 {
    00187     ASSERT(!IrpTrackingData->RefTrackingCount);
    00188 }
    00189
    00190 VOID
    00191 IovpAssertNewRequest(
    00192     IN PIOV_REQUEST_PACKET  IrpTrackingData,
    00193     IN PDEVICE_OBJECT       DeviceObject,
    00194     IN PIO_STACK_LOCATION   IrpLastSp OPTIONAL,
    00195     IN PIO_STACK_LOCATION   IrpSp,
    00196     IN PIOV_STACK_LOCATION  StackLocationData
    00197     )
    00198 {
    00199     PIRP irp = IrpTrackingData->TrackedIrp;
    00200     NTSTATUS currentStatus, lastStatus;
    00201     BOOLEAN newRequest, statusChanged, infoChanged, firstRequest;
    00202     PDEVICE_OBJECT possiblePdo;
    00203     ULONG doeFlags;
    00204     PDRIVER_OBJECT driverObject;
    00205     PDEVICE_NODE deviceNode;
    00206     UCHAR ansiBuffer[ 256 ];
    00207     PDEVICE_CAPABILITIES deviceCapabilities;
    00208
    00209     currentStatus = irp->IoStatus.Status;
    00210     lastStatus = StackLocationData->RequestsFirstStackLocation->LastStatusBlock.Status;
    00211     statusChanged = (currentStatus != lastStatus);
    00212     infoChanged = (irp->IoStatus.Information != StackLocationData->RequestsFirstStackLocation->LastStatusBlock.Information);
    00213     firstRequest = ((StackLocationData->RequestsFirstStackLocation->Flags&STACKFLAG_FIRST_REQUEST) != 0);
    00214
    00215     if ((IrpTrackingData->Flags&TRACKFLAG_IO_ALLOCATED)&&
    00216         (!(IrpTrackingData->Flags&TRACKFLAG_WATERMARKED))) {
    00217
    00218         if (IovpIsSystemRestrictedIrp(IrpSp)) {
    00219
    00220             //
    00221             // We've caught somebody initiating an IRP they shouldn't be sending!
    00222             //
    00223             // ADRIAO BUGBUG 01/02/1999 -
    00224             //     This can't be enabled until all the restricted system IRP's
    00225             // in the kernel have been watermarked!
    00226             //
    00227 #if 0
    00228             WDM_FAIL_CALLER4(
    00229                 (DCERROR_RESTRICTED_IRP, DCPARAM_IRP, irp)
    00230                 );
    00231 #endif
    00232         }
    00233     }
    00234
    00235     //
    00236     // Verify new IRPs start out life accordingly
    00237     //
    00238     switch(IrpSp->MajorFunction) {
    00239
    00240         case IRP_MJ_PNP:
    00241
    00242             if (currentStatus!=STATUS_NOT_SUPPORTED) {
    00243
    00244                 //
    00245                 // This is a special WDM (9x) compatibility hack.
    00246                 //
    00247                 if (IrpSp->MinorFunction != IRP_MN_FILTER_RESOURCE_REQUIREMENTS) {
    00248
    00249                     WDM_FAIL_CALLER4(
    00250                         (DCERROR_PNP_IRP_BAD_INITIAL_STATUS, DCPARAM_IRP, irp)
    00251                         );
    00252                 }
    00253
    00254                 //
    00255                 // Don't blame anyone else for this guy's mistake.
    00256                 //
    00257                 if (!NT_SUCCESS(currentStatus)) {
    00258
    00259                     IrpTrackingData->Flags |= TRACKFLAG_PASSED_FAILURE;
    00260                 }
    00261             }
    00262
    00263             if (IrpSp->MinorFunction == IRP_MN_QUERY_CAPABILITIES) {
    00264
    00265                 deviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
    00266
    00267                 if (IopIsMemoryRangeReadable(deviceCapabilities, sizeof(DEVICE_CAPABILITIES))) {
    00268
    00269                     //
    00270                     // Verify fields are initialized correctly
    00271                     //
    00272                     if (deviceCapabilities->Version < 1) {
    00273
    00274                         //
    00275                         // Whoops, it didn't initialize the version correctly!
    00276                         //
    00277                         WDM_FAIL_CALLER4(
    00278                             (DCERROR_PNP_QUERY_CAP_BAD_VERSION, DCPARAM_IRP, irp)
    00279                             );
    00280
    00281                     }
    00282
    00283                     if (deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES)) {
    00284
    00285                         //
    00286                         // Whoops, it didn't initialize the size field correctly!
    00287                         //
    00288                         WDM_FAIL_CALLER4(
    00289                             (DCERROR_PNP_QUERY_CAP_BAD_SIZE, DCPARAM_IRP, irp)
    00290                             );
    00291                     }
    00292
    00293                     if (deviceCapabilities->Address != (ULONG) -1) {
    00294
    00295                         //
    00296                         // Whoops, it didn't initialize the address field correctly!
    00297                         //
    00298                         WDM_FAIL_CALLER4(
    00299                             (DCERROR_PNP_QUERY_CAP_BAD_ADDRESS, DCPARAM_IRP, irp)
    00300                             );
    00301                     }
    00302
    00303                     if (deviceCapabilities->UINumber != (ULONG) -1) {
    00304
    00305                         //
    00306                         // Whoops, it didn't initialize the UI number field correctly!
    00307                         //
    00308                         WDM_FAIL_CALLER4(
    00309                             (DCERROR_PNP_QUERY_CAP_BAD_UI_NUM, DCPARAM_IRP, irp)
    00310                             );
    00311                     }
    00312                 }
    00313             }
    00314
    00315             break;
    00316
    00317         case IRP_MJ_POWER:
    00318             if (currentStatus!=STATUS_NOT_SUPPORTED) {
    00319
    00320                 WDM_FAIL_CALLER6(
    00321                     (DCERROR_POWER_IRP_BAD_INITIAL_STATUS, DCPARAM_IRP, irp)
    00322                     );
    00323
    00324                 //
    00325                 // Don't blame anyone else for this guy's mistake.
    00326                 //
    00327                 if (!NT_SUCCESS(currentStatus)) {
    00328
    00329                     IrpTrackingData->Flags |= TRACKFLAG_PASSED_FAILURE;
    00330                 }
    00331             }
    00332             break;
    00333
    00334         case IRP_MJ_SYSTEM_CONTROL:
    00335
    00336             if (currentStatus!=STATUS_NOT_SUPPORTED) {
    00337
    00338                 WDM_FAIL_CALLER4(
    00339                     (DCERROR_WMI_IRP_BAD_INITIAL_STATUS, DCPARAM_IRP, irp)
    00340                     );
    00341
    00342                 //
    00343                 // Don't blame anyone else for this guy's mistake.
    00344                 //
    00345                 if (!NT_SUCCESS(currentStatus)) {
    00346
    00347                     IrpTrackingData->Flags |= TRACKFLAG_PASSED_FAILURE;
    00348                 }
    00349             }
    00350             break;
    00351
    00352         default:
    00353             break;
    00354     }
    00355
    00356     //
    00357     // If this is a target device relation IRP, verify the appropriate
    00358     // object will be referenced.
    00359     //
    00360     if ((IrpSp->MajorFunction == IRP_MJ_PNP)&&
    00361         (IrpSp->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)&&
    00362         (IrpSp->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)) {
    00363
    00364         possiblePdo = IovpGetLowestDevice(DeviceObject);
    00365         if (possiblePdo) {
    00366
    00367             if ((possiblePdo->DeviceObjectExtension->DeviceNode)&&(StackLocationData->ReferencingObject == NULL)) {
    00368
    00369                 //
    00370                 // Got'm!
    00371                 //
    00372                 StackLocationData->Flags |= STACKFLAG_CHECK_FOR_REFERENCE;
    00373                 StackLocationData->ReferencingObject = possiblePdo;
    00374                 StackLocationData->ReferencingCount = IovpStartObRefMonitoring(possiblePdo);
    00375                 IrpTrackingData->RefTrackingCount++;
    00376             }
    00377
    00378             //
    00379             // Free our reference (we will have one if we are snapshotting anyway)
    00380             //
    00381             ObDereferenceObject(possiblePdo);
    00382         }
    00383     }
    00384
    00385 /*
    00386     //
    00387     // Print out some stuff...
    00388     //
    00389     if (IrpSp->MajorFunction == IRP_MJ_PNP) {
    00390         switch(IrpSp->MinorFunction) {
    00391
    00392             case IRP_MN_QUERY_DEVICE_RELATIONS:
    00393                 if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) {
    00394                     break;
    00395                 }
    00396
    00397                 //
    00398                 // Fall through...
    00399                 //
    00400
    00401             case IRP_MN_START_DEVICE:
    00402             case IRP_MN_REMOVE_DEVICE:
    00403             case IRP_MN_STOP_DEVICE:
    00404                 possiblePdo = IovpGetLowestDevice(DeviceObject) ;
    00405                 deviceNode = (PDEVICE_NODE) possiblePdo->DeviceObjectExtension->DeviceNode ;
    00406
    00407                 if (deviceNode) {
    00408
    00409                     strcpy(ansiBuffer, "<not set>") ;
    00410
    00411                     if (deviceNode->InstancePath.Buffer) {
    00412
    00413                         KeBugCheckUnicodeToAnsi( &deviceNode->InstancePath, ansiBuffer, sizeof( ansiBuffer ));
    00414                     }
    00415
    00416                     DbgPrint("PNP: %s ( %08lx) initiating IRP_MJ_PNP.%s\n",
    00417                         ansiBuffer,
    00418                         possiblePdo,
    00419                         PnPIrpNames[IrpSp->MinorFunction]
    00420                         );
    00421                 }
    00422
    00423                 ObDereferenceObject(possiblePdo) ;
    00424                 break;
    00425             default:
    00426                 break;
    00427         }
    00428     }
    00429 */
    00430 }
    00431
    00432 VOID
    00433 IovpAssertIrpStackDownward(
    00434     IN PIOV_REQUEST_PACKET  IrpTrackingData,
    00435     IN PDEVICE_OBJECT       DeviceObject,
    00436     IN PIO_STACK_LOCATION   IrpLastSp OPTIONAL,
    00437     IN PIO_STACK_LOCATION   IrpSp,
    00438     IN PIOV_STACK_LOCATION  StackLocationData
    00439     )
    00440 {
    00441     PIRP irp = IrpTrackingData->TrackedIrp;
    00442     NTSTATUS currentStatus, lastStatus;
    00443     BOOLEAN newRequest, statusChanged, infoChanged, firstRequest;
    00444     PDEVICE_OBJECT possiblePdo;
    00445     ULONG doeFlags;
    00446     PDRIVER_OBJECT driverObject;
    00447     PDEVICE_NODE deviceNode;
    00448     UCHAR ansiBuffer[ 256 ];
    00449     PDEVICE_CAPABILITIES deviceCapabilities;
    00450     PIOV_SESSION_DATA iovSessionData;
    00451
    00452     currentStatus = irp->IoStatus.Status;
    00453     lastStatus = StackLocationData->RequestsFirstStackLocation->LastStatusBlock.Status;
    00454     statusChanged = (currentStatus != lastStatus);
    00455     infoChanged = (irp->IoStatus.Information != StackLocationData->RequestsFirstStackLocation->LastStatusBlock.Information);
    00456     firstRequest = ((StackLocationData->RequestsFirstStackLocation->Flags&STACKFLAG_FIRST_REQUEST) != 0);
    00457     iovSessionData = IovpTrackingDataGetCurrentSessionData(IrpTrackingData);
    00458
    00459     //
    00460     // Do we have a "new" function to process?
    00461     //
    00462     newRequest = IovpAssertIsNewRequest(IrpLastSp, IrpSp);
    00463
    00464     //
    00465     // Verify the IRP was forwarded properly
    00466     //
    00467     switch(iovSessionData->ForwardMethod) {
    00468
    00469         case SKIPPED_A_DO:
    00470
    00471             switch(IrpSp->MajorFunction) {
    00472                 case IRP_MJ_PNP:
    00473                 case IRP_MJ_SYSTEM_CONTROL:
    00474
    00475                     WDM_FAIL_CALLER4(
    00476                         (DCERROR_SKIPPED_DEVICE_OBJECT, DCPARAM_IRP, irp)
    00477                         );
    00478
    00479                     break;
    00480                 case IRP_MJ_POWER:
    00481                     //
    00482                     // Unwind back through PoCallDriver...
    00483                     //
    00484                     WDM_FAIL_CALLER6(
    00485                         (DCERROR_SKIPPED_DEVICE_OBJECT, DCPARAM_IRP, irp)
    00486                         );
    00487
    00488                     break;
    00489
    00490                 default:
    00491                     break;
    00492
    00493             }
    00494             break;
    00495
    00496         case STARTED_TOP_OF_STACK:
    00497         case FORWARDED_TO_NEXT_DO:
    00498             //
    00499             // Perfectly normal
    00500             //
    00501             break;
    00502
    00503         case STARTED_INSIDE_STACK:
    00504             //
    00505             // Probably an Internal irp (query cap's, etc)
    00506             //
    00507             break;
    00508
    00509         case CHANGED_STACKS_MID_STACK:
    00510             //ASSERT(0);
    00511             break ;
    00512
    00513         case CHANGED_STACKS_AT_BOTTOM:
    00514
    00515             //
    00516             // This is scary as we are very likely to run out of
    00517             // stack locations. In theory, it is safe to do this if one
    00518             // is careful though...
    00519             //
    00520             // ADRIAO BUGBUG ?? - I should check to see if there are
    00521             //                    enough theoritical stack locations:
    00522             //                    If there are we may be OK. Also
    00523             //                    verify the "jump" in stack loc's from
    00524             //                    the lower dude (5 to 8 instead of 5 to 6)
    00525             //                    account for the stack size of the
    00526             //                    "outbound" forward (ie, 2)
    00527 #if 0
    00528             switch(IrpSp->MajorFunction) {
    00529                 case IRP_MJ_PNP:
    00530                     ASSERT(0);
    00531             }
    00532 #endif
    00533             break ;
    00534     }
    00535
    00536     //
    00537     // For some IRP major's going down a stack, there *must* be a handler
    00538     //
    00539     driverObject = DeviceObject->DriverObject;
    00540     switch(IrpSp->MajorFunction) {
    00541
    00542         case IRP_MJ_PNP:
    00543             //
    00544             // Umm, this would be waaay too bizarre to fail. Actually, video
    00545             // miniports do this. Yick.
    00546             //
    00547 #if 0
    00548             ASSERT((driverObject->MajorFunction[IrpSp->MajorFunction] != IopInvalidDeviceRequest) ||
    00549                     ((DeviceObject->DeviceObjectExtension->DeviceNode == NULL) &&
    00550                     (DeviceObject->DeviceObjectExtension->AttachedTo == NULL)));
    00551 #endif
    00552             break;
    00553
    00554         case IRP_MJ_POWER:
    00555         case IRP_MJ_SYSTEM_CONTROL:
    00556             if (driverObject->MajorFunction[IrpSp->MajorFunction] == IopInvalidDeviceRequest) {
    00557
    00558                 WDM_FAIL_ROUTINE((
    00559                     DCERROR_MISSING_DISPATCH_FUNCTION,
    00560                     DCPARAM_IRP + DCPARAM_ROUTINE,
    00561                     irp,
    00562                     driverObject->MajorFunction[IRP_MJ_PNP]
    00563                     ));
    00564
    00565                 StackLocationData->Flags |= STACKFLAG_NO_HANDLER;
    00566             }
    00567             break;
    00568
    00569         default:
    00570             break;
    00571     }
    00572
    00573     //
    00574     // Verify IRQL's are legal
    00575     //
    00576     switch(IrpSp->MajorFunction) {
    00577
    00578         case IRP_MJ_POWER:
    00579         case IRP_MJ_READ:
    00580         case IRP_MJ_WRITE:
    00581
    00582             //
    00583             // Fall through
    00584             //
    00585             // ADRIAO BUGBUG #06 06/11/98 - Figure out when the next two are
    00586             // restricted to IRQL<DISPATCH_LEVEL...
    00587             //
    00588         case IRP_MJ_DEVICE_CONTROL:
    00589         case IRP_MJ_INTERNAL_DEVICE_CONTROL:
    00590             break;
    00591         default:
    00592             if (iovSessionData->ForwardMethod != FORWARDED_TO_NEXT_DO) {
    00593                 break;
    00594             }
    00595
    00596             if ((IrpTrackingData->CallerIrql >= DISPATCH_LEVEL) &&
    00597                 (!(IrpTrackingData->Flags & TRACKFLAG_PASSED_AT_BAD_IRQL))) {
    00598
    00599                 WDM_FAIL_CALLER4(
    00600                     (DCERROR_DISPATCH_CALLED_AT_BAD_IRQL, DCPARAM_IRP, irp)
    00601                     );
    00602
    00603                 IrpTrackingData->Flags |= TRACKFLAG_PASSED_AT_BAD_IRQL;
    00604             }
    00605     }
    00606
    00607     //
    00608     // The following is only executed if we are not a new IRP...
    00609     //
    00610     if (IrpLastSp == NULL) {
    00611         return;
    00612     }
    00613
    00614     //
    00615     // Let's verify bogus IRPs haven't been touched...
    00616     //
    00617     // BUGBUG ADRIAO ?? - Invent better Info/Status/Func memory...
    00618     //
    00619     if (IrpTrackingData->Flags&TRACKFLAG_BOGUS) {
    00620
    00621         if (newRequest && (!firstRequest)) {
    00622
    00623             WDM_FAIL_CALLER4(
    00624                 (DCERROR_BOGUS_FUNC_TRASHED, DCPARAM_IRP, irp)
    00625                 );
    00626         }
    00627
    00628         if (statusChanged) {
    00629
    00630             if (IrpSp->MinorFunction == 0xFF) {
    00631
    00632                 WDM_FAIL_CALLER4(
    00633                     (DCERROR_BOGUS_MINOR_STATUS_TRASHED, DCPARAM_IRP, irp)
    00634                     );
    00635
    00636             } else {
    00637
    00638                 WDM_FAIL_CALLER4(
    00639                     (DCERROR_BOGUS_STATUS_TRASHED, DCPARAM_IRP, irp)
    00640                     );
    00641             }
    00642
    00643         }
    00644
    00645         if (infoChanged) {
    00646
    00647             WDM_FAIL_CALLER4(
    00648                 (DCERROR_BOGUS_INFO_TRASHED, DCPARAM_IRP, irp)
    00649                 );
    00650         }
    00651     }
    00652
    00653     //
    00654     // Verify PnP IRPs
    00655     //
    00656     // ADRIAO BUGBUG 01/02/1999 -
    00657     //     This doesn't quite work right for RAW PDO's, as they in truth have
    00658     // no one to IoCallDriver so we never see those IRPs. This needs to be
    00659     // *request* based in the upward code...
    00660     //
    00661     if (IrpSp->MajorFunction == IRP_MJ_PNP) {
    00662
    00663         //
    00664         // The only legit failure code to pass down is STATUS_NOT_SUPPORTED
    00665         //
    00666         if ((!NT_SUCCESS(currentStatus)) && (currentStatus != STATUS_NOT_SUPPORTED) &&
    00667             (!(IrpTrackingData->Flags&TRACKFLAG_PASSED_FAILURE))) {
    00668
    00669             WDM_FAIL_CALLER4(
    00670                 (DCERROR_PNP_FAILURE_FORWARDED, DCPARAM_IRP, irp)
    00671                 );
    00672
    00673             //
    00674             // Don't blame anyone else for this dude's mistakes...
    00675             //
    00676             IrpTrackingData->Flags |= TRACKFLAG_PASSED_FAILURE;
    00677         }
    00678
    00679         //
    00680         // Status of a PnP IRP may not be converted to
    00681         // STATUS_NOT_SUPPORTED on the way down
    00682         //
    00683         if ((currentStatus == STATUS_NOT_SUPPORTED)&&statusChanged) {
    00684
    00685             WDM_FAIL_CALLER4(
    00686                 (DCERROR_PNP_IRP_STATUS_RESET, DCPARAM_IRP, irp)
    00687                 );
    00688         }
    00689
    00690         //
    00691         // Some IRPs FDO's are required to handle before passing down. And
    00692         // some IRPs should not be touched by the FDO. Assert it is so...
    00693         //
    00694         if (iovSessionData->DeviceLastCalled) {
    00695             doeFlags = iovSessionData->DeviceLastCalled->DeviceObjectExtension->ExtensionFlags;
    00696         } else {
    00697             doeFlags = 0;
    00698         }
    00699
    00700         //
    00701         // How could a Raw FDO (aka a PDO) get here? Well, a PDO could forward
    00702         // to another stack if he's purposely reserved enough stack locations
    00703         // for that eventuality...
    00704         //
    00705         //ASSERT(!(doeFlags&DOE_RAW_FDO));
    00706
    00707         if (doeFlags&DOE_DESIGNATED_FDO) {
    00708
    00709             switch(IrpSp->MinorFunction) {
    00710
    00711                 case IRP_MN_SURPRISE_REMOVAL:
    00712                     //
    00713                     // ADRIAO BUGBUG 01/22/1999 -
    00714                     //     We are exempting this IRP from support
    00715                     // (ie, voting success or failure) because it is
    00716                     // late in the product. This is in my opinion quite
    00717                     // braindead, but so be it.
    00718                     //
    00719                     break;
    00720                 case IRP_MN_START_DEVICE:
    00721                 case IRP_MN_QUERY_REMOVE_DEVICE:
    00722                 case IRP_MN_REMOVE_DEVICE:
    00723                 case IRP_MN_CANCEL_REMOVE_DEVICE:
    00724                 case IRP_MN_STOP_DEVICE:
    00725                 case IRP_MN_QUERY_STOP_DEVICE:
    00726                 case IRP_MN_CANCEL_STOP_DEVICE:
    00727
    00728                     //
    00729                     // The FDO must set the status as appropriate. If he set a
    00730                     // completion routine, he can do it there (and thus we cannot
    00731                     // check). If he has not though, we can indeed verify he has
    00732                     // responded to the IRP!
    00733                     //
    00734                     if ((currentStatus == STATUS_NOT_SUPPORTED)&&(!IrpSp->CompletionRoutine)) {
    00735
    00736                         WDM_FAIL_CALLER4(
    00737                             (DCERROR_PNP_IRP_NEEDS_FDO_HANDLING, DCPARAM_IRP, irp)
    00738                             );
    00739                     }
    00740                     break ;
    00741                 case IRP_MN_QUERY_DEVICE_RELATIONS:
    00742                     switch(IrpSp->Parameters.QueryDeviceRelations.Type) {
    00743                         case TargetDeviceRelation:
    00744                             if ((currentStatus != STATUS_NOT_SUPPORTED)&&(!(doeFlags&DOE_RAW_FDO))) {
    00745
    00746                                 WDM_FAIL_CALLER4(
    00747                                     (DCERROR_PNP_IRP_FDO_HANDS_OFF, DCPARAM_IRP, irp)
    00748                                     );
    00749                             }
    00750                             break;
    00751                        case BusRelations:
    00752                        case PowerRelations:
    00753                        case RemovalRelations:
    00754
    00755                        case EjectionRelations:
    00756
    00757                            //
    00758                            // Ejection relations are usually a bad idea for
    00759                            // FDO's - As stopping a device implies powerdown,
    00760                            // RemovalRelations are usually the proper response
    00761                            // for an FDO. One exception is ISAPNP, as PCI-to-ISA
    00762                            // bridges can never be powered down.
    00763                            //
    00764
    00765                        default:
    00766                            break;
    00767                     }
    00768                     break;
    00769                 case IRP_MN_QUERY_INTERFACE:
    00770                 case IRP_MN_QUERY_CAPABILITIES:
    00771                 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    00772                     break;
    00773                 case IRP_MN_QUERY_DEVICE_TEXT:
    00774                 case IRP_MN_READ_CONFIG:
    00775                 case IRP_MN_WRITE_CONFIG:
    00776                 case IRP_MN_EJECT:
    00777                 case IRP_MN_SET_LOCK:
    00778                 case IRP_MN_QUERY_RESOURCES:
    00779                 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    00780                 case IRP_MN_QUERY_BUS_INFORMATION:
    00781                     if ((currentStatus != STATUS_NOT_SUPPORTED)&&(!(doeFlags&DOE_RAW_FDO))) {
    00782
    00783                         WDM_FAIL_CALLER4(
    00784                             (DCERROR_PNP_IRP_FDO_HANDS_OFF, DCPARAM_IRP, irp)
    00785                             );
    00786                     }
    00787                     break;
    00788                 case IRP_MN_QUERY_ID:
    00789                     switch(IrpSp->Parameters.QueryId.IdType) {
    00790
    00791                         case BusQueryDeviceID:
    00792                         case BusQueryHardwareIDs:
    00793                         case BusQueryCompatibleIDs:
    00794                         case BusQueryInstanceID:
    00795                             if ((currentStatus != STATUS_NOT_SUPPORTED)&&(!(doeFlags&DOE_RAW_FDO))) {
    00796
    00797                                 WDM_FAIL_CALLER4(
    00798                                     (DCERROR_PNP_IRP_FDO_HANDS_OFF, DCPARAM_IRP, irp)
    00799                                     );
    00800                             }
    00801                             break;
    00802                         default:
    00803                             break;
    00804                     }
    00805                     break;
    00806                 case IRP_MN_QUERY_PNP_DEVICE_STATE:
    00807                 case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
    00808                     break;
    00809                 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
    00810                     //
    00811                     // ADRIAO BUGBUG 09/25/98 - Is this really optional for an FDO?
    00812                     //
    00813                     break;
    00814                 default:
    00815                     break;
    00816             }
    00817         }
    00818     }
    00819
    00820     //
    00821     // Verify Power IRPs
    00822     //
    00823     if (IrpSp->MajorFunction == IRP_MJ_POWER) {
    00824
    00825         //
    00826         // The only legit failure code to pass down is STATUS_NOT_SUPPORTED
    00827         //
    00828         if ((!NT_SUCCESS(currentStatus)) && (currentStatus != STATUS_NOT_SUPPORTED) &&
    00829             (!(IrpTrackingData->Flags&TRACKFLAG_PASSED_FAILURE))) {
    00830
    00831             WDM_FAIL_CALLER6(
    00832                 (DCERROR_POWER_FAILURE_FORWARDED, DCPARAM_IRP, irp)
    00833                 );
    00834
    00835             //
    00836             // Don't blame anyone else for this dude's mistakes...
    00837             //
    00838             IrpTrackingData->Flags |= TRACKFLAG_PASSED_FAILURE;
    00839         }
    00840
    00841         //
    00842         // Status of a Power IRP may not be converted to
    00843         // STATUS_NOT_SUPPORTED on the way down
    00844         //
    00845         if ((currentStatus == STATUS_NOT_SUPPORTED)&&statusChanged) {
    00846
    00847             WDM_FAIL_CALLER6(
    00848                 (DCERROR_POWER_IRP_STATUS_RESET, DCPARAM_IRP, irp)
    00849                 );
    00850         }
    00851     }
    00852
    00853     if (!IovpAssertIsValidIrpStatus(IrpSp, currentStatus)) {
    00854
    00855         switch(IrpSp->MajorFunction) {
    00856             case IRP_MJ_POWER:
    00857
    00858                 WDM_FAIL_CALLER6((DCERROR_INVALID_STATUS, DCPARAM_IRP, irp));
    00859                 break;
    00860
    00861             default:
    00862
    00863                 WDM_FAIL_CALLER4((DCERROR_INVALID_STATUS, DCPARAM_IRP, irp));
    00864                 break;
    00865         }
    00866     }
    00867 }
    00868
    00869 VOID
    00870 IovpAssertIrpStackUpward(
    00871     IN PIOV_REQUEST_PACKET  IrpTrackingData,
    00872     IN PIO_STACK_LOCATION   IrpSp,
    00873     IN PIOV_STACK_LOCATION  StackLocationData,
    00874     IN BOOLEAN              IsNewlyCompleted,
    00875     IN BOOLEAN              RequestFinalized
    00876     )
    00877 {
    00878     PIRP irp = IrpTrackingData->TrackedIrp;
    00879     NTSTATUS currentStatus, lastStatus;
    00880     BOOLEAN mustPassDown, isBogusIrp, isPdo, statusChanged, infoChanged;
    00881     PIOV_STACK_LOCATION originalRequestSLD;
    00882     PVOID routine;
    00883     LONG referencesTaken;
    00884     PDEVICE_OBJECT possiblePdo;
    00885     PDEVICE_NODE deviceNode;
    00886     UCHAR ansiBuffer[ 256 ];
    00887
    00888     currentStatus = irp->IoStatus.Status;
    00889     lastStatus = StackLocationData->RequestsFirstStackLocation->LastStatusBlock.Status;
    00890     statusChanged = (currentStatus != lastStatus);
    00891     infoChanged = (irp->IoStatus.Information != StackLocationData->RequestsFirstStackLocation->LastStatusBlock.Information);
    00892
    00893     //
    00894     // Who'd we call for this one?
    00895     //
    00896     routine = StackLocationData->LastDispatch;
    00897     ASSERT(routine) ;
    00898
    00899     //
    00900     // If this "Request" has been "Completed", perform some checks
    00901     //
    00902     if (IsNewlyCompleted) {
    00903
    00904         //
    00905         // Remember bogosity...
    00906         //
    00907         isBogusIrp = ((IrpTrackingData->Flags&TRACKFLAG_BOGUS)!=0);
    00908
    00909         //
    00910         // Is this a PDO?
    00911         //
    00912         isPdo = ((StackLocationData->Flags&STACKFLAG_REACHED_PDO)!=0);
    00913
    00914         //
    00915         // Was anything completed too early?
    00916         // A driver may outright fail almost anything but a bogus IRP
    00917         //
    00918         mustPassDown = (!(StackLocationData->Flags&STACKFLAG_NO_HANDLER));
    00919         mustPassDown &= (!isPdo);
    00920
    00921         switch(IrpSp->MajorFunction) {
    00922
    00923             case IRP_MJ_SYSTEM_CONTROL:
    00924                 mustPassDown &= ((PDEVICE_OBJECT) IrpSp->Parameters.WMI.ProviderId != IrpSp->DeviceObject);
    00925                 if (mustPassDown) {
    00926
    00927                      WDM_FAIL_ROUTINE((
    00928                          DCERROR_WMI_IRP_NOT_FORWARDED,
    00929                          DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ,
    00930                          irp,
    00931                          routine,
    00932                          IrpSp->Parameters.WMI.ProviderId
    00933                          ));
    00934                 }
    00935                 break;
    00936
    00937             case IRP_MJ_PNP:
    00938                 mustPassDown &= (isBogusIrp || NT_SUCCESS(currentStatus) || (currentStatus == STATUS_NOT_SUPPORTED));
    00939                 if (mustPassDown) {
    00940
    00941                     //
    00942                     // Print appropriate error message
    00943                     //
    00944                     if (IrpTrackingData->Flags&TRACKFLAG_BOGUS) {
    00945
    00946                         WDM_FAIL_ROUTINE((
    00947                             DCERROR_BOGUS_PNP_IRP_COMPLETED,
    00948                             DCPARAM_IRP + DCPARAM_ROUTINE,
    00949                             irp,
    00950                             routine
    00951                             ));
    00952
    00953                     } else if (NT_SUCCESS(currentStatus)) {
    00954
    00955                         WDM_FAIL_ROUTINE((
    00956                             DCERROR_SUCCESSFUL_PNP_IRP_NOT_FORWARDED,
    00957                             DCPARAM_IRP + DCPARAM_ROUTINE,
    00958                             irp,
    00959                             routine
    00960                             ));
    00961
    00962                     } else if (currentStatus == STATUS_NOT_SUPPORTED) {
    00963
    00964                         WDM_FAIL_ROUTINE((
    00965                             DCERROR_UNTOUCHED_PNP_IRP_NOT_FORWARDED,
    00966                             DCPARAM_IRP + DCPARAM_ROUTINE,
    00967                             irp,
    00968                             routine
    00969                             ));
    00970                     }
    00971                 }
    00972                 break;
    00973
    00974             case IRP_MJ_POWER:
    00975                 mustPassDown &= (isBogusIrp || NT_SUCCESS(currentStatus) || (currentStatus == STATUS_NOT_SUPPORTED));
    00976                 if (mustPassDown) {
    00977
    00978                     //
    00979                     // Print appropriate error message
    00980                     //
    00981                     if (IrpTrackingData->Flags&TRACKFLAG_BOGUS) {
    00982
    00983                         WDM_FAIL_ROUTINE((
    00984                             DCERROR_BOGUS_POWER_IRP_COMPLETED,
    00985                             DCPARAM_IRP + DCPARAM_ROUTINE,
    00986                             irp,
    00987                             routine
    00988                             ));
    00989
    00990                     } else if (NT_SUCCESS(currentStatus)) {
    00991
    00992                         WDM_FAIL_ROUTINE((
    00993                             DCERROR_SUCCESSFUL_POWER_IRP_NOT_FORWARDED,
    00994                             DCPARAM_IRP + DCPARAM_ROUTINE,
    00995                             irp,
    00996                             routine
    00997                             ));
    00998
    00999                     } else if (currentStatus == STATUS_NOT_SUPPORTED) {
    01000
    01001                         WDM_FAIL_ROUTINE((
    01002                             DCERROR_UNTOUCHED_POWER_IRP_NOT_FORWARDED,
    01003                             DCPARAM_IRP + DCPARAM_ROUTINE,
    01004                             irp,
    01005                             routine
    01006                             ));
    01007                     }
    01008                 }
    01009                 break;
    01010         }
    01011
    01012         //
    01013         // Did the PDO respond to it's required set of IRPs?
    01014         //
    01015         if (isPdo) {
    01016
    01017             switch(IrpSp->MajorFunction) {
    01018
    01019                 case IRP_MJ_PNP:
    01020
    01021                     switch(IrpSp->MinorFunction) {
    01022
    01023                         case IRP_MN_SURPRISE_REMOVAL:
    01024
    01025                             //
    01026                             // ADRIAO BUGBUG 01/22/1999 -
    01027                             //     We are exempting this IRP from support
    01028                             // (ie, voting success or failure) because it is
    01029                             // late in the product. This is in my opinion quite
    01030                             // braindead, but so be it.
    01031                             //
    01032                             break;
    01033
    01034                         case IRP_MN_START_DEVICE:
    01035                         case IRP_MN_QUERY_REMOVE_DEVICE:
    01036                         case IRP_MN_REMOVE_DEVICE:
    01037                         case IRP_MN_CANCEL_REMOVE_DEVICE:
    01038                         case IRP_MN_STOP_DEVICE:
    01039                         case IRP_MN_QUERY_STOP_DEVICE:
    01040                         case IRP_MN_CANCEL_STOP_DEVICE:
    01041                             if (currentStatus == STATUS_NOT_SUPPORTED) {
    01042
    01043                                 WDM_FAIL_ROUTINE((
    01044                                     DCERROR_PNP_IRP_NEEDS_PDO_HANDLING,
    01045                                     DCPARAM_IRP + DCPARAM_ROUTINE,
    01046                                     irp,
    01047                                     routine
    01048                                     ));
    01049                             }
    01050                             break;
    01051                         case IRP_MN_QUERY_DEVICE_RELATIONS:
    01052                             switch(IrpSp->Parameters.QueryDeviceRelations.Type) {
    01053                                 case BusRelations:
    01054                                 case PowerRelations:
    01055                                 case RemovalRelations:
    01056                                 case EjectionRelations:
    01057                                     //
    01058                                     // Optionals or FDO's
    01059                                     //
    01060                                     break;
    01061                                 case TargetDeviceRelation:
    01062                                     if (currentStatus == STATUS_NOT_SUPPORTED) {
    01063
    01064                                         WDM_FAIL_ROUTINE((
    01065                                             DCERROR_PNP_IRP_NEEDS_PDO_HANDLING,
    01066                                             DCPARAM_IRP + DCPARAM_ROUTINE,
    01067                                             irp,
    01068                                             routine
    01069                                             ));
    01070
    01071                                     } else if (NT_SUCCESS(currentStatus)) {
    01072
    01073                                         if (irp->IoStatus.Information == (ULONG_PTR) NULL) {
    01074
    01075                                             WDM_FAIL_ROUTINE((
    01076                                                 DCERROR_TARGET_RELATION_LIST_EMPTY,
    01077                                                 DCPARAM_IRP + DCPARAM_ROUTINE,
    01078                                                 irp,
    01079                                                 routine
    01080                                                 ));
    01081                                         }
    01082
    01083                                         //
    01084                                         // ADRIAO BUGBUG ?? - I could also assert the Information
    01085                                         // matches DeviceObject.
    01086                                         //
    01087                                     }
    01088                                     break;
    01089                                 default:
    01090                                     break;
    01091                             }
    01092                             break;
    01093                         case IRP_MN_QUERY_INTERFACE:
    01094                         case IRP_MN_QUERY_CAPABILITIES:
    01095                         case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    01096                         case IRP_MN_QUERY_DEVICE_TEXT:
    01097                         case IRP_MN_READ_CONFIG:
    01098                         case IRP_MN_WRITE_CONFIG:
    01099                         case IRP_MN_EJECT:
    01100                         case IRP_MN_SET_LOCK:
    01101                         case IRP_MN_QUERY_RESOURCES:
    01102                         case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    01103                         case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
    01104                             break;
    01105                         case IRP_MN_QUERY_ID:
    01106                             switch(IrpSp->Parameters.QueryId.IdType) {
    01107
    01108                                 case BusQueryDeviceID:
    01109                                 case BusQueryHardwareIDs:
    01110                                 case BusQueryCompatibleIDs:
    01111                                 case BusQueryInstanceID:
    01112                                 default:
    01113                                     break;
    01114                             }
    01115                             break ;
    01116                         case IRP_MN_QUERY_PNP_DEVICE_STATE:
    01117                         case IRP_MN_QUERY_BUS_INFORMATION:
    01118                         case IRP_MN_DEVICE_USAGE_NOTIFICATION:
    01119                         default:
    01120                             break ;
    01121                     }
    01122                 default:
    01123                     break;
    01124             }
    01125         }
    01126
    01127         //
    01128         // Was TargetDeviceRelation implemented correctly?
    01129         //
    01130         originalRequestSLD = StackLocationData->RequestsFirstStackLocation;
    01131
    01132         if (originalRequestSLD->Flags&STACKFLAG_CHECK_FOR_REFERENCE) {
    01133
    01134             ASSERT ((IrpSp->MajorFunction == IRP_MJ_PNP)&&
    01135                 (IrpSp->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)&&
    01136                 (IrpSp->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation));
    01137
    01138             ASSERT(originalRequestSLD->ReferencingObject);
    01139             ASSERT(IrpTrackingData->RefTrackingCount);
    01140
    01141             referencesTaken = IovpStopObRefMonitoring(
    01142                 originalRequestSLD->ReferencingObject,
    01143                 originalRequestSLD->ReferencingCount
    01144                 );
    01145
    01146             IrpTrackingData->RefTrackingCount--;
    01147             originalRequestSLD->ReferencingObject = NULL;
    01148
    01149             originalRequestSLD->Flags&=~STACKFLAG_CHECK_FOR_REFERENCE;
    01150
    01151             if (NT_SUCCESS(currentStatus)&&(!referencesTaken)) {
    01152
    01153                 WDM_FAIL_ROUTINE((
    01154                     DCERROR_TARGET_RELATION_NEEDS_REF,
    01155                     DCPARAM_IRP + DCPARAM_ROUTINE,
    01156                     irp,
    01157                     routine
    01158                     ));
    01159             }
    01160         }
    01161     }
    01162
    01163     //
    01164     // Did anyone stomp the status erroneously?
    01165     //
    01166     if ((currentStatus == STATUS_NOT_SUPPORTED)&&statusChanged) {
    01167
    01168         //
    01169         // Status of a PnP or Power IRP may not be converted from success to
    01170         // STATUS_NOT_SUPPORTED on the way down.
    01171         //
    01172         switch(IrpSp->MajorFunction) {
    01173
    01174             case IRP_MJ_PNP:
    01175
    01176                 WDM_FAIL_ROUTINE((
    01177                     DCERROR_PNP_IRP_STATUS_RESET,
    01178                     DCPARAM_IRP + DCPARAM_ROUTINE,
    01179                     irp,
    01180                     routine
    01181                     ));
    01182
    01183                 break;
    01184
    01185             case IRP_MJ_POWER:
    01186
    01187                 WDM_FAIL_ROUTINE((
    01188                     DCERROR_POWER_IRP_STATUS_RESET,
    01189                     DCPARAM_IRP + DCPARAM_ROUTINE,
    01190                     irp,
    01191                     routine
    01192                     ));
    01193
    01194                 break;
    01195         }
    01196     }
    01197
    01198     //
    01199     // Did they touch something stupid?
    01200     //
    01201     if (IrpTrackingData->Flags&TRACKFLAG_BOGUS) {
    01202
    01203         if (statusChanged) {
    01204
    01205             if (IrpSp->MinorFunction == 0xFF) {
    01206
    01207                 WDM_FAIL_ROUTINE((
    01208                     DCERROR_BOGUS_MINOR_STATUS_TRASHED,
    01209                     DCPARAM_IRP + DCPARAM_ROUTINE,
    01210                     irp,
    01211                     routine
    01212                     ));
    01213
    01214             } else {
    01215
    01216                 WDM_FAIL_ROUTINE((
    01217                     DCERROR_BOGUS_STATUS_TRASHED,
    01218                     DCPARAM_IRP + DCPARAM_ROUTINE,
    01219                     irp,
    01220                     routine
    01221                     ));
    01222             }
    01223         }
    01224
    01225         if (infoChanged) {
    01226
    01227             WDM_FAIL_ROUTINE((
    01228                 DCERROR_BOGUS_INFO_TRASHED,
    01229                 DCPARAM_IRP + DCPARAM_ROUTINE,
    01230                 irp,
    01231                 routine
    01232                 ));
    01233         }
    01234     }
    01235
    01236     if (!IovpAssertIsValidIrpStatus(IrpSp, currentStatus)) {
    01237
    01238         WDM_FAIL_ROUTINE(
    01239             (DCERROR_INVALID_STATUS, DCPARAM_IRP + DCPARAM_ROUTINE, irp, routine)
    01240             );
    01241     }
    01242
    01243 /*
    01244     //
    01245     // Print out some stuff...
    01246     //
    01247     if (RequestFinalized&&(IrpSp->MajorFunction == IRP_MJ_PNP)) {
    01248         switch(IrpSp->MinorFunction) {
    01249
    01250             case IRP_MN_QUERY_DEVICE_RELATIONS:
    01251                 if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) {
    01252                    break;
    01253                 }
    01254
    01255                 //
    01256                 // Fall through...
    01257                 //
    01258
    01259             case IRP_MN_START_DEVICE:
    01260             case IRP_MN_REMOVE_DEVICE:
    01261             case IRP_MN_STOP_DEVICE:
    01262                 possiblePdo = IovpGetLowestDevice(IrpSp->DeviceObject) ;
    01263                 deviceNode = (PDEVICE_NODE) possiblePdo->DeviceObjectExtension->DeviceNode ;
    01264                 if (deviceNode) {
    01265
    01266                     strcpy(ansiBuffer, "<not set>") ;
    01267
    01268                     if (deviceNode->InstancePath.Buffer) {
    01269
    01270                         KeBugCheckUnicodeToAnsi( &deviceNode->InstancePath, ansiBuffer, sizeof( ansiBuffer ));
    01271                     }
    01272
    01273                     DbgPrint("PNP: %s ( %08lx) completing IRP_MJ_PNP.%s with %08lx\n",
    01274                         ansiBuffer,
    01275                         possiblePdo,
    01276                         PnPIrpNames[IrpSp->MinorFunction],
    01277                         currentStatus
    01278                         );
    01279                 }
    01280                 ObDereferenceObject(possiblePdo) ;
    01281                 break;
    01282             default:
    01283                 break;
    01284         }
    01285     }
    01286 */
    01287 }
    01288
    01289 BOOLEAN
    01290 IovpAssertIsValidIrpStatus(
    01291     IN PIO_STACK_LOCATION IrpSp,
    01292     IN NTSTATUS Status
    01293     )
    01294 /*++
    01295
    01296     Description:
    01297         As per the title, this function determines whether an IRP status is
    01298         valid or probably random trash. See NTStatus.h for info on how status
    01299         codes break down...
    01300
    01301     Returns:
    01302
    01303         TRUE iff IRP status looks to be valid. FALSE otherwise.
    01304 --*/
    01305 {
    01306     ULONG severity;
    01307     ULONG customer;
    01308     ULONG reserved;
    01309     ULONG facility;
    01310     ULONG code;
    01311     ULONG lanManClass;
    01312
    01313     severity = (((ULONG)Status) >> 30)&3;
    01314     customer = (((ULONG)Status) >> 29)&1;
    01315     reserved = (((ULONG)Status) >> 28)&1;
    01316     facility = (((ULONG)Status) >> 16)&0xFFF;
    01317     code =     (((ULONG)Status) & 0xFFFF);
    01318
    01319     //
    01320     // If reserved set, definitely bogus...
    01321     //
    01322     if (reserved) {
    01323
    01324         return FALSE;
    01325     }
    01326
    01327     //
    01328     // Is this a microsoft defined return code? If not, do no checking.
    01329     //
    01330     if (customer) {
    01331
    01332         return TRUE;
    01333     }
    01334
    01335     //
    01336     // ADRIAO N.B. 10/04/1999 -
    01337     //     The current methodology for doling out error codes appears to be
    01338     // fairly chaotic. The primary kernel mode status codes are defined in
    01339     // ntstatus.h. However, rtl\generr.c should also be consulted to see which
    01340     // error codes can bubble up to user mode. Many OLE error codes from
    01341     // winerror.h are now being used within the kernel itself.
    01342     //
    01343     if (facility < 0x20) {
    01344
    01345         //
    01346         // Facilities under 20 are currently legal.
    01347         //
    01348         switch(severity) {
    01349             case STATUS_SEVERITY_SUCCESS:       return (code < 0x200);
    01350             case STATUS_SEVERITY_INFORMATIONAL:
    01351
    01352                 //
    01353                 // ADRIAO BUGBUG 10/09/1999 -
    01354                 //     This should really be 0x50, but we've been testing with
    01355                 // 0x400 for a while (and we don't want to change it just before
    01356                 // Win2k ships).
    01357                 //
    01358                                                 return (code < 0x400);
    01359             case STATUS_SEVERITY_WARNING:       return (code < 0x400);
    01360             case STATUS_SEVERITY_ERROR:         break;
    01361         }
    01362
    01363         //
    01364         // Why the heck does WOW use such an odd error code?
    01365         //
    01366         return (code < 0x400)||(code == 0x9898);
    01367
    01368     } else if (facility == 0x98) {
    01369
    01370         //
    01371         // This is the lan manager service. In the case on Lan Man, the code
    01372         // field is further subdivided into a class field.
    01373         //
    01374         lanManClass = code >> 12;
    01375         code &= 0xFFF;
    01376
    01377         //
    01378         // Do no testing here.
    01379         //
    01380         return TRUE;
    01381
    01382     } else {
    01383
    01384         //
    01385         // Not known, probably bogus.
    01386         //
    01387         return FALSE;
    01388     }
    01389 }
    01390
    01391 VOID
    01392 IovpThrowChaffAtStartedPdoStack(
    01393     IN PDEVICE_OBJECT DeviceObject
    01394     )
    01395 /*++
    01396
    01397     Description:
    01398         As per the title, we are going to throw some IRPs at the stack to
    01399         see if they are handled correctly.
    01400
    01401     Returns:
    01402
    01403         Nothing
    01404 --*/
    01405
    01406 {
    01407     IO_STACK_LOCATION irpSp;
    01408     PDEVICE_OBJECT lowestDeviceObject;
    01409     PDEVICE_RELATIONS targetDeviceRelationList;
    01410     INTERFACE interface;
    01411     NTSTATUS status;
    01412
    01413     PAGED_CODE();
    01414
    01415     //
    01416     // Initialize the stack location to pass to IopSynchronousCall()
    01417     //
    01418     RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION));
    01419
    01420     //
    01421     // send lots of bogus PNP IRPs
    01422     //
    01423     irpSp.MajorFunction = IRP_MJ_PNP;
    01424     irpSp.MinorFunction = 0xff;
    01425     IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) 0, NULL, TRUE);
    01426
    01427     irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS ;
    01428     irpSp.Parameters.QueryDeviceRelations.Type = (DEVICE_RELATION_TYPE) -1 ;
    01429     IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) 0, NULL, TRUE);
    01430
    01431 #ifdef HACKHACKS_ENABLED
    01432     if (!(IovpHackFlags&HACKFLAG_FOR_ACPI)) {
    01433 #endif
    01434         //
    01435         // ADRIAO HACKHACK 08/16/1999 - Fix ACPI to enable more chaff
    01436         //
    01437         irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS ;
    01438         irpSp.Parameters.QueryDeviceRelations.Type = (DEVICE_RELATION_TYPE) -1 ;
    01439         IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) -1, NULL, TRUE) ;
    01440 #ifdef HACKHACKS_ENABLED
    01441     }
    01442 #endif
    01443
    01444     irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_TEXT ;
    01445     irpSp.Parameters.QueryDeviceText.DeviceTextType = (DEVICE_TEXT_TYPE) -1 ;
    01446     IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) 0, NULL, TRUE);
    01447
    01448     irpSp.MinorFunction = IRP_MN_QUERY_ID ;
    01449     irpSp.Parameters.QueryId.IdType = (BUS_QUERY_ID_TYPE) -1 ;
    01450     IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) 0, NULL, TRUE);
    01451
    01452 #ifdef HACKHACKS_ENABLED
    01453     if (!(IovpHackFlags&HACKFLAG_FOR_BOGUSIRPS)) {
    01454 #endif
    01455
    01456         //
    01457         // Send a bogus WMI IRP
    01458         //
    01459         // Note that we aren't sending this IRP to any stack that doesn't terminate
    01460         // with a devnode. The WmiSystemControl export from WmiLib says
    01461         // "NotWmiIrp if it sees these. The callers should still pass down the
    01462         // IRP.
    01463         //
    01464         lowestDeviceObject = IovpGetLowestDevice(DeviceObject) ;
    01465         ASSERT(lowestDeviceObject) ;
    01466         ASSERT(lowestDeviceObject->DeviceObjectExtension->DeviceNode) ;
    01467
    01468         irpSp.MajorFunction = IRP_MJ_SYSTEM_CONTROL ;
    01469         irpSp.MinorFunction = 0xff;
    01470         irpSp.Parameters.WMI.ProviderId = (ULONG_PTR) lowestDeviceObject ;
    01471         IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) 0, NULL, TRUE);
    01472         ObDereferenceObject(lowestDeviceObject) ;
    01473
    01474         //
    01475         // And a bogus Power IRP
    01476         //
    01477         irpSp.MajorFunction = IRP_MJ_POWER ;
    01478         irpSp.MinorFunction = 0xff;
    01479         IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) 0, NULL, TRUE);
    01480
    01481 #ifdef HACKHACKS_ENABLED
    01482     }
    01483 #endif
    01484
    01485     //
    01486     // Target device relation test...
    01487     //
    01488     irpSp.MajorFunction = IRP_MJ_PNP ;
    01489     irpSp.MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS ;
    01490     irpSp.Parameters.QueryDeviceRelations.Type = TargetDeviceRelation ;
    01491     targetDeviceRelationList = NULL ;
    01492     status = IovpThrowBogusSynchronousIrp(
    01493         DeviceObject,
    01494         &irpSp,
    01495         (ULONG_PTR) 0,
    01496         (ULONG_PTR *) &targetDeviceRelationList,
    01497         FALSE
    01498         );
    01499
    01500     if (NT_SUCCESS(status)) {
    01501
    01502         ASSERT(targetDeviceRelationList) ;
    01503         ASSERT(targetDeviceRelationList->Count == 1) ;
    01504         ASSERT(targetDeviceRelationList->Objects[0]) ;
    01505         ObDereferenceObject(targetDeviceRelationList->Objects[0]) ;
    01506         ExFreePool(targetDeviceRelationList) ;
    01507
    01508     } else {
    01509
    01510         //
    01511         // IRP was asserted in other code. We need to do nothing here...
    01512         //
    01513     }
    01514
    01515     RtlZeroMemory(&interface, sizeof(INTERFACE));
    01516     irpSp.MinorFunction = IRP_MN_QUERY_INTERFACE;
    01517     irpSp.Parameters.QueryInterface.Size = -1;
    01518     irpSp.Parameters.QueryInterface.Version = 1;
    01519     irpSp.Parameters.QueryInterface.InterfaceType = &GUID_BOGUS_INTERFACE;
    01520     irpSp.Parameters.QueryInterface.Interface = &interface;
    01521     irpSp.Parameters.QueryInterface.InterfaceSpecificData = (PVOID) -1;
    01522     IovpThrowBogusSynchronousIrp(DeviceObject, &irpSp, (ULONG_PTR) 0, NULL, TRUE);
    01523
    01524     //
    01525     // ADRIAO BUGBUG #03 06/05/98 - Need more chaff. Very much more.
    01526     // For example, bogus device usage notifications, etc...
    01527     //
    01528 }
    01529
    01530 NTSTATUS
    01531 IovpThrowBogusSynchronousIrp(
    01532     IN PDEVICE_OBJECT DeviceObject,
    01533     IN PIO_STACK_LOCATION TopStackLocation,
    01534     IN OUT OPTIONAL ULONG_PTR Information,
    01535     IN OUT ULONG_PTR *InformationOut OPTIONAL,
    01536     IN BOOLEAN IsBogus
    01537     )
    01538
    01539 /*++
    01540
    01541 Routine Description:
    01542
    01543     This function sends a synchronous irp to the top level device
    01544     object which roots on DeviceObject. It differs from IopSynchronousIrp
    01545     in that it sets the IRP_DIAG_IS_BOGUS flag, and passes in possibly
    01546     nonzero information.
    01547
    01548 Parameters:
    01549
    01550     DeviceObject - Supplies the device object of the device being removed.
    01551
    01552     TopStackLocation - Supplies a pointer to the parameter block for the irp.
    01553
    01554 Return Value:
    01555
    01556     NTSTATUS code.
    01557
    01558 --*/
    01559
    01560 {
    01561     PIRP irp;
    01562     PIO_STACK_LOCATION irpSp;
    01563     IO_STATUS_BLOCK statusBlock;
    01564     KEVENT event;
    01565     NTSTATUS status;
    01566     PDEVICE_OBJECT topDeviceObject;
    01567
    01568     PAGED_CODE();
    01569
    01570     //
    01571     // Get a pointer to the topmost device object in the stack of devices,
    01572     // beginning with the deviceObject.
    01573     //
    01574
    01575     topDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
    01576
    01577     //
    01578     // Begin by allocating the IRP for this request.  Do not charge quota to
    01579     // the current process for this IRP.
    01580     //
    01581
    01582     irp = IoAllocateIrp(topDeviceObject->StackSize, FALSE);
    01583     if (irp == NULL){
    01584
    01585         ObDereferenceObject(topDeviceObject) ;
    01586         return STATUS_INSUFFICIENT_RESOURCES;
    01587     }
    01588
    01589     if (IsBogus) {
    01590
    01591         SPECIALIRP_WATERMARK_IRP(irp, IRP_BOGUS);
    01592     }
    01593
    01594     //
    01595     // Initialize it to failure.
    01596     //
    01597     irp->IoStatus.Status = statusBlock.Status = STATUS_NOT_SUPPORTED;
    01598     irp->IoStatus.Information = statusBlock.Information = Information;
    01599
    01600     //
    01601     // Set the pointer to the status block and initialized event.
    01602     //
    01603
    01604     KeInitializeEvent( &event,
    01605                        SynchronizationEvent,
    01606                        FALSE );
    01607
    01608     irp->UserIosb = &statusBlock;
    01609     irp->UserEvent = &event;
    01610
    01611     //
    01612     // Set the address of the current thread (for debugging)
    01613     //
    01614     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    01615
    01616     //
    01617     // Queue this irp onto the current thread. We do this because we are not
    01618     // collecting this IRP with a STATUS_MORE_PROCESSING_REQUIRED completion
    01619     // routine - an APC will be scheduled and we *must* give it a thread.
    01620     //
    01621     IopQueueThreadIrp(irp);
    01622
    01623     //
    01624     // Get a pointer to the stack location of the first driver which will be
    01625     // invoked.  This is where the function codes and parameters are set.
    01626     //
    01627
    01628     irpSp = IoGetNextIrpStackLocation(irp);
    01629
    01630     //
    01631     // Copy in the caller-supplied stack location contents
    01632     //
    01633
    01634     *irpSp = *TopStackLocation;
    01635
    01636     //
    01637     // Call the driver
    01638     //
    01639
    01640     status = IoCallDriver(topDeviceObject, irp);
    01641     ObDereferenceObject(topDeviceObject) ;
    01642
    01643     //
    01644     // If a driver returns STATUS_PENDING, we will wait for it to complete
    01645     //
    01646     if (status == STATUS_PENDING) {
    01647         (VOID) KeWaitForSingleObject( &event,
    01648                                       Executive,
    01649                                       KernelMode,
    01650                                       FALSE,
    01651                                       (PLARGE_INTEGER) NULL );
    01652         status = statusBlock.Status;
    01653     }
    01654
    01655     if (InformationOut) {
    01656
    01657         *InformationOut = statusBlock.Information ;
    01658     }
    01659
    01660     return status;
    01661 }
    01662
    01663 LONG
    01664 IovpStartObRefMonitoring(
    01665     IN PDEVICE_OBJECT DeviceObject
    01666     )
    01667 /*++
    01668
    01669   Description:
    01670
    01671      Determines if ObRef has not been called between a call to this
    01672      function and a subsequent call to IovpStopObRefMonitoring.
    01673
    01674   Arguments:
    01675
    01676      Device object to monitor.
    01677
    01678   Return Value:
    01679
    01680      A start skew time to pass into IovpStopObRefMonitoring.
    01681
    01682      N.B. - A reference count is taken by this API and released
    01683             by IovpStopObRefMonitoring. That reference is not
    01684             counted among the noticed calls to ObRef.
    01685 --*/
    01686 {
    01687     //
    01688     // ADRIAO BUGBUG 10/05/1999 -
    01689     //     Parclass reroutes target-device-relation IRPs around the tree. That
    01690     // design will be fixed for NT5.1, but in the meantime this means we will
    01691     // not be able to test this driver functionality.
    01692     //
    01693 #if  0
    01694     POBJECT_HEADER ObjectHeader;
    01695     POBJECT_HEADER_NAME_INFO NameInfo;
    01696     LONG startSkew, pointerCount ;
    01697
    01698     ObReferenceObject(DeviceObject) ;
    01699
    01700     ObjectHeader = OBJECT_TO_OBJECT_HEADER(DeviceObject);
    01701     NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
    01702
    01703     ASSERT(NameInfo) ;
    01704     //
    01705     // We will always decrement DbgDereferenceCount prior to PointerCount,
    01706     // so any race conditions will look like an increment occured, which
    01707     // is an allowable misread...
    01708     //
    01709     do {
    01710         pointerCount = ObjectHeader->PointerCount ;
    01711         startSkew = pointerCount - NameInfo->DbgDereferenceCount ;
    01712
    01713     } while(pointerCount != ObjectHeader->PointerCount) ;
    01714
    01715     return startSkew ;
    01716 #else
    01717     return 1;
    01718 #endif
    01719 }
    01720
    01721 LONG
    01722 IovpStopObRefMonitoring(
    01723     IN PDEVICE_OBJECT DeviceObject,
    01724     IN LONG StartSkew
    01725     )
    01726 /*++
    01727
    01728   Description:
    01729
    01730      Determines if ObRef has not been called between a call to
    01731      IovpStartObRefMonitoring and a call to this API.
    01732
    01733      In a race condition (say ObDereferenceObject is ran in-simo
    01734      with this function), the return is gaurenteed to err on
    01735      the side of a reference occuring.
    01736
    01737   Arguments:
    01738
    01739      Device Object and the skew returned by IovpStartObRefMonitoring
    01740
    01741   Return Value:
    01742
    01743      Number of calls to ObRef that occured throughout the monitored timeframe.
    01744      Note that the return could be positive even though the reference count
    01745      actually dropped (ie, one ObRef and two ObDeref's).
    01746
    01747 --*/
    01748 {
    01749     //
    01750     // ADRIAO BUGBUG 10/05/1999 -
    01751     //     Parclass reroutes target-device-relation IRPs around the tree. That
    01752     // design will be fixed for NT5.1, but in the meantime this means we will
    01753     // not be able to test this driver functionality.
    01754     //
    01755 #if  0
    01756     POBJECT_HEADER ObjectHeader;
    01757     POBJECT_HEADER_NAME_INFO NameInfo;
    01758     LONG currentSkew, refDelta, pointerCount ;
    01759
    01760     ObjectHeader = OBJECT_TO_OBJECT_HEADER(DeviceObject);
    01761     NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
    01762
    01763     ASSERT(NameInfo) ;
    01764
    01765     //
    01766     // We will always decrement DbgDereferenceCount prior to PointerCount,
    01767     // so any race conditions will look like an increment occured, which
    01768     // is an allowable misread...
    01769     //
    01770     do {
    01771         pointerCount = ObjectHeader->PointerCount ;
    01772         currentSkew = pointerCount - NameInfo->DbgDereferenceCount ;
    01773
    01774     } while(pointerCount != ObjectHeader->PointerCount) ;
    01775
    01776     refDelta = currentSkew - StartSkew ;
    01777     ASSERT(refDelta>=0) ;
    01778
    01779     ObDereferenceObject(DeviceObject) ;
    01780
    01781     return refDelta ;
    01782 #else
    01783     return 1;
    01784 #endif
    01785 }
    01786
    01787 BOOLEAN
    01788 IovpIsSystemRestrictedIrp(
    01789     PIO_STACK_LOCATION IrpSp
    01790     )
    01791 {
    01792     switch(IrpSp->MajorFunction) {
    01793
    01794         case IRP_MJ_PNP:
    01795             switch(IrpSp->MinorFunction) {
    01796                 case IRP_MN_START_DEVICE:
    01797                 case IRP_MN_QUERY_REMOVE_DEVICE:
    01798                 case IRP_MN_REMOVE_DEVICE:
    01799                 case IRP_MN_CANCEL_REMOVE_DEVICE:
    01800                 case IRP_MN_STOP_DEVICE:
    01801                 case IRP_MN_QUERY_STOP_DEVICE:
    01802                 case IRP_MN_CANCEL_STOP_DEVICE:
    01803                 case IRP_MN_SURPRISE_REMOVAL:
    01804                     return TRUE;
    01805
    01806                 case IRP_MN_QUERY_DEVICE_RELATIONS:
    01807                     switch(IrpSp->Parameters.QueryDeviceRelations.Type) {
    01808                         case BusRelations:
    01809                         case PowerRelations:
    01810                             return TRUE;
    01811                         case RemovalRelations:
    01812                         case EjectionRelations:
    01813                         case TargetDeviceRelation:
    01814                             return FALSE;
    01815                         default:
    01816                             break;
    01817                     }
    01818                     break;
    01819                 case IRP_MN_QUERY_INTERFACE:
    01820                 case IRP_MN_QUERY_CAPABILITIES:
    01821                     return FALSE;
    01822                 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    01823                 case IRP_MN_QUERY_DEVICE_TEXT:
    01824                     return TRUE;
    01825                 case IRP_MN_READ_CONFIG:
    01826                 case IRP_MN_WRITE_CONFIG:
    01827                     return FALSE;
    01828                 case IRP_MN_EJECT:
    01829                 case IRP_MN_SET_LOCK:
    01830                 case IRP_MN_QUERY_RESOURCES:
    01831                 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    01832                 case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
    01833                     return TRUE;
    01834                 case IRP_MN_QUERY_ID:
    01835                     switch(IrpSp->Parameters.QueryId.IdType) {
    01836
    01837                         case BusQueryHardwareIDs:
    01838                         case BusQueryCompatibleIDs:
    01839                             return TRUE;
    01840                         case BusQueryDeviceID:
    01841                         case BusQueryInstanceID:
    01842                             return FALSE;
    01843                         default:
    01844                             break;
    01845                     }
    01846                     break ;
    01847                 case IRP_MN_QUERY_PNP_DEVICE_STATE:
    01848                 case IRP_MN_QUERY_BUS_INFORMATION:
    01849                     return TRUE;
    01850                 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
    01851                     return FALSE;
    01852                 default:
    01853                     break ;
    01854             }
    01855
    01856         case IRP_MJ_POWER:
    01857             switch(IrpSp->MinorFunction) {
    01858                 case IRP_MN_POWER_SEQUENCE:
    01859                     return FALSE;
    01860                 case IRP_MN_QUERY_POWER:
    01861                 case IRP_MN_SET_POWER:
    01862                 case IRP_MN_WAIT_WAKE:
    01863                     return TRUE;
    01864                 default:
    01865                     break;
    01866             }
    01867         default:
    01868             return FALSE;
    01869     }
    01870
    01871     return TRUE;
    01872 }
    01873
    01874 #endif // NO_SPECIAL_IRP
    01875
    01876