int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool) { Log(("vboxClipboardConnect\n")); if (g_ctx.pClient != NULL) { /* One client only. */ return VERR_NOT_SUPPORTED; } pClient->pCtx = &g_ctx; pClient->pCtx->pClient = pClient; /* Sync the host clipboard content with the client. */ vboxClipboardSync (pClient); return VINF_SUCCESS; }
/** * Enable the shared clipboard - called by the hgcm clipboard subsystem. * * @param pClient Structure containing context information about the guest system * @returns RT status code */ int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool) { if (g_ctx.pClient != NULL) { /* One client only. */ return VERR_NOT_SUPPORTED; } vboxSvcClipboardLock(); pClient->pCtx = &g_ctx; pClient->pCtx->pClient = pClient; /* Initially sync the host clipboard content with the client. */ int rc = vboxClipboardSync (pClient); vboxSvcClipboardUnlock(); return rc; }
static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM) { #ifndef UNIT_TEST LogRel2 (("svcLoadState: u32ClientID = %d\n", u32ClientID)); VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient; /* Existing client can not be in async state yet. */ Assert (!pClient->fAsync); /* Save the client ID for data validation. */ /** @todo isn't this the same as u32ClientID? Playing safe for now... */ uint32_t const u32ClientIDOld = pClient->u32ClientID; /* Restore the client data. */ uint32_t lenOrVer; int rc = SSMR3GetU32 (pSSM, &lenOrVer); AssertRCReturn (rc, rc); if (lenOrVer == UINT32_C (0x80000002)) { rc = SSMR3GetStructEx (pSSM, pClient, sizeof(*pClient), 0 /*fFlags*/, &g_aClipboardClientDataFields[0], NULL); AssertRCReturn (rc, rc); } else if (lenOrVer == (SSMR3HandleHostBits (pSSM) == 64 ? 72 : 48)) { /** * SSM descriptor table for the CLIPSAVEDSTATEDATA structure. */ static SSMFIELD const s_aClipSavedStateDataFields30[] = { SSMFIELD_ENTRY_IGN_HCPTR( CLIPSAVEDSTATEDATA, pNext), SSMFIELD_ENTRY_IGN_HCPTR( CLIPSAVEDSTATEDATA, pPrev), SSMFIELD_ENTRY_IGN_HCPTR( CLIPSAVEDSTATEDATA, pCtx), SSMFIELD_ENTRY( CLIPSAVEDSTATEDATA, u32ClientID), SSMFIELD_ENTRY_CUSTOM(fMsgQuit+fMsgReadData+fMsgFormats, RT_OFFSETOF(CLIPSAVEDSTATEDATA, u32ClientID) + 4, 4), SSMFIELD_ENTRY_IGN_HCPTR( CLIPSAVEDSTATEDATA, async.callHandle), SSMFIELD_ENTRY_IGN_HCPTR( CLIPSAVEDSTATEDATA, async.paParms), SSMFIELD_ENTRY_IGNORE( CLIPSAVEDSTATEDATA, data.pv), SSMFIELD_ENTRY_IGNORE( CLIPSAVEDSTATEDATA, data.cb), SSMFIELD_ENTRY_IGNORE( CLIPSAVEDSTATEDATA, data.u32Format), SSMFIELD_ENTRY_IGNORE( CLIPSAVEDSTATEDATA, u32AvailableFormats), SSMFIELD_ENTRY( CLIPSAVEDSTATEDATA, u32RequestedFormat), SSMFIELD_ENTRY_TERM() }; CLIPSAVEDSTATEDATA savedState; RT_ZERO (savedState); rc = SSMR3GetStructEx (pSSM, &savedState, sizeof(savedState), SSMSTRUCT_FLAGS_MEM_BAND_AID, &s_aClipSavedStateDataFields30[0], NULL); AssertRCReturn (rc, rc); pClient->fMsgQuit = savedState.fMsgQuit; pClient->fMsgReadData = savedState.fMsgReadData; pClient->fMsgFormats = savedState.fMsgFormats; pClient->u32RequestedFormat = savedState.u32RequestedFormat; } else { LogRel (("Client data size mismatch: got %#x\n", lenOrVer)); return VERR_SSM_DATA_UNIT_FORMAT_CHANGED; } /* Verify the client ID. */ if (pClient->u32ClientID != u32ClientIDOld) { LogRel (("Client ID mismatch: expected %d, got %d\n", u32ClientIDOld, pClient->u32ClientID)); pClient->u32ClientID = u32ClientIDOld; return VERR_SSM_DATA_UNIT_FORMAT_CHANGED; } /* Actual host data are to be reported to guest (SYNC). */ vboxClipboardSync (pClient); #endif /* !UNIT_TEST */ return VINF_SUCCESS; }