VirtualBox

Changeset 80637 in vbox for trunk


Ignore:
Timestamp:
Sep 6, 2019 4:54:36 PM (5 years ago)
Author:
vboxsync
Message:

Shared Clipboard: Implemented new saved state handling for new protocol.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/VBoxClipboardSvc.h

    r80623 r80637  
    6060#include <VBox/GuestHost/SharedClipboard-uri.h>
    6161#endif
     62
     63/*
     64 * The saved state versions.
     65 * We're using it as a version field with the high bit set.
     66 */
     67/** Older saved states (VBox < 6.1). Includes protocol v0 state. */
     68#define VBOX_SHARED_CLIPBOARD_SSM_VER_0          UINT32_C(0x80000002)
     69/** Protocol v1 is being used. */
     70#define VBOX_SHARED_CLIPBOARD_SSM_VER_1          UINT32_C(0x80000003)
    6271
    6372/*
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r80623 r80637  
    6969} VBOXCLIPBOARDCLIENTMSG, *PVBOXCLIPBOARDCLIENTMSG;
    7070
    71 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    7271typedef struct VBOXCLIPBOARDCLIENTURISTATE
    7372{
    74     /** Whether to start a new transfer. */
    75     bool                          fTransferStart;
    7673    /** Directory of the transfer to start. */
    7774    SHAREDCLIPBOARDURITRANSFERDIR enmTransferDir;
    7875} VBOXCLIPBOARDCLIENTURISTATE, *PVBOXCLIPBOARDCLIENTURISTATE;
    79 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    80 
    81 /**
    82  * Structure for keeping the old client state tracking,
    83  * needed for compatbility to older Guest Additions (for now). Remove this later.
    84  */
    85 typedef struct VBOXCLIPBOARDCLIENTSTATEOLD
    86 {
    87     /** The guest is waiting for a message. */
    88     bool fAsync;
    89     /** The guest is waiting for data from the host */
    90     bool fReadPending;
    91     /** Whether the host host has sent a quit message. */
    92     bool fHostMsgQuit;
    93     /** Whether the host host has requested reading clipboard data from the guest. */
    94     bool fHostMsgReadData;
    95     /** Whether the host host has reported its available formats. */
    96     bool fHostMsgFormats;
    97 
    98     struct {
    99         VBOXHGCMCALLHANDLE callHandle;
    100         uint32_t           cParms;
    101         VBOXHGCMSVCPARM   *paParms;
    102     } async;
    103 
    104     struct {
    105         VBOXHGCMCALLHANDLE callHandle;
    106         uint32_t           cParms;
    107         VBOXHGCMSVCPARM   *paParms;
    108     } asyncRead;
    109 
    110     struct {
    111          void *pv;
    112          uint32_t cb;
    113          uint32_t u32Format;
    114     } data;
    115 
    116     uint32_t u32AvailableFormats;
    117     uint32_t u32RequestedFormat;
    118 } VBOXCLIPBOARDCLIENTSTATEOLD;
    11976
    12077/**
     
    13693    uint32_t                         cbChunkSize;
    13794    SHAREDCLIPBOARDSOURCE            enmSource;
    138 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    13995    /** The client's URI state. */
    14096    VBOXCLIPBOARDCLIENTURISTATE      URI;
    141 #endif
    14297} VBOXCLIPBOARDCLIENTSTATE, *PVBOXCLIPBOARDCLIENTSTATE;
    14398
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r80627 r80637  
    16991699
    17001700#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    1701     pClientState->URI.fTransferStart = false;
    17021701    pClientState->URI.enmTransferDir = SHAREDCLIPBOARDURITRANSFERDIR_UNKNOWN;
    17031702#else
     
    17731772}
    17741773
    1775 #ifndef UNIT_TEST
    17761774/**
    1777  * SSM descriptor table for the VBOXCLIPBOARDCLIENTSTATEOLD structure.
    1778  * Legacy, do not use anymore.
    1779  */
    1780 static SSMFIELD const g_aClipboardSSMFieldsV0[] =
    1781 {
    1782     SSMFIELD_ENTRY_OLD(uClientID,               sizeof(uint32_t)),
    1783     SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTSTATEOLD, fHostMsgQuit),
    1784     SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTSTATEOLD, fHostMsgReadData),
    1785     SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTSTATEOLD, fHostMsgFormats),
    1786     SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTSTATEOLD, u32RequestedFormat),
     1775 * SSM descriptor table for the VBOXCLIPBOARDCLIENTSTATE structure.
     1776 */
     1777static SSMFIELD const s_aShClSSMClientState[] =
     1778{
     1779    SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTSTATE, uProtocolVer),
     1780    SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTSTATE, cbChunkSize),
     1781    SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTSTATE, enmSource),
    17871782    SSMFIELD_ENTRY_TERM()
    17881783};
    1789 #endif
     1784
     1785/**
     1786 * SSM descriptor table for the VBOXCLIPBOARDCLIENTURISTATE structure.
     1787 */
     1788static SSMFIELD const s_aShClSSMClientURIState[] =
     1789{
     1790    SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTURISTATE, enmTransferDir),
     1791    SSMFIELD_ENTRY_TERM()
     1792};
     1793
     1794/**
     1795 * SSM descriptor table for the header of the VBOXCLIPBOARDCLIENTMSG structure.
     1796 * The actual message parameters will be serialized separately.
     1797 */
     1798static SSMFIELD const s_aShClSSMClientMsgHdr[] =
     1799{
     1800    SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTMSG, m_uMsg),
     1801    SSMFIELD_ENTRY(VBOXCLIPBOARDCLIENTMSG, m_cParms),
     1802    SSMFIELD_ENTRY_TERM()
     1803};
     1804
     1805/**
     1806 * SSM descriptor table for the VBOXSHCLMSGCTX structure.
     1807 */
     1808static SSMFIELD const s_aShClSSMClientMsgCtx[] =
     1809{
     1810    SSMFIELD_ENTRY(VBOXSHCLMSGCTX, uContextID),
     1811    SSMFIELD_ENTRY_TERM()
     1812};
    17901813
    17911814static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
     
    18021825    LogFunc(("u32ClientID=%RU32\n", u32ClientID));
    18031826
    1804     //PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pvClient;
    1805     RT_NOREF(pvClient);
    1806 
    1807     /* This field used to be the length. We're using it as a version field
    1808        with the high bit set. */
    1809     SSMR3PutU32(pSSM, UINT32_C(0x80000002));
    1810 
    1811     VBOXCLIPBOARDCLIENTSTATEOLD Dummy;
    1812     RT_ZERO(Dummy);
    1813 
    1814     int rc = SSMR3PutStructEx(pSSM, &Dummy, sizeof(Dummy),
    1815                               0 /*fFlags*/, &g_aClipboardSSMFieldsV0[0], NULL);
     1827    PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pvClient;
     1828    AssertPtr(pClient);
     1829
     1830    /* Write Shared Clipboard saved state version. */
     1831    SSMR3PutU32(pSSM, VBOX_SHARED_CLIPBOARD_SSM_VER_1);
     1832
     1833    int rc = SSMR3PutStructEx(pSSM, &pClient->State, sizeof(pClient->State), 0 /*fFlags*/, &s_aShClSSMClientState[0], NULL);
    18161834    AssertRCReturn(rc, rc);
     1835
     1836    rc = SSMR3PutStructEx(pSSM, &pClient->State.URI, sizeof(pClient->State.URI), 0 /*fFlags*/, &s_aShClSSMClientURIState[0], NULL);
     1837    AssertRCReturn(rc, rc);
     1838
     1839    /* Serialize the client's internal message queue. */
     1840    rc = SSMR3PutU64(pSSM, (uint64_t)pClient->queueMsg.size());
     1841    AssertRCReturn(rc, rc);
     1842
     1843    for (size_t i = 0; i < pClient->queueMsg.size(); i++)
     1844    {
     1845        PVBOXCLIPBOARDCLIENTMSG pMsg = pClient->queueMsg.at(i);
     1846        AssertPtr(pMsg);
     1847
     1848        rc = SSMR3PutStructEx(pSSM, pMsg, sizeof(VBOXCLIPBOARDCLIENTMSG), 0 /*fFlags*/, &s_aShClSSMClientMsgHdr[0], NULL);
     1849        AssertRCReturn(rc, rc);
     1850
     1851        rc = SSMR3PutStructEx(pSSM, &pMsg->m_Ctx, sizeof(VBOXSHCLMSGCTX), 0 /*fFlags*/, &s_aShClSSMClientMsgCtx[0], NULL);
     1852        AssertRCReturn(rc, rc);
     1853
     1854        for (uint32_t p = 0; p < pMsg->m_cParms; p++)
     1855        {
     1856            rc = HGCMSvcSSMR3Put(&pMsg->m_paParms[p], pSSM);
     1857            AssertRCReturn(rc, rc);
     1858        }
     1859    }
    18171860
    18181861#else  /* UNIT_TEST */
     
    18221865}
    18231866
     1867static int svcLoadStateV0(uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion)
     1868{
     1869    RT_NOREF(u32ClientID, pvClient, pSSM, uVersion);
     1870
     1871    uint32_t uMarker;
     1872    int rc = SSMR3GetU32(pSSM, &uMarker);   /* Begin marker. */
     1873    AssertRC(rc);
     1874    Assert(uMarker == UINT32_C(0x19200102)  /* SSMR3STRUCT_BEGIN */);
     1875
     1876    rc = SSMR3Skip(pSSM, sizeof(uint32_t)); /* Client ID */
     1877    AssertRCReturn(rc, rc);
     1878
     1879    bool fValue;
     1880    rc = SSMR3GetBool(pSSM, &fValue);       /* fHostMsgQuit */
     1881    AssertRCReturn(rc, rc);
     1882
     1883    rc = SSMR3GetBool(pSSM, &fValue);       /* fHostMsgReadData */
     1884    AssertRCReturn(rc, rc);
     1885
     1886    rc = SSMR3GetBool(pSSM, &fValue);       /* fHostMsgFormats */
     1887    AssertRCReturn(rc, rc);
     1888
     1889    uint32_t fFormats;
     1890    rc = SSMR3GetU32(pSSM, &fFormats);      /* u32RequestedFormat */
     1891    AssertRCReturn(rc, rc);
     1892
     1893    rc = SSMR3GetU32(pSSM, &uMarker);       /* End marker. */
     1894    AssertRCReturn(rc, rc);
     1895    Assert(uMarker == UINT32_C(0x19920406) /* SSMR3STRUCT_END */);
     1896
     1897    return VINF_SUCCESS;
     1898}
     1899
    18241900static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion)
    18251901{
     
    18311907    PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pvClient;
    18321908    AssertPtr(pClient);
    1833 
    1834     /* Save the client ID for data validation. */
    1835     /** @todo isn't this the same as u32ClientID? Playing safe for now... */
    1836     uint32_t const u32ClientIDOld = pClient->State.u32ClientID;
    18371909
    18381910    /* Restore the client data. */
     
    18401912    int rc = SSMR3GetU32(pSSM, &lenOrVer);
    18411913    AssertRCReturn(rc, rc);
    1842     if (lenOrVer == UINT32_C(0x80000002))
    1843     {
    1844         uint32_t uMarker;
    1845         rc = SSMR3GetU32(pSSM, &uMarker);      /* Begin marker. */
    1846         AssertRC(rc);
    1847         Assert(uMarker == UINT32_C(0x19200102) /* SSMR3STRUCT_BEGIN */);
    1848 
    1849         rc = SSMR3Skip(pSSM, sizeof(uint32_t) + (3 * sizeof(bool)) + sizeof(uint32_t));
     1914    if (lenOrVer == VBOX_SHARED_CLIPBOARD_SSM_VER_0)
     1915    {
     1916        return svcLoadStateV0(u32ClientID, pvClient, pSSM, uVersion);
     1917    }
     1918    else if (lenOrVer == VBOX_SHARED_CLIPBOARD_SSM_VER_1)
     1919    {
     1920        rc = SSMR3GetStructEx(pSSM, &pClient->State, sizeof(pClient->State), 0 /*fFlags*/, &s_aShClSSMClientState[0], NULL);
    18501921        AssertRCReturn(rc, rc);
    18511922
    1852         rc = SSMR3GetU32(pSSM, &uMarker);      /* End marker. */
    1853         AssertRC(rc);
    1854         Assert(uMarker == UINT32_C(0x19920406) /* SSMR3STRUCT_END */);
     1923        rc = SSMR3GetStructEx(pSSM, &pClient->State.URI, sizeof(pClient->State.URI), 0 /*fFlags*/, &s_aShClSSMClientURIState[0], NULL);
     1924        AssertRCReturn(rc, rc);
     1925
     1926        /* Load the client's internal message queue. */
     1927        uint64_t cMsg;
     1928        rc = SSMR3GetU64(pSSM, &cMsg);
     1929        AssertRCReturn(rc, rc);
     1930
     1931        for (uint64_t i = 0; i < cMsg; i++)
     1932        {
     1933            PVBOXCLIPBOARDCLIENTMSG pMsg = (PVBOXCLIPBOARDCLIENTMSG)RTMemAlloc(sizeof(VBOXCLIPBOARDCLIENTMSG));
     1934            AssertPtrReturn(pMsg, VERR_NO_MEMORY);
     1935
     1936            rc = SSMR3GetStructEx(pSSM, pMsg, sizeof(VBOXCLIPBOARDCLIENTMSG), 0 /*fFlags*/, &s_aShClSSMClientMsgHdr[0], NULL);
     1937            AssertRCReturn(rc, rc);
     1938
     1939            rc = SSMR3GetStructEx(pSSM, &pMsg->m_Ctx, sizeof(VBOXSHCLMSGCTX), 0 /*fFlags*/, &s_aShClSSMClientMsgCtx[0], NULL);
     1940            AssertRCReturn(rc, rc);
     1941
     1942            pMsg->m_paParms = (PVBOXHGCMSVCPARM)RTMemAllocZ(sizeof(VBOXHGCMSVCPARM) * pMsg->m_cParms);
     1943            AssertPtrReturn(pMsg->m_paParms, VERR_NO_MEMORY);
     1944
     1945            for (uint32_t p = 0; p < pMsg->m_cParms; p++)
     1946            {
     1947                rc = HGCMSvcSSMR3Get(&pMsg->m_paParms[p], pSSM);
     1948                AssertRCReturn(rc, rc);
     1949            }
     1950
     1951            rc = vboxSvcClipboardMsgAdd(pClient, pMsg, true /* fAppend */);
     1952            AssertRCReturn(rc, rc);
     1953        }
    18551954    }
    18561955    else
    18571956    {
    1858         LogFunc(("Client data size mismatch: got %#x\n", lenOrVer));
    1859         return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    1860     }
    1861 
    1862     /* Verify the client ID. */
    1863     if (pClient->State.u32ClientID != u32ClientIDOld)
    1864     {
    1865         LogFunc(("Client ID mismatch: expected %d, got %d\n", u32ClientIDOld, pClient->State.u32ClientID));
    1866         pClient->State.u32ClientID = u32ClientIDOld;
     1957        LogRel(("Shared Clipboard: Unknown saved state version (%#x)\n", lenOrVer));
    18671958        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    18681959    }
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