VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceImpl.cpp@ 100450

Last change on this file since 100450 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/* $Id: tstClipboardServiceImpl.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Shared Clipboard host service implementation (backend) test case.
4 */
5
6/*
7 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#include "../VBoxSharedClipboardSvc-internal.h"
29
30#include <VBox/HostServices/VBoxClipboardSvc.h>
31#ifdef RT_OS_WINDOWS
32# include <VBox/GuestHost/SharedClipboard-win.h>
33#endif
34
35#include <iprt/assert.h>
36#include <iprt/string.h>
37#include <iprt/test.h>
38
39extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad(VBOXHGCMSVCFNTABLE *ptable);
40
41static SHCLCLIENT g_Client;
42static VBOXHGCMSVCHELPERS g_Helpers = { NULL };
43
44/** Simple call handle structure for the guest call completion callback */
45struct VBOXHGCMCALLHANDLE_TYPEDEF
46{
47 /** Where to store the result code */
48 int32_t rc;
49};
50
51/** Call completion callback for guest calls. */
52static DECLCALLBACK(int) callComplete(VBOXHGCMCALLHANDLE callHandle, int32_t rc)
53{
54 callHandle->rc = rc;
55 return VINF_SUCCESS;
56}
57
58static int setupTable(VBOXHGCMSVCFNTABLE *pTable)
59{
60 pTable->cbSize = sizeof(*pTable);
61 pTable->u32Version = VBOX_HGCM_SVC_VERSION;
62 g_Helpers.pfnCallComplete = callComplete;
63 pTable->pHelpers = &g_Helpers;
64 return VBoxHGCMSvcLoad(pTable);
65}
66
67int ShClBackendInit(PSHCLBACKEND, VBOXHGCMSVCFNTABLE *) { return VINF_SUCCESS; }
68void ShClBackendDestroy(PSHCLBACKEND) { }
69int ShClBackendDisconnect(PSHCLBACKEND, PSHCLCLIENT) { return VINF_SUCCESS; }
70int ShClBackendConnect(PSHCLBACKEND, PSHCLCLIENT, bool) { return VINF_SUCCESS; }
71int ShClBackendReportFormats(PSHCLBACKEND, PSHCLCLIENT, SHCLFORMATS) { AssertFailed(); return VINF_SUCCESS; }
72int ShClBackendReadData(PSHCLBACKEND, PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t, unsigned int *) { AssertFailed(); return VERR_WRONG_ORDER; }
73int ShClBackendWriteData(PSHCLBACKEND, PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t) { AssertFailed(); return VINF_SUCCESS; }
74int ShClBackendSync(PSHCLBACKEND, PSHCLCLIENT) { return VINF_SUCCESS; }
75
76static void testAnnounceAndReadData(void)
77{
78 struct VBOXHGCMSVCPARM parms[2];
79 VBOXHGCMSVCFNTABLE table;
80 int rc;
81
82 RTTestISub("Setting up client ...");
83 RTTestIDisableAssertions();
84
85 rc = setupTable(&table);
86 RTTESTI_CHECK_MSG_RETV(RT_SUCCESS(rc), ("rc=%Rrc\n", rc));
87 /* Unless we are bidirectional the host message requests will be dropped. */
88 HGCMSvcSetU32(&parms[0], VBOX_SHCL_MODE_BIDIRECTIONAL);
89 rc = table.pfnHostCall(NULL, VBOX_SHCL_HOST_FN_SET_MODE, 1, parms);
90 RTTESTI_CHECK_RC_OK(rc);
91 rc = shClSvcClientInit(&g_Client, 1 /* clientId */);
92 RTTESTI_CHECK_RC_OK(rc);
93
94 RTTestIRestoreAssertions();
95}
96
97#ifdef RT_OS_WINDOWS
98# include "VBoxOrgCfHtml1.h" /* From chrome 97.0.4692.71 */
99# include "VBoxOrgMimeHtml1.h"
100
101static void testHtmlCf(void)
102{
103 RTTestISub("CF_HTML");
104
105 char *pszOutput = NULL;
106 uint32_t cbOutput = UINT32_MAX/2;
107 RTTestIDisableAssertions();
108 RTTESTI_CHECK_RC(SharedClipboardWinConvertCFHTMLToMIME("", 0, &pszOutput, &cbOutput), VERR_INVALID_PARAMETER);
109 RTTestIRestoreAssertions();
110
111 pszOutput = NULL;
112 cbOutput = UINT32_MAX/2;
113 RTTESTI_CHECK_RC(SharedClipboardWinConvertCFHTMLToMIME((char *)&g_abVBoxOrgCfHtml1[0], g_cbVBoxOrgCfHtml1,
114 &pszOutput, &cbOutput), VINF_SUCCESS);
115 RTTESTI_CHECK(cbOutput == g_cbVBoxOrgMimeHtml1);
116 RTTESTI_CHECK(memcmp(pszOutput, g_abVBoxOrgMimeHtml1, cbOutput) == 0);
117 RTMemFree(pszOutput);
118
119
120 static RTSTRTUPLE const s_aRoundTrips[] =
121 {
122 { RT_STR_TUPLE("") },
123 { RT_STR_TUPLE("1") },
124 { RT_STR_TUPLE("12") },
125 { RT_STR_TUPLE("123") },
126 { RT_STR_TUPLE("1234") },
127 { RT_STR_TUPLE("12345") },
128 { RT_STR_TUPLE("123456") },
129 { RT_STR_TUPLE("1234567") },
130 { RT_STR_TUPLE("12345678") },
131 { RT_STR_TUPLE("123456789") },
132 { RT_STR_TUPLE("1234567890") },
133 { RT_STR_TUPLE("<h2>asdfkjhasdflhj</h2>") },
134 { RT_STR_TUPLE("<h2>asdfkjhasdflhj</h2>\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") },
135 { (const char *)g_abVBoxOrgMimeHtml1, sizeof(g_abVBoxOrgMimeHtml1) },
136 };
137
138 for (size_t i = 0; i < RT_ELEMENTS(s_aRoundTrips); i++)
139 {
140 int rc;
141 char *pszCfHtml = NULL;
142 uint32_t cbCfHtml = UINT32_MAX/2;
143 rc = SharedClipboardWinConvertMIMEToCFHTML(s_aRoundTrips[i].psz, s_aRoundTrips[i].cch + 1, &pszCfHtml, &cbCfHtml);
144 if (rc == VINF_SUCCESS)
145 {
146 if (strlen(pszCfHtml) + 1 != cbCfHtml)
147 RTTestIFailed("#%u: SharedClipboardWinConvertMIMEToCFHTML(%s, %#zx,,) returned incorrect length: %#x, actual %#zx",
148 i, s_aRoundTrips[i].psz, s_aRoundTrips[i].cch, cbCfHtml, strlen(pszCfHtml) + 1);
149
150 char *pszHtml = NULL;
151 uint32_t cbHtml = UINT32_MAX/4;
152 rc = SharedClipboardWinConvertCFHTMLToMIME(pszCfHtml, (uint32_t)strlen(pszCfHtml), &pszHtml, &cbHtml);
153 if (rc == VINF_SUCCESS)
154 {
155 if (strlen(pszHtml) + 1 != cbHtml)
156 RTTestIFailed("#%u: SharedClipboardWinConvertCFHTMLToMIME(%s, %#zx,,) returned incorrect length: %#x, actual %#zx",
157 i, pszHtml, strlen(pszHtml), cbHtml, strlen(pszHtml) + 1);
158 if (strcmp(pszHtml, s_aRoundTrips[i].psz) != 0)
159 RTTestIFailed("#%u: roundtrip for '%s' LB %#zx failed, ended up with '%s'",
160 i, s_aRoundTrips[i].psz, s_aRoundTrips[i].cch, pszHtml);
161 RTMemFree(pszHtml);
162 }
163 else
164 RTTestIFailed("#%u: SharedClipboardWinConvertCFHTMLToMIME(%s, %#zx,,) returned %Rrc, expected VINF_SUCCESS",
165 i, pszCfHtml, strlen(pszCfHtml), rc);
166 RTMemFree(pszCfHtml);
167 }
168 else
169 RTTestIFailed("#%u: SharedClipboardWinConvertMIMEToCFHTML(%s, %#zx,,) returned %Rrc, expected VINF_SUCCESS",
170 i, s_aRoundTrips[i].psz, s_aRoundTrips[i].cch, rc);
171 }
172}
173
174#endif /* RT_OS_WINDOWS */
175
176
177int main(int argc, char *argv[])
178{
179 /*
180 * Init the runtime, test and say hello.
181 */
182 const char *pcszExecName;
183 NOREF(argc);
184 pcszExecName = strrchr(argv[0], '/');
185 pcszExecName = pcszExecName ? pcszExecName + 1 : argv[0];
186 RTTEST hTest;
187 RTEXITCODE rcExit = RTTestInitAndCreate(pcszExecName, &hTest);
188 if (rcExit != RTEXITCODE_SUCCESS)
189 return rcExit;
190 RTTestBanner(hTest);
191
192 /*
193 * Run the tests.
194 */
195 testAnnounceAndReadData();
196#ifdef RT_OS_WINDOWS
197 testHtmlCf();
198#endif
199
200 /*
201 * Summary
202 */
203 return RTTestSummaryAndDestroy(hTest);
204}
205
Note: See TracBrowser for help on using the repository browser.

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