VirtualBox

Changeset 32317 in vbox


Ignore:
Timestamp:
Sep 8, 2010 12:21:34 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
65657
Message:

Guest Additions/Windows: Various fixes for VBoxGuest PnP handling, cleanup data.

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

Legend:

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

    r32273 r32317  
    3535 VBoxGuest_DEFS.linux    = KBUILD_MODNAME=KBUILD_STR\(vboxguest\) KBUILD_BASENAME=KBUILD_STR\(vboxguest\) DEBUG_HASH=2 DEBUG_HASH2=3 EXPORT_SYMTAB
    3636 VBoxGuest_DEFS.solaris  = VBOX_SVN_REV=$(VBOX_SVN_REV)
    37  VBoxGuest_DEFS.win      = VBOX_REBOOT_ON_UNINSTALL VBOX_SVN_REV=$(VBOX_SVN_REV) # VBOX_WITH_VRDP_SESSION_HANDLING
     37 VBoxGuest_DEFS.win      = VBOX_SVN_REV=$(VBOX_SVN_REV) # VBOX_WITH_VRDP_SESSION_HANDLING
     38 ifeq ($(KBUILD_TYPE),release)
     39  # Allow stopping/removing the driver without a reboot
     40  # in debug mode; this is very useful for testing the shutdown stuff!
     41  VBoxGuest_DEFS.win    += VBOX_REBOOT_ON_UNINSTALL
     42 endif
    3843 ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
    3944  VBoxGuest_DEFS.win    += VBOX_WITH_GUEST_BUGCHECK_DETECTION
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp

    r32283 r32317  
    264264                vboxguestwinUnmapVMMDevMemory(pDevExt);
    265265            }
    266             pIrp->IoStatus.Status = rc;
    267             pIrp->IoStatus.Information = 0;
    268             IoCompleteRequest(pIrp, IO_NO_INCREMENT);
     266            break;
     267        }
     268
     269        case IRP_MN_QUERY_PNP_DEVICE_STATE:
     270        {
     271            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_PNP_DEVICE_STATE\n"));
     272            break;
     273        }
     274
     275        case IRP_MN_CANCEL_REMOVE_DEVICE:
     276        {
     277            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_REMOVE_DEVICE\n"));
    269278            break;
    270279        }
     
    281290                pDevExt->win.s.devState = PENDINGREMOVE;
    282291            }
    283 
    284             pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
    285             pIrp->IoStatus.Information = 0;
    286             IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    287292            rc = STATUS_UNSUCCESSFUL;
    288 
    289             Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Refuse with rc = %p\n", pIrp->IoStatus.Status));
     293            Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Refuse with rc = %Rrc\n", rc));
    290294#else
    291             pIrp->IoStatus.Status = STATUS_SUCCESS;
    292295            if (pDevExt->win.s.devState == WORKING)
    293296                pDevExt->win.s.devState = PENDINGREMOVE;
     297#endif /* VBOX_REBOOT_ON_UNINSTALL */
     298            break;
     299        }
     300
     301        case IRP_MN_REMOVE_DEVICE:
     302        {
     303            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: REMOVE_DEVICE\n"));
     304            if (pDevExt->win.s.devState == PENDINGREMOVE)
     305            {
     306                rc = vboxguestwinCleanup(pDevObj, pIrp);
     307                if (NT_SUCCESS(rc))
     308                {
     309                    /*
     310                     * We need to send the remove down the stack before we detach,
     311                     * but we don't need to wait for the completion of this operation
     312                     * (and to register a completion routine).
     313                     */
     314                    pIrp->IoStatus.Status = STATUS_SUCCESS;
     315                    IoSkipCurrentIrpStackLocation(pIrp);
     316
     317                    if (pDevExt->win.s.pNextLowerDriver != NULL)
     318                    {
     319                        rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
     320                        IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
     321
     322                        Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
     323                    }
     324
     325                    Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Removing device ...\n"));
     326
     327                    /* Remove DOS device + symbolic link. */
     328                    UNICODE_STRING win32Name;
     329                    RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
     330                    IoDeleteSymbolicLink(&win32Name);
     331
     332                    pDevExt->win.s.devState = REMOVED;
     333
     334                    Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Deleting device ...\n"));
     335
     336                    /* Last action: Delete our device! pDevObj is *not* failed
     337                     * anymore after this call! */
     338                    IoDeleteDevice(pDevObj);
     339
     340                    Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Device removed!\n"));
     341                    return rc; /* Make sure that we don't do anything below here anymore! */
     342                }
     343                else
     344                    Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Error while cleaning up, rc = 0x%x\n", rc));
     345            }
     346            else
     347                Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Devices state is not PENDINGREMOVE but %d\n",
     348                     pDevExt->win.s.devState));
     349            break;
     350        }
     351
     352        case IRP_MN_CANCEL_STOP_DEVICE:
     353        {
     354            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_STOP_DEVICE\n"));
     355            break;
     356        }
     357
     358        case IRP_MN_QUERY_STOP_DEVICE:
     359        {
     360            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_STOP_DEVICE\n"));
     361            if (pDevExt->win.s.devState == WORKING)
     362                pDevExt->win.s.devState = PENDINGSTOP;
     363#ifdef VBOX_REBOOT_ON_UNINSTALL
     364            Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Device cannot be stopped!\n"));
     365
     366            /* The device can not be stopped without a reboot. */
     367            pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
     368            Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Refuse with rc = 0x%x\n", rc));
     369#endif /* VBOX_REBOOT_ON_UNINSTALL */
     370            break;
     371        }
     372
     373        case IRP_MN_STOP_DEVICE:
     374        {
     375            Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: STOP_DEVICE\n"));
     376
     377            if (pDevExt->win.s.devState == PENDINGSTOP)
     378            {
     379                rc = vboxguestwinCleanup(pDevObj, pIrp);
     380                if (NT_SUCCESS(rc))
     381                {
     382                    pDevExt->win.s.devState = STOPPED;
     383                    IoInvalidateDeviceState(pDevObj);
     384                    Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Device has been disabled\n"));
     385                }
     386                else
     387                    Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Error while cleaning up, rc = 0x%x\n", rc));
     388            }
     389            else
     390                Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Devices state is not PENDINGSTOP but %d\n",
     391                     pDevExt->win.s.devState));
     392            break;
     393        }
     394
     395        default:
     396        {
    294397            IoSkipCurrentIrpStackLocation(pIrp);
    295398            rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
    296 #endif /* VBOX_REBOOT_ON_UNINSTALL */
    297             break;
    298         }
    299 
    300         case IRP_MN_REMOVE_DEVICE:
    301         {
    302             Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: REMOVE_DEVICE\n"));
    303 
    304             /** @todo Merge Remove and Stop, make a helper for common actions. */
    305             pIrp->IoStatus.Status = STATUS_SUCCESS;
    306 
    307             /* According to MSDN we have to unmap previously mapped memory. */
    308             vboxguestwinUnmapVMMDevMemory(pDevExt);
    309 
    310             /* Destroy device extension and clean up everything else. */
    311             VBoxGuestDeleteDevExt(pDevExt);
    312 
    313             if (pDevExt->win.s.pNextLowerDriver != NULL)
    314                 IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
    315 
    316 #ifdef VBOX_WITH_HGCM
    317             if (pDevExt->SessionSpinlock != NIL_RTSPINLOCK)
    318                 RTSpinlockDestroy(pDevExt->SessionSpinlock);
    319 #endif
    320             /* Remove DOS device + symbolic link. */
    321             UNICODE_STRING win32Name;
    322             RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
    323             IoDeleteSymbolicLink(&win32Name);
    324             IoDeleteDevice(pDevObj);
    325             pDevExt->win.s.devState = REMOVED;
    326             IoSkipCurrentIrpStackLocation(pIrp);
    327             rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
    328             break;
    329         }
    330 
    331         case IRP_MN_QUERY_STOP_DEVICE:
    332         {
    333             Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_STOP_DEVICE\n"));
    334 #ifdef VBOX_REBOOT_ON_UNINSTALL
    335             Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Device cannot be stopped!\n"));
    336 
    337             /* The device can not be stopped without a reboot. */
    338             if (pDevExt->win.s.devState == WORKING)
    339                 pDevExt->win.s.devState = PENDINGSTOP;
    340             pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
    341             IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    342             rc = STATUS_UNSUCCESSFUL;
    343 #else
    344             pIrp->IoStatus.Status = STATUS_SUCCESS;
    345             if (pDevExt->win.s.devState == WORKING)
    346             {
    347                 pDevExt->win.s.devState = PENDINGSTOP;
    348             }
    349             IoSkipCurrentIrpStackLocation(pIrp);
    350             rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
    351 #endif /* VBOX_REBOOT_ON_UNINSTALL */
    352             break;
    353         }
    354 
    355         case IRP_MN_STOP_DEVICE:
    356         {
    357             Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: STOP_DEVICE\n"));
    358 
    359             pIrp->IoStatus.Status = STATUS_SUCCESS;
    360             if (pDevExt->win.s.devState == PENDINGSTOP)
    361             {
    362                 VbglTerminate();
    363 
    364                 /* According to MSDN we have to unmap previously mapped memory. */
    365                 vboxguestwinUnmapVMMDevMemory(pDevExt);
    366 
    367                 pDevExt->win.s.devState = STOPPED;
    368                 Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Device has been disabled\n"));
    369             }
    370             else
    371             {
    372                 Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Devices state is not PENDINGSTOP but %d\n",
    373                      pDevExt->win.s.devState));
    374             }
    375             IoSkipCurrentIrpStackLocation(pIrp);
    376             rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
    377             break;
    378         }
    379 
    380         default:
    381         {
    382             IoSkipCurrentIrpStackLocation(pIrp);
    383             rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
     399            return rc;
    384400        }
    385401    }
     402
     403    pIrp->IoStatus.Status = rc;
     404    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
     405
     406    Log(("VBoxGuest::vboxguestwinGuestPnp: Returning with rc = 0x%x\n", rc));
    386407    return rc;
    387408}
     
    448469#endif
    449470}
     471
    450472
    451473/**
     
    551573                            /* Tell the VMM that we no longer support mouse pointer integration. */
    552574                            VMMDevReqMouseStatus *pReq = NULL;
    553                             int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
    554                             if (RT_SUCCESS(rc))
     575                            int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
     576                            if (RT_SUCCESS(vrc))
    555577                            {
    556578                                pReq->mouseFeatures = 0;
     
    558580                                pReq->pointerYPos = 0;
    559581
    560                                 rc = VbglGRPerform(&pReq->header);
    561                                 if (RT_FAILURE(rc))
     582                                vrc = VbglGRPerform(&pReq->header);
     583                                if (RT_FAILURE(vrc))
    562584                                {
    563585                                    Log(("VBoxGuest::PowerStateRequest: error communicating new power status to VMMDev. "
    564                                              "rc = %Rrc\n", rc));
     586                                             "vrc = %Rrc\n", vrc));
    565587                                }
    566588
    567589                                VbglGRFree(&pReq->header);
    568590                            }
     591
     592                            /* Cleanup. */
     593                            vboxguestwinCleanup(pDevObj, pIrp);
    569594                            break;
    570595                        }
     
    579604
    580605                                VMMDevPowerStateRequest *pReq = pDevExt->win.s.pPowerStateRequest;
    581                                 int rc = VERR_NOT_IMPLEMENTED;
     606                                int vrc = VERR_NOT_IMPLEMENTED;
    582607                                if (pReq)
    583608                                {
     
    585610                                    pReq->powerState = VMMDevPowerState_PowerOff;
    586611
    587                                     rc = VbglGRPerform(&pReq->header);
     612                                    vrc = VbglGRPerform(&pReq->header);
    588613                                }
    589                                 if (RT_FAILURE(rc))
     614                                if (RT_FAILURE(vrc))
    590615                                {
    591616                                    Log(("VBoxGuest::PowerStateRequest: Error communicating new power status to VMMDev. "
    592                                              "rc = %Rrc\n", rc));
     617                                             "vrc = %Rrc\n", vrc));
    593618                                }
     619
     620                                /* No need to do cleanup here; at this point we should've been
     621                                 * turned off by VMMDev already! */
    594622                            }
    595623                            break;
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp

    r32279 r32317  
    274274
    275275/**
     276 * Cleans up all data (like device extension and guest mapping).
     277 *
     278 * @param   pDrvObj     Driver object.
     279 * @param   pIrp        Request packet.
     280 */
     281NTSTATUS vboxguestwinCleanup(PDEVICE_OBJECT pDevObj, PIRP pIrp)
     282{
     283    Log(("VBoxGuest::vboxguestwinCleanup\n"));
     284
     285    NOREF(pIrp);
     286    PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
     287
     288    if (pDevExt)
     289    {
     290        /* According to MSDN we have to unmap previously mapped memory. */
     291        vboxguestwinUnmapVMMDevMemory(pDevExt);
     292
     293        /* Destroy device extension and clean up everything else. */
     294        VBoxGuestDeleteDevExt(pDevExt);
     295    }
     296    return STATUS_SUCCESS;
     297}
     298
     299
     300/**
    276301 * Unload the driver.
    277302 *
     
    301326    NTSTATUS rc = IoDeleteSymbolicLink(&win32Name);
    302327
    303 #ifdef VBOX_WITH_HGCM
    304     if (pDevExt->SessionSpinlock != NIL_RTSPINLOCK)
    305     {
    306         int rc2 = RTSpinlockDestroy(pDevExt->SessionSpinlock);
    307         Log(("VBoxGuest::vboxguestwinGuestUnload: spinlock destroyed with rc=%Rrc\n", rc2));
    308     }
    309 #endif
    310328    IoDeleteDevice(pDrvObj->DeviceObject);
     329#else /* TARGET_NT4 */
     330    /* On a PnP driver this routine will be called after
     331     * IRP_MN_REMOVE_DEVICE (where we already did the cleanup),
     332     * so don't do anything here (yet). */
    311333#endif
    312334
     
    332354    NTSTATUS           rc       = STATUS_SUCCESS;
    333355
    334     pIrp->IoStatus.Information  = 0;
    335     pIrp->IoStatus.Status = STATUS_SUCCESS;
    336 
    337356    /*
    338357     * We are not remotely similar to a directory...
     
    342361    {
    343362        Log(("VBoxGuest::vboxguestwinGuestCreate: Uhm, we're not a directory!\n"));
    344         pIrp->IoStatus.Status = STATUS_NOT_A_DIRECTORY;
     363        rc = STATUS_NOT_A_DIRECTORY;
    345364    }
    346365    else
     
    371390
    372391    /* Complete the request! */
     392    pIrp->IoStatus.Information  = 0;
     393    pIrp->IoStatus.Status = rc;
    373394    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    374395
    375     Log(("VBoxGuest::vboxguestwinGuestCreate: Returning 0x%x\n", pIrp->IoStatus.Status));
    376     return pIrp->IoStatus.Status;
     396    Log(("VBoxGuest::vboxguestwinGuestCreate: Returning 0x%x\n", rc));
     397    return rc;
    377398}
    378399
     
    406427
    407428    return STATUS_SUCCESS;
    408 }
    409 
    410 
    411 /** A quick implementation of AtomicTestAndClear for uint32_t and multiple
    412  *  bits.
    413  */
    414 static uint32_t guestAtomicBitsTestAndClear(void *pu32Bits, uint32_t u32Mask)
    415 {
    416     AssertPtrReturn(pu32Bits, 0);
    417     LogFlowFunc(("*pu32Bits=0x%x, u32Mask=0x%x\n", *(long *)pu32Bits,
    418                  u32Mask));
    419     uint32_t u32Result = 0;
    420     uint32_t u32WorkingMask = u32Mask;
    421     int iBitOffset = ASMBitFirstSetU32 (u32WorkingMask);
    422 
    423     while (iBitOffset > 0)
    424     {
    425         bool fSet = ASMAtomicBitTestAndClear(pu32Bits, iBitOffset - 1);
    426         if (fSet)
    427             u32Result |= 1 << (iBitOffset - 1);
    428         u32WorkingMask &= ~(1 << (iBitOffset - 1));
    429         iBitOffset = ASMBitFirstSetU32 (u32WorkingMask);
    430     }
    431     LogFlowFunc(("Returning 0x%x\n", u32Result));
    432     return u32Result;
    433429}
    434430
     
    978974
    979975#ifdef DEBUG
     976/** A quick implementation of AtomicTestAndClear for uint32_t and multiple
     977 *  bits.
     978 */
     979static uint32_t guestAtomicBitsTestAndClear(void *pu32Bits, uint32_t u32Mask)
     980{
     981    AssertPtrReturn(pu32Bits, 0);
     982    LogFlowFunc(("*pu32Bits=0x%x, u32Mask=0x%x\n", *(long *)pu32Bits,
     983                 u32Mask));
     984    uint32_t u32Result = 0;
     985    uint32_t u32WorkingMask = u32Mask;
     986    int iBitOffset = ASMBitFirstSetU32 (u32WorkingMask);
     987
     988    while (iBitOffset > 0)
     989    {
     990        bool fSet = ASMAtomicBitTestAndClear(pu32Bits, iBitOffset - 1);
     991        if (fSet)
     992            u32Result |= 1 << (iBitOffset - 1);
     993        u32WorkingMask &= ~(1 << (iBitOffset - 1));
     994        iBitOffset = ASMBitFirstSetU32 (u32WorkingMask);
     995    }
     996    LogFlowFunc(("Returning 0x%x\n", u32Result));
     997    return u32Result;
     998}
     999
    9801000static VOID vboxguestwinTestAtomicTestAndClearBitsU32(uint32_t u32Mask, uint32_t u32Bits,
    9811001                                                      uint32_t u32Exp)
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h

    r32266 r32317  
    174174
    175175RT_C_DECLS_BEGIN
     176NTSTATUS   vboxguestwinCleanup(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    176177NTSTATUS   vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    177178VOID       vboxguestwinDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext);
Note: See TracChangeset for help on using the changeset viewer.

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