VirtualBox

Changeset 36060 in vbox


Ignore:
Timestamp:
Feb 23, 2011 11:20:04 AM (14 years ago)
Author:
vboxsync
Message:

VBoxGuest-win: PNP cleanup: process only required PNP IRPs according to MSDN.

Location:
trunk/src/VBox/Additions/common/VBoxGuest
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk

    r33676 r36060  
    4444  VBoxGuest_DEFS.win    += VBOX_WITH_GUEST_BUGCHECK_DETECTION
    4545 endif
     46 #VBoxGuest_DEFS.win     += LOG_ENABLED LOG_TO_BACKDOOR
    4647 VBoxGuest_DEPS.solaris += $(VBOX_SVN_REV_KMK)
    4748 VBoxGuest_DEPS.linux   += $(VBOX_SVN_REV_HEADER)
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp

    r32457 r36060  
    154154        {
    155155            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: START_DEVICE\n"));
     156
     157            /* This must be handled first by the lower driver. */
    156158            rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
    157159
     
    184186        }
    185187
    186         case IRP_MN_QUERY_PNP_DEVICE_STATE:
    187         {
    188             Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_PNP_DEVICE_STATE\n"));
    189             break;
    190         }
    191 
    192188        case IRP_MN_CANCEL_REMOVE_DEVICE:
    193189        {
    194190            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_REMOVE_DEVICE\n"));
    195             break;
     191
     192            /* This must be handled first by the lower driver. */
     193            rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
     194
     195            if (NT_SUCCESS(rc) && pDevExt->win.s.devState == PENDINGREMOVE)
     196            {
     197                /* Return to the state prior to receiving the IRP_MN_QUERY_REMOVE_DEVICE request. */
     198                pDevExt->win.s.devState = pDevExt->win.s.prevDevState;
     199            }
     200
     201            /* Complete the IRP. */
     202            break;
     203        }
     204
     205        case IRP_MN_SURPRISE_REMOVAL:
     206        {
     207            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: IRP_MN_SURPRISE_REMOVAL\n"));
     208
     209            VBOXGUEST_UPDATE_DEVSTATE(pDevExt, SURPRISEREMOVED);
     210
     211            /* Do nothing here actually. Cleanup is done in IRP_MN_REMOVE_DEVICE.
     212             * This request is not expected for VBoxGuest.
     213             */
     214            LogRel(("VBoxGuest: unexpected device removal\n"));
     215
     216            /* Pass to the lower driver. */
     217            pIrp->IoStatus.Status = STATUS_SUCCESS;
     218
     219            IoSkipCurrentIrpStackLocation(pIrp);
     220
     221            rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
     222
     223            /* Do not complete the IRP. */
     224            return rc;
    196225        }
    197226
     
    201230
    202231#ifdef VBOX_REBOOT_ON_UNINSTALL
    203             /* The device can not be removed without a reboot. */
    204             if (pDevExt->win.s.devState == WORKING)
    205             {
    206                 Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Device cannot be removed without a reboot!\n"));
    207                 pDevExt->win.s.devState = PENDINGREMOVE;
    208             }
     232            Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Device cannot be removed without a reboot.\n"));
    209233            rc = STATUS_UNSUCCESSFUL;
    210             Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Refuse with rc = %Rrc\n", rc));
    211 #else
    212             if (pDevExt->win.s.devState == WORKING)
    213                 pDevExt->win.s.devState = PENDINGREMOVE;
    214234#endif /* VBOX_REBOOT_ON_UNINSTALL */
     235
     236            if (NT_SUCCESS(rc))
     237            {
     238                VBOXGUEST_UPDATE_DEVSTATE(pDevExt, PENDINGREMOVE);
     239
     240                /* This IRP passed down to lower driver. */
     241                pIrp->IoStatus.Status = STATUS_SUCCESS;
     242
     243                rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
     244
     245                /* Do not complete the IRP. */
     246                return rc;
     247            }
     248
     249            /* Complete the IRP on failure. */
    215250            break;
    216251        }
     
    219254        {
    220255            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: REMOVE_DEVICE\n"));
    221             if (pDevExt->win.s.devState == PENDINGREMOVE)
    222             {
    223                 rc = vboxguestwinCleanup(pDevObj);
    224                 if (NT_SUCCESS(rc))
    225                 {
    226                     /*
    227                      * We need to send the remove down the stack before we detach,
    228                      * but we don't need to wait for the completion of this operation
    229                      * (and to register a completion routine).
    230                      */
    231                     pIrp->IoStatus.Status = STATUS_SUCCESS;
    232                     IoSkipCurrentIrpStackLocation(pIrp);
    233 
    234                     if (pDevExt->win.s.pNextLowerDriver != NULL)
    235                     {
    236                         rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
    237                         IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
    238 
    239                         Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
    240                     }
    241 
    242                     Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Removing device ...\n"));
    243 
    244                     /* Remove DOS device + symbolic link. */
    245                     UNICODE_STRING win32Name;
    246                     RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
    247                     IoDeleteSymbolicLink(&win32Name);
    248 
    249                     pDevExt->win.s.devState = REMOVED;
    250 
    251                     Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Deleting device ...\n"));
    252 
    253                     /* Last action: Delete our device! pDevObj is *not* failed
    254                      * anymore after this call! */
    255                     IoDeleteDevice(pDevObj);
    256 
    257                     Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Device removed!\n"));
    258                     return rc; /* Make sure that we don't do anything below here anymore! */
    259                 }
    260                 else
    261                     Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Error while cleaning up, rc = 0x%x\n", rc));
    262             }
    263             else
    264                 Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Devices state is not PENDINGREMOVE but %d\n",
    265                      pDevExt->win.s.devState));
    266             break;
     256
     257            VBOXGUEST_UPDATE_DEVSTATE(pDevExt, REMOVED);
     258
     259            /* Free hardware resources. */
     260            /* @todo this should actually free I/O ports, interrupts, etc. */
     261            rc = vboxguestwinCleanup(pDevObj);
     262            Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: vboxguestwinCleanup rc = 0x%08X\n", rc));
     263
     264            /*
     265             * We need to send the remove down the stack before we detach,
     266             * but we don't need to wait for the completion of this operation
     267             * (and to register a completion routine).
     268             */
     269            pIrp->IoStatus.Status = STATUS_SUCCESS;
     270
     271            IoSkipCurrentIrpStackLocation(pIrp);
     272
     273            rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
     274            Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
     275
     276            IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
     277
     278            Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Removing device ...\n"));
     279
     280            /* Destroy device extension and clean up everything else. */
     281            VBoxGuestDeleteDevExt(pDevExt);
     282
     283            /* Remove DOS device + symbolic link. */
     284            UNICODE_STRING win32Name;
     285            RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
     286            IoDeleteSymbolicLink(&win32Name);
     287
     288            Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Deleting device ...\n"));
     289
     290            /* Last action: Delete our device! pDevObj is *not* failed
     291             * anymore after this call! */
     292            IoDeleteDevice(pDevObj);
     293
     294            Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Device removed!\n"));
     295
     296            /* Propagating rc from IoCallDriver. */
     297            return rc; /* Make sure that we don't do anything below here anymore! */
    267298        }
    268299
     
    270301        {
    271302            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_STOP_DEVICE\n"));
     303
     304            /* This must be handled first by the lower driver. */
     305            rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
     306
     307            if (NT_SUCCESS(rc) && pDevExt->win.s.devState == PENDINGSTOP)
     308            {
     309                /* Return to the state prior to receiving the IRP_MN_QUERY_STOP_DEVICE request. */
     310                pDevExt->win.s.devState = pDevExt->win.s.prevDevState;
     311            }
     312
     313            /* Complete the IRP. */
    272314            break;
    273315        }
     
    276318        {
    277319            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_STOP_DEVICE\n"));
    278             if (pDevExt->win.s.devState == WORKING)
    279                 pDevExt->win.s.devState = PENDINGSTOP;
     320
    280321#ifdef VBOX_REBOOT_ON_UNINSTALL
    281             Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Device cannot be stopped!\n"));
    282 
    283             /* The device can not be stopped without a reboot. */
     322            Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Device cannot be stopped without a reboot!\n"));
    284323            pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
    285             Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Refuse with rc = 0x%x\n", rc));
    286324#endif /* VBOX_REBOOT_ON_UNINSTALL */
     325
     326            if (NT_SUCCESS(rc))
     327            {
     328                VBOXGUEST_UPDATE_DEVSTATE(pDevExt, PENDINGSTOP);
     329
     330                /* This IRP passed down to lower driver. */
     331                pIrp->IoStatus.Status = STATUS_SUCCESS;
     332
     333                rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
     334
     335                /* Do not complete the IRP. */
     336                return rc;
     337            }
     338
     339            /* Complete the IRP on failure. */
    287340            break;
    288341        }
     
    292345            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: STOP_DEVICE\n"));
    293346
    294             if (pDevExt->win.s.devState == PENDINGSTOP)
    295             {
    296                 rc = vboxguestwinCleanup(pDevObj);
    297                 if (NT_SUCCESS(rc))
    298                 {
    299                     pDevExt->win.s.devState = STOPPED;
    300                     IoInvalidateDeviceState(pDevObj);
    301                     Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Device has been disabled\n"));
    302                 }
    303                 else
    304                     Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Error while cleaning up, rc = 0x%x\n", rc));
    305             }
    306             else
    307                 Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Devices state is not PENDINGSTOP but %d\n",
    308                      pDevExt->win.s.devState));
    309             break;
     347            VBOXGUEST_UPDATE_DEVSTATE(pDevExt, STOPPED);
     348
     349            /* Free hardware resources. */
     350            /* @todo this should actually free I/O ports, interrupts, etc. */
     351            rc = vboxguestwinCleanup(pDevObj);
     352            Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: cleaning up, rc = 0x%x\n", rc));
     353
     354            /* Pass to the lower driver. */
     355            pIrp->IoStatus.Status = STATUS_SUCCESS;
     356
     357            IoSkipCurrentIrpStackLocation(pIrp);
     358
     359            rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
     360            Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
     361
     362            return rc;
    310363        }
    311364
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp

    r34551 r36060  
    223223
    224224            pDevExt->win.s.pDeviceObject = pDeviceObject;
     225            pDevExt->win.s.prevDevState = STOPPED;
    225226            pDevExt->win.s.devState = STOPPED;
    226227
     
    501502        /* Ready to rumble! */
    502503        Log(("VBoxGuest::vboxguestwinInit: Device is ready!\n"));
    503         pDevExt->win.s.devState = WORKING;
     504        VBOXGUEST_UPDATE_DEVSTATE(pDevExt, WORKING);
    504505    }
    505506    else
     
    514515
    515516/**
    516  * Cleans up all data (like device extension and guest mapping).
     517 * Cleans up hardware resources.
     518 * Do not delete DevExt here.
    517519 *
    518520 * @param   pDrvObj     Driver object.
     
    530532        /* According to MSDN we have to unmap previously mapped memory. */
    531533        vboxguestwinUnmapVMMDevMemory(pDevExt);
    532 
    533         /* Destroy device extension and clean up everything else. */
    534         VBoxGuestDeleteDevExt(pDevExt);
    535534    }
    536535    return STATUS_SUCCESS;
     
    548547#ifdef TARGET_NT4
    549548    vboxguestwinCleanup(pDrvObj->DeviceObject);
     549
     550    /* Destroy device extension and clean up everything else. */
     551    if (pDrvObj->DeviceObject && pDrvObj->DeviceObject->DeviceExtension)
     552        VBoxGuestDeleteDevExt((PVBOXGUESTDEVEXT)pDrvObj->DeviceObject->DeviceExtension);
     553
    550554    /*
    551555     * I don't think it's possible to unload a driver which processes have
     
    582586    NTSTATUS           rc       = STATUS_SUCCESS;
    583587
    584     /*
    585      * We are not remotely similar to a directory...
    586      * (But this is possible.)
    587      */
    588     if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
    589     {
     588    if (pDevExt->win.s.devState != WORKING)
     589    {
     590        Log(("VBoxGuest::vboxguestwinGuestCreate: device is not working currently: %d!\n",
     591             pDevExt->win.s.devState));
     592        rc = STATUS_UNSUCCESSFUL;
     593    }
     594    else if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
     595    {
     596        /*
     597         * We are not remotely similar to a directory...
     598         * (But this is possible.)
     599         */
    590600        Log(("VBoxGuest::vboxguestwinGuestCreate: Uhm, we're not a directory!\n"));
    591601        rc = STATUS_NOT_A_DIRECTORY;
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h

    r32475 r36060  
    104104    /** Device state. */
    105105    DEVSTATE devState;
     106    DEVSTATE prevDevState;
    106107
    107108    /** Last system power action set (see VBoxGuestPower). */
     
    116117    PVBOXGUESTSESSION pKernelSession;
    117118} VBOXGUESTDEVEXTWIN, *PVBOXGUESTDEVEXTWIN;
     119
     120#define VBOXGUEST_UPDATE_DEVSTATE(_pDevExt, _newDevState) do {    \
     121    (_pDevExt)->win.s.prevDevState =  (_pDevExt)->win.s.devState; \
     122    (_pDevExt)->win.s.devState = (_newDevState);                  \
     123} while (0)
    118124
    119125
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette