VirtualBox

Ignore:
Timestamp:
Sep 3, 2019 6:51:43 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133071
Message:

Shared Clipboard: Try to decrypt the service extension logic more and put the service extension state into an own struct. Documentation here and there to (hopefully) make more sense of it.

Location:
trunk/src/VBox/HostServices/SharedClipboard
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r80468 r80557  
    182182
    183183/**
    184  * Structure for keeping a single (HGCM) client map entry.
    185  * Currently empty.
    186  */
    187 typedef struct _VBOXCLIPBOARDCLIENTMAPENTRY
    188 {
    189 } VBOXCLIPBOARDCLIENTMAPENTRY;
    190 
    191 /**
    192184 * Structure for keeping a single event source map entry.
    193185 * Currently empty.
     
    197189} VBOXCLIPBOARDEVENTSOURCEMAPENTRY;
    198190
    199 /** Map holding information about connected HGCM clients. Key is the (unique) HGCM client ID. */
    200 typedef std::map<uint32_t, VBOXCLIPBOARDCLIENTMAPENTRY> ClipboardClientMap;
     191/** Map holding information about connected HGCM clients. Key is the (unique) HGCM client ID.
     192 *  The value is a weak pointer to PVBOXCLIPBOARDCLIENT, which is owned by HGCM. */
     193typedef std::map<uint32_t, PVBOXCLIPBOARDCLIENT> ClipboardClientMap;
    201194
    202195/** Map holding information about event sources. Key is the (unique) event source ID. */
     
    205198/** Simple queue (list) which holds deferred (waiting) clients. */
    206199typedef std::list<uint32_t> ClipboardClientQueue;
     200
     201/**
     202 * Structure for keeping the Shared Clipboard service extension state.
     203 *
     204 * A service extension is optional, and can be installed by a host component
     205 * to communicate with the Shared Clipboard host service.
     206 */
     207typedef struct _VBOXCLIPBOARDEXTSTATE
     208{
     209    /** Pointer to the actual service extension handle. */
     210    PFNHGCMSVCEXT  pfnExtension;
     211    /** Opaque pointer to extension-provided data. Don't touch. */
     212    void          *pvExtension;
     213    /** The HGCM client ID currently assigned to this service extension.
     214     *  At the moment only one HGCM client can be assigned per extension. */
     215    uint32_t       uClientID;
     216    /** Whether the host service is reading clipboard data currently. */
     217    bool           fReadingData;
     218    /** Whether the service extension has sent the clipboard formats while
     219     *  the the host service is reading clipboard data from it. */
     220    bool           fDelayedAnnouncement;
     221    /** The actual clipboard formats announced while the host service
     222     *  is reading clipboard data from the extension. */
     223    uint32_t       uDelayedFormats;
     224} VBOXCLIPBOARDEXTSTATE, *PVBOXCLIPBOARDEXTSTATE;
    207225
    208226/*
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp

    r80468 r80557  
    4040*   Externals                                                                                                                    *
    4141*********************************************************************************************************************************/
    42 extern PFNHGCMSVCEXT g_pfnExtension;
    43 extern void *g_pvExtension;
     42extern VBOXCLIPBOARDEXTSTATE g_ExtState;
    4443extern PVBOXHGCMSVCHELPERS g_pHelpers;
    45 
    4644extern ClipboardClientQueue g_listClientsDeferred;
    4745
     
    12381236    RT_NOREF(paParms, tsArrival);
    12391237
    1240     LogFlowFunc(("uClient=%RU32, u32Function=%RU32 (%s), cParms=%RU32, g_pfnExtension=%p\n",
    1241                  pClient->uClientID, u32Function, VBoxClipboardGuestMsgToStr(u32Function), cParms, g_pfnExtension));
     1238    LogFlowFunc(("uClient=%RU32, u32Function=%RU32 (%s), cParms=%RU32, g_ExtState.pfnExtension=%p\n",
     1239                 pClient->uClientID, u32Function, VBoxClipboardGuestMsgToStr(u32Function), cParms, g_ExtState.pfnExtension));
    12421240
    12431241    /* Check if we've the right mode set. */
     
    12501248    /* A (valid) service extension is needed because VBoxSVC needs to keep track of the
    12511249     * clipboard areas cached on the host. */
    1252     if (!g_pfnExtension)
     1250    if (!g_ExtState.pfnExtension)
    12531251    {
    12541252#ifdef DEBUG_andy
    1255         AssertPtr(g_pfnExtension);
     1253        AssertPtr(g_ExtState.pfnExtension);
    12561254#endif
    12571255        LogFunc(("Invalid / no service extension set, skipping URI handling\n"));
     
    19181916    int rc;
    19191917
    1920     if (g_pfnExtension)
     1918    if (g_ExtState.pfnExtension)
    19211919    {
    19221920        VBOXCLIPBOARDEXTAREAPARMS parms;
     
    19261924
    19271925        /* As the meta data is now complete, register a new clipboard on the host side. */
    1928         rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_REGISTER, &parms, sizeof(parms));
     1926        rc = g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_REGISTER, &parms, sizeof(parms));
    19291927        if (RT_SUCCESS(rc))
    19301928        {
     
    19631961    int rc = VINF_SUCCESS;
    19641962
    1965     if (g_pfnExtension)
     1963    if (g_ExtState.pfnExtension)
    19661964    {
    19671965        VBOXCLIPBOARDEXTAREAPARMS parms;
     
    19701968        parms.uID = pTransfer->pArea->GetID();
    19711969
    1972         rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_UNREGISTER, &parms, sizeof(parms));
     1970        rc = g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_UNREGISTER, &parms, sizeof(parms));
    19731971        if (RT_SUCCESS(rc))
    19741972        {
     
    20162014    int rc = VINF_SUCCESS;
    20172015
    2018     if (g_pfnExtension)
     2016    if (g_ExtState.pfnExtension)
    20192017    {
    20202018        VBOXCLIPBOARDEXTAREAPARMS parms;
     
    20272025         *
    20282026         * This might fail if the host does not have a most recent clipboard area (yet). */
    2029         rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_ATTACH, &parms, sizeof(parms));
     2027        rc = g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_ATTACH, &parms, sizeof(parms));
    20302028        if (RT_SUCCESS(rc))
    20312029            rc = pTransfer->pArea->OpenTemp(parms.uID /* Area ID */);
     
    20612059    int rc = VINF_SUCCESS;
    20622060
    2063     if (g_pfnExtension)
     2061    if (g_ExtState.pfnExtension)
    20642062    {
    20652063        VBOXCLIPBOARDEXTAREAPARMS parms;
     
    20672065        parms.uID = uAreaID;
    20682066
    2069         rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_DETACH, &parms, sizeof(parms));
     2067        rc = g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_DETACH, &parms, sizeof(parms));
    20702068
    20712069        LogFlowFunc(("Detached client %RU32 from clipboard area %RU32 with rc=%Rrc\n",
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r80552 r80557  
    244244static uint32_t g_uMode;
    245245
    246 PFNHGCMSVCEXT g_pfnExtension;
    247 void *g_pvExtension;
    248 
    249 /* Serialization of data reading and format announcements from the RDP client. */
    250 static bool g_fReadingData = false;
    251 static bool g_fDelayedAnnouncement = false;
    252 static uint32_t g_u32DelayedFormats = 0;
    253 
    254246/** Is the clipboard running in headless mode? */
    255247static bool g_fHeadless = false;
     248
     249/** Holds the service extension state. */
     250VBOXCLIPBOARDEXTSTATE g_ExtState = { 0 };
    256251
    257252/** Global map of all connected clients. */
     
    876871    if (RT_SUCCESS(rc))
    877872    {
    878         if (g_pfnExtension)
     873        if (g_ExtState.pfnExtension)
    879874        {
    880875            VBOXCLIPBOARDEXTPARMS parms;
    881876            RT_ZERO(parms);
    882877
    883             parms.u32Format = dataBlock.uFormat;
     878            parms.uFormat  = dataBlock.uFormat;
    884879            parms.u.pvData  = dataBlock.pvData;
    885880            parms.cbData    = dataBlock.cbData;
    886881
    887             g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_WRITE, &parms, sizeof(parms));
     882            g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_WRITE, &parms, sizeof(parms));
    888883        }
    889884
     
    11201115            if (RT_SUCCESS(rc))
    11211116            {
    1122                 VBOXCLIPBOARDCLIENTMAPENTRY ClientEntry;
    1123                 RT_ZERO(ClientEntry);
    1124 
    1125                 g_mapClients[u32ClientID] = ClientEntry; /** @todo Handle OOM / collisions? */
     1117                /* Assign weak pointer to client map .*/
     1118                g_mapClients[u32ClientID] = pClient; /** @todo Handle OOM / collisions? */
     1119
     1120                /* For now we ASSUME that the first client ever connected is in charge for
     1121                 * communicating withe the service extension.
     1122                 *
     1123                 ** @todo This needs to be fixed ASAP w/o breaking older guest / host combos. */
     1124                if (g_ExtState.uClientID == 0)
     1125                    g_ExtState.uClientID = u32ClientID;
    11261126            }
    11271127        }
     
    13191319                    if (RT_SUCCESS(rc))
    13201320                    {
    1321             #if 0
    1322                         if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     1321                        if (g_ExtState.pfnExtension)
    13231322                        {
    1324                             /* Tell the guest that we want to start a reading transfer
    1325                              * (from guest to the host). */
    1326                             rc = vboxSvcClipboardReportMsg(pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_START,
    1327                                                            0 /* u32Formats == 0 means reading data */);
    1328 
    1329                             /* Note: Announcing the actual format will be done in the
    1330                                      host service guest call URI handler (vboxSvcClipboardURIHandler). */
     1323                            VBOXCLIPBOARDEXTPARMS parms;
     1324                            RT_ZERO(parms);
     1325
     1326                            parms.uFormat = u32Formats;
     1327
     1328                            g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE, &parms, sizeof(parms));
    13311329                        }
    1332                         else /* Announce simple formats to the OS-specific service implemenation. */
    1333             #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    1334                         {
    1335                             if (g_pfnExtension)
    1336                             {
    1337                                 VBOXCLIPBOARDEXTPARMS parms;
    1338                                 RT_ZERO(parms);
    1339                                 parms.u32Format = u32Formats;
    1340 
    1341                                 g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE, &parms, sizeof (parms));
    1342                             }
    1343 
    1344                             VBOXCLIPBOARDCLIENTCMDCTX cmdCtx;
    1345                             RT_ZERO(cmdCtx);
    1346 
    1347                             SHAREDCLIPBOARDFORMATDATA formatData;
    1348                             RT_ZERO(formatData);
    1349 
    1350                             formatData.uFormats = u32Formats;
    1351 
    1352                             rc = VBoxClipboardSvcImplFormatAnnounce(pClient, &cmdCtx, &formatData);
    1353                         }
     1330
     1331                        VBOXCLIPBOARDCLIENTCMDCTX cmdCtx;
     1332                        RT_ZERO(cmdCtx);
     1333
     1334                        SHAREDCLIPBOARDFORMATDATA formatData;
     1335                        RT_ZERO(formatData);
     1336
     1337                        formatData.uFormats = u32Formats;
     1338
     1339                        rc = VBoxClipboardSvcImplFormatAnnounce(pClient, &cmdCtx, &formatData);
    13541340                    }
    13551341                }
     
    14471433                            uint32_t cbActual = 0;
    14481434
    1449                             if (g_pfnExtension)
     1435                            /* If there is a service extension active, try reading data from it first. */
     1436                            if (g_ExtState.pfnExtension)
    14501437                            {
    14511438                                VBOXCLIPBOARDEXTPARMS parms;
    14521439                                RT_ZERO(parms);
    14531440
    1454                                 parms.u32Format = u32Format;
    1455                                 parms.u.pvData  = pv;
    1456                                 parms.cbData    = cb;
    1457 
    1458                                 g_fReadingData = true;
    1459 
    1460                                 rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_READ, &parms, sizeof (parms));
    1461                                 LogFlowFunc(("DATA: g_fDelayedAnnouncement = %d, g_u32DelayedFormats = 0x%x\n", g_fDelayedAnnouncement, g_u32DelayedFormats));
    1462 
    1463                                 if (g_fDelayedAnnouncement)
     1441                                parms.uFormat  = u32Format;
     1442                                parms.u.pvData = pv;
     1443                                parms.cbData   = cb;
     1444
     1445                                g_ExtState.fReadingData = true;
     1446
     1447                                /* Read clipboard data from the extension. */
     1448                                rc = g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_DATA_READ,
     1449                                                             &parms, sizeof(parms));
     1450
     1451                                LogFlowFunc(("g_ExtState.fDelayedAnnouncement=%RTbool, g_ExtState.uDelayedFormats=0x%x\n",
     1452                                             g_ExtState.fDelayedAnnouncement, g_ExtState.uDelayedFormats));
     1453
     1454                                /* Did the extension send the clipboard formats yet?
     1455                                 * Otherwise, do this now. */
     1456                                if (g_ExtState.fDelayedAnnouncement)
    14641457                                {
    1465                                     vboxSvcClipboardOldReportMsg(pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_WRITE, g_u32DelayedFormats);
    1466                                     g_fDelayedAnnouncement = false;
    1467                                     g_u32DelayedFormats = 0;
     1458                                    vboxSvcClipboardOldReportMsg(pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_WRITE,
     1459                                                                 g_ExtState.uDelayedFormats);
     1460
     1461                                    g_ExtState.fDelayedAnnouncement = false;
     1462                                    g_ExtState.uDelayedFormats = 0;
    14681463                                }
    14691464
    1470                                 g_fReadingData = false;
    1471 
    1472                                 if (RT_SUCCESS (rc))
     1465                                g_ExtState.fReadingData = false;
     1466
     1467                                if (RT_SUCCESS(rc))
    14731468                                {
    14741469                                    cbActual = parms.cbData;
    14751470                                }
    14761471                            }
     1472
     1473                            /* Note: The host clipboard *always* has precedence over the service extension above,
     1474                             *       so data which has been read above might get overridden by the host clipboard eventually. */
    14771475
    14781476                            /* Release any other pending read, as we only
     
    14941492                            }
    14951493
    1496                             /* Remember our read request until it is completed.
    1497                              * See the protocol description above for more
    1498                              * information. */
     1494                            /*
     1495                             * Remember our read request until it is completed.
     1496                             * See the protocol description above for more information.
     1497                             */
    14991498                            if (rc == VINF_HGCM_ASYNC_EXECUTE)
    15001499                            {
     
    18221821    int rc = VINF_SUCCESS;
    18231822
    1824     PVBOXCLIPBOARDCLIENT pClient = NULL; /** @todo FIX !!! */
    1825 
    1826     if (pClient != NULL)
    1827     {
     1823    /* Figure out if the client in charge for the service extension still is connected. */
     1824    ClipboardClientMap::const_iterator itClient = g_mapClients.find(g_ExtState.uClientID);
     1825    if (itClient != g_mapClients.end())
     1826    {
     1827        PVBOXCLIPBOARDCLIENT pClient = itClient->second;
     1828        AssertPtr(pClient);
     1829
    18281830        switch (u32Function)
    18291831        {
     1832            /* The service extension announces formats to the guest. */
    18301833            case VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE:
    18311834            {
    1832                 LogFlowFunc(("VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE: g_fReadingData=%RTbool\n", g_fReadingData));
    1833                 if (g_fReadingData)
    1834                 {
    1835                     g_fDelayedAnnouncement = true;
    1836                     g_u32DelayedFormats = u32Format;
    1837                 }
    1838             #if 0
     1835                LogFlowFunc(("VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE: g_ExtState.fReadingData=%RTbool\n", g_ExtState.fReadingData));
     1836                if (g_ExtState.fReadingData)
     1837                {
     1838                    g_ExtState.fDelayedAnnouncement = true;
     1839                    g_ExtState.uDelayedFormats = u32Format;
     1840                }
    18391841                else
    18401842                {
    1841                     vboxSvcClipboardReportMsg(g_pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_REPORT_FORMATS, u32Format);
    1842                 }
    1843             #endif
    1844             } break;
    1845 
    1846 #if 0
     1843                    rc = vboxSvcClipboardOldReportMsg(pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_WRITE, u32Format);
     1844                }
     1845
     1846                break;
     1847            }
     1848
     1849            /* The service extension wants read data from the guest. */
    18471850            case VBOX_CLIPBOARD_EXT_FN_DATA_READ:
    18481851            {
    1849                 vboxSvcClipboardReportMsg(g_pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, u32Format);
    1850             } break;
    1851 #endif
     1852                rc = vboxSvcClipboardOldReportMsg(pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, u32Format);
     1853                break;
     1854            }
    18521855
    18531856            default:
     
    18561859        }
    18571860    }
     1861    else
     1862        rc = VERR_NOT_FOUND;
    18581863
    18591864    LogFlowFuncLeaveRC(rc);
     
    18711876    {
    18721877        /* Install extension. */
    1873         g_pfnExtension = pfnExtension;
    1874         g_pvExtension = pvExtension;
     1878        g_ExtState.pfnExtension = pfnExtension;
     1879        g_ExtState.pvExtension = pvExtension;
    18751880
    18761881        parms.u.pfnCallback = extCallback;
    1877         g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));
     1882
     1883        g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));
    18781884    }
    18791885    else
    18801886    {
    1881         if (g_pfnExtension)
    1882             g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));
     1887        if (g_ExtState.pfnExtension)
     1888            g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK, &parms, sizeof(parms));
    18831889
    18841890        /* Uninstall extension. */
    1885         g_pfnExtension = NULL;
    1886         g_pvExtension = NULL;
     1891        g_ExtState.pfnExtension = NULL;
     1892        g_ExtState.pvExtension = NULL;
    18871893    }
    18881894
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