VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp@ 84198

Last change on this file since 84198 was 84198, checked in by vboxsync, 5 years ago

Guest Control/VbglR3: Added VbglR3GuestCtrlSessionHasChanged() to invalidate the internal state because the (VM) session has been changed (i.e. restored). bugref:9320

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 60.2 KB
Line 
1/* $Id: VBoxGuestR3LibGuestCtrl.cpp 84198 2020-05-08 08:09:50Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest control.
4 */
5
6/*
7 * Copyright (C) 2010-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/string.h>
32#include <iprt/mem.h>
33#include <iprt/assert.h>
34#include <iprt/cpp/autores.h>
35#include <iprt/stdarg.h>
36#include <VBox/err.h>
37#include <VBox/log.h>
38#include <VBox/HostServices/GuestControlSvc.h>
39
40#ifndef RT_OS_WINDOWS
41# include <signal.h>
42#endif
43
44#include "VBoxGuestR3LibInternal.h"
45
46using namespace guestControl;
47
48
49/*********************************************************************************************************************************
50* Global Variables *
51*********************************************************************************************************************************/
52/** Set if GUEST_MSG_PEEK_WAIT and friends are supported. */
53static int g_fVbglR3GuestCtrlHavePeekGetCancel = -1;
54
55
56/**
57 * Connects to the guest control service.
58 *
59 * @returns VBox status code
60 * @param pidClient Where to put The client ID on success. The client ID
61 * must be passed to all the other calls to the service.
62 */
63VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pidClient)
64{
65 return VbglR3HGCMConnect("VBoxGuestControlSvc", pidClient);
66}
67
68
69/**
70 * Disconnect from the guest control service.
71 *
72 * @returns VBox status code.
73 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
74 */
75VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t idClient)
76{
77 return VbglR3HGCMDisconnect(idClient);
78}
79
80
81/**
82 * Waits until a new host message arrives.
83 * This will block until a message becomes available.
84 *
85 * @returns VBox status code.
86 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
87 * @param pidMsg Where to store the message id.
88 * @param pcParameters Where to store the number of parameters which will
89 * be received in a second call to the host.
90 */
91static int vbglR3GuestCtrlMsgWaitFor(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters)
92{
93 AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
94 AssertPtrReturn(pcParameters, VERR_INVALID_POINTER);
95
96 HGCMMsgWaitFor Msg;
97 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
98 GUEST_MSG_WAIT, /* Tell the host we want our next message. */
99 2); /* Just peek for the next message! */
100 VbglHGCMParmUInt32Set(&Msg.msg, 0);
101 VbglHGCMParmUInt32Set(&Msg.num_parms, 0);
102
103 /*
104 * We should always get a VERR_TOO_MUCH_DATA response here, see
105 * guestControl::HostMessage::Peek() and its caller ClientState::SendReply().
106 * We accept success too here, in case someone decide to make the protocol
107 * slightly more sane.
108 *
109 * Note! A really sane protocol design would have a separate call for getting
110 * info about a pending message (returning VINF_SUCCESS), and a separate
111 * one for retriving the actual message parameters. Not this weird
112 * stuff, to put it rather bluntly.
113 *
114 * Note! As a result of this weird design, we are not able to correctly
115 * retrieve message if we're interrupted by a signal, like SIGCHLD.
116 * Because IPRT wants to use waitpid(), we're forced to have a handler
117 * installed for SIGCHLD, so when working with child processes there
118 * will be signals in the air and we will get VERR_INTERRUPTED returns.
119 * The way HGCM handles interrupted calls is to silently (?) drop them
120 * as they complete (see VMMDev), so the server knows little about it
121 * and just goes on to the next message inline.
122 *
123 * So, as a "temporary" mesasure, we block SIGCHLD here while waiting,
124 * because it will otherwise be impossible do simple stuff like 'mkdir'
125 * on a mac os x guest, and probably most other unix guests.
126 */
127#ifdef RT_OS_WINDOWS
128 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
129#else
130 sigset_t SigSet;
131 sigemptyset(&SigSet);
132 sigaddset(&SigSet, SIGCHLD);
133 sigprocmask(SIG_BLOCK, &SigSet, NULL);
134 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
135 sigprocmask(SIG_UNBLOCK, &SigSet, NULL);
136#endif
137 if ( rc == VERR_TOO_MUCH_DATA
138 || RT_SUCCESS(rc))
139 {
140 int rc2 = VbglHGCMParmUInt32Get(&Msg.msg, pidMsg);
141 if (RT_SUCCESS(rc2))
142 {
143 rc2 = VbglHGCMParmUInt32Get(&Msg.num_parms, pcParameters);
144 if (RT_SUCCESS(rc2))
145 {
146 /* Ok, so now we know what message type and how much parameters there are. */
147 return rc;
148 }
149 }
150 rc = rc2;
151 }
152 *pidMsg = UINT32_MAX - 1;
153 *pcParameters = UINT32_MAX - 2;
154 return rc;
155}
156
157
158/**
159 * Determins the value of g_fVbglR3GuestCtrlHavePeekGetCancel.
160 *
161 * @returns true if supported, false if not.
162 * @param idClient The client ID to use for the testing.
163 */
164DECL_NO_INLINE(static, bool) vbglR3GuestCtrlDetectPeekGetCancelSupport(uint32_t idClient)
165{
166 /*
167 * Seems we get VINF_SUCCESS back from the host if we try unsupported
168 * guest control messages, so we need to supply some random message
169 * parameters and check that they change.
170 */
171 uint32_t const idDummyMsg = UINT32_C(0x8350bdca);
172 uint32_t const cDummyParmeters = UINT32_C(0x7439604f);
173 uint32_t const cbDummyMask = UINT32_C(0xc0ffe000);
174 Assert(cDummyParmeters > VMMDEV_MAX_HGCM_PARMS);
175
176 int rc;
177 struct
178 {
179 VBGLIOCHGCMCALL Hdr;
180 HGCMFunctionParameter idMsg;
181 HGCMFunctionParameter cParams;
182 HGCMFunctionParameter acbParams[14];
183 } PeekCall;
184 Assert(RT_ELEMENTS(PeekCall.acbParams) + 2 < VMMDEV_MAX_HGCM_PARMS);
185
186 do
187 {
188 memset(&PeekCall, 0xf6, sizeof(PeekCall));
189 VBGL_HGCM_HDR_INIT(&PeekCall.Hdr, idClient, GUEST_MSG_PEEK_NOWAIT, 16);
190 VbglHGCMParmUInt32Set(&PeekCall.idMsg, idDummyMsg);
191 VbglHGCMParmUInt32Set(&PeekCall.cParams, cDummyParmeters);
192 for (uint32_t i = 0; i < RT_ELEMENTS(PeekCall.acbParams); i++)
193 VbglHGCMParmUInt32Set(&PeekCall.acbParams[i], i | cbDummyMask);
194
195 rc = VbglR3HGCMCall(&PeekCall.Hdr, sizeof(PeekCall));
196 } while (rc == VERR_INTERRUPTED);
197
198 LogRel2(("vbglR3GuestCtrlDetectPeekGetCancelSupport: rc=%Rrc %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x\n",
199 rc, PeekCall.idMsg.u.value32, PeekCall.cParams.u.value32,
200 PeekCall.acbParams[ 0].u.value32, PeekCall.acbParams[ 1].u.value32,
201 PeekCall.acbParams[ 2].u.value32, PeekCall.acbParams[ 3].u.value32,
202 PeekCall.acbParams[ 4].u.value32, PeekCall.acbParams[ 5].u.value32,
203 PeekCall.acbParams[ 6].u.value32, PeekCall.acbParams[ 7].u.value32,
204 PeekCall.acbParams[ 8].u.value32, PeekCall.acbParams[ 9].u.value32,
205 PeekCall.acbParams[10].u.value32, PeekCall.acbParams[11].u.value32,
206 PeekCall.acbParams[12].u.value32, PeekCall.acbParams[13].u.value32));
207
208 /*
209 * VERR_TRY_AGAIN is likely and easy.
210 */
211 if ( rc == VERR_TRY_AGAIN
212 && PeekCall.idMsg.u.value32 == 0
213 && PeekCall.cParams.u.value32 == 0
214 && PeekCall.acbParams[0].u.value32 == 0
215 && PeekCall.acbParams[1].u.value32 == 0
216 && PeekCall.acbParams[2].u.value32 == 0
217 && PeekCall.acbParams[3].u.value32 == 0)
218 {
219 g_fVbglR3GuestCtrlHavePeekGetCancel = 1;
220 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Supported (#1)\n"));
221 return true;
222 }
223
224 /*
225 * VINF_SUCCESS is annoying but with 16 parameters we've got plenty to check.
226 */
227 if ( rc == VINF_SUCCESS
228 && PeekCall.idMsg.u.value32 != idDummyMsg
229 && PeekCall.idMsg.u.value32 != 0
230 && PeekCall.cParams.u.value32 <= VMMDEV_MAX_HGCM_PARMS)
231 {
232 for (uint32_t i = 0; i < RT_ELEMENTS(PeekCall.acbParams); i++)
233 if (PeekCall.acbParams[i].u.value32 != (i | cbDummyMask))
234 {
235 g_fVbglR3GuestCtrlHavePeekGetCancel = 0;
236 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Not supported (#1)\n"));
237 return false;
238 }
239 g_fVbglR3GuestCtrlHavePeekGetCancel = 1;
240 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Supported (#2)\n"));
241 return true;
242 }
243
244 /*
245 * Okay, pretty sure it's not supported then.
246 */
247 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Not supported (#3)\n"));
248 g_fVbglR3GuestCtrlHavePeekGetCancel = 0;
249 return false;
250}
251
252
253/**
254 * Reads g_fVbglR3GuestCtrlHavePeekGetCancel and resolved -1.
255 *
256 * @returns true if supported, false if not.
257 * @param idClient The client ID to use for the testing.
258 */
259DECLINLINE(bool) vbglR3GuestCtrlSupportsPeekGetCancel(uint32_t idClient)
260{
261 int fState = g_fVbglR3GuestCtrlHavePeekGetCancel;
262 if (RT_LIKELY(fState != -1))
263 return fState != 0;
264 return vbglR3GuestCtrlDetectPeekGetCancelSupport(idClient);
265}
266
267
268/**
269 * Figures which getter function to use to retrieve the message.
270 */
271DECLINLINE(uint32_t) vbglR3GuestCtrlGetMsgFunctionNo(uint32_t idClient)
272{
273 return vbglR3GuestCtrlSupportsPeekGetCancel(idClient) ? GUEST_MSG_GET : GUEST_MSG_WAIT;
274}
275
276
277/**
278 * Checks if the host supports the optimizes message and session functions.
279 *
280 * @returns true / false.
281 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
282 * We may need to use this for checking.
283 * @since 6.0
284 */
285VBGLR3DECL(bool) VbglR3GuestCtrlSupportsOptimizations(uint32_t idClient)
286{
287 return vbglR3GuestCtrlSupportsPeekGetCancel(idClient);
288}
289
290
291/**
292 * Make us the guest control master client.
293 *
294 * @returns VBox status code.
295 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
296 */
297VBGLR3DECL(int) VbglR3GuestCtrlMakeMeMaster(uint32_t idClient)
298{
299 int rc;
300 do
301 {
302 VBGLIOCHGCMCALL Hdr;
303 VBGL_HGCM_HDR_INIT(&Hdr, idClient, GUEST_MSG_MAKE_ME_MASTER, 0);
304 rc = VbglR3HGCMCall(&Hdr, sizeof(Hdr));
305 } while (rc == VERR_INTERRUPTED);
306 return rc;
307}
308
309
310/**
311 * Reports features to the host and retrieve host feature set.
312 *
313 * @returns VBox status code.
314 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
315 * @param fGuestFeatures Features to report, VBOX_GUESTCTRL_GF_XXX.
316 * @param pfHostFeatures Where to store the features VBOX_GUESTCTRL_HF_XXX.
317 */
318VBGLR3DECL(int) VbglR3GuestCtrlReportFeatures(uint32_t idClient, uint64_t fGuestFeatures, uint64_t *pfHostFeatures)
319{
320 int rc;
321 do
322 {
323 struct
324 {
325 VBGLIOCHGCMCALL Hdr;
326 HGCMFunctionParameter f64Features0;
327 HGCMFunctionParameter f64Features1;
328 } Msg;
329 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_REPORT_FEATURES, 2);
330 VbglHGCMParmUInt64Set(&Msg.f64Features0, fGuestFeatures);
331 VbglHGCMParmUInt64Set(&Msg.f64Features1, VBOX_GUESTCTRL_GF_1_MUST_BE_ONE);
332
333 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
334 if (RT_SUCCESS(rc))
335 {
336 Assert(Msg.f64Features0.type == VMMDevHGCMParmType_64bit);
337 Assert(Msg.f64Features1.type == VMMDevHGCMParmType_64bit);
338 if (Msg.f64Features1.u.value64 & VBOX_GUESTCTRL_GF_1_MUST_BE_ONE)
339 rc = VERR_NOT_SUPPORTED;
340 else if (pfHostFeatures)
341 *pfHostFeatures = Msg.f64Features0.u.value64;
342 break;
343 }
344 } while (rc == VERR_INTERRUPTED);
345 return rc;
346
347}
348
349
350/**
351 * Query the host features.
352 *
353 * @returns VBox status code.
354 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
355 * @param pfHostFeatures Where to store the host feature, VBOX_GUESTCTRL_HF_XXX.
356 */
357VBGLR3DECL(int) VbglR3GuestCtrlQueryFeatures(uint32_t idClient, uint64_t *pfHostFeatures)
358{
359 int rc;
360 do
361 {
362 struct
363 {
364 VBGLIOCHGCMCALL Hdr;
365 HGCMFunctionParameter f64Features0;
366 HGCMFunctionParameter f64Features1;
367 } Msg;
368 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_QUERY_FEATURES, 2);
369 VbglHGCMParmUInt64Set(&Msg.f64Features0, 0);
370 VbglHGCMParmUInt64Set(&Msg.f64Features1, RT_BIT_64(63));
371
372 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
373 if (RT_SUCCESS(rc))
374 {
375 Assert(Msg.f64Features0.type == VMMDevHGCMParmType_64bit);
376 Assert(Msg.f64Features1.type == VMMDevHGCMParmType_64bit);
377 if (Msg.f64Features1.u.value64 & RT_BIT_64(63))
378 rc = VERR_NOT_SUPPORTED;
379 else if (pfHostFeatures)
380 *pfHostFeatures = Msg.f64Features0.u.value64;
381 break;
382 }
383 } while (rc == VERR_INTERRUPTED);
384 return rc;
385
386}
387
388
389/**
390 * Peeks at the next host message, waiting for one to turn up.
391 *
392 * @returns VBox status code.
393 * @retval VERR_INTERRUPTED if interrupted. Does the necessary cleanup, so
394 * caller just have to repeat this call.
395 * @retval VERR_VM_RESTORED if the VM has been restored (idRestoreCheck).
396 *
397 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
398 * @param pidMsg Where to store the message id.
399 * @param pcParameters Where to store the number of parameters which will
400 * be received in a second call to the host.
401 * @param pidRestoreCheck Pointer to the VbglR3GetSessionId() variable to use
402 * for the VM restore check. Optional.
403 *
404 * @note Restore check is only performed optimally with a 6.0 host.
405 */
406VBGLR3DECL(int) VbglR3GuestCtrlMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck)
407{
408 AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
409 AssertPtrReturn(pcParameters, VERR_INVALID_POINTER);
410
411 int rc;
412 if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient))
413 {
414 struct
415 {
416 VBGLIOCHGCMCALL Hdr;
417 HGCMFunctionParameter idMsg; /* Doubles as restore check on input. */
418 HGCMFunctionParameter cParameters;
419 } Msg;
420 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_PEEK_WAIT, 2);
421 VbglHGCMParmUInt64Set(&Msg.idMsg, pidRestoreCheck ? *pidRestoreCheck : 0);
422 VbglHGCMParmUInt32Set(&Msg.cParameters, 0);
423 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
424 LogRel2(("VbglR3GuestCtrlMsgPeekWait -> %Rrc\n", rc));
425 if (RT_SUCCESS(rc))
426 {
427 AssertMsgReturn( Msg.idMsg.type == VMMDevHGCMParmType_64bit
428 && Msg.cParameters.type == VMMDevHGCMParmType_32bit,
429 ("msg.type=%d num_parms.type=%d\n", Msg.idMsg.type, Msg.cParameters.type),
430 VERR_INTERNAL_ERROR_3);
431
432 *pidMsg = (uint32_t)Msg.idMsg.u.value64;
433 *pcParameters = Msg.cParameters.u.value32;
434 return rc;
435 }
436
437 /*
438 * If interrupted we must cancel the call so it doesn't prevent us from making another one.
439 */
440 if (rc == VERR_INTERRUPTED)
441 {
442 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_CANCEL, 0);
443 int rc2 = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg.Hdr));
444 AssertRC(rc2);
445 }
446
447 /*
448 * If restored, update pidRestoreCheck.
449 */
450 if (rc == VERR_VM_RESTORED && pidRestoreCheck)
451 *pidRestoreCheck = Msg.idMsg.u.value64;
452
453 *pidMsg = UINT32_MAX - 1;
454 *pcParameters = UINT32_MAX - 2;
455 return rc;
456 }
457
458 /*
459 * Fallback if host < v6.0.
460 *
461 * Note! The restore check isn't perfect. Would require checking afterwards
462 * and stash the result if we were restored during the call. Too much
463 * hazzle for a downgrade scenario.
464 */
465 if (pidRestoreCheck)
466 {
467 uint64_t idRestoreCur = *pidRestoreCheck;
468 rc = VbglR3GetSessionId(&idRestoreCur);
469 if (RT_SUCCESS(rc) && idRestoreCur != *pidRestoreCheck)
470 {
471 *pidRestoreCheck = idRestoreCur;
472 return VERR_VM_RESTORED;
473 }
474 }
475
476 rc = vbglR3GuestCtrlMsgWaitFor(idClient, pidMsg, pcParameters);
477 if (rc == VERR_TOO_MUCH_DATA)
478 rc = VINF_SUCCESS;
479 return rc;
480}
481
482
483/**
484 * Asks the host guest control service to set a message filter to this
485 * client so that it only will receive certain messages in the future.
486 * The filter(s) are a bitmask for the context IDs, served from the host.
487 *
488 * @return IPRT status code.
489 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
490 * @param uValue The value to filter messages for.
491 * @param uMaskAdd Filter mask to add.
492 * @param uMaskRemove Filter mask to remove.
493 */
494VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t idClient, uint32_t uValue, uint32_t uMaskAdd, uint32_t uMaskRemove)
495{
496 HGCMMsgFilterSet Msg;
497
498 /* Tell the host we want to set a filter. */
499 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_FILTER_SET, 4);
500 VbglHGCMParmUInt32Set(&Msg.value, uValue);
501 VbglHGCMParmUInt32Set(&Msg.mask_add, uMaskAdd);
502 VbglHGCMParmUInt32Set(&Msg.mask_remove, uMaskRemove);
503 VbglHGCMParmUInt32Set(&Msg.flags, 0 /* Flags, unused */);
504
505 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
506}
507
508
509VBGLR3DECL(int) VbglR3GuestCtrlMsgReply(PVBGLR3GUESTCTRLCMDCTX pCtx,
510 int rc)
511{
512 return VbglR3GuestCtrlMsgReplyEx(pCtx, rc, 0 /* uType */,
513 NULL /* pvPayload */, 0 /* cbPayload */);
514}
515
516
517VBGLR3DECL(int) VbglR3GuestCtrlMsgReplyEx(PVBGLR3GUESTCTRLCMDCTX pCtx,
518 int rc, uint32_t uType,
519 void *pvPayload, uint32_t cbPayload)
520{
521 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
522 /* Everything else is optional. */
523
524 HGCMMsgReply Msg;
525 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_REPLY, 4);
526 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
527 VbglHGCMParmUInt32Set(&Msg.type, uType);
528 VbglHGCMParmUInt32Set(&Msg.rc, (uint32_t)rc); /* int vs. uint32_t */
529 VbglHGCMParmPtrSet(&Msg.payload, pvPayload, cbPayload);
530
531 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
532}
533
534/**
535 * Tell the host to skip the current message replying VERR_NOT_SUPPORTED
536 *
537 * @return IPRT status code.
538 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
539 * @param rcSkip The status code to pass back to Main when skipping.
540 * @param idMsg The message ID to skip, pass UINT32_MAX to pass any.
541 */
542VBGLR3DECL(int) VbglR3GuestCtrlMsgSkip(uint32_t idClient, int rcSkip, uint32_t idMsg)
543{
544 if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient))
545 {
546 struct
547 {
548 VBGLIOCHGCMCALL Hdr;
549 HGCMFunctionParameter rcSkip;
550 HGCMFunctionParameter idMsg;
551 } Msg;
552 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SKIP, 2);
553 VbglHGCMParmUInt32Set(&Msg.rcSkip, (uint32_t)rcSkip);
554 VbglHGCMParmUInt32Set(&Msg.idMsg, idMsg);
555 return VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
556 }
557
558 /* This is generally better than nothing... */
559 return VbglR3GuestCtrlMsgSkipOld(idClient);
560}
561
562
563/**
564 * Tells the host service to skip the current message returned by
565 * VbglR3GuestCtrlMsgWaitFor().
566 *
567 * @return IPRT status code.
568 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
569 */
570VBGLR3DECL(int) VbglR3GuestCtrlMsgSkipOld(uint32_t idClient)
571{
572 HGCMMsgSkip Msg;
573
574 /* Tell the host we want to skip the current assigned message. */
575 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_SKIP_OLD, 1);
576 VbglHGCMParmUInt32Set(&Msg.flags, 0 /* Flags, unused */);
577 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
578}
579
580
581/**
582 * Asks the host to cancel (release) all pending waits which were deferred.
583 *
584 * @returns VBox status code.
585 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
586 */
587VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t idClient)
588{
589 HGCMMsgCancelPendingWaits Msg;
590 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_CANCEL, 0);
591 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
592}
593
594
595/**
596 * Prepares a session.
597 * @since 6.0
598 * @sa GUEST_SESSION_PREPARE
599 */
600VBGLR3DECL(int) VbglR3GuestCtrlSessionPrepare(uint32_t idClient, uint32_t idSession, void const *pvKey, uint32_t cbKey)
601{
602 int rc;
603 do
604 {
605 struct
606 {
607 VBGLIOCHGCMCALL Hdr;
608 HGCMFunctionParameter idSession;
609 HGCMFunctionParameter pKey;
610 } Msg;
611 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_PREPARE, 2);
612 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
613 VbglHGCMParmPtrSet(&Msg.pKey, (void *)pvKey, cbKey);
614 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
615 } while (rc == VERR_INTERRUPTED);
616 return rc;
617}
618
619
620/**
621 * Accepts a session.
622 * @since 6.0
623 * @sa GUEST_SESSION_ACCEPT
624 */
625VBGLR3DECL(int) VbglR3GuestCtrlSessionAccept(uint32_t idClient, uint32_t idSession, void const *pvKey, uint32_t cbKey)
626{
627 int rc;
628 do
629 {
630 struct
631 {
632 VBGLIOCHGCMCALL Hdr;
633 HGCMFunctionParameter idSession;
634 HGCMFunctionParameter pKey;
635 } Msg;
636 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_ACCEPT, 2);
637 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
638 VbglHGCMParmPtrSet(&Msg.pKey, (void *)pvKey, cbKey);
639 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
640 } while (rc == VERR_INTERRUPTED);
641 return rc;
642}
643
644
645/**
646 * Cancels a prepared session.
647 * @since 6.0
648 * @sa GUEST_SESSION_CANCEL_PREPARED
649 */
650VBGLR3DECL(int) VbglR3GuestCtrlSessionCancelPrepared(uint32_t idClient, uint32_t idSession)
651{
652 int rc;
653 do
654 {
655 struct
656 {
657 VBGLIOCHGCMCALL Hdr;
658 HGCMFunctionParameter idSession;
659 } Msg;
660 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_CANCEL_PREPARED, 1);
661 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
662 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
663 } while (rc == VERR_INTERRUPTED);
664 return rc;
665}
666
667
668/**
669 * Invalidates the internal state because the (VM) session has been changed (i.e. restored).
670 *
671 * @returns VBox status code.
672 * @param idClient Client ID to use for invalidating state.
673 * @param idNewControlSession New control session ID. Currently unused.
674 */
675VBGLR3DECL(int) VbglR3GuestCtrlSessionHasChanged(uint32_t idClient, uint64_t idNewControlSession)
676{
677 RT_NOREF(idNewControlSession);
678
679 vbglR3GuestCtrlDetectPeekGetCancelSupport(idClient);
680
681 return VINF_SUCCESS;
682}
683
684
685/**
686 * Asks a specific guest session to close.
687 *
688 * @return IPRT status code.
689 * @param pCtx Host context.
690 * @param fFlags Some kind of flag. Figure it out yourself.
691 ** @todo Docs!
692 */
693VBGLR3DECL(int) VbglR3GuestCtrlSessionClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t fFlags)
694{
695 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
696 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
697
698 HGCMMsgSessionClose Msg;
699 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_CLOSE, pCtx->uNumParms);
700 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
701 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
702
703 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
704}
705
706
707VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uType, int32_t iResult)
708{
709 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
710
711 HGCMMsgSessionNotify Msg;
712 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_NOTIFY, 3);
713 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
714 VbglHGCMParmUInt32Set(&Msg.type, uType);
715 VbglHGCMParmUInt32Set(&Msg.result, (uint32_t)iResult);
716
717 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
718}
719
720
721/**
722 * Retrieves a HOST_SESSION_CREATE message.
723 */
724VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
725 uint32_t *puProtocol,
726 char *pszUser, uint32_t cbUser,
727 char *pszPassword, uint32_t cbPassword,
728 char *pszDomain, uint32_t cbDomain,
729 uint32_t *pfFlags, uint32_t *pidSession)
730{
731 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
732 AssertReturn(pCtx->uNumParms == 6, VERR_INVALID_PARAMETER);
733
734 AssertPtrReturn(puProtocol, VERR_INVALID_POINTER);
735 AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
736 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
737 AssertPtrReturn(pszDomain, VERR_INVALID_POINTER);
738 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
739
740 int rc;
741 do
742 {
743 HGCMMsgSessionOpen Msg;
744 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
745 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CREATE);
746 VbglHGCMParmUInt32Set(&Msg.protocol, 0);
747 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
748 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
749 VbglHGCMParmPtrSet(&Msg.domain, pszDomain, cbDomain);
750 VbglHGCMParmUInt32Set(&Msg.flags, 0);
751
752 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
753 if (RT_SUCCESS(rc))
754 {
755 Msg.context.GetUInt32(&pCtx->uContextID);
756 Msg.protocol.GetUInt32(puProtocol);
757 Msg.flags.GetUInt32(pfFlags);
758
759 if (pidSession)
760 *pidSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
761 }
762
763 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
764 return rc;
765}
766
767
768/**
769 * Retrieves a HOST_SESSION_CLOSE message.
770 */
771VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfFlags, uint32_t *pidSession)
772{
773 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
774 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
775
776 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
777
778 int rc;
779 do
780 {
781 HGCMMsgSessionClose Msg;
782 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
783 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CLOSE);
784 VbglHGCMParmUInt32Set(&Msg.flags, 0);
785
786 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
787 if (RT_SUCCESS(rc))
788 {
789 Msg.context.GetUInt32(&pCtx->uContextID);
790 Msg.flags.GetUInt32(pfFlags);
791
792 if (pidSession)
793 *pidSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
794 }
795 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
796 return rc;
797}
798
799
800/**
801 * Retrieves a HOST_PATH_RENAME message.
802 */
803VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx,
804 char *pszSource, uint32_t cbSource,
805 char *pszDest, uint32_t cbDest,
806 uint32_t *pfFlags)
807{
808 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
809 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
810
811 AssertPtrReturn(pszSource, VERR_INVALID_POINTER);
812 AssertReturn(cbSource, VERR_INVALID_PARAMETER);
813 AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
814 AssertReturn(cbDest, VERR_INVALID_PARAMETER);
815 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
816
817 int rc;
818 do
819 {
820 HGCMMsgPathRename Msg;
821 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
822 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_RENAME);
823 VbglHGCMParmPtrSet(&Msg.source, pszSource, cbSource);
824 VbglHGCMParmPtrSet(&Msg.dest, pszDest, cbDest);
825 VbglHGCMParmUInt32Set(&Msg.flags, 0);
826
827 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
828 if (RT_SUCCESS(rc))
829 {
830 Msg.context.GetUInt32(&pCtx->uContextID);
831 Msg.flags.GetUInt32(pfFlags);
832 }
833
834 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
835 return rc;
836}
837
838
839/**
840 * Retrieves a HOST_PATH_USER_DOCUMENTS message.
841 */
842VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserDocuments(PVBGLR3GUESTCTRLCMDCTX pCtx)
843{
844 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
845 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
846
847 int rc;
848 do
849 {
850 HGCMMsgPathUserDocuments Msg;
851 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
852 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_DOCUMENTS);
853
854 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
855 if (RT_SUCCESS(rc))
856 Msg.context.GetUInt32(&pCtx->uContextID);
857 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
858 return rc;
859}
860
861
862/**
863 * Retrieves a HOST_PATH_USER_HOME message.
864 */
865VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserHome(PVBGLR3GUESTCTRLCMDCTX pCtx)
866{
867 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
868 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
869
870 int rc;
871 do
872 {
873 HGCMMsgPathUserHome Msg;
874 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
875 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_HOME);
876
877 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
878 if (RT_SUCCESS(rc))
879 Msg.context.GetUInt32(&pCtx->uContextID);
880 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
881 return rc;
882}
883
884
885/**
886 * Retrieves a HOST_EXEC_CMD message.
887 *
888 * @todo Move the parameters in an own struct!
889 */
890VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLCMDCTX pCtx,
891 char *pszCmd, uint32_t cbCmd,
892 uint32_t *pfFlags,
893 char *pszArgs, uint32_t cbArgs, uint32_t *pcArgs,
894 char *pszEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars,
895 char *pszUser, uint32_t cbUser,
896 char *pszPassword, uint32_t cbPassword,
897 uint32_t *puTimeoutMS,
898 uint32_t *puPriority,
899 uint64_t *puAffinity, uint32_t cbAffinity, uint32_t *pcAffinity)
900{
901 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
902
903 AssertPtrReturn(pszCmd, VERR_INVALID_POINTER);
904 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
905 AssertPtrReturn(pszArgs, VERR_INVALID_POINTER);
906 AssertPtrReturn(pcArgs, VERR_INVALID_POINTER);
907 AssertPtrReturn(pszEnv, VERR_INVALID_POINTER);
908 AssertPtrReturn(pcbEnv, VERR_INVALID_POINTER);
909 AssertPtrReturn(pcEnvVars, VERR_INVALID_POINTER);
910 AssertPtrReturn(puTimeoutMS, VERR_INVALID_POINTER);
911
912 int rc;
913 do
914 {
915 HGCMMsgProcExec Msg;
916 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
917 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_CMD);
918 VbglHGCMParmPtrSet(&Msg.cmd, pszCmd, cbCmd);
919 VbglHGCMParmUInt32Set(&Msg.flags, 0);
920 VbglHGCMParmUInt32Set(&Msg.num_args, 0);
921 VbglHGCMParmPtrSet(&Msg.args, pszArgs, cbArgs);
922 VbglHGCMParmUInt32Set(&Msg.num_env, 0);
923 VbglHGCMParmUInt32Set(&Msg.cb_env, 0);
924 VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv);
925 if (pCtx->uProtocol < 2)
926 {
927 AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
928 AssertReturn(cbUser, VERR_INVALID_PARAMETER);
929 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
930 AssertReturn(pszPassword, VERR_INVALID_PARAMETER);
931
932 VbglHGCMParmPtrSet(&Msg.u.v1.username, pszUser, cbUser);
933 VbglHGCMParmPtrSet(&Msg.u.v1.password, pszPassword, cbPassword);
934 VbglHGCMParmUInt32Set(&Msg.u.v1.timeout, 0);
935 }
936 else
937 {
938 AssertPtrReturn(puAffinity, VERR_INVALID_POINTER);
939 AssertReturn(cbAffinity, VERR_INVALID_PARAMETER);
940
941 VbglHGCMParmUInt32Set(&Msg.u.v2.timeout, 0);
942 VbglHGCMParmUInt32Set(&Msg.u.v2.priority, 0);
943 VbglHGCMParmUInt32Set(&Msg.u.v2.num_affinity, 0);
944 VbglHGCMParmPtrSet(&Msg.u.v2.affinity, puAffinity, cbAffinity);
945 }
946
947 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
948 if (RT_SUCCESS(rc))
949 {
950 Msg.context.GetUInt32(&pCtx->uContextID);
951 Msg.flags.GetUInt32(pfFlags);
952 Msg.num_args.GetUInt32(pcArgs);
953 Msg.num_env.GetUInt32(pcEnvVars);
954 Msg.cb_env.GetUInt32(pcbEnv);
955 if (pCtx->uProtocol < 2)
956 Msg.u.v1.timeout.GetUInt32(puTimeoutMS);
957 else
958 {
959 Msg.u.v2.timeout.GetUInt32(puTimeoutMS);
960 Msg.u.v2.priority.GetUInt32(puPriority);
961 Msg.u.v2.num_affinity.GetUInt32(pcAffinity);
962 }
963 }
964 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
965 return rc;
966}
967
968
969/**
970 * Allocates and gets host data, based on the message id.
971 *
972 * This will block until data becomes available.
973 *
974 * @returns VBox status code.
975 ** @todo Docs!
976 */
977VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
978 uint32_t *puPID, uint32_t *puHandle, uint32_t *pfFlags)
979{
980 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
981 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
982
983 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
984 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
985 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
986
987 int rc;
988 do
989 {
990 HGCMMsgProcOutput Msg;
991 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
992 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_GET_OUTPUT);
993 VbglHGCMParmUInt32Set(&Msg.pid, 0);
994 VbglHGCMParmUInt32Set(&Msg.handle, 0);
995 VbglHGCMParmUInt32Set(&Msg.flags, 0);
996
997 rc = VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMMsgProcOutput, data));
998 if (RT_SUCCESS(rc))
999 {
1000 Msg.context.GetUInt32(&pCtx->uContextID);
1001 Msg.pid.GetUInt32(puPID);
1002 Msg.handle.GetUInt32(puHandle);
1003 Msg.flags.GetUInt32(pfFlags);
1004 }
1005 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1006 return rc;
1007}
1008
1009
1010/**
1011 * Retrieves the input data from host which then gets sent to the started
1012 * process (HOST_EXEC_SET_INPUT).
1013 *
1014 * This will block until data becomes available.
1015 */
1016VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1017 uint32_t *puPID, uint32_t *pfFlags,
1018 void *pvData, uint32_t cbData,
1019 uint32_t *pcbSize)
1020{
1021 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1022 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1023
1024 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1025 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1026 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1027 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1028
1029 int rc;
1030 do
1031 {
1032 HGCMMsgProcInput Msg;
1033 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1034 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_SET_INPUT);
1035 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1036 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1037 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1038 VbglHGCMParmUInt32Set(&Msg.size, 0);
1039
1040 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1041 if (RT_SUCCESS(rc))
1042 {
1043 Msg.context.GetUInt32(&pCtx->uContextID);
1044 Msg.pid.GetUInt32(puPID);
1045 Msg.flags.GetUInt32(pfFlags);
1046 Msg.size.GetUInt32(pcbSize);
1047 }
1048 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1049
1050 if ( rc != VERR_TOO_MUCH_DATA
1051 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1052 return rc;
1053 return VERR_BUFFER_OVERFLOW;
1054}
1055
1056
1057/**
1058 * Retrieves a HOST_DIR_REMOVE message.
1059 */
1060VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx,
1061 char *pszPath, uint32_t cbPath,
1062 uint32_t *pfFlags)
1063{
1064 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1065 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1066
1067 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1068 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1069 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1070
1071 int rc;
1072 do
1073 {
1074 HGCMMsgDirRemove Msg;
1075 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1076 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_REMOVE);
1077 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
1078 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1079
1080 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1081 if (RT_SUCCESS(rc))
1082 {
1083 Msg.context.GetUInt32(&pCtx->uContextID);
1084 Msg.flags.GetUInt32(pfFlags);
1085 }
1086 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1087 return rc;
1088}
1089
1090
1091/**
1092 * Retrieves a HOST_FILE_OPEN message.
1093 */
1094VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
1095 char *pszFileName, uint32_t cbFileName,
1096 char *pszAccess, uint32_t cbAccess,
1097 char *pszDisposition, uint32_t cbDisposition,
1098 char *pszSharing, uint32_t cbSharing,
1099 uint32_t *puCreationMode,
1100 uint64_t *poffAt)
1101{
1102 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1103 AssertReturn(pCtx->uNumParms == 7, VERR_INVALID_PARAMETER);
1104
1105 AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
1106 AssertReturn(cbFileName, VERR_INVALID_PARAMETER);
1107 AssertPtrReturn(pszAccess, VERR_INVALID_POINTER);
1108 AssertReturn(cbAccess, VERR_INVALID_PARAMETER);
1109 AssertPtrReturn(pszDisposition, VERR_INVALID_POINTER);
1110 AssertReturn(cbDisposition, VERR_INVALID_PARAMETER);
1111 AssertPtrReturn(pszSharing, VERR_INVALID_POINTER);
1112 AssertReturn(cbSharing, VERR_INVALID_PARAMETER);
1113 AssertPtrReturn(puCreationMode, VERR_INVALID_POINTER);
1114 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
1115
1116 int rc;
1117 do
1118 {
1119 HGCMMsgFileOpen Msg;
1120 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1121 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_OPEN);
1122 VbglHGCMParmPtrSet(&Msg.filename, pszFileName, cbFileName);
1123 VbglHGCMParmPtrSet(&Msg.openmode, pszAccess, cbAccess);
1124 VbglHGCMParmPtrSet(&Msg.disposition, pszDisposition, cbDisposition);
1125 VbglHGCMParmPtrSet(&Msg.sharing, pszSharing, cbSharing);
1126 VbglHGCMParmUInt32Set(&Msg.creationmode, 0);
1127 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1128
1129 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1130 if (RT_SUCCESS(rc))
1131 {
1132 Msg.context.GetUInt32(&pCtx->uContextID);
1133 Msg.creationmode.GetUInt32(puCreationMode);
1134 Msg.offset.GetUInt64(poffAt);
1135 }
1136 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1137 return rc;
1138}
1139
1140
1141/**
1142 * Retrieves a HOST_FILE_CLOSE message.
1143 */
1144VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1145{
1146 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1147
1148 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1149 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1150
1151 int rc;
1152 do
1153 {
1154 HGCMMsgFileClose Msg;
1155 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1156 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_CLOSE);
1157 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1158
1159 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1160 if (RT_SUCCESS(rc))
1161 {
1162 Msg.context.GetUInt32(&pCtx->uContextID);
1163 Msg.handle.GetUInt32(puHandle);
1164 }
1165 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1166 return rc;
1167}
1168
1169
1170/**
1171 * Retrieves a HOST_FILE_READ message.
1172 */
1173VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead)
1174{
1175 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1176
1177 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1178 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1179 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
1180
1181 int rc;
1182 do
1183 {
1184 HGCMMsgFileRead Msg;
1185 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1186 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ);
1187 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1188 VbglHGCMParmUInt32Set(&Msg.size, 0);
1189
1190 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1191 if (RT_SUCCESS(rc))
1192 {
1193 Msg.context.GetUInt32(&pCtx->uContextID);
1194 Msg.handle.GetUInt32(puHandle);
1195 Msg.size.GetUInt32(puToRead);
1196 }
1197 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1198 return rc;
1199}
1200
1201
1202/**
1203 * Retrieves a HOST_FILE_READ_AT message.
1204 */
1205VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLCMDCTX pCtx,
1206 uint32_t *puHandle, uint32_t *puToRead, uint64_t *poffAt)
1207{
1208 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1209
1210 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1211 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1212 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
1213
1214 int rc;
1215 do
1216 {
1217 HGCMMsgFileReadAt Msg;
1218 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1219 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ_AT);
1220 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1221 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1222 VbglHGCMParmUInt32Set(&Msg.size, 0);
1223
1224 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1225 if (RT_SUCCESS(rc))
1226 {
1227 Msg.context.GetUInt32(&pCtx->uContextID);
1228 Msg.handle.GetUInt32(puHandle);
1229 Msg.offset.GetUInt64(poffAt);
1230 Msg.size.GetUInt32(puToRead);
1231 }
1232 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1233 return rc;
1234}
1235
1236
1237/**
1238 * Retrieves a HOST_FILE_WRITE message.
1239 */
1240VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
1241 void *pvData, uint32_t cbData, uint32_t *pcbSize)
1242{
1243 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1244
1245 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1246 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1247 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1248 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1249 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1250
1251 int rc;
1252 do
1253 {
1254 HGCMMsgFileWrite Msg;
1255 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1256 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE);
1257 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1258 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1259 VbglHGCMParmUInt32Set(&Msg.size, 0);
1260
1261 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1262 if (RT_SUCCESS(rc))
1263 {
1264 Msg.context.GetUInt32(&pCtx->uContextID);
1265 Msg.handle.GetUInt32(puHandle);
1266 Msg.size.GetUInt32(pcbSize);
1267 }
1268 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1269
1270 if ( rc != VERR_TOO_MUCH_DATA
1271 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1272 return rc;
1273 return VERR_BUFFER_OVERFLOW;
1274}
1275
1276
1277/**
1278 * Retrieves a HOST_FILE_WRITE_AT message.
1279 */
1280VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
1281 void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *poffAt)
1282{
1283 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1284
1285 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1286 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1287 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1288 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1289 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1290
1291 int rc;
1292 do
1293 {
1294 HGCMMsgFileWriteAt Msg;
1295 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1296 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE_AT);
1297 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1298 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1299 VbglHGCMParmUInt32Set(&Msg.size, 0);
1300 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1301
1302 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1303 if (RT_SUCCESS(rc))
1304 {
1305 Msg.context.GetUInt32(&pCtx->uContextID);
1306 Msg.handle.GetUInt32(puHandle);
1307 Msg.size.GetUInt32(pcbSize);
1308 Msg.offset.GetUInt64(poffAt);
1309 }
1310 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1311
1312 if ( rc != VERR_TOO_MUCH_DATA
1313 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1314 return rc;
1315 return VERR_BUFFER_OVERFLOW;
1316}
1317
1318
1319/**
1320 * Retrieves a HOST_FILE_SEEK message.
1321 */
1322VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLCMDCTX pCtx,
1323 uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *poffAt)
1324{
1325 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1326
1327 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1328 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1329 AssertPtrReturn(puSeekMethod, VERR_INVALID_POINTER);
1330 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
1331
1332 int rc;
1333 do
1334 {
1335 HGCMMsgFileSeek Msg;
1336 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1337 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_SEEK);
1338 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1339 VbglHGCMParmUInt32Set(&Msg.method, 0);
1340 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1341
1342 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1343 if (RT_SUCCESS(rc))
1344 {
1345 Msg.context.GetUInt32(&pCtx->uContextID);
1346 Msg.handle.GetUInt32(puHandle);
1347 Msg.method.GetUInt32(puSeekMethod);
1348 Msg.offset.GetUInt64(poffAt);
1349 }
1350 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1351 return rc;
1352}
1353
1354
1355/**
1356 * Retrieves a HOST_FILE_TELL message.
1357 */
1358VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1359{
1360 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1361
1362 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1363 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1364
1365 int rc;
1366 do
1367 {
1368 HGCMMsgFileTell Msg;
1369 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1370 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_TELL);
1371 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1372
1373 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1374 if (RT_SUCCESS(rc))
1375 {
1376 Msg.context.GetUInt32(&pCtx->uContextID);
1377 Msg.handle.GetUInt32(puHandle);
1378 }
1379 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1380 return rc;
1381}
1382
1383
1384/**
1385 * Retrieves a HOST_FILE_SET_SIZE message.
1386 */
1387VBGLR3DECL(int) VbglR3GuestCtrlFileGetSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint64_t *pcbNew)
1388{
1389 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1390
1391 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1392 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1393 AssertPtrReturn(pcbNew, VERR_INVALID_POINTER);
1394
1395 int rc;
1396 do
1397 {
1398 HGCMMsgFileSetSize Msg;
1399 VBGL_HGCM_HDR_INIT(&Msg.Hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1400 VbglHGCMParmUInt32Set(&Msg.id32Context, HOST_MSG_FILE_SET_SIZE);
1401 VbglHGCMParmUInt32Set(&Msg.id32Handle, 0);
1402 VbglHGCMParmUInt64Set(&Msg.cb64NewSize, 0);
1403
1404 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
1405 if (RT_SUCCESS(rc))
1406 {
1407 Msg.id32Context.GetUInt32(&pCtx->uContextID);
1408 Msg.id32Handle.GetUInt32(puHandle);
1409 Msg.cb64NewSize.GetUInt64(pcbNew);
1410 }
1411 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1412 return rc;
1413}
1414
1415
1416/**
1417 * Retrieves a HOST_EXEC_TERMINATE message.
1418 */
1419VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID)
1420{
1421 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1422
1423 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1424 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1425
1426 int rc;
1427 do
1428 {
1429 HGCMMsgProcTerminate Msg;
1430 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1431 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_TERMINATE);
1432 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1433
1434 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1435 if (RT_SUCCESS(rc))
1436 {
1437 Msg.context.GetUInt32(&pCtx->uContextID);
1438 Msg.pid.GetUInt32(puPID);
1439 }
1440 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1441 return rc;
1442}
1443
1444
1445/**
1446 * Retrieves a HOST_EXEC_WAIT_FOR message.
1447 */
1448VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLCMDCTX pCtx,
1449 uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS)
1450{
1451 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1452
1453 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1454 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1455
1456 int rc;
1457 do
1458 {
1459 HGCMMsgProcWaitFor Msg;
1460 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1461 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_WAIT_FOR);
1462 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1463 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1464 VbglHGCMParmUInt32Set(&Msg.timeout, 0);
1465
1466 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1467 if (RT_SUCCESS(rc))
1468 {
1469 Msg.context.GetUInt32(&pCtx->uContextID);
1470 Msg.pid.GetUInt32(puPID);
1471 Msg.flags.GetUInt32(puWaitFlags);
1472 Msg.timeout.GetUInt32(puTimeoutMS);
1473 }
1474 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1475 return rc;
1476}
1477
1478
1479VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
1480 uint32_t uRc, uint32_t uFileHandle)
1481{
1482 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1483
1484 HGCMReplyFileNotify Msg;
1485 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1486 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1487 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_OPEN);
1488 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1489 VbglHGCMParmUInt32Set(&Msg.u.open.handle, uFileHandle);
1490
1491 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.open));
1492}
1493
1494
1495VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx,
1496 uint32_t uRc)
1497{
1498 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1499
1500 HGCMReplyFileNotify Msg;
1501 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
1502 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1503 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_CLOSE);
1504 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1505
1506 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
1507}
1508
1509
1510VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
1511{
1512 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1513
1514 HGCMReplyFileNotify Msg;
1515 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
1516 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1517 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_ERROR);
1518 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1519
1520 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
1521}
1522
1523
1524VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx,
1525 uint32_t uRc,
1526 void *pvData, uint32_t cbData)
1527{
1528 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1529
1530 HGCMReplyFileNotify Msg;
1531 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1532 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1533 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_READ);
1534 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1535 VbglHGCMParmPtrSet(&Msg.u.read.data, pvData, cbData);
1536
1537 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.read));
1538}
1539
1540
1541VBGLR3DECL(int) VbglR3GuestCtrlFileCbReadOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc,
1542 void *pvData, uint32_t cbData, int64_t offNew)
1543{
1544 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1545
1546 HGCMReplyFileNotify Msg;
1547 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 5);
1548 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1549 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_READ_OFFSET);
1550 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1551 VbglHGCMParmPtrSet(&Msg.u.ReadOffset.pvData, pvData, cbData);
1552 VbglHGCMParmUInt64Set(&Msg.u.ReadOffset.off64New, (uint64_t)offNew);
1553
1554 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.ReadOffset));
1555}
1556
1557
1558VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten)
1559{
1560 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1561
1562 HGCMReplyFileNotify Msg;
1563 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1564 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1565 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_WRITE);
1566 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1567 VbglHGCMParmUInt32Set(&Msg.u.write.written, cbWritten);
1568
1569 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.write));
1570}
1571
1572
1573VBGLR3DECL(int) VbglR3GuestCtrlFileCbWriteOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten, int64_t offNew)
1574{
1575 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1576
1577 HGCMReplyFileNotify Msg;
1578 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 5);
1579 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1580 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_WRITE_OFFSET);
1581 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1582 VbglHGCMParmUInt32Set(&Msg.u.WriteOffset.cb32Written, cbWritten);
1583 VbglHGCMParmUInt64Set(&Msg.u.WriteOffset.off64New, (uint64_t)offNew);
1584
1585 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.WriteOffset));
1586}
1587
1588
1589VBGLR3DECL(int) VbglR3GuestCtrlFileCbSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t offCurrent)
1590{
1591 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1592
1593 HGCMReplyFileNotify Msg;
1594 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1595 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1596 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_SEEK);
1597 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1598 VbglHGCMParmUInt64Set(&Msg.u.seek.offset, offCurrent);
1599
1600 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.seek));
1601}
1602
1603
1604VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t offCurrent)
1605{
1606 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1607
1608 HGCMReplyFileNotify Msg;
1609 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1610 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1611 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_TELL);
1612 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1613 VbglHGCMParmUInt64Set(&Msg.u.tell.offset, offCurrent);
1614
1615 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.tell));
1616}
1617
1618
1619VBGLR3DECL(int) VbglR3GuestCtrlFileCbSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t cbNew)
1620{
1621 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1622
1623 HGCMReplyFileNotify Msg;
1624 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1625 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1626 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_SET_SIZE);
1627 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1628 VbglHGCMParmUInt64Set(&Msg.u.SetSize.cb64Size, cbNew);
1629
1630 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.SetSize));
1631}
1632
1633
1634/**
1635 * Callback for reporting a guest process status (along with some other stuff) to the host.
1636 *
1637 * @returns VBox status code.
1638 ** @todo Docs!
1639 */
1640VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx,
1641 uint32_t uPID, uint32_t uStatus, uint32_t fFlags,
1642 void *pvData, uint32_t cbData)
1643{
1644 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1645
1646 HGCMMsgProcStatus Msg;
1647 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_STATUS, 5);
1648 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1649 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1650 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
1651 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1652 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1653
1654 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1655}
1656
1657
1658/**
1659 * Sends output (from stdout/stderr) from a running process.
1660 *
1661 * @returns VBox status code.
1662 ** @todo Docs!
1663 */
1664VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1665 uint32_t uPID,uint32_t uHandle, uint32_t fFlags,
1666 void *pvData, uint32_t cbData)
1667{
1668 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1669
1670 HGCMMsgProcOutput Msg;
1671 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_OUTPUT, 5);
1672 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1673 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1674 VbglHGCMParmUInt32Set(&Msg.handle, uHandle);
1675 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1676 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1677
1678 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1679}
1680
1681
1682/**
1683 * Callback for reporting back the input status of a guest process to the host.
1684 *
1685 * @returns VBox status code.
1686 ** @todo Docs!
1687 */
1688VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1689 uint32_t uPID, uint32_t uStatus,
1690 uint32_t fFlags, uint32_t cbWritten)
1691{
1692 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1693
1694 HGCMMsgProcStatusInput Msg;
1695 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_INPUT_STATUS, 5);
1696 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1697 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1698 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
1699 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1700 VbglHGCMParmUInt32Set(&Msg.written, cbWritten);
1701
1702 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1703}
1704
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