VirtualBox

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

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

VbglR3: Fixed copy & paste bugs in VbglR3GuestCtrlReportFeatures and VbglR3GuestCtrlQueryFeatures. bugref:9320

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 59.7 KB
Line 
1/* $Id: VBoxGuestR3LibGuestCtrl.cpp 79428 2019-06-30 10:12:44Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest control.
4 */
5
6/*
7 * Copyright (C) 2010-2019 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 * Asks a specific guest session to close.
670 *
671 * @return IPRT status code.
672 * @param pCtx Host context.
673 * @param fFlags Some kind of flag. Figure it out yourself.
674 ** @todo Docs!
675 */
676VBGLR3DECL(int) VbglR3GuestCtrlSessionClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t fFlags)
677{
678 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
679 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
680
681 HGCMMsgSessionClose Msg;
682 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_CLOSE, pCtx->uNumParms);
683 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
684 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
685
686 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
687}
688
689
690VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uType, int32_t iResult)
691{
692 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
693
694 HGCMMsgSessionNotify Msg;
695 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_NOTIFY, 3);
696 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
697 VbglHGCMParmUInt32Set(&Msg.type, uType);
698 VbglHGCMParmUInt32Set(&Msg.result, (uint32_t)iResult);
699
700 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
701}
702
703
704/**
705 * Retrieves a HOST_SESSION_CREATE message.
706 */
707VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
708 uint32_t *puProtocol,
709 char *pszUser, uint32_t cbUser,
710 char *pszPassword, uint32_t cbPassword,
711 char *pszDomain, uint32_t cbDomain,
712 uint32_t *pfFlags, uint32_t *pidSession)
713{
714 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
715 AssertReturn(pCtx->uNumParms == 6, VERR_INVALID_PARAMETER);
716
717 AssertPtrReturn(puProtocol, VERR_INVALID_POINTER);
718 AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
719 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
720 AssertPtrReturn(pszDomain, VERR_INVALID_POINTER);
721 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
722
723 int rc;
724 do
725 {
726 HGCMMsgSessionOpen Msg;
727 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
728 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CREATE);
729 VbglHGCMParmUInt32Set(&Msg.protocol, 0);
730 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
731 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
732 VbglHGCMParmPtrSet(&Msg.domain, pszDomain, cbDomain);
733 VbglHGCMParmUInt32Set(&Msg.flags, 0);
734
735 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
736 if (RT_SUCCESS(rc))
737 {
738 Msg.context.GetUInt32(&pCtx->uContextID);
739 Msg.protocol.GetUInt32(puProtocol);
740 Msg.flags.GetUInt32(pfFlags);
741
742 if (pidSession)
743 *pidSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
744 }
745
746 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
747 return rc;
748}
749
750
751/**
752 * Retrieves a HOST_SESSION_CLOSE message.
753 */
754VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfFlags, uint32_t *pidSession)
755{
756 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
757 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
758
759 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
760
761 int rc;
762 do
763 {
764 HGCMMsgSessionClose Msg;
765 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
766 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CLOSE);
767 VbglHGCMParmUInt32Set(&Msg.flags, 0);
768
769 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
770 if (RT_SUCCESS(rc))
771 {
772 Msg.context.GetUInt32(&pCtx->uContextID);
773 Msg.flags.GetUInt32(pfFlags);
774
775 if (pidSession)
776 *pidSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
777 }
778 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
779 return rc;
780}
781
782
783/**
784 * Retrieves a HOST_PATH_RENAME message.
785 */
786VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx,
787 char *pszSource, uint32_t cbSource,
788 char *pszDest, uint32_t cbDest,
789 uint32_t *pfFlags)
790{
791 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
792 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
793
794 AssertPtrReturn(pszSource, VERR_INVALID_POINTER);
795 AssertReturn(cbSource, VERR_INVALID_PARAMETER);
796 AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
797 AssertReturn(cbDest, VERR_INVALID_PARAMETER);
798 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
799
800 int rc;
801 do
802 {
803 HGCMMsgPathRename Msg;
804 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
805 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_RENAME);
806 VbglHGCMParmPtrSet(&Msg.source, pszSource, cbSource);
807 VbglHGCMParmPtrSet(&Msg.dest, pszDest, cbDest);
808 VbglHGCMParmUInt32Set(&Msg.flags, 0);
809
810 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
811 if (RT_SUCCESS(rc))
812 {
813 Msg.context.GetUInt32(&pCtx->uContextID);
814 Msg.flags.GetUInt32(pfFlags);
815 }
816
817 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
818 return rc;
819}
820
821
822/**
823 * Retrieves a HOST_PATH_USER_DOCUMENTS message.
824 */
825VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserDocuments(PVBGLR3GUESTCTRLCMDCTX pCtx)
826{
827 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
828 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
829
830 int rc;
831 do
832 {
833 HGCMMsgPathUserDocuments Msg;
834 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
835 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_DOCUMENTS);
836
837 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
838 if (RT_SUCCESS(rc))
839 Msg.context.GetUInt32(&pCtx->uContextID);
840 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
841 return rc;
842}
843
844
845/**
846 * Retrieves a HOST_PATH_USER_HOME message.
847 */
848VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserHome(PVBGLR3GUESTCTRLCMDCTX pCtx)
849{
850 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
851 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
852
853 int rc;
854 do
855 {
856 HGCMMsgPathUserHome Msg;
857 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
858 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_HOME);
859
860 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
861 if (RT_SUCCESS(rc))
862 Msg.context.GetUInt32(&pCtx->uContextID);
863 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
864 return rc;
865}
866
867
868/**
869 * Retrieves a HOST_EXEC_CMD message.
870 *
871 * @todo Move the parameters in an own struct!
872 */
873VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLCMDCTX pCtx,
874 char *pszCmd, uint32_t cbCmd,
875 uint32_t *pfFlags,
876 char *pszArgs, uint32_t cbArgs, uint32_t *pcArgs,
877 char *pszEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars,
878 char *pszUser, uint32_t cbUser,
879 char *pszPassword, uint32_t cbPassword,
880 uint32_t *puTimeoutMS,
881 uint32_t *puPriority,
882 uint64_t *puAffinity, uint32_t cbAffinity, uint32_t *pcAffinity)
883{
884 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
885
886 AssertPtrReturn(pszCmd, VERR_INVALID_POINTER);
887 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
888 AssertPtrReturn(pszArgs, VERR_INVALID_POINTER);
889 AssertPtrReturn(pcArgs, VERR_INVALID_POINTER);
890 AssertPtrReturn(pszEnv, VERR_INVALID_POINTER);
891 AssertPtrReturn(pcbEnv, VERR_INVALID_POINTER);
892 AssertPtrReturn(pcEnvVars, VERR_INVALID_POINTER);
893 AssertPtrReturn(puTimeoutMS, VERR_INVALID_POINTER);
894
895 int rc;
896 do
897 {
898 HGCMMsgProcExec Msg;
899 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
900 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_CMD);
901 VbglHGCMParmPtrSet(&Msg.cmd, pszCmd, cbCmd);
902 VbglHGCMParmUInt32Set(&Msg.flags, 0);
903 VbglHGCMParmUInt32Set(&Msg.num_args, 0);
904 VbglHGCMParmPtrSet(&Msg.args, pszArgs, cbArgs);
905 VbglHGCMParmUInt32Set(&Msg.num_env, 0);
906 VbglHGCMParmUInt32Set(&Msg.cb_env, 0);
907 VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv);
908 if (pCtx->uProtocol < 2)
909 {
910 AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
911 AssertReturn(cbUser, VERR_INVALID_PARAMETER);
912 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
913 AssertReturn(pszPassword, VERR_INVALID_PARAMETER);
914
915 VbglHGCMParmPtrSet(&Msg.u.v1.username, pszUser, cbUser);
916 VbglHGCMParmPtrSet(&Msg.u.v1.password, pszPassword, cbPassword);
917 VbglHGCMParmUInt32Set(&Msg.u.v1.timeout, 0);
918 }
919 else
920 {
921 AssertPtrReturn(puAffinity, VERR_INVALID_POINTER);
922 AssertReturn(cbAffinity, VERR_INVALID_PARAMETER);
923
924 VbglHGCMParmUInt32Set(&Msg.u.v2.timeout, 0);
925 VbglHGCMParmUInt32Set(&Msg.u.v2.priority, 0);
926 VbglHGCMParmUInt32Set(&Msg.u.v2.num_affinity, 0);
927 VbglHGCMParmPtrSet(&Msg.u.v2.affinity, puAffinity, cbAffinity);
928 }
929
930 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
931 if (RT_SUCCESS(rc))
932 {
933 Msg.context.GetUInt32(&pCtx->uContextID);
934 Msg.flags.GetUInt32(pfFlags);
935 Msg.num_args.GetUInt32(pcArgs);
936 Msg.num_env.GetUInt32(pcEnvVars);
937 Msg.cb_env.GetUInt32(pcbEnv);
938 if (pCtx->uProtocol < 2)
939 Msg.u.v1.timeout.GetUInt32(puTimeoutMS);
940 else
941 {
942 Msg.u.v2.timeout.GetUInt32(puTimeoutMS);
943 Msg.u.v2.priority.GetUInt32(puPriority);
944 Msg.u.v2.num_affinity.GetUInt32(pcAffinity);
945 }
946 }
947 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
948 return rc;
949}
950
951
952/**
953 * Allocates and gets host data, based on the message id.
954 *
955 * This will block until data becomes available.
956 *
957 * @returns VBox status code.
958 ** @todo Docs!
959 */
960VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
961 uint32_t *puPID, uint32_t *puHandle, uint32_t *pfFlags)
962{
963 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
964 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
965
966 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
967 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
968 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
969
970 int rc;
971 do
972 {
973 HGCMMsgProcOutput Msg;
974 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
975 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_GET_OUTPUT);
976 VbglHGCMParmUInt32Set(&Msg.pid, 0);
977 VbglHGCMParmUInt32Set(&Msg.handle, 0);
978 VbglHGCMParmUInt32Set(&Msg.flags, 0);
979
980 rc = VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMMsgProcOutput, data));
981 if (RT_SUCCESS(rc))
982 {
983 Msg.context.GetUInt32(&pCtx->uContextID);
984 Msg.pid.GetUInt32(puPID);
985 Msg.handle.GetUInt32(puHandle);
986 Msg.flags.GetUInt32(pfFlags);
987 }
988 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
989 return rc;
990}
991
992
993/**
994 * Retrieves the input data from host which then gets sent to the started
995 * process (HOST_EXEC_SET_INPUT).
996 *
997 * This will block until data becomes available.
998 */
999VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1000 uint32_t *puPID, uint32_t *pfFlags,
1001 void *pvData, uint32_t cbData,
1002 uint32_t *pcbSize)
1003{
1004 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1005 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1006
1007 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1008 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1009 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1010 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1011
1012 int rc;
1013 do
1014 {
1015 HGCMMsgProcInput Msg;
1016 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1017 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_SET_INPUT);
1018 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1019 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1020 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1021 VbglHGCMParmUInt32Set(&Msg.size, 0);
1022
1023 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1024 if (RT_SUCCESS(rc))
1025 {
1026 Msg.context.GetUInt32(&pCtx->uContextID);
1027 Msg.pid.GetUInt32(puPID);
1028 Msg.flags.GetUInt32(pfFlags);
1029 Msg.size.GetUInt32(pcbSize);
1030 }
1031 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1032
1033 if ( rc != VERR_TOO_MUCH_DATA
1034 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1035 return rc;
1036 return VERR_BUFFER_OVERFLOW;
1037}
1038
1039
1040/**
1041 * Retrieves a HOST_DIR_REMOVE message.
1042 */
1043VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx,
1044 char *pszPath, uint32_t cbPath,
1045 uint32_t *pfFlags)
1046{
1047 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1048 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1049
1050 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1051 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1052 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1053
1054 int rc;
1055 do
1056 {
1057 HGCMMsgDirRemove Msg;
1058 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1059 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_REMOVE);
1060 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
1061 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1062
1063 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1064 if (RT_SUCCESS(rc))
1065 {
1066 Msg.context.GetUInt32(&pCtx->uContextID);
1067 Msg.flags.GetUInt32(pfFlags);
1068 }
1069 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1070 return rc;
1071}
1072
1073
1074/**
1075 * Retrieves a HOST_FILE_OPEN message.
1076 */
1077VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
1078 char *pszFileName, uint32_t cbFileName,
1079 char *pszAccess, uint32_t cbAccess,
1080 char *pszDisposition, uint32_t cbDisposition,
1081 char *pszSharing, uint32_t cbSharing,
1082 uint32_t *puCreationMode,
1083 uint64_t *poffAt)
1084{
1085 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1086 AssertReturn(pCtx->uNumParms == 7, VERR_INVALID_PARAMETER);
1087
1088 AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
1089 AssertReturn(cbFileName, VERR_INVALID_PARAMETER);
1090 AssertPtrReturn(pszAccess, VERR_INVALID_POINTER);
1091 AssertReturn(cbAccess, VERR_INVALID_PARAMETER);
1092 AssertPtrReturn(pszDisposition, VERR_INVALID_POINTER);
1093 AssertReturn(cbDisposition, VERR_INVALID_PARAMETER);
1094 AssertPtrReturn(pszSharing, VERR_INVALID_POINTER);
1095 AssertReturn(cbSharing, VERR_INVALID_PARAMETER);
1096 AssertPtrReturn(puCreationMode, VERR_INVALID_POINTER);
1097 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
1098
1099 int rc;
1100 do
1101 {
1102 HGCMMsgFileOpen Msg;
1103 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1104 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_OPEN);
1105 VbglHGCMParmPtrSet(&Msg.filename, pszFileName, cbFileName);
1106 VbglHGCMParmPtrSet(&Msg.openmode, pszAccess, cbAccess);
1107 VbglHGCMParmPtrSet(&Msg.disposition, pszDisposition, cbDisposition);
1108 VbglHGCMParmPtrSet(&Msg.sharing, pszSharing, cbSharing);
1109 VbglHGCMParmUInt32Set(&Msg.creationmode, 0);
1110 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1111
1112 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1113 if (RT_SUCCESS(rc))
1114 {
1115 Msg.context.GetUInt32(&pCtx->uContextID);
1116 Msg.creationmode.GetUInt32(puCreationMode);
1117 Msg.offset.GetUInt64(poffAt);
1118 }
1119 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1120 return rc;
1121}
1122
1123
1124/**
1125 * Retrieves a HOST_FILE_CLOSE message.
1126 */
1127VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1128{
1129 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1130
1131 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1132 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1133
1134 int rc;
1135 do
1136 {
1137 HGCMMsgFileClose Msg;
1138 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1139 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_CLOSE);
1140 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1141
1142 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1143 if (RT_SUCCESS(rc))
1144 {
1145 Msg.context.GetUInt32(&pCtx->uContextID);
1146 Msg.handle.GetUInt32(puHandle);
1147 }
1148 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1149 return rc;
1150}
1151
1152
1153/**
1154 * Retrieves a HOST_FILE_READ message.
1155 */
1156VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead)
1157{
1158 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1159
1160 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1161 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1162 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
1163
1164 int rc;
1165 do
1166 {
1167 HGCMMsgFileRead Msg;
1168 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1169 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ);
1170 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1171 VbglHGCMParmUInt32Set(&Msg.size, 0);
1172
1173 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1174 if (RT_SUCCESS(rc))
1175 {
1176 Msg.context.GetUInt32(&pCtx->uContextID);
1177 Msg.handle.GetUInt32(puHandle);
1178 Msg.size.GetUInt32(puToRead);
1179 }
1180 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1181 return rc;
1182}
1183
1184
1185/**
1186 * Retrieves a HOST_FILE_READ_AT message.
1187 */
1188VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLCMDCTX pCtx,
1189 uint32_t *puHandle, uint32_t *puToRead, uint64_t *poffAt)
1190{
1191 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1192
1193 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1194 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1195 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
1196
1197 int rc;
1198 do
1199 {
1200 HGCMMsgFileReadAt Msg;
1201 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1202 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ_AT);
1203 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1204 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1205 VbglHGCMParmUInt32Set(&Msg.size, 0);
1206
1207 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1208 if (RT_SUCCESS(rc))
1209 {
1210 Msg.context.GetUInt32(&pCtx->uContextID);
1211 Msg.handle.GetUInt32(puHandle);
1212 Msg.offset.GetUInt64(poffAt);
1213 Msg.size.GetUInt32(puToRead);
1214 }
1215 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1216 return rc;
1217}
1218
1219
1220/**
1221 * Retrieves a HOST_FILE_WRITE message.
1222 */
1223VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
1224 void *pvData, uint32_t cbData, uint32_t *pcbSize)
1225{
1226 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1227
1228 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1229 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1230 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1231 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1232 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1233
1234 int rc;
1235 do
1236 {
1237 HGCMMsgFileWrite Msg;
1238 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1239 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE);
1240 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1241 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1242 VbglHGCMParmUInt32Set(&Msg.size, 0);
1243
1244 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1245 if (RT_SUCCESS(rc))
1246 {
1247 Msg.context.GetUInt32(&pCtx->uContextID);
1248 Msg.handle.GetUInt32(puHandle);
1249 Msg.size.GetUInt32(pcbSize);
1250 }
1251 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1252
1253 if ( rc != VERR_TOO_MUCH_DATA
1254 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1255 return rc;
1256 return VERR_BUFFER_OVERFLOW;
1257}
1258
1259
1260/**
1261 * Retrieves a HOST_FILE_WRITE_AT message.
1262 */
1263VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
1264 void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *poffAt)
1265{
1266 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1267
1268 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1269 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1270 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1271 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1272 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1273
1274 int rc;
1275 do
1276 {
1277 HGCMMsgFileWriteAt Msg;
1278 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1279 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE_AT);
1280 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1281 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1282 VbglHGCMParmUInt32Set(&Msg.size, 0);
1283 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1284
1285 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1286 if (RT_SUCCESS(rc))
1287 {
1288 Msg.context.GetUInt32(&pCtx->uContextID);
1289 Msg.handle.GetUInt32(puHandle);
1290 Msg.size.GetUInt32(pcbSize);
1291 Msg.offset.GetUInt64(poffAt);
1292 }
1293 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1294
1295 if ( rc != VERR_TOO_MUCH_DATA
1296 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1297 return rc;
1298 return VERR_BUFFER_OVERFLOW;
1299}
1300
1301
1302/**
1303 * Retrieves a HOST_FILE_SEEK message.
1304 */
1305VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLCMDCTX pCtx,
1306 uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *poffAt)
1307{
1308 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1309
1310 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1311 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1312 AssertPtrReturn(puSeekMethod, VERR_INVALID_POINTER);
1313 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
1314
1315 int rc;
1316 do
1317 {
1318 HGCMMsgFileSeek Msg;
1319 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1320 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_SEEK);
1321 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1322 VbglHGCMParmUInt32Set(&Msg.method, 0);
1323 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1324
1325 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1326 if (RT_SUCCESS(rc))
1327 {
1328 Msg.context.GetUInt32(&pCtx->uContextID);
1329 Msg.handle.GetUInt32(puHandle);
1330 Msg.method.GetUInt32(puSeekMethod);
1331 Msg.offset.GetUInt64(poffAt);
1332 }
1333 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1334 return rc;
1335}
1336
1337
1338/**
1339 * Retrieves a HOST_FILE_TELL message.
1340 */
1341VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1342{
1343 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1344
1345 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1346 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1347
1348 int rc;
1349 do
1350 {
1351 HGCMMsgFileTell Msg;
1352 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1353 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_TELL);
1354 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1355
1356 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1357 if (RT_SUCCESS(rc))
1358 {
1359 Msg.context.GetUInt32(&pCtx->uContextID);
1360 Msg.handle.GetUInt32(puHandle);
1361 }
1362 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1363 return rc;
1364}
1365
1366
1367/**
1368 * Retrieves a HOST_FILE_SET_SIZE message.
1369 */
1370VBGLR3DECL(int) VbglR3GuestCtrlFileGetSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint64_t *pcbNew)
1371{
1372 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1373
1374 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1375 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1376 AssertPtrReturn(pcbNew, VERR_INVALID_POINTER);
1377
1378 int rc;
1379 do
1380 {
1381 HGCMMsgFileSetSize Msg;
1382 VBGL_HGCM_HDR_INIT(&Msg.Hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1383 VbglHGCMParmUInt32Set(&Msg.id32Context, HOST_MSG_FILE_SET_SIZE);
1384 VbglHGCMParmUInt32Set(&Msg.id32Handle, 0);
1385 VbglHGCMParmUInt64Set(&Msg.cb64NewSize, 0);
1386
1387 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
1388 if (RT_SUCCESS(rc))
1389 {
1390 Msg.id32Context.GetUInt32(&pCtx->uContextID);
1391 Msg.id32Handle.GetUInt32(puHandle);
1392 Msg.cb64NewSize.GetUInt64(pcbNew);
1393 }
1394 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1395 return rc;
1396}
1397
1398
1399/**
1400 * Retrieves a HOST_EXEC_TERMINATE message.
1401 */
1402VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID)
1403{
1404 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1405
1406 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1407 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1408
1409 int rc;
1410 do
1411 {
1412 HGCMMsgProcTerminate Msg;
1413 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1414 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_TERMINATE);
1415 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1416
1417 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1418 if (RT_SUCCESS(rc))
1419 {
1420 Msg.context.GetUInt32(&pCtx->uContextID);
1421 Msg.pid.GetUInt32(puPID);
1422 }
1423 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1424 return rc;
1425}
1426
1427
1428/**
1429 * Retrieves a HOST_EXEC_WAIT_FOR message.
1430 */
1431VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLCMDCTX pCtx,
1432 uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS)
1433{
1434 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1435
1436 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1437 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1438
1439 int rc;
1440 do
1441 {
1442 HGCMMsgProcWaitFor Msg;
1443 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1444 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_WAIT_FOR);
1445 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1446 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1447 VbglHGCMParmUInt32Set(&Msg.timeout, 0);
1448
1449 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1450 if (RT_SUCCESS(rc))
1451 {
1452 Msg.context.GetUInt32(&pCtx->uContextID);
1453 Msg.pid.GetUInt32(puPID);
1454 Msg.flags.GetUInt32(puWaitFlags);
1455 Msg.timeout.GetUInt32(puTimeoutMS);
1456 }
1457 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1458 return rc;
1459}
1460
1461
1462VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
1463 uint32_t uRc, uint32_t uFileHandle)
1464{
1465 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1466
1467 HGCMReplyFileNotify Msg;
1468 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1469 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1470 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_OPEN);
1471 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1472 VbglHGCMParmUInt32Set(&Msg.u.open.handle, uFileHandle);
1473
1474 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.open));
1475}
1476
1477
1478VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx,
1479 uint32_t uRc)
1480{
1481 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1482
1483 HGCMReplyFileNotify Msg;
1484 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
1485 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1486 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_CLOSE);
1487 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1488
1489 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
1490}
1491
1492
1493VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
1494{
1495 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1496
1497 HGCMReplyFileNotify Msg;
1498 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
1499 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1500 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_ERROR);
1501 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1502
1503 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
1504}
1505
1506
1507VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx,
1508 uint32_t uRc,
1509 void *pvData, uint32_t cbData)
1510{
1511 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1512
1513 HGCMReplyFileNotify Msg;
1514 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1515 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1516 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_READ);
1517 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1518 VbglHGCMParmPtrSet(&Msg.u.read.data, pvData, cbData);
1519
1520 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.read));
1521}
1522
1523
1524VBGLR3DECL(int) VbglR3GuestCtrlFileCbReadOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc,
1525 void *pvData, uint32_t cbData, int64_t offNew)
1526{
1527 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1528
1529 HGCMReplyFileNotify Msg;
1530 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 5);
1531 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1532 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_READ_OFFSET);
1533 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1534 VbglHGCMParmPtrSet(&Msg.u.ReadOffset.pvData, pvData, cbData);
1535 VbglHGCMParmUInt64Set(&Msg.u.ReadOffset.off64New, (uint64_t)offNew);
1536
1537 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.read));
1538}
1539
1540
1541VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten)
1542{
1543 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1544
1545 HGCMReplyFileNotify Msg;
1546 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1547 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1548 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_WRITE);
1549 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1550 VbglHGCMParmUInt32Set(&Msg.u.write.written, cbWritten);
1551
1552 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.write));
1553}
1554
1555
1556VBGLR3DECL(int) VbglR3GuestCtrlFileCbWriteOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten, int64_t offNew)
1557{
1558 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1559
1560 HGCMReplyFileNotify Msg;
1561 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 5);
1562 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1563 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_WRITE_OFFSET);
1564 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1565 VbglHGCMParmUInt32Set(&Msg.u.WriteOffset.cb32Written, cbWritten);
1566 VbglHGCMParmUInt64Set(&Msg.u.WriteOffset.off64New, (uint64_t)offNew);
1567
1568 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.write));
1569}
1570
1571
1572VBGLR3DECL(int) VbglR3GuestCtrlFileCbSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t offCurrent)
1573{
1574 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1575
1576 HGCMReplyFileNotify Msg;
1577 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1578 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1579 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_SEEK);
1580 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1581 VbglHGCMParmUInt64Set(&Msg.u.seek.offset, offCurrent);
1582
1583 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.seek));
1584}
1585
1586
1587VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t offCurrent)
1588{
1589 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1590
1591 HGCMReplyFileNotify Msg;
1592 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1593 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1594 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_TELL);
1595 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1596 VbglHGCMParmUInt64Set(&Msg.u.tell.offset, offCurrent);
1597
1598 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.tell));
1599}
1600
1601
1602VBGLR3DECL(int) VbglR3GuestCtrlFileCbSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t cbNew)
1603{
1604 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1605
1606 HGCMReplyFileNotify Msg;
1607 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1608 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1609 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_SET_SIZE);
1610 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1611 VbglHGCMParmUInt64Set(&Msg.u.SetSize.cb64Size, cbNew);
1612
1613 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.SetSize));
1614}
1615
1616
1617/**
1618 * Callback for reporting a guest process status (along with some other stuff) to the host.
1619 *
1620 * @returns VBox status code.
1621 ** @todo Docs!
1622 */
1623VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx,
1624 uint32_t uPID, uint32_t uStatus, uint32_t fFlags,
1625 void *pvData, uint32_t cbData)
1626{
1627 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1628
1629 HGCMMsgProcStatus Msg;
1630 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_STATUS, 5);
1631 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1632 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1633 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
1634 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1635 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1636
1637 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1638}
1639
1640
1641/**
1642 * Sends output (from stdout/stderr) from a running process.
1643 *
1644 * @returns VBox status code.
1645 ** @todo Docs!
1646 */
1647VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1648 uint32_t uPID,uint32_t uHandle, uint32_t fFlags,
1649 void *pvData, uint32_t cbData)
1650{
1651 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1652
1653 HGCMMsgProcOutput Msg;
1654 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_OUTPUT, 5);
1655 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1656 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1657 VbglHGCMParmUInt32Set(&Msg.handle, uHandle);
1658 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1659 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1660
1661 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1662}
1663
1664
1665/**
1666 * Callback for reporting back the input status of a guest process to the host.
1667 *
1668 * @returns VBox status code.
1669 ** @todo Docs!
1670 */
1671VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1672 uint32_t uPID, uint32_t uStatus,
1673 uint32_t fFlags, uint32_t cbWritten)
1674{
1675 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1676
1677 HGCMMsgProcStatusInput Msg;
1678 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_INPUT_STATUS, 5);
1679 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1680 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1681 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
1682 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1683 VbglHGCMParmUInt32Set(&Msg.written, cbWritten);
1684
1685 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1686}
1687
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