VirtualBox

Changeset 1681 in vbox


Ignore:
Timestamp:
Mar 23, 2007 2:45:10 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
19817
Message:

Implemented HGCM save/load state

Location:
trunk/src/VBox
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/VMMDev/VBoxDev.cpp

    r1624 r1681  
    2222
    2323/* #define LOG_ENABLED */
    24 
    25 #define TIMESYNC_BACKDOOR
    2624
    2725#include <stdio.h>
     
    904902                Log(("VMMDevReq_HGCMConnect\n"));
    905903
    906                 requestHeader->rc = vmmdevHGCMConnect (pData, pHGCMConnect);
     904                requestHeader->rc = vmmdevHGCMConnect (pData, pHGCMConnect, (RTGCPHYS)u32);
    907905            }
    908906            break;
     
    926924
    927925                Log(("VMMDevReq_VMMDevHGCMDisconnect\n"));
    928                 requestHeader->rc = vmmdevHGCMDisconnect (pData, pHGCMDisconnect);
     926                requestHeader->rc = vmmdevHGCMDisconnect (pData, pHGCMDisconnect, (RTGCPHYS)u32);
    929927            }
    930928            break;
     
    951949                Log(("%.*Vhxd\n", requestHeader->size, requestHeader));
    952950
    953                 requestHeader->rc = vmmdevHGCMCall (pData, pHGCMCall);
     951                requestHeader->rc = vmmdevHGCMCall (pData, pHGCMCall, (RTGCPHYS)u32);
    954952            }
    955953            break;
     
    14731471
    14741472
    1475 #define VMMDEV_SSM_VERSION 2
     1473#define VMMDEV_SSM_VERSION 3
    14761474
    14771475/**
     
    14921490    SSMR3PutBool(pSSMHandle, pData->fNewGuestFilterMask);
    14931491    SSMR3PutU32(pSSMHandle, pData->u32NewGuestFilterMask);
     1492    SSMR3PutU32(pSSMHandle, pData->u32GuestFilterMask);
    14941493    SSMR3PutU32(pSSMHandle, pData->u32HostEventFlags);
    14951494    // here be dragons (probably)
     
    15001499    SSMR3PutU32(pSSMHandle, pData->fu32AdditionsOk);
    15011500    SSMR3PutU32(pSSMHandle, pData->u32VideoAccelEnabled);
     1501
     1502#ifdef VBOX_HGCM
     1503    vmmdevHGCMSaveState (pData, pSSMHandle);
     1504#endif /* VBOX_HGCM */
     1505
    15021506    return VINF_SUCCESS;
    15031507}
     
    15231527    SSMR3GetBool(pSSMHandle, &pData->fNewGuestFilterMask);
    15241528    SSMR3GetU32(pSSMHandle, &pData->u32NewGuestFilterMask);
     1529    SSMR3GetU32(pSSMHandle, &pData->u32GuestFilterMask);
    15251530    SSMR3GetU32(pSSMHandle, &pData->u32HostEventFlags);
    15261531//    SSMR3GetBool(pSSMHandle, &pData->pVMMDevRAMHC->fHaveEvents);
     
    15311536    SSMR3GetU32(pSSMHandle, &pData->fu32AdditionsOk);
    15321537    SSMR3GetU32(pSSMHandle, &pData->u32VideoAccelEnabled);
     1538
     1539#ifdef VBOX_HGCM
     1540    vmmdevHGCMLoadState (pData, pSSMHandle);
     1541#endif /* VBOX_HGCM */
    15331542
    15341543    /*
     
    15581567{
    15591568    VMMDevState *pData = PDMINS2DATA(pDevIns, VMMDevState*);
     1569
     1570#ifdef VBOX_HGCM
     1571    vmmdevHGCMLoadStateDone (pData, pSSMHandle);
     1572#endif /* VBOX_HGCM */
    15601573
    15611574    VMMDevNotifyGuest (pData, VMMDEV_EVENT_RESTORED);
     
    17181731        AssertMsgFailed(("VMMDev SUPPageAlloc(%#x,) -> %d\n", VMMDEV_RAM_SIZE, rc));
    17191732    }
     1733   
     1734#ifdef VBOX_HGCM
     1735    rc = RTCritSectInit(&pData->critsectHGCMCmdList);
     1736    AssertRC(rc);
     1737#endif /* VBOX_HGCM */
    17201738
    17211739    /* initialize the VMMDev memory */
  • trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp

    r1562 r1681  
    5757struct VBOXHGCMCMD
    5858{
     59    /* Active commands, list is protected by critsectHGCMCmdList. */
     60    struct VBOXHGCMCMD *pNext;
     61    struct VBOXHGCMCMD *pPrev;
     62   
     63    /* GC ptr of the command header. */
     64    RTGCPHYS GCPtr;
     65
    5966    /* Pointer to guest request. */
    6067    VMMDevHGCMRequestHeader *pHeader;
     
    6269    /* Pointer to converted host parameters in case of a Call request. */
    6370    VBOXHGCMSVCPARM *paHostParms;
    64    
     71
    6572    /* Linear pointer parameters information. */
    6673    int cLinPtrs;
    67    
     74
    6875    /* Pointer to descriptions of linear pointers.  */
    6976    VBOXHGCMLINPTR *paLinPtrs;
    7077};
     78
     79static int vmmdevHGCMCmdListLock (VMMDevState *pVMMDevState)
     80{
     81    int rc = RTCritSectEnter (&pVMMDevState->critsectHGCMCmdList);
     82    AssertRC (rc);
     83    return rc;
     84}
     85
     86static void vmmdevHGCMCmdListUnlock (VMMDevState *pVMMDevState)
     87{
     88    int rc = RTCritSectLeave (&pVMMDevState->critsectHGCMCmdList);
     89    AssertRC (rc);
     90}
     91
     92static int vmmdevHGCMAddCommand (VMMDevState *pVMMDevState, PVBOXHGCMCMD pCmd, RTGCPHYS GCPtr)
     93{
     94    PPDMDEVINS pDevIns = pVMMDevState->pDevIns;
     95
     96    int rc = vmmdevHGCMCmdListLock (pVMMDevState);
     97   
     98    if (VBOX_SUCCESS (rc))
     99    {
     100        LogFlowFunc(("%p\n", pCmd));
     101
     102        /* Insert at the head of the list. The vmmdevHGCMLoadStateDone depends on this. */
     103        pCmd->pNext = pVMMDevState->pHGCMCmdList;
     104        pCmd->pPrev = NULL;
     105       
     106        if (pVMMDevState->pHGCMCmdList)
     107        {
     108            pVMMDevState->pHGCMCmdList->pPrev = pCmd;
     109        }
     110       
     111        pVMMDevState->pHGCMCmdList = pCmd;
     112       
     113        pCmd->GCPtr = GCPtr;
     114
     115        vmmdevHGCMCmdListUnlock (pVMMDevState);
     116    }
     117   
     118    return rc;
     119}
     120
     121static int vmmdevHGCMRemoveCommand (VMMDevState *pVMMDevState, PVBOXHGCMCMD pCmd)
     122{
     123    PPDMDEVINS pDevIns = pVMMDevState->pDevIns;
     124
     125    int rc = vmmdevHGCMCmdListLock (pVMMDevState);
     126   
     127    if (VBOX_SUCCESS (rc))
     128    {
     129        LogFlowFunc(("%p\n", pCmd));
     130
     131        if (pCmd->pNext)
     132        {
     133            pCmd->pNext->pPrev = pCmd->pPrev;
     134        }
     135        else
     136        {
     137           /* Tail, do nothing. */
     138        }
     139       
     140        if (pCmd->pPrev)
     141        {
     142            pCmd->pPrev->pNext = pCmd->pNext;
     143        }
     144        else
     145        {
     146            pVMMDevState->pHGCMCmdList = pCmd->pNext;
     147        }
     148
     149        vmmdevHGCMCmdListUnlock (pVMMDevState);
     150    }
     151   
     152    return rc;
     153}
    71154
    72155static int vmmdevHGCMSaveLinPtr (PPDMDEVINS pDevIns,
     
    183266}
    184267
    185 int vmmdevHGCMConnect (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect)
     268int vmmdevHGCMConnect (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect, RTGCPHYS GCPtr)
    186269{
    187270    int rc = VINF_SUCCESS;
    188271
    189     PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAlloc (sizeof (struct VBOXHGCMCMD));
     272    PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD));
    190273
    191274    if (pCmd)
    192275    {
     276        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
     277
    193278        pCmd->pHeader = &pHGCMConnect->header;
    194279        pCmd->paHostParms = NULL;
     
    210295}
    211296
    212 int vmmdevHGCMDisconnect (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect)
     297int vmmdevHGCMDisconnect (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, RTGCPHYS GCPtr)
    213298{
    214299    int rc = VINF_SUCCESS;
    215300
    216     PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAlloc (sizeof (struct VBOXHGCMCMD));
     301    PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD));
    217302
    218303    if (pCmd)
    219304    {
     305        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
     306
    220307        pCmd->pHeader = &pHGCMDisconnect->header;
    221308        pCmd->paHostParms = NULL;
     
    234321
    235322
    236 int vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall)
     323int vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, RTGCPHYS GCPtr)
    237324{
    238325    int rc = VINF_SUCCESS;
     
    271358            case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
    272359            case VMMDevHGCMParmType_LinAddr:     /* In & Out */
    273 #if 0
    274             case VMMDevHGCMParmType_Virt16Addr:
    275             case VMMDevHGCMParmType_VirtAddr:
    276 #endif
    277360            {
    278361                cbCmdSize += pGuestParm->u.Pointer.size;
     
    313396    }
    314397
     398    memset (pCmd, 0, sizeof (*pCmd));
     399   
    315400    pCmd->pHeader     = &pHGCMCall->header;
    316401    pCmd->paHostParms = NULL;
     
    446531    if (VBOX_SUCCESS (rc))
    447532    {
     533        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
     534
    448535        /* Pass the function call to HGCM connector for actual processing */
    449536        rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pCmd, pHGCMCall->u32ClientID, pHGCMCall->u32Function, cParms, pCmd->paHostParms);
     
    472559    VMMDevState *pVMMDevState = PDMIHGCMPORT_2_VMMDEVSTATE(pInterface);
    473560
    474     /* Setup return codes. */
    475     pHeader->result = result;
    476 
    477     /* Update parameters and data buffers. */
    478 
    479     if (pHeader->header.requestType == VMMDevReq_HGCMCall)
    480     {
    481         VMMDevHGCMCall *pHGCMCall = (VMMDevHGCMCall *)pHeader;
    482 
    483         uint32_t cParms = pHGCMCall->cParms;
    484 
    485         HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
    486 
    487         VBOXHGCMSVCPARM *pHostParm = pCmd->paHostParms;
    488 
    489         uint32_t i;
    490         uint32_t iLinPtr = 0;
    491 
    492         for (i = 0; i < cParms; i++, pGuestParm++, pHostParm++)
    493         {
    494             switch (pGuestParm->type)
     561    if (result != VINF_HGCM_SAVE_STATE)
     562    {
     563        /* Setup return codes. */
     564        pHeader->result = result;
     565
     566        /* Update parameters and data buffers. */
     567
     568        if (pHeader->header.requestType == VMMDevReq_HGCMCall)
     569        {
     570            VMMDevHGCMCall *pHGCMCall = (VMMDevHGCMCall *)pHeader;
     571
     572            uint32_t cParms = pHGCMCall->cParms;
     573
     574            HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
     575
     576            VBOXHGCMSVCPARM *pHostParm = pCmd->paHostParms;
     577
     578            uint32_t i;
     579            uint32_t iLinPtr = 0;
     580
     581            for (i = 0; i < cParms; i++, pGuestParm++, pHostParm++)
    495582            {
    496                 case VMMDevHGCMParmType_32bit:
     583                switch (pGuestParm->type)
    497584                {
    498                     pGuestParm->u.value32 = pHostParm->u.uint32;
    499                 } break;
    500 
    501                 case VMMDevHGCMParmType_64bit:
    502                 {
    503                     pGuestParm->u.value64 = pHostParm->u.uint64;
    504                 } break;
    505 
    506                 case VMMDevHGCMParmType_PhysAddr:
    507                 {
    508                     /* do nothing */
    509                 } break;
    510 
    511                 case VMMDevHGCMParmType_LinAddr_In:  /* In (read) */
    512                 case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
    513                 case VMMDevHGCMParmType_LinAddr:     /* In & Out */
    514                 {
    515                     /* Copy buffer back to guest memory. */
    516                     uint32_t size = pGuestParm->u.Pointer.size;
    517 
    518                     if (size > 0 && pGuestParm->type != VMMDevHGCMParmType_LinAddr_In)
     585                    case VMMDevHGCMParmType_32bit:
    519586                    {
    520                         /* Use the saved page list. */
    521                         rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
    522 
    523 //                        RTGCPTR linearAddr = pGuestParm->u.Pointer.u.linearAddr;
    524 //
    525 //                        rc = pVMMDevState->pDevIns->pDevHlp->pfnPhysWriteGCVirt (pVMMDevState->pDevIns,
    526 //                                                                                 linearAddr,
    527 //                                                                                 pHostParm->u.pointer.addr,
    528 //                                                                                 size);
    529                         AssertReleaseRC(rc);
     587                        pGuestParm->u.value32 = pHostParm->u.uint32;
     588                    } break;
     589
     590                    case VMMDevHGCMParmType_64bit:
     591                    {
     592                        pGuestParm->u.value64 = pHostParm->u.uint64;
     593                    } break;
     594
     595                    case VMMDevHGCMParmType_PhysAddr:
     596                    {
     597                        /* do nothing */
     598                    } break;
     599
     600                    case VMMDevHGCMParmType_LinAddr_In:  /* In (read) */
     601                    case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
     602                    case VMMDevHGCMParmType_LinAddr:     /* In & Out */
     603                    {
     604                        /* Copy buffer back to guest memory. */
     605                        uint32_t size = pGuestParm->u.Pointer.size;
     606
     607                        if (size > 0 && pGuestParm->type != VMMDevHGCMParmType_LinAddr_In)
     608                        {
     609                            /* Use the saved page list. */
     610                            rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
     611                            AssertReleaseRC(rc);
     612                        }
     613                    } break;
     614
     615                    default:
     616                    {
     617                        /* This indicates that the guest request memory was corrupted. */
     618                        AssertReleaseMsgFailed(("hgcmCompleted: invalid parameter type %08X\n", pGuestParm->type));
    530619                    }
    531                 } break;
    532 
    533                 default:
    534                 {
    535                     /* This indicates that the guest request memory was corrupted. */
    536                     AssertReleaseMsgFailed(("hgcmCompleted: invalid parameter type %08X\n", pGuestParm->type));
    537620                }
    538621            }
    539622        }
    540     }
    541 
    542     /* Mark request as processed*/
    543     pHeader->fu32Flags |= VBOX_HGCM_REQ_DONE;
    544 
    545     VMMDevNotifyGuest (pVMMDevState, VMMDEV_EVENT_HGCM);
    546 
    547     if (pCmd->paLinPtrs)
    548     {
    549         RTMemFree (pCmd->paLinPtrs);
    550     }
    551        
    552     RTMemFree (pCmd);
     623
     624        /* Mark request as processed*/
     625        pHeader->fu32Flags |= VBOX_HGCM_REQ_DONE;
     626
     627        VMMDevNotifyGuest (pVMMDevState, VMMDEV_EVENT_HGCM);
     628
     629        /* It it assumed that VMMDev saves state after the HGCM services. */
     630        vmmdevHGCMRemoveCommand (pVMMDevState, pCmd);
     631
     632        if (pCmd->paLinPtrs)
     633        {
     634            RTMemFree (pCmd->paLinPtrs);
     635        }
     636       
     637        RTMemFree (pCmd);
     638    }
    553639
    554640    return;
    555641}
     642
     643/* @thread EMT */
     644int vmmdevHGCMSaveState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM)
     645{
     646    /* Save information about pending requests.
     647     * Only GCPtrs are of interest.
     648     */
     649    int rc = VINF_SUCCESS;
     650
     651    LogFlowFunc(("\n"));
     652
     653    /* Compute how many commands are pending. */
     654    uint32_t cCmds = 0;
     655
     656    PVBOXHGCMCMD pIter = pVMMDevState->pHGCMCmdList;
     657
     658    while (pIter)
     659    {
     660        LogFlowFunc (("pIter %p\n", pIter));
     661        cCmds++;
     662        pIter = pIter->pNext;
     663    }
     664
     665    LogFlowFunc(("cCmds = %d\n", cCmds));
     666
     667    /* Save number of commands. */
     668    rc = SSMR3PutU32(pSSM, cCmds);
     669    AssertRCReturn(rc, rc);
     670
     671    if (cCmds > 0)
     672    {
     673        pIter = pVMMDevState->pHGCMCmdList;
     674
     675        while (pIter)
     676        {
     677            PVBOXHGCMCMD pNext = pIter->pNext;
     678
     679            LogFlowFunc (("Saving %VGp\n", pIter->GCPtr));
     680            rc = SSMR3PutGCPtr(pSSM, pIter->GCPtr);
     681            AssertRCReturn(rc, rc);
     682
     683            vmmdevHGCMRemoveCommand (pVMMDevState, pIter);
     684
     685            pIter = pNext;
     686        }
     687    }
     688
     689    return rc;
     690}
     691
     692/* @thread EMT */
     693int vmmdevHGCMLoadState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM)
     694{
     695    int rc = VINF_SUCCESS;
     696
     697    LogFlowFunc(("\n"));
     698
     699    /* Read how many commands were pending. */
     700    uint32_t cCmds = 0;
     701    rc = SSMR3GetU32(pSSM, &cCmds);
     702    AssertRCReturn(rc, rc);
     703
     704    LogFlowFunc(("cCmds = %d\n", cCmds));
     705
     706    while (cCmds--)
     707    {
     708        RTGCPHYS GCPtr;
     709        rc = SSMR3GetGCPtr(pSSM, &GCPtr);
     710        AssertRCReturn(rc, rc);
     711
     712        LogFlowFunc (("Restoring %VGp\n", GCPtr));
     713
     714        PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD));
     715        AssertReturn(pCmd, VERR_NO_MEMORY);
     716
     717        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
     718    }
     719
     720    return rc;
     721}
     722
     723/* @thread EMT */
     724int vmmdevHGCMLoadStateDone(VMMDevState *pVMMDevState, PSSMHANDLE pSSM)
     725{
     726    LogFlowFunc(("\n"));
     727
     728    /* Reissue pending requests. */
     729    PPDMDEVINS pDevIns = pVMMDevState->pDevIns;
     730
     731    int rc = vmmdevHGCMCmdListLock (pVMMDevState);
     732
     733    if (VBOX_SUCCESS (rc))
     734    {
     735        PVBOXHGCMCMD pIter = pVMMDevState->pHGCMCmdList;
     736
     737        while (pIter)
     738        {
     739            LogFlowFunc (("pIter %p\n", pIter));
     740
     741            PVBOXHGCMCMD pNext = pIter->pNext;
     742
     743            VMMDevRequestHeader *requestHeader = NULL;
     744            rc = PDMDevHlpPhys2HCVirt(pDevIns, pIter->GCPtr, 0, (PRTHCPTR)&requestHeader);
     745
     746            if (VBOX_FAILURE(rc) || !requestHeader)
     747            {
     748                AssertMsgFailed(("VMMDev::LoadStateDone: could not convert guest physical address to host virtual!!! rc = %Vrc\n", rc));
     749            }
     750            else
     751            {
     752                /* the structure size must be greater or equal to the header size */
     753                if (requestHeader->size < sizeof(VMMDevRequestHeader))
     754                {
     755                    Log(("VMMDev request header size too small! size = %d\n", requestHeader->size));
     756                }
     757                else
     758                {
     759                    /* check the version of the header structure */
     760                    if (requestHeader->version != VMMDEV_REQUEST_HEADER_VERSION)
     761                    {
     762                        Log(("VMMDev: guest header version (0x%08X) differs from ours (0x%08X)\n", requestHeader->version, VMMDEV_REQUEST_HEADER_VERSION));
     763                    }
     764                    else
     765                    {
     766                        Log(("VMMDev request issued: %d\n", requestHeader->requestType));
     767
     768                        switch (requestHeader->requestType)
     769                        {
     770                            case VMMDevReq_HGCMConnect:
     771                            {
     772                                if (requestHeader->size < sizeof(VMMDevHGCMConnect))
     773                                {
     774                                    AssertMsgFailed(("VMMDevReq_HGCMConnect structure has invalid size!\n"));
     775                                    requestHeader->rc = VERR_INVALID_PARAMETER;
     776                                }
     777                                else if (!pVMMDevState->pHGCMDrv)
     778                                {
     779                                    Log(("VMMDevReq_HGCMConnect HGCM Connector is NULL!\n"));
     780                                    requestHeader->rc = VERR_NOT_SUPPORTED;
     781                                }
     782                                else
     783                                {
     784                                    VMMDevHGCMConnect *pHGCMConnect = (VMMDevHGCMConnect *)requestHeader;
     785
     786                                    Log(("VMMDevReq_HGCMConnect\n"));
     787
     788                                    requestHeader->rc = vmmdevHGCMConnect (pVMMDevState, pHGCMConnect, pIter->GCPtr);
     789                                }
     790                                break;
     791                            }
     792
     793                            case VMMDevReq_HGCMDisconnect:
     794                            {
     795                                if (requestHeader->size < sizeof(VMMDevHGCMDisconnect))
     796                                {
     797                                    AssertMsgFailed(("VMMDevReq_HGCMDisconnect structure has invalid size!\n"));
     798                                    requestHeader->rc = VERR_INVALID_PARAMETER;
     799                                }
     800                                else if (!pVMMDevState->pHGCMDrv)
     801                                {
     802                                    Log(("VMMDevReq_HGCMDisconnect HGCM Connector is NULL!\n"));
     803                                    requestHeader->rc = VERR_NOT_SUPPORTED;
     804                                }
     805                                else
     806                                {
     807                                    VMMDevHGCMDisconnect *pHGCMDisconnect = (VMMDevHGCMDisconnect *)requestHeader;
     808
     809                                    Log(("VMMDevReq_VMMDevHGCMDisconnect\n"));
     810                                    requestHeader->rc = vmmdevHGCMDisconnect (pVMMDevState, pHGCMDisconnect, pIter->GCPtr);
     811                                }
     812                                break;
     813                            }
     814
     815                            case VMMDevReq_HGCMCall:
     816                            {
     817                                if (requestHeader->size < sizeof(VMMDevHGCMCall))
     818                                {
     819                                    AssertMsgFailed(("VMMDevReq_HGCMCall structure has invalid size!\n"));
     820                                    requestHeader->rc = VERR_INVALID_PARAMETER;
     821                                }
     822                                else if (!pVMMDevState->pHGCMDrv)
     823                                {
     824                                    Log(("VMMDevReq_HGCMCall HGCM Connector is NULL!\n"));
     825                                    requestHeader->rc = VERR_NOT_SUPPORTED;
     826                                }
     827                                else
     828                                {
     829                                    VMMDevHGCMCall *pHGCMCall = (VMMDevHGCMCall *)requestHeader;
     830
     831                                    Log(("VMMDevReq_HGCMCall: sizeof (VMMDevHGCMRequest) = %04X\n", sizeof (VMMDevHGCMCall)));
     832
     833                                    Log(("%.*Vhxd\n", requestHeader->size, requestHeader));
     834
     835                                    requestHeader->rc = vmmdevHGCMCall (pVMMDevState, pHGCMCall, pIter->GCPtr);
     836                                }
     837                                break;
     838                            }
     839                            default:
     840                               AssertReleaseFailed();
     841                        }
     842                    }
     843                }
     844            }
     845
     846            vmmdevHGCMRemoveCommand (pVMMDevState, pIter);
     847            pIter = pNext;
     848        }
     849
     850        vmmdevHGCMCmdListUnlock (pVMMDevState);
     851    }
     852   
     853    return rc;
     854}
  • trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.h

    r1 r1681  
    3232
    3333__BEGIN_DECLS
    34 DECLCALLBACK(int) vmmdevHGCMConnect (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect);
    35 DECLCALLBACK(int) vmmdevHGCMDisconnect (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect);
    36 DECLCALLBACK(int) vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall);
     34DECLCALLBACK(int) vmmdevHGCMConnect (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect, RTGCPHYS GCPtr);
     35DECLCALLBACK(int) vmmdevHGCMDisconnect (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, RTGCPHYS GCPtr);
     36DECLCALLBACK(int) vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, RTGCPHYS GCPtr);
    3737
    3838DECLCALLBACK(void) hgcmCompleted (PPDMIHGCMPORT pInterface, int32_t result, PVBOXHGCMCMD pCmdPtr);
     39
     40int vmmdevHGCMSaveState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM);
     41int vmmdevHGCMLoadState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM);
     42int vmmdevHGCMLoadStateDone(VMMDevState *pVMMDevState, PSSMHANDLE pSSM);
    3943__END_DECLS
    4044
  • trunk/src/VBox/Devices/VMMDev/VMMDevState.h

    r1624 r1681  
    2828
    2929#include <VBox/pdm.h>
     30
     31#define TIMESYNC_BACKDOOR
    3032
    3133/** device structure containing all state information */
     
    137139    bool fBackdoorLogDisabled;
    138140
     141#ifdef VBOX_HGCM
     142    /** List of pending HGCM requests, used for saving the HGCM state. */
     143    PVBOXHGCMCMD pHGCMCmdList;
     144    /** Critical section to protect the list. */
     145    RTCRITSECT critsectHGCMCmdList;
     146#endif /* VBOX_HGCM */
     147
    139148} VMMDevState;
    140149
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r1596 r1681  
    20052005
    20062006    /// @todo (r=sander?) should move this into the shared folder class */
    2007     if (mpVM && mVMMDev->getShFlClientId())
     2007    if (mpVM && mVMMDev->isShFlActive())
    20082008    {
    20092009        /*
     
    20802080    CheckComRCReturnRC (autoVMCaller.rc());
    20812081
    2082     if (mpVM && mVMMDev->getShFlClientId())
     2082    if (mpVM && mVMMDev->isShFlActive())
    20832083    {
    20842084        /*
     
    64446444                }
    64456445
    6446                 if (console->getVMMDev()->getShFlClientId())
     6446                if (console->getVMMDev()->isShFlActive())
    64476447                {
    64486448                    /// @todo (dmik)
  • trunk/src/VBox/Main/Makefile

    r1565 r1681  
    2121DEPTH = ../../..
    2222include $(PATH_KBUILD)/header.kmk
     23
     24DEFS       += HGCMSS
    2325
    2426ifdef VRDP_MC
  • trunk/src/VBox/Main/VMMDevInterface.cpp

    r1386 r1681  
    298298static DECLCALLBACK(int) iface_hgcmConnect (PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, PHGCMSERVICELOCATION pServiceLocation, uint32_t *pu32ClientID)
    299299{
     300    LogFlowFunc(("Enter\n"));
     301
    300302    PDRVMAINVMMDEV pDrv = PDMIHGCMCONNECTOR_2_MAINVMMDEV(pInterface);
    301303
     
    305307static DECLCALLBACK(int) iface_hgcmDisconnect (PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, uint32_t u32ClientID)
    306308{
     309    LogFlowFunc(("Enter\n"));
     310
    307311    PDRVMAINVMMDEV pDrv = PDMIHGCMCONNECTOR_2_MAINVMMDEV(pInterface);
    308312
     
    313317                                         uint32_t cParms, PVBOXHGCMSVCPARM paParms)
    314318{
     319    LogFlowFunc(("Enter\n"));
     320
    315321    PDRVMAINVMMDEV pDrv = PDMIHGCMCONNECTOR_2_MAINVMMDEV(pInterface);
    316322
     
    327333static DECLCALLBACK(int) iface_hgcmSave(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
    328334{
     335    LogFlowFunc(("Enter\n"));
     336
     337#ifdef HGCMSS
     338    return hgcmSaveStateInternal (pSSM);
     339#else
    329340    PDRVMAINVMMDEV pDrv = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
    330341   
     
    334345
    335346    return hgcmSaveStateInternal (pDrv->pVMMDev->mSharedFolderClientId, pSSM);
     347#endif /* HGCMSS */
    336348}
    337349
     
    347359static DECLCALLBACK(int) iface_hgcmLoad(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t u32Version)
    348360{
     361    LogFlowFunc(("Enter\n"));
     362
     363#ifdef HGCMSS
     364    if (u32Version != HGCM_SSM_VERSION)
     365        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     366
     367    return hgcmLoadStateInternal (pSSM);
     368#else
    349369    PDRVMAINVMMDEV pDrv = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
    350370    uint32_t       u32HandleCount;
     
    385405
    386406    return hgcmLoadStateInternal (pDrv->pVMMDev->mSharedFolderClientId, pSSM);
     407#endif /* HGCMSS */
    387408}
    388409
     
    450471    LogFlow(("VMMDev::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
    451472#ifdef VBOX_HGCM
     473#ifndef HGCMSS
    452474    /* Unload Shared Folder HGCM service */
    453475    if (pData->pVMMDev->mSharedFolderClientId)
     
    458480        pData->pVMMDev->hgcmDisconnect(cmd, pData->pVMMDev->getShFlClientId());
    459481    }
     482#endif /* !HGCMSS */
    460483
    461484    hgcmReset ();
     
    478501    LogFlow(("VMMDev::drvReset: iInstance=%d\n", pDrvIns->iInstance));
    479502#ifdef VBOX_HGCM
     503#ifndef HGCMSS
    480504    /* Unload Shared Folder HGCM service */
    481505    uint64_t     dummy = 0;
     
    486510        pData->pVMMDev->hgcmDisconnect(cmd, pData->pVMMDev->getShFlClientId());
    487511    }
     512#endif /* !HGCMSS */
    488513   
    489514    hgcmReset ();
    490515
     516#ifndef HGCMSS
    491517    if (pData->pVMMDev->mSharedFolderClientId)
    492518    {
     
    506532        }
    507533    }
     534#endif /* !HGCMSS */
    508535#endif
    509536}
     
    592619#ifdef VBOX_HGCM
    593620
     621#ifdef HGCMSS
     622    rc = pData->pVMMDev->hgcmLoadService ("VBoxSharedFolders", "VBoxSharedFolders");
     623    pData->pVMMDev->fSharedFolderActive = VBOX_SUCCESS(rc);
     624    if (VBOX_SUCCESS(rc))
     625    {
     626        LogRel(("Shared Folders service loaded.\n"));
     627    }
     628    else
     629    {
     630        LogRel(("Failed to load Shared Folders service %Vrc\n", rc));
     631    }
     632#else
    594633    /* Load Shared Folder HGCM service */
    595634    HGCMSERVICELOCATION loc;
     
    617656        pData->pVMMDev->mSharedFolderClientId = 0;
    618657    }
     658#endif /* HGCMSS */
    619659    pDrvIns->pDrvHlp->pfnSSMRegister(pDrvIns, "HGCM", 0, HGCM_SSM_VERSION, 4096/* bad guess */, NULL, iface_hgcmSave, NULL, NULL, iface_hgcmLoad, NULL);
    620660#endif
  • trunk/src/VBox/Main/hgcm/HGCM.cpp

    r1577 r1681  
    2828#include "Logging.h"
    2929
    30 #include <string.h>
     30#include <malloc.h>
    3131
    3232#include "hgcm/HGCM.h"
     
    9898 */
    9999
     100/* The maximum allowed size of a service name in bytes. */
     101#define VBOX_HGCM_SVC_NAME_MAX_BYTES 1024
    100102
    101103/** Internal helper service object. HGCM code would use it to
     
    115117        static HGCMService *sm_pSvcListTail;
    116118
     119#ifdef HGCMSS
     120       static int sm_cServices;
     121#endif /* HGCMSS */
    117122
    118123        HGCMTHREADHANDLE m_thread;
     
    155160
    156161        static void Reset (void);
     162
     163#ifdef HGCMSS
     164        static int SaveState (PSSMHANDLE pSSM);
     165        static int LoadState (PSSMHANDLE pSSM);
     166#endif /* HGCMSS */
    157167   
    158168        static int FindService (HGCMService **ppsvc, HGCMServiceLocation *loc);
     
    165175        void DisconnectAll (void);
    166176
     177#ifdef HGCMSS
     178        int CreateAndConnectClient (uint32_t *pu32ClientIdOut, uint32_t u32ClientIdIn);
     179#endif /* HGCMSS */
     180                   
    167181        int Connect (uint32_t u32ClientID);
    168182        int Disconnect (uint32_t u32ClientID);
     
    384398HGCMService *HGCMService::sm_pSvcListHead = NULL;
    385399HGCMService *HGCMService::sm_pSvcListTail = NULL;
     400#ifdef HGCMSS
     401int HGCMService::sm_cServices = 0;
     402#endif /* HGCMSS */
    386403
    387404HGCMService::HGCMService ()
     
    429446
    430447static bool g_fResetting = false;
     448static bool g_fSaveState = false;
    431449
    432450static DECLCALLBACK(void) hgcmMsgCompletionCallback (int32_t result, HGCMMsgCore *pMsgCore)
     
    439457    if (pMsgHdr->pHGCMPort && !g_fResetting)
    440458    {
    441         pMsgHdr->pHGCMPort->pfnCompleted (pMsgHdr->pHGCMPort, result, pMsgHdr->pCmd);
     459        pMsgHdr->pHGCMPort->pfnCompleted (pMsgHdr->pHGCMPort, g_fSaveState? VINF_HGCM_SAVE_STATE: result, pMsgHdr->pCmd);
    442460    }
    443461
     
    566584
    567585                rc = VINF_SUCCESS;
    568                 if (pClient && pSvc->m_fntable.pfnLoadState)
     586
     587                if (pClient)
    569588                {
    570                     rc = pSvc->m_fntable.pfnLoadState (pMsg->u32ClientID, HGCM_CLIENT_DATA(pSvc, pClient), pMsg->pSSM);
     589                    if (pSvc->m_fntable.pfnLoadState)
     590                    {
     591                        rc = pSvc->m_fntable.pfnLoadState (pMsg->u32ClientID, HGCM_CLIENT_DATA(pSvc, pClient), pMsg->pSSM);
     592                    }
     593
    571594                    hgcmObjDereference (pClient);
    572595                }
     
    582605
    583606                rc = VINF_SUCCESS;
    584                 if (pClient && pSvc->m_fntable.pfnSaveState)
     607
     608                if (pClient)
    585609                {
    586                     rc = pSvc->m_fntable.pfnSaveState (pMsg->u32ClientID, HGCM_CLIENT_DATA(pSvc, pClient), pMsg->pSSM);
     610                    if (pSvc->m_fntable.pfnSaveState)
     611                    {
     612                        g_fSaveState = true;
     613                        rc = pSvc->m_fntable.pfnSaveState (pMsg->u32ClientID, HGCM_CLIENT_DATA(pSvc, pClient), pMsg->pSSM);
     614                        g_fSaveState = false;
     615                    }
     616
    587617                    hgcmObjDereference (pClient);
    588618                }
     
    688718    RTStrFree (m_pszSvcName);
    689719    m_pszSvcName = NULL;
     720   
     721    // @todo Adjust the list sm_cServices--;
    690722
    691723    LogFlow(("HGCMService::InstanceDestroy completed\n"));
     
    816848                sm_pSvcListHead = psvc;
    817849               
     850#ifdef HGCMSS
     851                sm_cServices++;
     852#endif /* HGCMSS */
     853               
    818854                LogFlow(("HGCMService::LoadService: service %p\n", psvc));
    819855            }
     
    844880    g_fResetting = false;
    845881}
     882
     883#ifdef HGCMSS
     884/* static */ int HGCMService::SaveState (PSSMHANDLE pSSM)
     885{
     886    /* Save the current handle count and restore afterwards to avoid client id conflicts. */
     887    int rc = SSMR3PutU32(pSSM, hgcmObjQueryHandleCount());
     888    AssertRCReturn(rc, rc);
     889
     890    LogFlowFunc(("%d services to be saved:\n", sm_cServices));
     891   
     892    /* Save number of services. */
     893    rc = SSMR3PutU32(pSSM, sm_cServices);
     894    AssertRCReturn(rc, rc);
     895
     896    /* Save every service. */
     897    HGCMService *pSvc = sm_pSvcListHead;
     898
     899    while (pSvc)
     900    {
     901        LogFlowFunc(("Saving service [%s]\n", pSvc->m_pszSvcName));
     902
     903        /* Save the length of the service name. */
     904        rc = SSMR3PutU32(pSSM, strlen(pSvc->m_pszSvcName) + 1);
     905        AssertRCReturn(rc, rc);
     906
     907        /* Save the name of the service. */
     908        rc = SSMR3PutStrZ(pSSM, pSvc->m_pszSvcName);
     909        AssertRCReturn(rc, rc);
     910
     911        /* Save the number of clients. */
     912        rc = SSMR3PutU32(pSSM, pSvc->m_cClients);
     913        AssertRCReturn(rc, rc);
     914
     915        /* Call the service for every client. Normally a service must not have
     916         * a global state to be saved: only per client info is relevant.
     917         * The global state of a service is configured during VM startup.
     918         */
     919        int i;
     920
     921        for (i = 0; i < pSvc->m_cClients; i++)
     922        {
     923            void *pvState = NULL;
     924            uint32_t cbState = 0;
     925
     926            uint32_t u32ClientID = pSvc->m_paClientIds[i];
     927
     928            Log(("client id 0x%08X\n", u32ClientID));
     929
     930            /* Save the client id. */
     931            rc = SSMR3PutU32(pSSM, u32ClientID);
     932            AssertRCReturn(rc, rc);
     933
     934            /* Call the service, so the operation is executed by the service thread. */
     935            rc = pSvc->SaveState (u32ClientID, pSSM);
     936            AssertRCReturn(rc, rc);
     937        }
     938
     939        pSvc = pSvc->m_pSvcNext;
     940    }
     941
     942    return VINF_SUCCESS;
     943}
     944
     945/* static */ int HGCMService::LoadState (PSSMHANDLE pSSM)
     946{
     947    /* Restore handle count to avoid client id conflicts. */
     948    uint32_t u32;
     949
     950    int rc = SSMR3GetU32(pSSM, &u32);
     951    AssertRCReturn(rc, rc);
     952
     953    hgcmObjSetHandleCount(u32);
     954
     955    /* Get the number of services. */
     956    uint32_t cServices;
     957
     958    rc = SSMR3GetU32(pSSM, &cServices);
     959    AssertRCReturn(rc, rc);
     960   
     961    LogFlowFunc(("%d services to be restored:\n", cServices));
     962
     963    while (cServices--)
     964    {
     965        /* Get the length of the service name. */
     966        rc = SSMR3GetU32(pSSM, &u32);
     967        AssertRCReturn(rc, rc);
     968        AssertReturn(u32 <= VBOX_HGCM_SVC_NAME_MAX_BYTES, VERR_SSM_UNEXPECTED_DATA);
     969       
     970        char *pszServiceName = (char *)alloca (u32);
     971
     972        /* Get the service name. */
     973        rc = SSMR3GetStrZ(pSSM, pszServiceName, u32);
     974        AssertRCReturn(rc, rc);
     975       
     976        LogFlowFunc(("Restoring service [%s]\n", pszServiceName));
     977   
     978        /* Resolve the service instance. */
     979        HGCMService *pSvc = FindServiceByName (pszServiceName);
     980        AssertReturn(pSvc, VERR_SSM_UNEXPECTED_DATA);
     981           
     982        /* Get the number of clients. */
     983        uint32_t cClients;
     984        rc = SSMR3GetU32(pSSM, &cClients);
     985        AssertRCReturn(rc, rc);
     986       
     987        while (cClients--)
     988        {
     989            /* Get the client id. */
     990            uint32_t u32ClientID;
     991            rc = SSMR3GetU32(pSSM, &u32ClientID);
     992            AssertRCReturn(rc, rc);
     993
     994            /* Connect the client. */
     995            rc = pSvc->CreateAndConnectClient (NULL, u32ClientID);
     996            AssertRCReturn(rc, rc);
     997
     998            /* Call the service, so the operation is executed by the service thread. */
     999            rc = pSvc->LoadState (u32ClientID, pSSM);
     1000            AssertRCReturn(rc, rc);
     1001        }
     1002    }
     1003
     1004    return VINF_SUCCESS;
     1005}
     1006#endif /* HGCMSS */
    8461007
    8471008void HGCMService::ReleaseService (void)
     
    9611122}
    9621123
     1124#ifdef HGCMSS
     1125/* Create a new client instance and connect it to the service.
     1126 *
     1127 * @param pu32ClientIdOut If not NULL, then the method must generate a new handle for the client.
     1128 *                        If NULL, use the given 'u32ClientIdIn' handle.
     1129 * @param u32ClientIdIn   The handle for the client, when 'pu32ClientIdOut' is NULL.
     1130 *
     1131 */
     1132int HGCMService::CreateAndConnectClient (uint32_t *pu32ClientIdOut, uint32_t u32ClientIdIn)
     1133{
     1134    /* Allocate a client information structure */
     1135    HGCMClient *pClient = new HGCMClient ();
     1136
     1137    if (!pClient)
     1138    {
     1139        LogWarningFunc(("Could not allocate HGCMClient!!!\n"));
     1140        return VERR_NO_MEMORY;
     1141    }
     1142
     1143    uint32_t handle;
     1144   
     1145    if (pu32ClientIdOut != NULL)
     1146    {
     1147        handle = hgcmObjGenerateHandle (pClient);
     1148    }
     1149    else
     1150    {
     1151        handle = hgcmObjAssignHandle (pClient, u32ClientIdIn);
     1152    }
     1153
     1154    AssertRelease(handle);
     1155
     1156    int rc = pClient->Init (this);
     1157
     1158    if (VBOX_SUCCESS(rc))
     1159    {
     1160        rc = Connect (handle);
     1161    }
     1162
     1163    if (VBOX_FAILURE(rc))
     1164    {
     1165        hgcmObjDeleteHandle (handle);
     1166    }
     1167    else
     1168    {
     1169        if (pu32ClientIdOut != NULL)
     1170        {
     1171            *pu32ClientIdOut = handle;
     1172        }
     1173    }
     1174   
     1175    return rc;
     1176}
     1177#endif /* HGCMSS */
    9631178
    9641179int HGCMService::Connect (uint32_t u32ClientID)
     
    12421457                if (VBOX_SUCCESS (rc))
    12431458                {
     1459#ifdef HGCMSS
     1460                    rc = pService->CreateAndConnectClient (pMsg->pu32ClientID, 0);
     1461#else
    12441462                    /* Allocate a client information structure */
    12451463
     
    12731491                        }
    12741492                    }
     1493#endif /* HGCMSS */
    12751494                }
    12761495
     
    13491568            } break;
    13501569
     1570#ifdef HGCMSS
     1571            case HGCMMSGID_LOADSTATE:
     1572            {
     1573                LogFlow(("HGCMMSGID_LOADSTATE\n"));
     1574
     1575                HGCMMsgLoadSaveState *pMsg = (HGCMMsgLoadSaveState *)pMsgCore;
     1576
     1577                rc = HGCMService::LoadState (pMsg->pSSM);
     1578            } break;
     1579
     1580            case HGCMMSGID_SAVESTATE:
     1581            {
     1582                LogFlow(("HGCMMSGID_SAVESTATE\n"));
     1583
     1584                HGCMMsgLoadSaveState *pMsg = (HGCMMsgLoadSaveState *)pMsgCore;
     1585
     1586                rc = HGCMService::SaveState (pMsg->pSSM);
     1587            } break;
     1588#endif /* HGCMSS */
     1589           
    13511590            default:
    13521591            {
     
    14711710}
    14721711
     1712#ifdef HGCMSS
     1713static int hgcmLoadSaveStateSend (PSSMHANDLE pSSM, uint32_t u32MsgId)
     1714{
     1715    /* Forward the request to the main HGCM thread. */
     1716    LogFlowFunc(("u32MsgId = %d\n", u32MsgId));
     1717
     1718    HGCMMSGHANDLE hMsg = 0;
     1719
     1720    int rc = hgcmMsgAlloc (g_hgcmThread, &hMsg, u32MsgId, hgcmMessageAlloc);
     1721
     1722    if (VBOX_SUCCESS(rc))
     1723    {
     1724        HGCMMsgLoadSaveState *pMsg = (HGCMMsgLoadSaveState *)hgcmObjReference (hMsg, HGCMOBJ_MSG);
     1725        AssertRelease(pMsg);
     1726
     1727        pMsg->u32ClientID = 0; /* @todo not used. */
     1728        pMsg->pSSM        = pSSM;
     1729
     1730        rc = hgcmMsgSend (hMsg);
     1731
     1732        hgcmObjDereference (pMsg);
     1733    }
     1734
     1735    LogFlowFunc(("rc = %Vrc\n", rc));
     1736
     1737    return rc;
     1738}
     1739
     1740int hgcmSaveStateInternal (PSSMHANDLE pSSM)
     1741{
     1742    return hgcmLoadSaveStateSend (pSSM, HGCMMSGID_SAVESTATE);
     1743}
     1744
     1745int hgcmLoadStateInternal (PSSMHANDLE pSSM)
     1746{
     1747    return hgcmLoadSaveStateSend (pSSM, HGCMMSGID_LOADSTATE);
     1748}
     1749#else
    14731750int hgcmSaveStateInternal (uint32_t u32ClientID, PSSMHANDLE pSSM)
    14741751{
     
    15151792    return rc;
    15161793}
     1794#endif /* HGCMSS */
    15171795
    15181796int hgcmLoadInternal (const char *pszServiceName, const char *pszServiceLibrary)
  • trunk/src/VBox/Main/hgcm/HGCMObjects.cpp

    r1398 r1681  
    3333static RTCRITSECT g_critsect;
    3434
    35 static uint32_t volatile g_u32HandleCount;
     35/* There are internal handles, which are not saved,
     36 * and client handles, which are saved.
     37 * They use different range of values:
     38 *     1..7FFFFFFF for clients,
     39 *     0x80000001..0xFFFFFFFF for other handles.
     40 */
     41static uint32_t volatile g_u32InternalHandleCount;
     42static uint32_t volatile g_u32ClientHandleCount;
    3643
    3744static PAVLULNODECORE g_pTree;
     
    5461    LogFlow(("MAIN::hgcmObjInit\n"));
    5562
    56     g_u32HandleCount = 0;
     63    g_u32InternalHandleCount = 0x80000000;
     64    g_u32ClientHandleCount = 0;
    5765    g_pTree = NULL;
    5866
     
    7280}
    7381
    74 uint32_t hgcmObjGenerateHandle (HGCMObject *pObject)
     82uint32_t hgcmObjMake (HGCMObject *pObject, uint32_t u32HandleIn)
    7583{
    7684    int handle = 0;
     
    8593
    8694        /* Generate a new handle value. */
    87 
    88         uint32_t u32Start = g_u32HandleCount;
     95       
     96        uint32_t volatile *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
     97                                                       &g_u32ClientHandleCount:
     98                                                       &g_u32InternalHandleCount;
     99
     100        uint32_t u32Start = *pu32HandleCountSource;
    89101
    90102        for (;;)
    91103        {
    92             uint32_t Key = ASMAtomicIncU32 (&g_u32HandleCount);
    93 
    94             if (Key == u32Start)
    95             {
    96                 /* Rollover. Something is wrong. */
    97                 break;
    98             }
    99 
    100             /* 0 is not a valid handle. */
    101             if (Key == 0)
    102             {
    103                 continue;
     104            uint32_t Key;
     105           
     106            if (u32HandleIn == 0)
     107            {
     108                Key = ASMAtomicIncU32 (pu32HandleCountSource);
     109
     110                if (Key == u32Start)
     111                {
     112                    /* Rollover. Something is wrong. */
     113                    AssertReleaseFailed ();
     114                    break;
     115                }
     116
     117                /* 0 and 0x80000000 are not valid handles. */
     118                if ((Key & 0x7FFFFFFF) == 0)
     119                {
     120                    /* Over the invalid value, reinitialize the source. */
     121                    *pu32HandleCountSource = pObject->Type () == HGCMOBJ_CLIENT?
     122                                                 0:
     123                                                 0x80000000;
     124                    continue;
     125                }
     126            }
     127            else
     128            {
     129                Key = u32HandleIn;
    104130            }
    105131
     
    112138            if (!bRC)
    113139            {
    114                 continue;
     140                if (u32HandleIn == 0)
     141                {
     142                    /* Try another generated handle. */
     143                    continue;
     144                }
     145                else
     146                {
     147                    /* Could not use the specified handle. */
     148                    break;
     149                }
    115150            }
    116151
     
    123158            /* Store returned handle. */
    124159            handle = Key;
     160           
     161            Log(("Object key inserted 0x%08X\n", Key));
    125162
    126163            break;
     
    134171    }
    135172
    136     LogFlow(("MAIN::hgcmObjGenerateHandle: handle = %d, rc = %Vrc, return void\n", handle, rc));
     173    LogFlow(("MAIN::hgcmObjGenerateHandle: handle = 0x%08X, rc = %Vrc, return void\n", handle, rc));
    137174
    138175    return handle;
    139176}
    140177
     178uint32_t hgcmObjGenerateHandle (HGCMObject *pObject)
     179{
     180    return hgcmObjMake (pObject, 0);
     181}
     182
     183uint32_t hgcmObjAssignHandle (HGCMObject *pObject, uint32_t u32Handle)
     184{
     185    return hgcmObjMake (pObject, u32Handle);
     186}
     187
    141188void hgcmObjDeleteHandle (uint32_t handle)
    142189{
    143190    int rc = VINF_SUCCESS;
    144191
    145     LogFlow(("MAIN::hgcmObjDeleteHandle: handle %d\n", handle));
     192    LogFlow(("MAIN::hgcmObjDeleteHandle: handle 0x%08X\n", handle));
    146193
    147194    if (handle)
     
    175222HGCMObject *hgcmObjReference (uint32_t handle, HGCMOBJ_TYPE enmObjType)
    176223{
    177     LogFlow(("MAIN::hgcmObjReference: handle %d\n", handle));
     224    LogFlow(("MAIN::hgcmObjReference: handle 0x%08X\n", handle));
    178225
    179226    HGCMObject *pObject = NULL;
     
    222269uint32_t hgcmObjQueryHandleCount ()
    223270{
    224     return g_u32HandleCount;
    225 }
    226 
    227 void hgcmObjSetHandleCount (uint32_t u32HandleCount)
    228 {
    229     Assert(g_u32HandleCount <= u32HandleCount);
     271    return g_u32ClientHandleCount;
     272}
     273
     274void hgcmObjSetHandleCount (uint32_t u32ClientHandleCount)
     275{
     276    Assert(g_u32ClientHandleCount <= u32ClientHandleCount);
    230277
    231278    int rc = hgcmObjEnter ();
     
    233280    if (VBOX_SUCCESS(rc))
    234281    {
    235         if (g_u32HandleCount <= u32HandleCount)
    236             g_u32HandleCount = u32HandleCount;
     282        if (g_u32ClientHandleCount <= u32ClientHandleCount)
     283            g_u32ClientHandleCount = u32ClientHandleCount;
    237284        hgcmObjLeave ();
    238285   }
  • trunk/src/VBox/Main/hgcm/HGCMThread.cpp

    r1385 r1681  
    121121        HGCMMsgCore *m_pFreeTail;
    122122
     123        HGCMTHREADHANDLE m_handle;
    123124
    124125        inline int Enter (void);
     
    151152#define HGCM_MSG_F_IN_PROCESS (0x00000004)
    152153
    153 void HGCMMsgCore::InitializeCore (uint32_t u32MsgId, HGCMThread *pThread)
     154void HGCMMsgCore::InitializeCore (uint32_t u32MsgId, HGCMTHREADHANDLE hThread)
    154155{
    155156    m_u32Version  = HGCMMSG_VERSION;
     
    161162    m_rcSend      = VINF_SUCCESS;
    162163
    163     m_pThread     = pThread;
    164 }
    165 
     164    m_pThread = (HGCMThread *)hgcmObjReference (hThread, HGCMOBJ_THREAD);
     165    AssertRelease (m_pThread);
     166}
     167
     168/* virtual */ HGCMMsgCore::~HGCMMsgCore ()
     169{
     170    if (m_pThread)
     171    {
     172        hgcmObjDereference (m_pThread);
     173        m_pThread = NULL;
     174    }
     175}
    166176
    167177/*
     
    209219    m_pMsgInProcessTail (NULL),
    210220    m_pFreeHead (NULL),
    211     m_pFreeTail (NULL)
     221    m_pFreeTail (NULL),
     222    m_handle (0)
    212223{
    213224    memset (&m_critsect, 0, sizeof (m_critsect));
     
    266277                m_pfnThread = pfnThread;
    267278                m_pvUser    = pvUser;
     279                m_handle    = handle;
    268280
    269281                m_fu32ThreadFlags = HGCMMSG_TF_INITIALIZING;
     
    349361    if (VBOX_SUCCESS(rc))
    350362    {
    351         /* Reference the thread because pMsg contains the pointer to it. */
    352         Reference ();
    353 
    354363        /* Initialize just allocated message core */
    355         pmsg->InitializeCore (u32MsgId, this);
     364        pmsg->InitializeCore (u32MsgId, m_handle);
    356365
    357366        /* and the message specific data. */
     
    524533
    525534    AssertRelease(pMsg->m_pThread == this);
    526     AssertRelease((pMsg->m_fu32Flags & HGCM_MSG_F_IN_PROCESS) != 0);
     535    AssertReleaseMsg((pMsg->m_fu32Flags & HGCM_MSG_F_IN_PROCESS) != 0, ("%p %x\n", pMsg, pMsg->m_fu32Flags));
    527536
    528537    if (pMsg->m_pfnCallback)
  • trunk/src/VBox/Main/include/VMMDev.h

    r1 r1681  
    3737    struct DRVMAINVMMDEV *mpDrv;
    3838
     39#ifdef HGCMSS
     40    bool fSharedFolderActive;
     41    bool isShFlActive()
     42    {
     43        return fSharedFolderActive;
     44    }
     45#else
    3946    uint32_t mSharedFolderClientId;
    4047    uint32_t getShFlClientId()
     
    4249        return mSharedFolderClientId;
    4350    }
     51#endif /* HGCMSS */
    4452
    4553    Console *getParent()
  • trunk/src/VBox/Main/include/hgcm/HGCM.h

    r1385 r1681  
    3131
    3232/* HGCM saved state version */
    33 #define HGCM_SSM_VERSION    1
     33#define HGCM_SSM_VERSION    2
    3434
    3535__BEGIN_DECLS
     
    4545int hgcmHostCallInternal (const char *pszServiceName, uint32_t function, uint32_t cParms, VBOXHGCMSVCPARM aParms[]);
    4646
     47#ifdef HGCMSS
     48int hgcmSaveStateInternal (PSSMHANDLE pSSM);
     49int hgcmLoadStateInternal (PSSMHANDLE pSSM);
     50#else
    4751int hgcmSaveStateInternal (uint32_t clientID, PSSMHANDLE pSSM);
    4852int hgcmLoadStateInternal (uint32_t clientID, PSSMHANDLE pSSM);
     53#endif /* HGCMSS */
    4954
    5055__END_DECLS
  • trunk/src/VBox/Main/include/hgcm/HGCMObjects.h

    r1400 r1681  
    5050{
    5151    private:
    52     friend uint32_t hgcmObjGenerateHandle (HGCMObject *pObject);
     52    friend uint32_t hgcmObjMake (HGCMObject *pObject, uint32_t u32HandleIn);
    5353
    5454        int32_t volatile cRef;
     
    105105
    106106uint32_t hgcmObjGenerateHandle (HGCMObject *pObject);
     107uint32_t hgcmObjAssignHandle (HGCMObject *pObject, uint32_t u32Handle);
    107108
    108109void hgcmObjDeleteHandle (uint32_t handle);
  • trunk/src/VBox/Main/include/hgcm/HGCMThread.h

    r1385 r1681  
    6464        uint32_t m_u32Version;
    6565
    66         /** Thread the message belongs to. */
     66        /** Thread the message belongs to, referenced by the message. */
    6767        HGCMThread *m_pThread;
    6868
     
    8484        int32_t m_rcSend;
    8585
    86         void InitializeCore (uint32_t u32MsgId, HGCMThread *pThread);
     86        void InitializeCore (uint32_t u32MsgId, HGCMTHREADHANDLE hThread);
    8787
    8888    protected:
    89         virtual ~HGCMMsgCore () {};
     89        virtual ~HGCMMsgCore ();
    9090
    9191    public:
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