VirtualBox

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

Last change on this file since 78554 was 76958, checked in by vboxsync, 6 years ago

Guest Control: Unifying terminology for (client/host) commands, functions and messages; it's all about messages now. Renaming, no functional changes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.2 KB
Line 
1/* $Id: VBoxGuestR3LibGuestCtrl.cpp 76958 2019-01-23 18:23:04Z 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 * Peeks at the next host message, waiting for one to turn up.
312 *
313 * @returns VBox status code.
314 * @retval VERR_INTERRUPTED if interrupted. Does the necessary cleanup, so
315 * caller just have to repeat this call.
316 * @retval VERR_VM_RESTORED if the VM has been restored (idRestoreCheck).
317 *
318 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
319 * @param pidMsg Where to store the message id.
320 * @param pcParameters Where to store the number of parameters which will
321 * be received in a second call to the host.
322 * @param pidRestoreCheck Pointer to the VbglR3GetSessionId() variable to use
323 * for the VM restore check. Optional.
324 *
325 * @note Restore check is only performed optimally with a 6.0 host.
326 */
327VBGLR3DECL(int) VbglR3GuestCtrlMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck)
328{
329 AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
330 AssertPtrReturn(pcParameters, VERR_INVALID_POINTER);
331
332 int rc;
333 if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient))
334 {
335 struct
336 {
337 VBGLIOCHGCMCALL Hdr;
338 HGCMFunctionParameter idMsg; /* Doubles as restore check on input. */
339 HGCMFunctionParameter cParameters;
340 } Msg;
341 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_PEEK_WAIT, 2);
342 VbglHGCMParmUInt64Set(&Msg.idMsg, pidRestoreCheck ? *pidRestoreCheck : 0);
343 VbglHGCMParmUInt32Set(&Msg.cParameters, 0);
344 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
345 LogRel2(("VbglR3GuestCtrlMsgPeekWait -> %Rrc\n", rc));
346 if (RT_SUCCESS(rc))
347 {
348 AssertMsgReturn( Msg.idMsg.type == VMMDevHGCMParmType_64bit
349 && Msg.cParameters.type == VMMDevHGCMParmType_32bit,
350 ("msg.type=%d num_parms.type=%d\n", Msg.idMsg.type, Msg.cParameters.type),
351 VERR_INTERNAL_ERROR_3);
352
353 *pidMsg = (uint32_t)Msg.idMsg.u.value64;
354 *pcParameters = Msg.cParameters.u.value32;
355 return rc;
356 }
357
358 /*
359 * If interrupted we must cancel the call so it doesn't prevent us from making another one.
360 */
361 if (rc == VERR_INTERRUPTED)
362 {
363 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_CANCEL, 0);
364 int rc2 = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg.Hdr));
365 AssertRC(rc2);
366 }
367
368 /*
369 * If restored, update pidRestoreCheck.
370 */
371 if (rc == VERR_VM_RESTORED && pidRestoreCheck)
372 *pidRestoreCheck = Msg.idMsg.u.value64;
373
374 *pidMsg = UINT32_MAX - 1;
375 *pcParameters = UINT32_MAX - 2;
376 return rc;
377 }
378
379 /*
380 * Fallback if host < v6.0.
381 *
382 * Note! The restore check isn't perfect. Would require checking afterwards
383 * and stash the result if we were restored during the call. Too much
384 * hazzle for a downgrade scenario.
385 */
386 if (pidRestoreCheck)
387 {
388 uint64_t idRestoreCur = *pidRestoreCheck;
389 rc = VbglR3GetSessionId(&idRestoreCur);
390 if (RT_SUCCESS(rc) && idRestoreCur != *pidRestoreCheck)
391 {
392 *pidRestoreCheck = idRestoreCur;
393 return VERR_VM_RESTORED;
394 }
395 }
396
397 rc = vbglR3GuestCtrlMsgWaitFor(idClient, pidMsg, pcParameters);
398 if (rc == VERR_TOO_MUCH_DATA)
399 rc = VINF_SUCCESS;
400 return rc;
401}
402
403
404/**
405 * Asks the host guest control service to set a message filter to this
406 * client so that it only will receive certain messages in the future.
407 * The filter(s) are a bitmask for the context IDs, served from the host.
408 *
409 * @return IPRT status code.
410 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
411 * @param uValue The value to filter messages for.
412 * @param uMaskAdd Filter mask to add.
413 * @param uMaskRemove Filter mask to remove.
414 */
415VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t idClient, uint32_t uValue, uint32_t uMaskAdd, uint32_t uMaskRemove)
416{
417 HGCMMsgFilterSet Msg;
418
419 /* Tell the host we want to set a filter. */
420 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_FILTER_SET, 4);
421 VbglHGCMParmUInt32Set(&Msg.value, uValue);
422 VbglHGCMParmUInt32Set(&Msg.mask_add, uMaskAdd);
423 VbglHGCMParmUInt32Set(&Msg.mask_remove, uMaskRemove);
424 VbglHGCMParmUInt32Set(&Msg.flags, 0 /* Flags, unused */);
425
426 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
427}
428
429
430VBGLR3DECL(int) VbglR3GuestCtrlMsgReply(PVBGLR3GUESTCTRLCMDCTX pCtx,
431 int rc)
432{
433 return VbglR3GuestCtrlMsgReplyEx(pCtx, rc, 0 /* uType */,
434 NULL /* pvPayload */, 0 /* cbPayload */);
435}
436
437
438VBGLR3DECL(int) VbglR3GuestCtrlMsgReplyEx(PVBGLR3GUESTCTRLCMDCTX pCtx,
439 int rc, uint32_t uType,
440 void *pvPayload, uint32_t cbPayload)
441{
442 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
443 /* Everything else is optional. */
444
445 HGCMMsgReply Msg;
446 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_REPLY, 4);
447 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
448 VbglHGCMParmUInt32Set(&Msg.type, uType);
449 VbglHGCMParmUInt32Set(&Msg.rc, (uint32_t)rc); /* int vs. uint32_t */
450 VbglHGCMParmPtrSet(&Msg.payload, pvPayload, cbPayload);
451
452 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
453}
454
455/**
456 * Tell the host to skip the current message replying VERR_NOT_SUPPORTED
457 *
458 * @return IPRT status code.
459 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
460 * @param rcSkip The status code to pass back to Main when skipping.
461 * @param idMsg The message ID to skip, pass UINT32_MAX to pass any.
462 */
463VBGLR3DECL(int) VbglR3GuestCtrlMsgSkip(uint32_t idClient, int rcSkip, uint32_t idMsg)
464{
465 if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient))
466 {
467 struct
468 {
469 VBGLIOCHGCMCALL Hdr;
470 HGCMFunctionParameter rcSkip;
471 HGCMFunctionParameter idMsg;
472 } Msg;
473 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SKIP, 2);
474 VbglHGCMParmUInt32Set(&Msg.rcSkip, (uint32_t)rcSkip);
475 VbglHGCMParmUInt32Set(&Msg.idMsg, idMsg);
476 return VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
477 }
478
479 /* This is generally better than nothing... */
480 return VbglR3GuestCtrlMsgSkipOld(idClient);
481}
482
483
484/**
485 * Tells the host service to skip the current message returned by
486 * VbglR3GuestCtrlMsgWaitFor().
487 *
488 * @return IPRT status code.
489 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
490 */
491VBGLR3DECL(int) VbglR3GuestCtrlMsgSkipOld(uint32_t idClient)
492{
493 HGCMMsgSkip Msg;
494
495 /* Tell the host we want to skip the current assigned message. */
496 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_SKIP_OLD, 1);
497 VbglHGCMParmUInt32Set(&Msg.flags, 0 /* Flags, unused */);
498 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
499}
500
501
502/**
503 * Asks the host to cancel (release) all pending waits which were deferred.
504 *
505 * @returns VBox status code.
506 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
507 */
508VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t idClient)
509{
510 HGCMMsgCancelPendingWaits Msg;
511 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_CANCEL, 0);
512 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
513}
514
515
516/**
517 * Prepares a session.
518 * @since 6.0
519 * @sa GUEST_SESSION_PREPARE
520 */
521VBGLR3DECL(int) VbglR3GuestCtrlSessionPrepare(uint32_t idClient, uint32_t idSession, void const *pvKey, uint32_t cbKey)
522{
523 int rc;
524 do
525 {
526 struct
527 {
528 VBGLIOCHGCMCALL Hdr;
529 HGCMFunctionParameter idSession;
530 HGCMFunctionParameter pKey;
531 } Msg;
532 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_PREPARE, 2);
533 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
534 VbglHGCMParmPtrSet(&Msg.pKey, (void *)pvKey, cbKey);
535 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
536 } while (rc == VERR_INTERRUPTED);
537 return rc;
538}
539
540
541/**
542 * Accepts a session.
543 * @since 6.0
544 * @sa GUEST_SESSION_ACCEPT
545 */
546VBGLR3DECL(int) VbglR3GuestCtrlSessionAccept(uint32_t idClient, uint32_t idSession, void const *pvKey, uint32_t cbKey)
547{
548 int rc;
549 do
550 {
551 struct
552 {
553 VBGLIOCHGCMCALL Hdr;
554 HGCMFunctionParameter idSession;
555 HGCMFunctionParameter pKey;
556 } Msg;
557 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_ACCEPT, 2);
558 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
559 VbglHGCMParmPtrSet(&Msg.pKey, (void *)pvKey, cbKey);
560 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
561 } while (rc == VERR_INTERRUPTED);
562 return rc;
563}
564
565
566/**
567 * Cancels a prepared session.
568 * @since 6.0
569 * @sa GUEST_SESSION_CANCEL_PREPARED
570 */
571VBGLR3DECL(int) VbglR3GuestCtrlSessionCancelPrepared(uint32_t idClient, uint32_t idSession)
572{
573 int rc;
574 do
575 {
576 struct
577 {
578 VBGLIOCHGCMCALL Hdr;
579 HGCMFunctionParameter idSession;
580 } Msg;
581 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_CANCEL_PREPARED, 1);
582 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
583 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
584 } while (rc == VERR_INTERRUPTED);
585 return rc;
586}
587
588
589/**
590 * Asks a specific guest session to close.
591 *
592 * @return IPRT status code.
593 * @param pCtx Host context.
594 * @param fFlags Some kind of flag. Figure it out yourself.
595 ** @todo Docs!
596 */
597VBGLR3DECL(int) VbglR3GuestCtrlSessionClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t fFlags)
598{
599 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
600 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
601
602 HGCMMsgSessionClose Msg;
603 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_CLOSE, pCtx->uNumParms);
604 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
605 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
606
607 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
608}
609
610
611VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uType, int32_t iResult)
612{
613 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
614
615 HGCMMsgSessionNotify Msg;
616 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_NOTIFY, 3);
617 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
618 VbglHGCMParmUInt32Set(&Msg.type, uType);
619 VbglHGCMParmUInt32Set(&Msg.result, (uint32_t)iResult);
620
621 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
622}
623
624
625/**
626 * Retrieves a HOST_SESSION_CREATE message.
627 */
628VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
629 uint32_t *puProtocol,
630 char *pszUser, uint32_t cbUser,
631 char *pszPassword, uint32_t cbPassword,
632 char *pszDomain, uint32_t cbDomain,
633 uint32_t *pfFlags, uint32_t *pidSession)
634{
635 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
636 AssertReturn(pCtx->uNumParms == 6, VERR_INVALID_PARAMETER);
637
638 AssertPtrReturn(puProtocol, VERR_INVALID_POINTER);
639 AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
640 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
641 AssertPtrReturn(pszDomain, VERR_INVALID_POINTER);
642 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
643
644 int rc;
645 do
646 {
647 HGCMMsgSessionOpen Msg;
648 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
649 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CREATE);
650 VbglHGCMParmUInt32Set(&Msg.protocol, 0);
651 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
652 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
653 VbglHGCMParmPtrSet(&Msg.domain, pszDomain, cbDomain);
654 VbglHGCMParmUInt32Set(&Msg.flags, 0);
655
656 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
657 if (RT_SUCCESS(rc))
658 {
659 Msg.context.GetUInt32(&pCtx->uContextID);
660 Msg.protocol.GetUInt32(puProtocol);
661 Msg.flags.GetUInt32(pfFlags);
662
663 if (pidSession)
664 *pidSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
665 }
666
667 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
668 return rc;
669}
670
671
672/**
673 * Retrieves a HOST_SESSION_CLOSE message.
674 */
675VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfFlags, uint32_t *pidSession)
676{
677 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
678 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
679
680 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
681
682 int rc;
683 do
684 {
685 HGCMMsgSessionClose Msg;
686 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
687 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CLOSE);
688 VbglHGCMParmUInt32Set(&Msg.flags, 0);
689
690 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
691 if (RT_SUCCESS(rc))
692 {
693 Msg.context.GetUInt32(&pCtx->uContextID);
694 Msg.flags.GetUInt32(pfFlags);
695
696 if (pidSession)
697 *pidSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
698 }
699 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
700 return rc;
701}
702
703
704/**
705 * Retrieves a HOST_PATH_RENAME message.
706 */
707VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx,
708 char *pszSource, uint32_t cbSource,
709 char *pszDest, uint32_t cbDest,
710 uint32_t *pfFlags)
711{
712 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
713 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
714
715 AssertPtrReturn(pszSource, VERR_INVALID_POINTER);
716 AssertReturn(cbSource, VERR_INVALID_PARAMETER);
717 AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
718 AssertReturn(cbDest, VERR_INVALID_PARAMETER);
719 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
720
721 int rc;
722 do
723 {
724 HGCMMsgPathRename Msg;
725 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
726 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_RENAME);
727 VbglHGCMParmPtrSet(&Msg.source, pszSource, cbSource);
728 VbglHGCMParmPtrSet(&Msg.dest, pszDest, cbDest);
729 VbglHGCMParmUInt32Set(&Msg.flags, 0);
730
731 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
732 if (RT_SUCCESS(rc))
733 {
734 Msg.context.GetUInt32(&pCtx->uContextID);
735 Msg.flags.GetUInt32(pfFlags);
736 }
737
738 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
739 return rc;
740}
741
742
743/**
744 * Retrieves a HOST_PATH_USER_DOCUMENTS message.
745 */
746VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserDocuments(PVBGLR3GUESTCTRLCMDCTX pCtx)
747{
748 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
749 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
750
751 int rc;
752 do
753 {
754 HGCMMsgPathUserDocuments Msg;
755 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
756 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_DOCUMENTS);
757
758 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
759 if (RT_SUCCESS(rc))
760 Msg.context.GetUInt32(&pCtx->uContextID);
761 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
762 return rc;
763}
764
765
766/**
767 * Retrieves a HOST_PATH_USER_HOME message.
768 */
769VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserHome(PVBGLR3GUESTCTRLCMDCTX pCtx)
770{
771 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
772 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
773
774 int rc;
775 do
776 {
777 HGCMMsgPathUserHome Msg;
778 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
779 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_HOME);
780
781 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
782 if (RT_SUCCESS(rc))
783 Msg.context.GetUInt32(&pCtx->uContextID);
784 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
785 return rc;
786}
787
788
789/**
790 * Retrieves a HOST_EXEC_CMD message.
791 *
792 * @todo Move the parameters in an own struct!
793 */
794VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLCMDCTX pCtx,
795 char *pszCmd, uint32_t cbCmd,
796 uint32_t *pfFlags,
797 char *pszArgs, uint32_t cbArgs, uint32_t *pcArgs,
798 char *pszEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars,
799 char *pszUser, uint32_t cbUser,
800 char *pszPassword, uint32_t cbPassword,
801 uint32_t *puTimeoutMS,
802 uint32_t *puPriority,
803 uint64_t *puAffinity, uint32_t cbAffinity, uint32_t *pcAffinity)
804{
805 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
806
807 AssertPtrReturn(pszCmd, VERR_INVALID_POINTER);
808 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
809 AssertPtrReturn(pszArgs, VERR_INVALID_POINTER);
810 AssertPtrReturn(pcArgs, VERR_INVALID_POINTER);
811 AssertPtrReturn(pszEnv, VERR_INVALID_POINTER);
812 AssertPtrReturn(pcbEnv, VERR_INVALID_POINTER);
813 AssertPtrReturn(pcEnvVars, VERR_INVALID_POINTER);
814 AssertPtrReturn(puTimeoutMS, VERR_INVALID_POINTER);
815
816 int rc;
817 do
818 {
819 HGCMMsgProcExec Msg;
820 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
821 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_CMD);
822 VbglHGCMParmPtrSet(&Msg.cmd, pszCmd, cbCmd);
823 VbglHGCMParmUInt32Set(&Msg.flags, 0);
824 VbglHGCMParmUInt32Set(&Msg.num_args, 0);
825 VbglHGCMParmPtrSet(&Msg.args, pszArgs, cbArgs);
826 VbglHGCMParmUInt32Set(&Msg.num_env, 0);
827 VbglHGCMParmUInt32Set(&Msg.cb_env, 0);
828 VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv);
829 if (pCtx->uProtocol < 2)
830 {
831 AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
832 AssertReturn(cbUser, VERR_INVALID_PARAMETER);
833 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
834 AssertReturn(pszPassword, VERR_INVALID_PARAMETER);
835
836 VbglHGCMParmPtrSet(&Msg.u.v1.username, pszUser, cbUser);
837 VbglHGCMParmPtrSet(&Msg.u.v1.password, pszPassword, cbPassword);
838 VbglHGCMParmUInt32Set(&Msg.u.v1.timeout, 0);
839 }
840 else
841 {
842 AssertPtrReturn(puAffinity, VERR_INVALID_POINTER);
843 AssertReturn(cbAffinity, VERR_INVALID_PARAMETER);
844
845 VbglHGCMParmUInt32Set(&Msg.u.v2.timeout, 0);
846 VbglHGCMParmUInt32Set(&Msg.u.v2.priority, 0);
847 VbglHGCMParmUInt32Set(&Msg.u.v2.num_affinity, 0);
848 VbglHGCMParmPtrSet(&Msg.u.v2.affinity, puAffinity, cbAffinity);
849 }
850
851 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
852 if (RT_SUCCESS(rc))
853 {
854 Msg.context.GetUInt32(&pCtx->uContextID);
855 Msg.flags.GetUInt32(pfFlags);
856 Msg.num_args.GetUInt32(pcArgs);
857 Msg.num_env.GetUInt32(pcEnvVars);
858 Msg.cb_env.GetUInt32(pcbEnv);
859 if (pCtx->uProtocol < 2)
860 Msg.u.v1.timeout.GetUInt32(puTimeoutMS);
861 else
862 {
863 Msg.u.v2.timeout.GetUInt32(puTimeoutMS);
864 Msg.u.v2.priority.GetUInt32(puPriority);
865 Msg.u.v2.num_affinity.GetUInt32(pcAffinity);
866 }
867 }
868 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
869 return rc;
870}
871
872
873/**
874 * Allocates and gets host data, based on the message id.
875 *
876 * This will block until data becomes available.
877 *
878 * @returns VBox status code.
879 ** @todo Docs!
880 */
881VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
882 uint32_t *puPID, uint32_t *puHandle, uint32_t *pfFlags)
883{
884 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
885 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
886
887 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
888 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
889 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
890
891 int rc;
892 do
893 {
894 HGCMMsgProcOutput Msg;
895 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
896 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_GET_OUTPUT);
897 VbglHGCMParmUInt32Set(&Msg.pid, 0);
898 VbglHGCMParmUInt32Set(&Msg.handle, 0);
899 VbglHGCMParmUInt32Set(&Msg.flags, 0);
900
901 rc = VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMMsgProcOutput, data));
902 if (RT_SUCCESS(rc))
903 {
904 Msg.context.GetUInt32(&pCtx->uContextID);
905 Msg.pid.GetUInt32(puPID);
906 Msg.handle.GetUInt32(puHandle);
907 Msg.flags.GetUInt32(pfFlags);
908 }
909 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
910 return rc;
911}
912
913
914/**
915 * Retrieves the input data from host which then gets sent to the started
916 * process (HOST_EXEC_SET_INPUT).
917 *
918 * This will block until data becomes available.
919 */
920VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
921 uint32_t *puPID, uint32_t *pfFlags,
922 void *pvData, uint32_t cbData,
923 uint32_t *pcbSize)
924{
925 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
926 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
927
928 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
929 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
930 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
931 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
932
933 int rc;
934 do
935 {
936 HGCMMsgProcInput Msg;
937 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
938 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_SET_INPUT);
939 VbglHGCMParmUInt32Set(&Msg.pid, 0);
940 VbglHGCMParmUInt32Set(&Msg.flags, 0);
941 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
942 VbglHGCMParmUInt32Set(&Msg.size, 0);
943
944 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
945 if (RT_SUCCESS(rc))
946 {
947 Msg.context.GetUInt32(&pCtx->uContextID);
948 Msg.pid.GetUInt32(puPID);
949 Msg.flags.GetUInt32(pfFlags);
950 Msg.size.GetUInt32(pcbSize);
951 }
952 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
953
954 if ( rc != VERR_TOO_MUCH_DATA
955 || g_fVbglR3GuestCtrlHavePeekGetCancel)
956 return rc;
957 return VERR_BUFFER_OVERFLOW;
958}
959
960
961/**
962 * Retrieves a HOST_DIR_REMOVE message.
963 */
964VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx,
965 char *pszPath, uint32_t cbPath,
966 uint32_t *pfFlags)
967{
968 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
969 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
970
971 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
972 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
973 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
974
975 int rc;
976 do
977 {
978 HGCMMsgDirRemove Msg;
979 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
980 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_REMOVE);
981 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
982 VbglHGCMParmUInt32Set(&Msg.flags, 0);
983
984 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
985 if (RT_SUCCESS(rc))
986 {
987 Msg.context.GetUInt32(&pCtx->uContextID);
988 Msg.flags.GetUInt32(pfFlags);
989 }
990 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
991 return rc;
992}
993
994
995/**
996 * Retrieves a HOST_FILE_OPEN message.
997 */
998VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
999 char *pszFileName, uint32_t cbFileName,
1000 char *pszAccess, uint32_t cbAccess,
1001 char *pszDisposition, uint32_t cbDisposition,
1002 char *pszSharing, uint32_t cbSharing,
1003 uint32_t *puCreationMode,
1004 uint64_t *poffAt)
1005{
1006 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1007 AssertReturn(pCtx->uNumParms == 7, VERR_INVALID_PARAMETER);
1008
1009 AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
1010 AssertReturn(cbFileName, VERR_INVALID_PARAMETER);
1011 AssertPtrReturn(pszAccess, VERR_INVALID_POINTER);
1012 AssertReturn(cbAccess, VERR_INVALID_PARAMETER);
1013 AssertPtrReturn(pszDisposition, VERR_INVALID_POINTER);
1014 AssertReturn(cbDisposition, VERR_INVALID_PARAMETER);
1015 AssertPtrReturn(pszSharing, VERR_INVALID_POINTER);
1016 AssertReturn(cbSharing, VERR_INVALID_PARAMETER);
1017 AssertPtrReturn(puCreationMode, VERR_INVALID_POINTER);
1018 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
1019
1020 int rc;
1021 do
1022 {
1023 HGCMMsgFileOpen Msg;
1024 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1025 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_OPEN);
1026 VbglHGCMParmPtrSet(&Msg.filename, pszFileName, cbFileName);
1027 VbglHGCMParmPtrSet(&Msg.openmode, pszAccess, cbAccess);
1028 VbglHGCMParmPtrSet(&Msg.disposition, pszDisposition, cbDisposition);
1029 VbglHGCMParmPtrSet(&Msg.sharing, pszSharing, cbSharing);
1030 VbglHGCMParmUInt32Set(&Msg.creationmode, 0);
1031 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1032
1033 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1034 if (RT_SUCCESS(rc))
1035 {
1036 Msg.context.GetUInt32(&pCtx->uContextID);
1037 Msg.creationmode.GetUInt32(puCreationMode);
1038 Msg.offset.GetUInt64(poffAt);
1039 }
1040 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1041 return rc;
1042}
1043
1044
1045/**
1046 * Retrieves a HOST_FILE_CLOSE message.
1047 */
1048VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1049{
1050 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1051
1052 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1053 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1054
1055 int rc;
1056 do
1057 {
1058 HGCMMsgFileClose Msg;
1059 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1060 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_CLOSE);
1061 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1062
1063 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1064 if (RT_SUCCESS(rc))
1065 {
1066 Msg.context.GetUInt32(&pCtx->uContextID);
1067 Msg.handle.GetUInt32(puHandle);
1068 }
1069 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1070 return rc;
1071}
1072
1073
1074/**
1075 * Retrieves a HOST_FILE_READ message.
1076 */
1077VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead)
1078{
1079 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1080
1081 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1082 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1083 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
1084
1085 int rc;
1086 do
1087 {
1088 HGCMMsgFileRead Msg;
1089 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1090 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ);
1091 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1092 VbglHGCMParmUInt32Set(&Msg.size, 0);
1093
1094 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1095 if (RT_SUCCESS(rc))
1096 {
1097 Msg.context.GetUInt32(&pCtx->uContextID);
1098 Msg.handle.GetUInt32(puHandle);
1099 Msg.size.GetUInt32(puToRead);
1100 }
1101 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1102 return rc;
1103}
1104
1105
1106/**
1107 * Retrieves a HOST_FILE_READ_AT message.
1108 */
1109VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLCMDCTX pCtx,
1110 uint32_t *puHandle, uint32_t *puToRead, uint64_t *poffAt)
1111{
1112 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1113
1114 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1115 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1116 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
1117
1118 int rc;
1119 do
1120 {
1121 HGCMMsgFileReadAt Msg;
1122 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1123 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ_AT);
1124 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1125 VbglHGCMParmUInt32Set(&Msg.offset, 0);
1126 VbglHGCMParmUInt32Set(&Msg.size, 0);
1127
1128 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1129 if (RT_SUCCESS(rc))
1130 {
1131 Msg.context.GetUInt32(&pCtx->uContextID);
1132 Msg.handle.GetUInt32(puHandle);
1133 Msg.offset.GetUInt64(poffAt);
1134 Msg.size.GetUInt32(puToRead);
1135 }
1136 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1137 return rc;
1138}
1139
1140
1141/**
1142 * Retrieves a HOST_FILE_WRITE message.
1143 */
1144VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
1145 void *pvData, uint32_t cbData, uint32_t *pcbSize)
1146{
1147 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1148
1149 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1150 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1151 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1152 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1153 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1154
1155 int rc;
1156 do
1157 {
1158 HGCMMsgFileWrite Msg;
1159 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1160 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE);
1161 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1162 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1163 VbglHGCMParmUInt32Set(&Msg.size, 0);
1164
1165 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1166 if (RT_SUCCESS(rc))
1167 {
1168 Msg.context.GetUInt32(&pCtx->uContextID);
1169 Msg.handle.GetUInt32(puHandle);
1170 Msg.size.GetUInt32(pcbSize);
1171 }
1172 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1173
1174 if ( rc != VERR_TOO_MUCH_DATA
1175 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1176 return rc;
1177 return VERR_BUFFER_OVERFLOW;
1178}
1179
1180
1181/**
1182 * Retrieves a HOST_FILE_WRITE_AT message.
1183 */
1184VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
1185 void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *poffAt)
1186{
1187 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1188
1189 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1190 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1191 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1192 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1193 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1194
1195 int rc;
1196 do
1197 {
1198 HGCMMsgFileWriteAt Msg;
1199 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1200 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE_AT);
1201 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1202 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1203 VbglHGCMParmUInt32Set(&Msg.size, 0);
1204 VbglHGCMParmUInt32Set(&Msg.offset, 0);
1205
1206 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1207 if (RT_SUCCESS(rc))
1208 {
1209 Msg.context.GetUInt32(&pCtx->uContextID);
1210 Msg.handle.GetUInt32(puHandle);
1211 Msg.size.GetUInt32(pcbSize);
1212 Msg.offset.GetUInt64(poffAt);
1213 }
1214 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1215
1216 if ( rc != VERR_TOO_MUCH_DATA
1217 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1218 return rc;
1219 return VERR_BUFFER_OVERFLOW;
1220}
1221
1222
1223/**
1224 * Retrieves a HOST_FILE_SEEK message.
1225 */
1226VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLCMDCTX pCtx,
1227 uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *poffAt)
1228{
1229 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1230
1231 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1232 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1233 AssertPtrReturn(puSeekMethod, VERR_INVALID_POINTER);
1234 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
1235
1236 int rc;
1237 do
1238 {
1239 HGCMMsgFileSeek Msg;
1240 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1241 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_SEEK);
1242 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1243 VbglHGCMParmUInt32Set(&Msg.method, 0);
1244 VbglHGCMParmUInt64Set(&Msg.offset, 0);
1245
1246 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1247 if (RT_SUCCESS(rc))
1248 {
1249 Msg.context.GetUInt32(&pCtx->uContextID);
1250 Msg.handle.GetUInt32(puHandle);
1251 Msg.method.GetUInt32(puSeekMethod);
1252 Msg.offset.GetUInt64(poffAt);
1253 }
1254 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1255 return rc;
1256}
1257
1258
1259/**
1260 * Retrieves a HOST_FILE_TELL message.
1261 */
1262VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1263{
1264 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1265
1266 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1267 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1268
1269 int rc;
1270 do
1271 {
1272 HGCMMsgFileTell Msg;
1273 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1274 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_TELL);
1275 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1276
1277 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1278 if (RT_SUCCESS(rc))
1279 {
1280 Msg.context.GetUInt32(&pCtx->uContextID);
1281 Msg.handle.GetUInt32(puHandle);
1282 }
1283 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1284 return rc;
1285}
1286
1287
1288/**
1289 * Retrieves a HOST_EXEC_TERMINATE message.
1290 */
1291VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID)
1292{
1293 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1294
1295 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1296 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1297
1298 int rc;
1299 do
1300 {
1301 HGCMMsgProcTerminate Msg;
1302 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1303 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_TERMINATE);
1304 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1305
1306 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1307 if (RT_SUCCESS(rc))
1308 {
1309 Msg.context.GetUInt32(&pCtx->uContextID);
1310 Msg.pid.GetUInt32(puPID);
1311 }
1312 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1313 return rc;
1314}
1315
1316
1317/**
1318 * Retrieves a HOST_EXEC_WAIT_FOR message.
1319 */
1320VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLCMDCTX pCtx,
1321 uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS)
1322{
1323 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1324
1325 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1326 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1327
1328 int rc;
1329 do
1330 {
1331 HGCMMsgProcWaitFor Msg;
1332 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1333 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_WAIT_FOR);
1334 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1335 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1336 VbglHGCMParmUInt32Set(&Msg.timeout, 0);
1337
1338 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1339 if (RT_SUCCESS(rc))
1340 {
1341 Msg.context.GetUInt32(&pCtx->uContextID);
1342 Msg.pid.GetUInt32(puPID);
1343 Msg.flags.GetUInt32(puWaitFlags);
1344 Msg.timeout.GetUInt32(puTimeoutMS);
1345 }
1346 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1347 return rc;
1348}
1349
1350
1351VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
1352 uint32_t uRc, uint32_t uFileHandle)
1353{
1354 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1355
1356 HGCMReplyFileNotify Msg;
1357 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1358 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1359 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_OPEN);
1360 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1361 VbglHGCMParmUInt32Set(&Msg.u.open.handle, uFileHandle);
1362
1363 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.open));
1364}
1365
1366
1367VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx,
1368 uint32_t uRc)
1369{
1370 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1371
1372 HGCMReplyFileNotify Msg;
1373 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
1374 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1375 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_CLOSE);
1376 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1377
1378 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
1379}
1380
1381
1382VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
1383{
1384 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1385
1386 HGCMReplyFileNotify Msg;
1387 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
1388 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1389 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_ERROR);
1390 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1391
1392 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
1393}
1394
1395
1396VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx,
1397 uint32_t uRc,
1398 void *pvData, uint32_t cbData)
1399{
1400 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1401
1402 HGCMReplyFileNotify Msg;
1403 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1404 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1405 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_READ);
1406 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1407 VbglHGCMParmPtrSet(&Msg.u.read.data, pvData, cbData);
1408
1409 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.read));
1410}
1411
1412
1413VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx,
1414 uint32_t uRc, uint32_t uWritten)
1415{
1416 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1417
1418 HGCMReplyFileNotify Msg;
1419 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1420 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1421 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_WRITE);
1422 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1423 VbglHGCMParmUInt32Set(&Msg.u.write.written, uWritten);
1424
1425 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.write));
1426}
1427
1428
1429VBGLR3DECL(int) VbglR3GuestCtrlFileCbSeek(PVBGLR3GUESTCTRLCMDCTX pCtx,
1430 uint32_t uRc, uint64_t uOffActual)
1431{
1432 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1433
1434 HGCMReplyFileNotify Msg;
1435 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1436 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1437 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_SEEK);
1438 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1439 VbglHGCMParmUInt64Set(&Msg.u.seek.offset, uOffActual);
1440
1441 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.seek));
1442}
1443
1444
1445VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx,
1446 uint32_t uRc, uint64_t uOffActual)
1447{
1448 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1449
1450 HGCMReplyFileNotify Msg;
1451 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
1452 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1453 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_TELL);
1454 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
1455 VbglHGCMParmUInt64Set(&Msg.u.tell.offset, uOffActual);
1456
1457 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.tell));
1458}
1459
1460
1461/**
1462 * Callback for reporting a guest process status (along with some other stuff) to the host.
1463 *
1464 * @returns VBox status code.
1465 ** @todo Docs!
1466 */
1467VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx,
1468 uint32_t uPID, uint32_t uStatus, uint32_t fFlags,
1469 void *pvData, uint32_t cbData)
1470{
1471 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1472
1473 HGCMMsgProcStatus Msg;
1474 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_STATUS, 5);
1475 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1476 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1477 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
1478 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1479 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1480
1481 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1482}
1483
1484
1485/**
1486 * Sends output (from stdout/stderr) from a running process.
1487 *
1488 * @returns VBox status code.
1489 ** @todo Docs!
1490 */
1491VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1492 uint32_t uPID,uint32_t uHandle, uint32_t fFlags,
1493 void *pvData, uint32_t cbData)
1494{
1495 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1496
1497 HGCMMsgProcOutput Msg;
1498 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_OUTPUT, 5);
1499 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1500 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1501 VbglHGCMParmUInt32Set(&Msg.handle, uHandle);
1502 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1503 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1504
1505 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1506}
1507
1508
1509/**
1510 * Callback for reporting back the input status of a guest process to the host.
1511 *
1512 * @returns VBox status code.
1513 ** @todo Docs!
1514 */
1515VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1516 uint32_t uPID, uint32_t uStatus,
1517 uint32_t fFlags, uint32_t cbWritten)
1518{
1519 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1520
1521 HGCMMsgProcStatusInput Msg;
1522 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_INPUT_STATUS, 5);
1523 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
1524 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
1525 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
1526 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
1527 VbglHGCMParmUInt32Set(&Msg.written, cbWritten);
1528
1529 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1530}
1531
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