VirtualBox

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

Last change on this file was 103415, checked in by vboxsync, 3 months ago

Additions,Main,VMM,Runtime: Fix some unused expression warnings, bugref:3409

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 111.8 KB
Line 
1/* $Id: VBoxGuestR3LibGuestCtrl.cpp 103415 2024-02-19 07:52:27Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest control.
4 */
5
6/*
7 * Copyright (C) 2010-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/string.h>
42#include <iprt/mem.h>
43#include <iprt/assert.h>
44#include <iprt/cpp/autores.h>
45#include <iprt/stdarg.h>
46#include <VBox/err.h>
47#include <VBox/log.h>
48#include <VBox/GuestHost/GuestControl.h>
49#include <VBox/HostServices/GuestControlSvc.h>
50
51#ifndef RT_OS_WINDOWS
52# include <signal.h>
53# ifdef RT_OS_DARWIN
54# include <pthread.h>
55# define sigprocmask pthread_sigmask /* On xnu sigprocmask works on the process, not the calling thread as elsewhere. */
56# endif
57#endif
58
59#include "VBoxGuestR3LibInternal.h"
60
61using namespace guestControl;
62
63
64/*********************************************************************************************************************************
65* Global Variables *
66*********************************************************************************************************************************/
67/** Set if GUEST_MSG_PEEK_WAIT and friends are supported. */
68static int g_fVbglR3GuestCtrlHavePeekGetCancel = -1;
69/** Represents the currently cached host features 0.
70 * Set to 0 if not available / not cached yet. */
71static uint64_t g_fVbglR3GuestCtrlHostFeatures0 = 0;
72
73
74/*********************************************************************************************************************************
75* Prototypes *
76*********************************************************************************************************************************/
77static int vbglR3GuestCtrlQueryFeatures(uint32_t idClient, uint64_t *pfHostFeatures0, uint64_t *pfHostFeatures1);
78
79
80/**
81 * Invalidates the internal state of the Guest Control API.
82 *
83 * @returns VBox status code.
84 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
85 */
86static int vbglR3GuestCtrlInvalidate(uint32_t idClient)
87{
88 uint64_t fVbglR3GuestCtrlHostFeatures0 = 0;
89 int const rc2 = vbglR3GuestCtrlQueryFeatures(idClient,
90 &fVbglR3GuestCtrlHostFeatures0, NULL /* pfHostFeatures1, unused */);
91 if (RT_SUCCESS(rc2))
92 {
93 /* Check if the host's feature set has changed. This might happen on a VM restore. */
94 if ( g_fVbglR3GuestCtrlHostFeatures0
95 && g_fVbglR3GuestCtrlHostFeatures0 != fVbglR3GuestCtrlHostFeatures0)
96 LogRelFunc(("Host feature set has changed (%#x -> %#x)\n",
97 g_fVbglR3GuestCtrlHostFeatures0, fVbglR3GuestCtrlHostFeatures0));
98
99 g_fVbglR3GuestCtrlHostFeatures0 = fVbglR3GuestCtrlHostFeatures0;
100 }
101 else
102 LogRelFunc(("Querying host features not supported, rc=%Rrc\n", rc2));
103 /* Note: Very old hosts don't know about querying host features, so this isn't fatal for the caller. */
104
105 return VINF_SUCCESS;
106}
107
108
109/**
110 * Connects to the guest control service.
111 *
112 * @returns VBox status code
113 * @param pidClient Where to put The client ID on success. The client ID
114 * must be passed to all the other calls to the service.
115 */
116VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pidClient)
117{
118 AssertPtrReturn(pidClient, VERR_INVALID_POINTER);
119
120 int rc = VbglR3HGCMConnect("VBoxGuestControlSvc", pidClient);
121 if (RT_SUCCESS(rc))
122 rc = vbglR3GuestCtrlInvalidate(*pidClient);
123
124 return rc;
125}
126
127
128/**
129 * Disconnect from the guest control service.
130 *
131 * @returns VBox status code.
132 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
133 */
134VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t idClient)
135{
136 return VbglR3HGCMDisconnect(idClient);
137}
138
139
140/**
141 * Waits until a new host message arrives.
142 * This will block until a message becomes available.
143 *
144 * @returns VBox status code.
145 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
146 * @param pidMsg Where to store the message id.
147 * @param pcParameters Where to store the number of parameters which will
148 * be received in a second call to the host.
149 */
150static int vbglR3GuestCtrlMsgWaitFor(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters)
151{
152 AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
153 AssertPtrReturn(pcParameters, VERR_INVALID_POINTER);
154
155 HGCMMsgWaitFor Msg;
156 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
157 GUEST_MSG_WAIT, /* Tell the host we want our next message. */
158 2); /* Just peek for the next message! */
159 VbglHGCMParmUInt32Set(&Msg.msg, 0);
160 VbglHGCMParmUInt32Set(&Msg.num_parms, 0);
161
162 /*
163 * We should always get a VERR_TOO_MUCH_DATA response here, see
164 * guestControl::HostMessage::Peek() and its caller ClientState::SendReply().
165 * We accept success too here, in case someone decide to make the protocol
166 * slightly more sane.
167 *
168 * Note! A really sane protocol design would have a separate call for getting
169 * info about a pending message (returning VINF_SUCCESS), and a separate
170 * one for retriving the actual message parameters. Not this weird
171 * stuff, to put it rather bluntly.
172 *
173 * Note! As a result of this weird design, we are not able to correctly
174 * retrieve message if we're interrupted by a signal, like SIGCHLD.
175 * Because IPRT wants to use waitpid(), we're forced to have a handler
176 * installed for SIGCHLD, so when working with child processes there
177 * will be signals in the air and we will get VERR_INTERRUPTED returns.
178 * The way HGCM handles interrupted calls is to silently (?) drop them
179 * as they complete (see VMMDev), so the server knows little about it
180 * and just goes on to the next message inline.
181 *
182 * So, as a "temporary" mesasure, we block SIGCHLD here while waiting,
183 * because it will otherwise be impossible do simple stuff like 'mkdir'
184 * on a mac os x guest, and probably most other unix guests.
185 */
186#ifdef RT_OS_WINDOWS
187 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
188#else
189 sigset_t SigSet;
190 sigemptyset(&SigSet);
191 sigaddset(&SigSet, SIGCHLD);
192 sigprocmask(SIG_BLOCK, &SigSet, NULL);
193 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
194 sigprocmask(SIG_UNBLOCK, &SigSet, NULL);
195#endif
196 if ( rc == VERR_TOO_MUCH_DATA
197 || RT_SUCCESS(rc))
198 {
199 int rc2 = VbglHGCMParmUInt32Get(&Msg.msg, pidMsg);
200 if (RT_SUCCESS(rc2))
201 {
202 rc2 = VbglHGCMParmUInt32Get(&Msg.num_parms, pcParameters);
203 if (RT_SUCCESS(rc2))
204 {
205 /* Ok, so now we know what message type and how much parameters there are. */
206 return rc;
207 }
208 }
209 rc = rc2;
210 }
211 *pidMsg = UINT32_MAX - 1;
212 *pcParameters = UINT32_MAX - 2;
213 return rc;
214}
215
216
217/**
218 * Determins the value of g_fVbglR3GuestCtrlHavePeekGetCancel.
219 *
220 * @returns true if supported, false if not.
221 * @param idClient The client ID to use for the testing.
222 */
223DECL_NO_INLINE(static, bool) vbglR3GuestCtrlDetectPeekGetCancelSupport(uint32_t idClient)
224{
225 /*
226 * Seems we get VINF_SUCCESS back from the host if we try unsupported
227 * guest control messages, so we need to supply some random message
228 * parameters and check that they change.
229 */
230 uint32_t const idDummyMsg = UINT32_C(0x8350bdca);
231 uint32_t const cDummyParmeters = UINT32_C(0x7439604f);
232 uint32_t const cbDummyMask = UINT32_C(0xc0ffe000);
233 Assert(cDummyParmeters > VMMDEV_MAX_HGCM_PARMS);
234
235 int rc;
236 struct
237 {
238 VBGLIOCHGCMCALL Hdr;
239 HGCMFunctionParameter idMsg;
240 HGCMFunctionParameter cParams;
241 HGCMFunctionParameter acbParams[14];
242 } PeekCall;
243 Assert(RT_ELEMENTS(PeekCall.acbParams) + 2 < VMMDEV_MAX_HGCM_PARMS);
244
245 do
246 {
247 memset(&PeekCall, 0xf6, sizeof(PeekCall));
248 VBGL_HGCM_HDR_INIT(&PeekCall.Hdr, idClient, GUEST_MSG_PEEK_NOWAIT, 16);
249 VbglHGCMParmUInt32Set(&PeekCall.idMsg, idDummyMsg);
250 VbglHGCMParmUInt32Set(&PeekCall.cParams, cDummyParmeters);
251 for (uint32_t i = 0; i < RT_ELEMENTS(PeekCall.acbParams); i++)
252 VbglHGCMParmUInt32Set(&PeekCall.acbParams[i], i | cbDummyMask);
253
254 rc = VbglR3HGCMCall(&PeekCall.Hdr, sizeof(PeekCall));
255 } while (rc == VERR_INTERRUPTED);
256
257 LogRel2(("vbglR3GuestCtrlDetectPeekGetCancelSupport: rc=%Rrc %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x %#x\n",
258 rc, PeekCall.idMsg.u.value32, PeekCall.cParams.u.value32,
259 PeekCall.acbParams[ 0].u.value32, PeekCall.acbParams[ 1].u.value32,
260 PeekCall.acbParams[ 2].u.value32, PeekCall.acbParams[ 3].u.value32,
261 PeekCall.acbParams[ 4].u.value32, PeekCall.acbParams[ 5].u.value32,
262 PeekCall.acbParams[ 6].u.value32, PeekCall.acbParams[ 7].u.value32,
263 PeekCall.acbParams[ 8].u.value32, PeekCall.acbParams[ 9].u.value32,
264 PeekCall.acbParams[10].u.value32, PeekCall.acbParams[11].u.value32,
265 PeekCall.acbParams[12].u.value32, PeekCall.acbParams[13].u.value32));
266
267 /*
268 * VERR_TRY_AGAIN is likely and easy.
269 */
270 if ( rc == VERR_TRY_AGAIN
271 && PeekCall.idMsg.u.value32 == 0
272 && PeekCall.cParams.u.value32 == 0
273 && PeekCall.acbParams[0].u.value32 == 0
274 && PeekCall.acbParams[1].u.value32 == 0
275 && PeekCall.acbParams[2].u.value32 == 0
276 && PeekCall.acbParams[3].u.value32 == 0)
277 {
278 g_fVbglR3GuestCtrlHavePeekGetCancel = 1;
279 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Supported (#1)\n"));
280 return true;
281 }
282
283 /*
284 * VINF_SUCCESS is annoying but with 16 parameters we've got plenty to check.
285 */
286 if ( rc == VINF_SUCCESS
287 && PeekCall.idMsg.u.value32 != idDummyMsg
288 && PeekCall.idMsg.u.value32 != 0
289 && PeekCall.cParams.u.value32 <= VMMDEV_MAX_HGCM_PARMS)
290 {
291 for (uint32_t i = 0; i < RT_ELEMENTS(PeekCall.acbParams); i++)
292 if (PeekCall.acbParams[i].u.value32 != (i | cbDummyMask))
293 {
294 g_fVbglR3GuestCtrlHavePeekGetCancel = 0;
295 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Not supported (#1)\n"));
296 return false;
297 }
298 g_fVbglR3GuestCtrlHavePeekGetCancel = 1;
299 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Supported (#2)\n"));
300 return true;
301 }
302
303 /*
304 * Okay, pretty sure it's not supported then.
305 */
306 LogRel(("vbglR3GuestCtrlDetectPeekGetCancelSupport: Not supported (#3)\n"));
307 g_fVbglR3GuestCtrlHavePeekGetCancel = 0;
308 return false;
309}
310
311
312/**
313 * Reads g_fVbglR3GuestCtrlHavePeekGetCancel and resolved -1.
314 *
315 * @returns true if supported, false if not.
316 * @param idClient The client ID to use for the testing.
317 */
318DECLINLINE(bool) vbglR3GuestCtrlSupportsPeekGetCancel(uint32_t idClient)
319{
320 int fState = g_fVbglR3GuestCtrlHavePeekGetCancel;
321 if (RT_LIKELY(fState != -1))
322 return fState != 0;
323 return vbglR3GuestCtrlDetectPeekGetCancelSupport(idClient);
324}
325
326
327/**
328 * Figures which getter function to use to retrieve the message.
329 */
330DECLINLINE(uint32_t) vbglR3GuestCtrlGetMsgFunctionNo(uint32_t idClient)
331{
332 return vbglR3GuestCtrlSupportsPeekGetCancel(idClient) ? GUEST_MSG_GET : GUEST_MSG_WAIT;
333}
334
335
336/**
337 * Checks if the host supports the optimizes message and session functions.
338 *
339 * @returns true / false.
340 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
341 * We may need to use this for checking.
342 * @since 6.0
343 */
344VBGLR3DECL(bool) VbglR3GuestCtrlSupportsOptimizations(uint32_t idClient)
345{
346 return vbglR3GuestCtrlSupportsPeekGetCancel(idClient);
347}
348
349
350/**
351 * Make us the guest control master client.
352 *
353 * @returns VBox status code.
354 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
355 */
356VBGLR3DECL(int) VbglR3GuestCtrlMakeMeMaster(uint32_t idClient)
357{
358 int rc;
359 do
360 {
361 VBGLIOCHGCMCALL Hdr;
362 VBGL_HGCM_HDR_INIT(&Hdr, idClient, GUEST_MSG_MAKE_ME_MASTER, 0);
363 rc = VbglR3HGCMCall(&Hdr, sizeof(Hdr));
364 } while (rc == VERR_INTERRUPTED);
365 return rc;
366}
367
368
369/**
370 * Reports features to the host and retrieve host features set.
371 *
372 * @returns VBox status code.
373 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
374 * @param fGuestFeatures Features to report, VBOX_GUESTCTRL_GF_XXX.
375 * @param pfHostFeatures Where to store the features VBOX_GUESTCTRL_HF_XXX.
376 */
377VBGLR3DECL(int) VbglR3GuestCtrlReportFeatures(uint32_t idClient, uint64_t fGuestFeatures, uint64_t *pfHostFeatures)
378{
379 int rc;
380 do
381 {
382 struct
383 {
384 VBGLIOCHGCMCALL Hdr;
385 HGCMFunctionParameter f64Features0;
386 HGCMFunctionParameter f64Features1;
387 } Msg;
388 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_REPORT_FEATURES, 2);
389 VbglHGCMParmUInt64Set(&Msg.f64Features0, fGuestFeatures);
390 VbglHGCMParmUInt64Set(&Msg.f64Features1, VBOX_GUESTCTRL_GF_1_MUST_BE_ONE);
391
392 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
393 if (RT_SUCCESS(rc))
394 {
395 Assert(Msg.f64Features0.type == VMMDevHGCMParmType_64bit);
396 Assert(Msg.f64Features1.type == VMMDevHGCMParmType_64bit);
397 if (Msg.f64Features1.u.value64 & VBOX_GUESTCTRL_GF_1_MUST_BE_ONE)
398 rc = VERR_NOT_SUPPORTED;
399 else if (pfHostFeatures)
400 *pfHostFeatures = Msg.f64Features0.u.value64;
401 break;
402 }
403 } while (rc == VERR_INTERRUPTED);
404 return rc;
405
406}
407
408
409/**
410 * Queries the host features, internal version.
411 *
412 * @returns VBox status code.
413 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
414 * @param pfHostFeatures0 Where to store the host features, VBOX_GUESTCTRL_HF_0_XXX.
415 * Optional and can be NULL.
416 * @param pfHostFeatures1 Where to store the host features, VBOX_GUESTCTRL_HF_1_XXX.
417 * Currently unused. Optional and can be NULL.
418 */
419static int vbglR3GuestCtrlQueryFeatures(uint32_t idClient, uint64_t *pfHostFeatures0, uint64_t *pfHostFeatures1)
420{
421 int rc;
422 do
423 {
424 struct
425 {
426 VBGLIOCHGCMCALL Hdr;
427 HGCMFunctionParameter f64Features0;
428 HGCMFunctionParameter f64Features1;
429 } Msg;
430 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_QUERY_FEATURES, 2);
431 VbglHGCMParmUInt64Set(&Msg.f64Features0, 0);
432 VbglHGCMParmUInt64Set(&Msg.f64Features1, RT_BIT_64(63));
433
434 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
435 if (RT_SUCCESS(rc))
436 {
437 Assert(Msg.f64Features0.type == VMMDevHGCMParmType_64bit);
438 Assert(Msg.f64Features1.type == VMMDevHGCMParmType_64bit);
439 if (Msg.f64Features1.u.value64 & RT_BIT_64(63))
440 rc = VERR_NOT_SUPPORTED;
441 else
442 {
443 if (pfHostFeatures0)
444 *pfHostFeatures0 = Msg.f64Features0.u.value64;
445 if (pfHostFeatures1)
446 *pfHostFeatures1 = Msg.f64Features1.u.value64;
447 }
448 break;
449 }
450 } while (rc == VERR_INTERRUPTED);
451 return rc;
452}
453
454
455/**
456 * Queries the host features.
457 *
458 * @returns VBox status code.
459 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
460 * @param pfHostFeatures Where to store the host features, VBOX_GUESTCTRL_HF_0_XXX. Optional and can be NULL.
461 */
462VBGLR3DECL(int) VbglR3GuestCtrlQueryFeatures(uint32_t idClient, uint64_t *pfHostFeatures)
463{
464 return vbglR3GuestCtrlQueryFeatures(idClient, pfHostFeatures, NULL /* pfHostFeatures1, unused */);
465}
466
467
468/**
469 * Peeks at the next host message, waiting for one to turn up.
470 *
471 * @returns VBox status code.
472 * @retval VERR_INTERRUPTED if interrupted. Does the necessary cleanup, so
473 * caller just have to repeat this call.
474 * @retval VERR_VM_RESTORED if the VM has been restored (idRestoreCheck).
475 *
476 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
477 * @param pidMsg Where to store the message id.
478 * @param pcParameters Where to store the number of parameters which will
479 * be received in a second call to the host.
480 * @param pidRestoreCheck Pointer to the VbglR3GetSessionId() variable to use
481 * for the VM restore check. Optional.
482 *
483 * @note Restore check is only performed optimally with a 6.0 host.
484 */
485VBGLR3DECL(int) VbglR3GuestCtrlMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck)
486{
487 AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
488 AssertPtrReturn(pcParameters, VERR_INVALID_POINTER);
489
490 int rc;
491 if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient))
492 {
493 struct
494 {
495 VBGLIOCHGCMCALL Hdr;
496 HGCMFunctionParameter idMsg; /* Doubles as restore check on input. */
497 HGCMFunctionParameter cParameters;
498 } Msg;
499 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_PEEK_WAIT, 2);
500 VbglHGCMParmUInt64Set(&Msg.idMsg, pidRestoreCheck ? *pidRestoreCheck : 0);
501 VbglHGCMParmUInt32Set(&Msg.cParameters, 0);
502 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
503 LogRel2(("VbglR3GuestCtrlMsgPeekWait -> %Rrc\n", rc));
504 if (RT_SUCCESS(rc))
505 {
506 AssertMsgReturn( Msg.idMsg.type == VMMDevHGCMParmType_64bit
507 && Msg.cParameters.type == VMMDevHGCMParmType_32bit,
508 ("msg.type=%d num_parms.type=%d\n", Msg.idMsg.type, Msg.cParameters.type),
509 VERR_INTERNAL_ERROR_3);
510
511 *pidMsg = (uint32_t)Msg.idMsg.u.value64;
512 *pcParameters = Msg.cParameters.u.value32;
513 return rc;
514 }
515
516 /*
517 * If interrupted we must cancel the call so it doesn't prevent us from making another one.
518 */
519 if (rc == VERR_INTERRUPTED)
520 {
521 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_CANCEL, 0);
522 int rc2 = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg.Hdr));
523 AssertRC(rc2);
524 }
525
526 /*
527 * If restored, update pidRestoreCheck.
528 */
529 if (rc == VERR_VM_RESTORED && pidRestoreCheck)
530 *pidRestoreCheck = Msg.idMsg.u.value64;
531
532 *pidMsg = UINT32_MAX - 1;
533 *pcParameters = UINT32_MAX - 2;
534 return rc;
535 }
536
537 /*
538 * Fallback if host < v6.0.
539 *
540 * Note! The restore check isn't perfect. Would require checking afterwards
541 * and stash the result if we were restored during the call. Too much
542 * hazzle for a downgrade scenario.
543 */
544 if (pidRestoreCheck)
545 {
546 uint64_t idRestoreCur = *pidRestoreCheck;
547 rc = VbglR3GetSessionId(&idRestoreCur);
548 if (RT_SUCCESS(rc) && idRestoreCur != *pidRestoreCheck)
549 {
550 *pidRestoreCheck = idRestoreCur;
551 return VERR_VM_RESTORED;
552 }
553 }
554
555 rc = vbglR3GuestCtrlMsgWaitFor(idClient, pidMsg, pcParameters);
556 if (rc == VERR_TOO_MUCH_DATA)
557 rc = VINF_SUCCESS;
558 return rc;
559}
560
561
562/**
563 * Asks the host guest control service to set a message filter to this
564 * client so that it only will receive certain messages in the future.
565 * The filter(s) are a bitmask for the context IDs, served from the host.
566 *
567 * @return IPRT status code.
568 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
569 * @param uValue The value to filter messages for.
570 * @param uMaskAdd Filter mask to add.
571 * @param uMaskRemove Filter mask to remove.
572 */
573VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t idClient, uint32_t uValue, uint32_t uMaskAdd, uint32_t uMaskRemove)
574{
575 HGCMMsgFilterSet Msg;
576
577 /* Tell the host we want to set a filter. */
578 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_FILTER_SET, 4);
579 VbglHGCMParmUInt32Set(&Msg.value, uValue);
580 VbglHGCMParmUInt32Set(&Msg.mask_add, uMaskAdd);
581 VbglHGCMParmUInt32Set(&Msg.mask_remove, uMaskRemove);
582 VbglHGCMParmUInt32Set(&Msg.flags, 0 /* Flags, unused */);
583
584 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
585}
586
587
588/**
589 * Replies to a message from the host.
590 *
591 * @returns VBox status code.
592 * @param pCtx Guest control command context to use.
593 * @param rc Guest rc to reply.
594 */
595VBGLR3DECL(int) VbglR3GuestCtrlMsgReply(PVBGLR3GUESTCTRLCMDCTX pCtx,
596 int rc)
597{
598 return VbglR3GuestCtrlMsgReplyEx(pCtx, rc, 0 /* uType */,
599 NULL /* pvPayload */, 0 /* cbPayload */);
600}
601
602
603/**
604 * Replies to a message from the host, extended version.
605 *
606 * @returns VBox status code.
607 * @param pCtx Guest control command context to use.
608 * @param rc Guest rc to reply.
609 * @param uType Reply type; not used yet and must be 0.
610 * @param pvPayload Pointer to data payload to reply. Optional.
611 * @param cbPayload Size of data payload (in bytes) to reply.
612 */
613VBGLR3DECL(int) VbglR3GuestCtrlMsgReplyEx(PVBGLR3GUESTCTRLCMDCTX pCtx,
614 int rc, uint32_t uType,
615 void *pvPayload, uint32_t cbPayload)
616{
617 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
618 /* Everything else is optional. */
619
620 HGCMMsgReply Msg;
621 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_REPLY, 4);
622 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
623 VbglHGCMParmUInt32Set(&Msg.type, uType);
624 VbglHGCMParmUInt32Set(&Msg.rc, (uint32_t)rc); /* int vs. uint32_t */
625 VbglHGCMParmPtrSet(&Msg.payload, pvPayload, cbPayload);
626
627 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
628}
629
630/**
631 * Tell the host to skip the current message replying VERR_NOT_SUPPORTED
632 *
633 * @return IPRT status code.
634 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
635 * @param rcSkip The status code to pass back to Main when skipping.
636 * @param idMsg The message ID to skip, pass UINT32_MAX to pass any.
637 */
638VBGLR3DECL(int) VbglR3GuestCtrlMsgSkip(uint32_t idClient, int rcSkip, uint32_t idMsg)
639{
640 if (vbglR3GuestCtrlSupportsPeekGetCancel(idClient))
641 {
642 struct
643 {
644 VBGLIOCHGCMCALL Hdr;
645 HGCMFunctionParameter rcSkip;
646 HGCMFunctionParameter idMsg;
647 } Msg;
648 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SKIP, 2);
649 VbglHGCMParmUInt32Set(&Msg.rcSkip, (uint32_t)rcSkip);
650 VbglHGCMParmUInt32Set(&Msg.idMsg, idMsg);
651 return VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
652 }
653
654 /* This is generally better than nothing... */
655 return VbglR3GuestCtrlMsgSkipOld(idClient);
656}
657
658
659/**
660 * Tells the host service to skip the current message returned by
661 * VbglR3GuestCtrlMsgWaitFor().
662 *
663 * @return IPRT status code.
664 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
665 */
666VBGLR3DECL(int) VbglR3GuestCtrlMsgSkipOld(uint32_t idClient)
667{
668 HGCMMsgSkip Msg;
669
670 /* Tell the host we want to skip the current assigned message. */
671 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_SKIP_OLD, 1);
672 VbglHGCMParmUInt32Set(&Msg.flags, 0 /* Flags, unused */);
673 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
674}
675
676
677/**
678 * Asks the host to cancel (release) all pending waits which were deferred.
679 *
680 * @returns VBox status code.
681 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
682 */
683VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t idClient)
684{
685 HGCMMsgCancelPendingWaits Msg;
686 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, GUEST_MSG_CANCEL, 0);
687 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
688}
689
690
691/**
692 * Prepares a session.
693 * @since 6.0
694 * @sa GUEST_SESSION_PREPARE
695 */
696VBGLR3DECL(int) VbglR3GuestCtrlSessionPrepare(uint32_t idClient, uint32_t idSession, void const *pvKey, uint32_t cbKey)
697{
698 int rc;
699 do
700 {
701 struct
702 {
703 VBGLIOCHGCMCALL Hdr;
704 HGCMFunctionParameter idSession;
705 HGCMFunctionParameter pKey;
706 } Msg;
707 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_PREPARE, 2);
708 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
709 VbglHGCMParmPtrSet(&Msg.pKey, (void *)pvKey, cbKey);
710 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
711 } while (rc == VERR_INTERRUPTED);
712 return rc;
713}
714
715
716/**
717 * Accepts a session.
718 * @since 6.0
719 * @sa GUEST_SESSION_ACCEPT
720 */
721VBGLR3DECL(int) VbglR3GuestCtrlSessionAccept(uint32_t idClient, uint32_t idSession, void const *pvKey, uint32_t cbKey)
722{
723 int rc;
724 do
725 {
726 struct
727 {
728 VBGLIOCHGCMCALL Hdr;
729 HGCMFunctionParameter idSession;
730 HGCMFunctionParameter pKey;
731 } Msg;
732 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_ACCEPT, 2);
733 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
734 VbglHGCMParmPtrSet(&Msg.pKey, (void *)pvKey, cbKey);
735 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
736 } while (rc == VERR_INTERRUPTED);
737 return rc;
738}
739
740
741/**
742 * Cancels a prepared session.
743 * @since 6.0
744 * @sa GUEST_SESSION_CANCEL_PREPARED
745 */
746VBGLR3DECL(int) VbglR3GuestCtrlSessionCancelPrepared(uint32_t idClient, uint32_t idSession)
747{
748 int rc;
749 do
750 {
751 struct
752 {
753 VBGLIOCHGCMCALL Hdr;
754 HGCMFunctionParameter idSession;
755 } Msg;
756 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, GUEST_MSG_SESSION_CANCEL_PREPARED, 1);
757 VbglHGCMParmUInt32Set(&Msg.idSession, idSession);
758 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
759 } while (rc == VERR_INTERRUPTED);
760 return rc;
761}
762
763
764/**
765 * Invalidates the internal state because the (VM) session has been changed (i.e. restored).
766 *
767 * @returns VBox status code.
768 * @param idClient Client ID to use for invalidating state.
769 * @param idNewControlSession New control session ID. Currently unused.
770 */
771VBGLR3DECL(int) VbglR3GuestCtrlSessionHasChanged(uint32_t idClient, uint64_t idNewControlSession)
772{
773 RT_NOREF(idNewControlSession);
774
775 vbglR3GuestCtrlDetectPeekGetCancelSupport(idClient);
776
777 return VINF_SUCCESS;
778}
779
780
781/**
782 * Asks a specific guest session to close.
783 *
784 * @return IPRT status code.
785 * @param pCtx Guest control command context to use.
786 * @param fFlags Some kind of flag. Figure it out yourself.
787 */
788VBGLR3DECL(int) VbglR3GuestCtrlSessionClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t fFlags)
789{
790 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
791 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
792
793 HGCMMsgSessionClose Msg;
794 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_CLOSE, pCtx->uNumParms);
795 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
796 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
797
798 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
799}
800
801
802/**
803 * Notifies a guest session.
804 *
805 * @returns VBox status code.
806 * @param pCtx Guest control command context to use.
807 * @param uType Notification type of type GUEST_SESSION_NOTIFYTYPE_XXX.
808 * @param iResult Result code (rc) to notify.
809 */
810VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uType, int32_t iResult)
811{
812 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
813
814 HGCMMsgSessionNotify Msg;
815 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_SESSION_NOTIFY, 3);
816 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
817 VbglHGCMParmUInt32Set(&Msg.type, uType);
818 VbglHGCMParmUInt32Set(&Msg.result, (uint32_t)iResult);
819
820 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
821}
822
823/**
824 * Initializes a session startup info, extended version.
825 *
826 * @returns VBox status code.
827 * @param pStartupInfo Session startup info to initializes.
828 * @param cbUser Size (in bytes) to use for the user name buffer.
829 * @param cbPassword Size (in bytes) to use for the password buffer.
830 * @param cbDomain Size (in bytes) to use for the domain name buffer.
831 */
832VBGLR3DECL(int) VbglR3GuestCtrlSessionStartupInfoInitEx(PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pStartupInfo,
833 size_t cbUser, size_t cbPassword, size_t cbDomain)
834{
835 AssertPtrReturn(pStartupInfo, VERR_INVALID_POINTER);
836
837 RT_BZERO(pStartupInfo, sizeof(VBGLR3GUESTCTRLSESSIONSTARTUPINFO));
838
839#define ALLOC_STR(a_Str, a_cb) \
840 if ((a_cb) > 0) \
841 { \
842 pStartupInfo->psz##a_Str = RTStrAlloc(a_cb); \
843 AssertPtrBreak(pStartupInfo->psz##a_Str); \
844 pStartupInfo->cb##a_Str = (uint32_t)a_cb; \
845 }
846
847 do
848 {
849 ALLOC_STR(User, cbUser);
850 ALLOC_STR(Password, cbPassword);
851 ALLOC_STR(Domain, cbDomain);
852
853 return VINF_SUCCESS;
854
855 } while (0);
856
857#undef ALLOC_STR
858
859 VbglR3GuestCtrlSessionStartupInfoDestroy(pStartupInfo);
860 return VERR_NO_MEMORY;
861}
862
863/**
864 * Initializes a session startup info.
865 *
866 * @returns VBox status code.
867 * @param pStartupInfo Session startup info to initializes.
868 */
869VBGLR3DECL(int) VbglR3GuestCtrlSessionStartupInfoInit(PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pStartupInfo)
870{
871 return VbglR3GuestCtrlSessionStartupInfoInitEx(pStartupInfo,
872 GUEST_PROC_DEF_USER_LEN, GUEST_PROC_DEF_PASSWORD_LEN,
873 GUEST_PROC_DEF_DOMAIN_LEN);
874}
875
876/**
877 * Destroys a session startup info.
878 *
879 * @param pStartupInfo Session startup info to destroy.
880 */
881VBGLR3DECL(void) VbglR3GuestCtrlSessionStartupInfoDestroy(PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pStartupInfo)
882{
883 if (!pStartupInfo)
884 return;
885
886 RTStrFree(pStartupInfo->pszUser);
887 RTStrFree(pStartupInfo->pszPassword);
888 RTStrFree(pStartupInfo->pszDomain);
889
890 RT_BZERO(pStartupInfo, sizeof(VBGLR3GUESTCTRLSESSIONSTARTUPINFO));
891}
892
893/**
894 * Free's a session startup info.
895 *
896 * @param pStartupInfo Session startup info to free.
897 * The pointer will not be valid anymore after return.
898 */
899VBGLR3DECL(void) VbglR3GuestCtrlSessionStartupInfoFree(PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pStartupInfo)
900{
901 if (!pStartupInfo)
902 return;
903
904 VbglR3GuestCtrlSessionStartupInfoDestroy(pStartupInfo);
905
906 RTMemFree(pStartupInfo);
907 pStartupInfo = NULL;
908}
909
910/**
911 * Duplicates a session startup info.
912 *
913 * @returns Duplicated session startup info on success, or NULL on error.
914 * @param pStartupInfo Session startup info to duplicate.
915 */
916VBGLR3DECL(PVBGLR3GUESTCTRLSESSIONSTARTUPINFO) VbglR3GuestCtrlSessionStartupInfoDup(PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pStartupInfo)
917{
918 AssertPtrReturn(pStartupInfo, NULL);
919
920 PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pStartupInfoDup = (PVBGLR3GUESTCTRLSESSIONSTARTUPINFO)
921 RTMemDup(pStartupInfo, sizeof(VBGLR3GUESTCTRLSESSIONSTARTUPINFO));
922 if (pStartupInfoDup)
923 {
924 do
925 {
926 pStartupInfoDup->pszUser = NULL;
927 pStartupInfoDup->pszPassword = NULL;
928 pStartupInfoDup->pszDomain = NULL;
929
930#define DUP_STR(a_Str) \
931 if (pStartupInfo->cb##a_Str) \
932 { \
933 pStartupInfoDup->psz##a_Str = (char *)RTStrDup(pStartupInfo->psz##a_Str); \
934 AssertPtrBreak(pStartupInfoDup->psz##a_Str); \
935 pStartupInfoDup->cb##a_Str = (uint32_t)strlen(pStartupInfoDup->psz##a_Str) + 1 /* Include terminator */; \
936 }
937 DUP_STR(User);
938 DUP_STR(Password);
939 DUP_STR(Domain);
940
941#undef DUP_STR
942
943 return pStartupInfoDup;
944
945 } while (0); /* To use break macros above. */
946
947 VbglR3GuestCtrlSessionStartupInfoFree(pStartupInfoDup);
948 }
949
950 return NULL;
951}
952
953/**
954 * Retrieves a HOST_SESSION_CREATE message.
955 *
956 * @returns VBox status code.
957 * @param pCtx Guest control command context to use.
958 * @param ppStartupInfo Where to store the allocated session startup info.
959 * Needs to be free'd by VbglR3GuestCtrlSessionStartupInfoFree().
960 */
961VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, PVBGLR3GUESTCTRLSESSIONSTARTUPINFO *ppStartupInfo)
962{
963 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
964 AssertReturn(pCtx->uNumParms == 6, VERR_INVALID_PARAMETER);
965 AssertPtrReturn(ppStartupInfo, VERR_INVALID_POINTER);
966
967 PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pStartupInfo
968 = (PVBGLR3GUESTCTRLSESSIONSTARTUPINFO)RTMemAlloc(sizeof(VBGLR3GUESTCTRLSESSIONSTARTUPINFO));
969 if (!pStartupInfo)
970 return VERR_NO_MEMORY;
971
972 int rc = VbglR3GuestCtrlSessionStartupInfoInit(pStartupInfo);
973 if (RT_FAILURE(rc))
974 {
975 VbglR3GuestCtrlSessionStartupInfoFree(pStartupInfo);
976 return rc;
977 }
978
979 do
980 {
981 HGCMMsgSessionOpen Msg;
982 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
983 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CREATE);
984 VbglHGCMParmUInt32Set(&Msg.protocol, 0);
985 VbglHGCMParmPtrSet(&Msg.username, pStartupInfo->pszUser, pStartupInfo->cbUser);
986 VbglHGCMParmPtrSet(&Msg.password, pStartupInfo->pszPassword, pStartupInfo->cbPassword);
987 VbglHGCMParmPtrSet(&Msg.domain, pStartupInfo->pszDomain, pStartupInfo->cbDomain);
988 VbglHGCMParmUInt32Set(&Msg.flags, 0);
989
990 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
991 if (RT_SUCCESS(rc))
992 {
993 Msg.context.GetUInt32(&pCtx->uContextID);
994 Msg.protocol.GetUInt32(&pStartupInfo->uProtocol);
995 Msg.flags.GetUInt32(&pStartupInfo->fFlags);
996
997 pStartupInfo->uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
998 }
999
1000 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1001
1002 if (RT_SUCCESS(rc))
1003 {
1004 *ppStartupInfo = pStartupInfo;
1005 }
1006 else
1007 VbglR3GuestCtrlSessionStartupInfoFree(pStartupInfo);
1008
1009 LogFlowFuncLeaveRC(rc);
1010 return rc;
1011}
1012
1013
1014/**
1015 * Retrieves a HOST_SESSION_CLOSE message.
1016 */
1017VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfFlags, uint32_t *pidSession)
1018{
1019 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1020 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1021
1022 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1023
1024 int rc;
1025 do
1026 {
1027 HGCMMsgSessionClose Msg;
1028 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1029 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SESSION_CLOSE);
1030 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1031
1032 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1033 if (RT_SUCCESS(rc))
1034 {
1035 Msg.context.GetUInt32(&pCtx->uContextID);
1036 Msg.flags.GetUInt32(pfFlags);
1037
1038 if (pidSession)
1039 *pidSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtx->uContextID);
1040 }
1041 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1042 return rc;
1043}
1044
1045
1046#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
1047/**
1048 * Retrieves a HOST_MSG_DIR_OPEN message.
1049 *
1050 * @returns VBox status code.
1051 * @param pCtx Guest control command context to use.
1052 * @param pszPath Where to return the directory path to open.
1053 * @param cbPath Size (in bytes) of \a pszPath.
1054 * @param pfFlags Where to return the directory listing flags.
1055 * @param enmFilter Where to return the directory filter type.
1056 * @param penmAttrAdd Where to return the additional attributes enumeration to use for reading directory entries later.
1057 * @param pfReadFlags Where to return the flags for reading directory entries later.
1058 */
1059VBGLR3DECL(int) VbglR3GuestCtrlDirGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfFlags,
1060 GSTCTLDIRFILTER *penmFilter, GSTCTLFSOBJATTRADD *penmReadAttrAdd, uint32_t *pfReadFlags)
1061{
1062 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1063 AssertReturn(pCtx->uNumParms == 6, VERR_INVALID_PARAMETER);
1064
1065 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1066 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1067 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1068 AssertPtrReturn(penmFilter, VERR_INVALID_POINTER);
1069 AssertPtrReturn(penmReadAttrAdd, VERR_INVALID_POINTER);
1070 AssertPtrReturn(pfReadFlags, VERR_INVALID_POINTER);
1071
1072 int rc;
1073 do
1074 {
1075 HGCMMsgDirOpen Msg;
1076 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1077 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_OPEN);
1078 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
1079 VbglHGCMParmUInt32Set(&Msg.filter, 0);
1080 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1081 VbglHGCMParmUInt32Set(&Msg.read_attr_add, 0);
1082 VbglHGCMParmUInt32Set(&Msg.read_flags, 0);
1083
1084 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1085 if (RT_SUCCESS(rc))
1086 {
1087 Msg.context.GetUInt32(&pCtx->uContextID);
1088 Msg.filter.GetUInt32((uint32_t *)penmFilter);
1089 Msg.flags.GetUInt32(pfFlags);
1090 Msg.read_attr_add.GetUInt32((uint32_t *)penmReadAttrAdd);
1091 Msg.read_flags.GetUInt32(pfReadFlags);
1092 }
1093 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1094 return rc;
1095}
1096
1097
1098/**
1099 * Retrieves a HOST_MSG_DIR_CLOSE message.
1100 *
1101 * @returns VBox status code.
1102 * @param pCtx Guest control command context to use.
1103 * @param puHandle Where to return the handle of the guest directory to close.
1104 */
1105VBGLR3DECL(int) VbglR3GuestCtrlDirGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1106{
1107 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1108 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1109
1110 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1111
1112 int rc;
1113 do
1114 {
1115 HGCMMsgDirClose Msg;
1116 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1117 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_CLOSE);
1118 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1119
1120 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1121 if (RT_SUCCESS(rc))
1122 {
1123 Msg.context.GetUInt32(&pCtx->uContextID);
1124 Msg.handle.GetUInt32(puHandle);
1125 }
1126 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1127 return rc;
1128}
1129
1130
1131/**
1132 * Retrieves a HOST_MSG_DIR_READ message.
1133 *
1134 * @returns VBox status code.
1135 * @param pCtx Guest control command context to use.
1136 * @param puHandle Where to return the directory handle to rewind.
1137 */
1138VBGLR3DECL(int) VbglR3GuestCtrlDirGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1139{
1140 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1141 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1142
1143 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1144
1145 int rc;
1146 do
1147 {
1148 HGCMMsgDirRead Msg;
1149 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1150 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_READ);
1151 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1152
1153 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1154 if (RT_SUCCESS(rc))
1155 {
1156 Msg.context.GetUInt32(&pCtx->uContextID);
1157 Msg.handle.GetUInt32(puHandle);
1158 }
1159 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1160 return rc;
1161}
1162
1163
1164/**
1165 * Retrieves a HOST_MSG_DIR_REWIND message.
1166 *
1167 * @returns VBox status code.
1168 * @param pCtx Guest control command context to use.
1169 * @param puHandle Where to return the directory handle to rewind.
1170 */
1171VBGLR3DECL(int) VbglR3GuestCtrlDirGetRewind(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
1172{
1173 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1174 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1175
1176 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1177
1178 int rc;
1179 do
1180 {
1181 HGCMMsgDirRewind Msg;
1182 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1183 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_REWIND);
1184 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1185
1186 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1187 if (RT_SUCCESS(rc))
1188 {
1189 Msg.context.GetUInt32(&pCtx->uContextID);
1190 Msg.handle.GetUInt32(puHandle);
1191 }
1192 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1193 return rc;
1194}
1195
1196
1197/**
1198 * Retrieves a HOST_MSG_DIR_LIST message.
1199 *
1200 * @returns VBox status code.
1201 * @param pCtx Guest control command context to use.
1202 * @param puHandle Where to return the directory handle to rewind.
1203 * @param pcEntries Where to return the number of directory entries to read.
1204 * @param pfFlags Where to return the directory listing flags.
1205 */
1206VBGLR3DECL(int) VbglR3GuestCtrlDirGetList(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *pcEntries, uint32_t *pfFlags)
1207{
1208 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1209 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1210
1211 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1212 AssertPtrReturn(pcEntries, VERR_INVALID_POINTER);
1213 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1214
1215 int rc;
1216 do
1217 {
1218 HGCMMsgDirList Msg;
1219 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1220 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_LIST);
1221 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1222 VbglHGCMParmUInt32Set(&Msg.num_entries, 0);
1223 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1224
1225 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1226 if (RT_SUCCESS(rc))
1227 {
1228 Msg.context.GetUInt32(&pCtx->uContextID);
1229 Msg.handle.GetUInt32(puHandle);
1230 Msg.num_entries.GetUInt32(pcEntries);
1231 Msg.flags.GetUInt32(pfFlags);
1232 }
1233 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1234 return rc;
1235}
1236#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
1237
1238
1239/**
1240 * Retrieves a HOST_PATH_RENAME message.
1241 *
1242 * @returns VBox status code.
1243 * @param pCtx Guest control command context to use.
1244 * @param pszSource Where to return the source path.
1245 * @param cbSource Size (in bytes) of \a pszSource.
1246 * @param pszDest Where to return the destination path.
1247 * @param cbDest Size (in bytes) of \a pszDest.
1248 * @param pfFlags Where to return the rename flags.
1249 */
1250VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx,
1251 char *pszSource, uint32_t cbSource,
1252 char *pszDest, uint32_t cbDest,
1253 uint32_t *pfFlags)
1254{
1255 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1256 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1257
1258 AssertPtrReturn(pszSource, VERR_INVALID_POINTER);
1259 AssertReturn(cbSource, VERR_INVALID_PARAMETER);
1260 AssertPtrReturn(pszDest, VERR_INVALID_POINTER);
1261 AssertReturn(cbDest, VERR_INVALID_PARAMETER);
1262 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1263
1264 int rc;
1265 do
1266 {
1267 HGCMMsgPathRename Msg;
1268 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1269 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_RENAME);
1270 VbglHGCMParmPtrSet(&Msg.source, pszSource, cbSource);
1271 VbglHGCMParmPtrSet(&Msg.dest, pszDest, cbDest);
1272 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1273
1274 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1275 if (RT_SUCCESS(rc))
1276 {
1277 Msg.context.GetUInt32(&pCtx->uContextID);
1278 Msg.flags.GetUInt32(pfFlags);
1279 }
1280
1281 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1282 return rc;
1283}
1284
1285
1286/**
1287 * Retrieves a HOST_PATH_USER_DOCUMENTS message.
1288 *
1289 * @param pCtx Guest control command context to use.
1290 */
1291VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserDocuments(PVBGLR3GUESTCTRLCMDCTX pCtx)
1292{
1293 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1294 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
1295
1296 int rc;
1297 do
1298 {
1299 HGCMMsgPathUserDocuments Msg;
1300 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1301 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_DOCUMENTS);
1302
1303 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1304 if (RT_SUCCESS(rc))
1305 Msg.context.GetUInt32(&pCtx->uContextID);
1306 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1307 return rc;
1308}
1309
1310
1311/**
1312 * Retrieves a HOST_PATH_USER_HOME message.
1313 *
1314 * @param pCtx Guest control command context to use.
1315 */
1316VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserHome(PVBGLR3GUESTCTRLCMDCTX pCtx)
1317{
1318 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1319 AssertReturn(pCtx->uNumParms == 1, VERR_INVALID_PARAMETER);
1320
1321 int rc;
1322 do
1323 {
1324 HGCMMsgPathUserHome Msg;
1325 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1326 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_PATH_USER_HOME);
1327
1328 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1329 if (RT_SUCCESS(rc))
1330 Msg.context.GetUInt32(&pCtx->uContextID);
1331 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1332 return rc;
1333}
1334
1335
1336/**
1337 * Retrieves a HOST_MSG_MOUNT_POINTS message.
1338 *
1339 * @param pCtx Guest control command context to use.
1340 * @param pfFlags Where to return the get mount point flags on success.
1341 */
1342VBGLR3DECL(int) VbglR3GuestCtrlGetMountPoints(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfFlags)
1343{
1344 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1345 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1346 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1347
1348 int rc;
1349 do
1350 {
1351 HGCMMsgMountPoints Msg;
1352 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1353 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_MOUNT_POINTS);
1354 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1355
1356 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1357 if (RT_SUCCESS(rc))
1358 {
1359 Msg.context.GetUInt32(&pCtx->uContextID);
1360 Msg.flags.GetUInt32(pfFlags);
1361 }
1362 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1363 return rc;
1364}
1365
1366
1367#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
1368/**
1369 * Retrieves a HOST_MSG_FS_QUERY_INFO message.
1370 *
1371 * @returns VBox status code.
1372 * @param pCtx Guest control command context to use.
1373 * @param pszPath Where to return the path of the file system object to query.
1374 * @param cbPath Size (in bytes) of \a pszPath.
1375 */
1376VBGLR3DECL(int) VbglR3GuestCtrlFsGetQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath)
1377{
1378 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1379
1380 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1381 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1382
1383 int rc;
1384 do
1385 {
1386 HGCMMsgFsQueryInfo Msg;
1387 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1388 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FS_QUERY_INFO);
1389 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
1390
1391 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1392 if (RT_SUCCESS(rc))
1393 Msg.context.GetUInt32(&pCtx->uContextID);
1394
1395 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1396 return rc;
1397}
1398
1399/**
1400 * Retrieves a HOST_MSG_FS_OBJ_QUERY_INFO message.
1401 *
1402 * @returns VBox status code.
1403 * @param pCtx Guest control command context to use.
1404 * @param pszPath Where to return the path of the file system object to query.
1405 * @param cbPath Size (in bytes) of \a pszPath.
1406 * @param penmAddAttrib Where to return the additional attributes enumeration.
1407 * @param pfFlags Where to return the flags for .
1408 */
1409VBGLR3DECL(int) VbglR3GuestCtrlFsObjGetQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx,
1410 char *pszPath, uint32_t cbPath, GSTCTLFSOBJATTRADD *penmAddAttrib,
1411 uint32_t *pfFlags)
1412{
1413 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1414 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1415
1416 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1417 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1418 AssertPtrReturn(penmAddAttrib, VERR_INVALID_POINTER);
1419 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1420
1421 int rc;
1422 do
1423 {
1424 HGCMMsgFsObjQueryInfo Msg;
1425 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1426 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FS_OBJ_QUERY_INFO);
1427 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
1428 VbglHGCMParmUInt32Set(&Msg.add_attributes, 0);
1429 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1430
1431 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1432 if (RT_SUCCESS(rc))
1433 {
1434 Msg.context.GetUInt32(&pCtx->uContextID);
1435 Msg.add_attributes.GetUInt32((uint32_t *)penmAddAttrib);
1436 Msg.flags.GetUInt32(pfFlags);
1437 }
1438
1439 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1440 return rc;
1441}
1442
1443
1444/**
1445 * Retrieves a HOST_MSG_FS_CREATE_TEMP message.
1446 *
1447 * @returns VBox status code.
1448 * @param pCtx Guest control command context to use.
1449 * @param pszTemplate Where to return the template name.
1450 * @param cbTemplate Size (in bytes) of \a pszTemplate.
1451 * @param pszPath Where to return the temporary directory path.
1452 * @param cbTemplate Size (in bytes) of \a pszPath.
1453 * @param pfFlags Where to return the creation flags.
1454 * @param pfMode Where to return the creation mode.
1455 */
1456VBGLR3DECL(int) VbglR3GuestCtrlFsGetCreateTemp(PVBGLR3GUESTCTRLCMDCTX pCtx,
1457 char *pszTemplate, uint32_t cbTemplate, char *pszPath, uint32_t cbPath,
1458 uint32_t *pfFlags, uint32_t *pfMode)
1459{
1460 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1461 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1462
1463 AssertPtrReturn(pszTemplate, VERR_INVALID_POINTER);
1464 AssertReturn(cbTemplate, VERR_INVALID_PARAMETER);
1465 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1466 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1467 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1468 AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
1469
1470 int rc;
1471 do
1472 {
1473 HGCMMsgFsCreateTemp Msg;
1474 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1475 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FS_CREATE_TEMP);
1476 VbglHGCMParmPtrSet(&Msg.template_name, pszTemplate, cbTemplate);
1477 VbglHGCMParmPtrSet(&Msg.tmpdir, pszPath, cbPath);
1478 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1479 VbglHGCMParmUInt32Set(&Msg.mode, 0);
1480
1481 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1482 if (RT_SUCCESS(rc))
1483 {
1484 Msg.context.GetUInt32(&pCtx->uContextID);
1485 Msg.flags.GetUInt32(pfFlags);
1486 Msg.mode.GetUInt32(pfMode);
1487 }
1488
1489 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1490 return rc;
1491}
1492#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
1493
1494
1495/**
1496 * Retrieves a HOST_MSG_SHUTDOWN message.
1497 *
1498 * @returns VBox status code.
1499 * @param pCtx Guest control command context to use.
1500 * @param pfAction Where to store the action flags on success.
1501 */
1502VBGLR3DECL(int) VbglR3GuestCtrlGetShutdown(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfAction)
1503{
1504 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1505 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
1506 AssertPtrReturn(pfAction, VERR_INVALID_POINTER);
1507
1508 int rc;
1509 do
1510 {
1511 HGCMMsgShutdown Msg;
1512 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1513 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_SHUTDOWN);
1514 VbglHGCMParmUInt32Set(&Msg.action, 0);
1515
1516 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1517 if (RT_SUCCESS(rc))
1518 {
1519 Msg.context.GetUInt32(&pCtx->uContextID);
1520 Msg.action.GetUInt32(pfAction);
1521 }
1522 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1523 return rc;
1524}
1525
1526/**
1527 * Initializes a process startup info, extended version.
1528 *
1529 * @returns VBox status code.
1530 * @param pStartupInfo Process startup info to initializes.
1531 * @param cbCmd Size (in bytes) to use for the command buffer.
1532 * @param cbArgs Size (in bytes) to use for the arguments buffer.
1533 * @param cbEnv Size (in bytes) to use for the environment buffer.
1534 * @param cbCwd Size (in bytes) to use for the current working directory.
1535 * @param cbUser Size (in bytes) to use for the user name buffer.
1536 * @param cbPassword Size (in bytes) to use for the password buffer.
1537 * @param cbDomain Size (in bytes) to use for the domain buffer.
1538 */
1539VBGLR3DECL(int) VbglR3GuestCtrlProcStartupInfoInitEx(PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo,
1540 size_t cbCmd, size_t cbArgs, size_t cbEnv,
1541 size_t cbCwd,
1542 size_t cbUser, size_t cbPassword, size_t cbDomain)
1543{
1544 AssertPtrReturn(pStartupInfo, VERR_INVALID_POINTER);
1545 AssertReturn(cbCmd, VERR_INVALID_PARAMETER);
1546 AssertReturn(cbArgs, VERR_INVALID_PARAMETER);
1547 AssertReturn(cbEnv, VERR_INVALID_PARAMETER);
1548 AssertReturn(cbCwd, VERR_INVALID_PARAMETER);
1549 AssertReturn(cbUser, VERR_INVALID_PARAMETER);
1550 AssertReturn(cbPassword, VERR_INVALID_PARAMETER);
1551 AssertReturn(cbDomain, VERR_INVALID_PARAMETER);
1552
1553 RT_BZERO(pStartupInfo, sizeof(VBGLR3GUESTCTRLPROCSTARTUPINFO));
1554
1555#define ALLOC_STR(a_Str, a_cb) \
1556 if ((a_cb) > 0) \
1557 { \
1558 pStartupInfo->psz##a_Str = RTStrAlloc(a_cb); \
1559 AssertPtrBreak(pStartupInfo->psz##a_Str); \
1560 pStartupInfo->cb##a_Str = (uint32_t)a_cb; \
1561 }
1562
1563 do
1564 {
1565 ALLOC_STR(Cmd, cbCmd);
1566 ALLOC_STR(Args, cbArgs);
1567 ALLOC_STR(Env, cbEnv);
1568 ALLOC_STR(Cwd, cbCwd);
1569 ALLOC_STR(User, cbUser);
1570 ALLOC_STR(Password, cbPassword);
1571 ALLOC_STR(Domain, cbDomain);
1572
1573 return VINF_SUCCESS;
1574
1575 } while (0);
1576
1577#undef ALLOC_STR
1578
1579 VbglR3GuestCtrlProcStartupInfoDestroy(pStartupInfo);
1580 return VERR_NO_MEMORY;
1581}
1582
1583/**
1584 * Initializes a process startup info with default values.
1585 *
1586 * @param pStartupInfo Process startup info to initialize.
1587 */
1588VBGLR3DECL(int) VbglR3GuestCtrlProcStartupInfoInit(PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo)
1589{
1590 return VbglR3GuestCtrlProcStartupInfoInitEx(pStartupInfo,
1591 GUEST_PROC_DEF_CMD_LEN, GUEST_PROC_DEF_ARGS_LEN, GUEST_PROC_DEF_ENV_LEN,
1592 GUEST_PROC_DEF_CWD_LEN,
1593 GUEST_PROC_DEF_USER_LEN /* Deprecated, now handled via session creation. */,
1594 GUEST_PROC_DEF_PASSWORD_LEN /* Ditto. */,
1595 GUEST_PROC_DEF_DOMAIN_LEN /* Ditto. */);
1596}
1597
1598/**
1599 * Destroys a process startup info.
1600 *
1601 * @param pStartupInfo Process startup info to destroy.
1602 */
1603VBGLR3DECL(void) VbglR3GuestCtrlProcStartupInfoDestroy(PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo)
1604{
1605 if (!pStartupInfo)
1606 return;
1607
1608 RTStrFree(pStartupInfo->pszCmd);
1609 RTStrFree(pStartupInfo->pszArgs);
1610 RTStrFree(pStartupInfo->pszEnv);
1611 RTStrFree(pStartupInfo->pszCwd);
1612 RTStrFree(pStartupInfo->pszUser);
1613 RTStrFree(pStartupInfo->pszPassword);
1614 RTStrFree(pStartupInfo->pszDomain);
1615
1616 RT_BZERO(pStartupInfo, sizeof(VBGLR3GUESTCTRLPROCSTARTUPINFO));
1617}
1618
1619/**
1620 * Free's a process startup info.
1621 *
1622 * @param pStartupInfo Process startup info to free.
1623 * The pointer will not be valid anymore after return.
1624 */
1625VBGLR3DECL(void) VbglR3GuestCtrlProcStartupInfoFree(PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo)
1626{
1627 if (!pStartupInfo)
1628 return;
1629
1630 VbglR3GuestCtrlProcStartupInfoDestroy(pStartupInfo);
1631
1632 RTMemFree(pStartupInfo);
1633 pStartupInfo = NULL;
1634}
1635
1636/**
1637 * Duplicates a process startup info.
1638 *
1639 * @returns Duplicated process startup info on success, or NULL on error.
1640 * @param pStartupInfo Process startup info to duplicate.
1641 */
1642VBGLR3DECL(PVBGLR3GUESTCTRLPROCSTARTUPINFO) VbglR3GuestCtrlProcStartupInfoDup(PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo)
1643{
1644 AssertPtrReturn(pStartupInfo, NULL);
1645
1646 PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfoDup = (PVBGLR3GUESTCTRLPROCSTARTUPINFO)
1647 RTMemDup(pStartupInfo, sizeof(VBGLR3GUESTCTRLPROCSTARTUPINFO));
1648 if (pStartupInfoDup)
1649 {
1650 do
1651 {
1652 pStartupInfoDup->pszCmd = NULL;
1653 pStartupInfoDup->pszArgs = NULL;
1654 pStartupInfoDup->pszEnv = NULL;
1655 pStartupInfoDup->pszCwd = NULL;
1656 pStartupInfoDup->pszUser = NULL;
1657 pStartupInfoDup->pszPassword = NULL;
1658 pStartupInfoDup->pszDomain = NULL;
1659
1660#define DUP_STR(a_Str) \
1661 if (pStartupInfo->cb##a_Str) \
1662 { \
1663 pStartupInfoDup->psz##a_Str = (char *)RTStrDup(pStartupInfo->psz##a_Str); \
1664 AssertPtrBreak(pStartupInfoDup->psz##a_Str); \
1665 pStartupInfoDup->cb##a_Str = (uint32_t)strlen(pStartupInfoDup->psz##a_Str) + 1 /* Include terminator */; \
1666 }
1667
1668#define DUP_MEM(a_Str) \
1669 if (pStartupInfo->cb##a_Str) \
1670 { \
1671 pStartupInfoDup->psz##a_Str = (char *)RTMemDup(pStartupInfo->psz##a_Str, pStartupInfo->cb##a_Str); \
1672 AssertPtrBreak(pStartupInfoDup->psz##a_Str); \
1673 pStartupInfoDup->cb##a_Str = (uint32_t)pStartupInfo->cb##a_Str; \
1674 }
1675
1676 DUP_STR(Cmd);
1677 DUP_MEM(Args);
1678 DUP_MEM(Env);
1679 DUP_MEM(Cwd);
1680 DUP_STR(User);
1681 DUP_STR(Password);
1682 DUP_STR(Domain);
1683
1684#undef DUP_STR
1685#undef DUP_MEM
1686
1687 return pStartupInfoDup;
1688
1689 } while (0); /* To use break macros above. */
1690
1691 VbglR3GuestCtrlProcStartupInfoFree(pStartupInfoDup);
1692 }
1693
1694 return NULL;
1695}
1696
1697/**
1698 * Retrieves a HOST_EXEC_CMD message.
1699 *
1700 * @returns VBox status code.
1701 * @param pCtx Guest control command context to use.
1702 * @param ppStartupInfo Where to store the allocated session startup info.
1703 * Needs to be free'd by VbglR3GuestCtrlProcStartupInfoFree().
1704 */
1705VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLCMDCTX pCtx, PVBGLR3GUESTCTRLPROCSTARTUPINFO *ppStartupInfo)
1706{
1707 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1708 AssertPtrReturn(ppStartupInfo, VERR_INVALID_POINTER);
1709
1710 PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo
1711 = (PVBGLR3GUESTCTRLPROCSTARTUPINFO)RTMemAlloc(sizeof(VBGLR3GUESTCTRLPROCSTARTUPINFO));
1712 if (!pStartupInfo)
1713 return VERR_NO_MEMORY;
1714
1715 int rc = VbglR3GuestCtrlProcStartupInfoInit(pStartupInfo);
1716 if (RT_FAILURE(rc))
1717 {
1718 VbglR3GuestCtrlProcStartupInfoFree(pStartupInfo);
1719 return rc;
1720 }
1721
1722 unsigned cRetries = 0;
1723 const unsigned cMaxRetries = 32; /* Should be enough for now. */
1724 const unsigned cGrowthFactor = 2; /* By how much the buffers will grow if they're too small yet. */
1725
1726 do
1727 {
1728 LogRel(("VbglR3GuestCtrlProcGetStart: Retrieving\n"));
1729
1730 HGCMMsgProcExec Msg;
1731 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1732 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_CMD);
1733 VbglHGCMParmPtrSet(&Msg.cmd, pStartupInfo->pszCmd, pStartupInfo->cbCmd);
1734 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1735 VbglHGCMParmUInt32Set(&Msg.num_args, 0);
1736 VbglHGCMParmPtrSet(&Msg.args, pStartupInfo->pszArgs, pStartupInfo->cbArgs);
1737 VbglHGCMParmUInt32Set(&Msg.num_env, 0);
1738 VbglHGCMParmUInt32Set(&Msg.cb_env, 0);
1739 VbglHGCMParmPtrSet(&Msg.env, pStartupInfo->pszEnv, pStartupInfo->cbEnv);
1740 if (pCtx->uProtocol < 2) /* Protocol v1, deprecated. */
1741 {
1742 VbglHGCMParmPtrSet(&Msg.u.v1.username, pStartupInfo->pszUser, pStartupInfo->cbUser);
1743 VbglHGCMParmPtrSet(&Msg.u.v1.password, pStartupInfo->pszPassword, pStartupInfo->cbPassword);
1744 VbglHGCMParmUInt32Set(&Msg.u.v1.timeout, 0);
1745 }
1746 else /* Protocol v2. */
1747 {
1748 VbglHGCMParmUInt32Set(&Msg.u.v2.timeout, 0);
1749 VbglHGCMParmUInt32Set(&Msg.u.v2.priority, 0);
1750 VbglHGCMParmUInt32Set(&Msg.u.v2.num_affinity, 0);
1751 VbglHGCMParmPtrSet(&Msg.u.v2.affinity, pStartupInfo->uAffinity, sizeof(pStartupInfo->uAffinity));
1752 }
1753
1754 /* CWD support was added in VBox 7.1. Otherwise just skip setting it. */
1755 if (g_fVbglR3GuestCtrlHostFeatures0 & VBOX_GUESTCTRL_HF_0_PROCESS_CWD)
1756 VbglHGCMParmPtrSet(&Msg.cwd, pStartupInfo->pszCwd, pStartupInfo->cbCwd);
1757
1758 /*
1759 * We need to calculate the data size ourselves here and not rely on sizeof(),
1760 * as sizeof(Msg) might be different to what the host expects.
1761 *
1762 * This first was needed when excluding the CWD support for hosts running VBox < 7.1.
1763 */
1764 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(VBGLIOCHGCMCALL) + pCtx->uNumParms * sizeof(HGCMFunctionParameter));
1765 if (RT_FAILURE(rc))
1766 {
1767 LogRel(("VbglR3GuestCtrlProcGetStart: 1 - %Rrc (retry %u, cbCmd=%RU32, cbCwd=%RU32, cbArgs=%RU32, cbEnv=%RU32)\n",
1768 rc, cRetries, pStartupInfo->cbCmd, pStartupInfo->cbCwd, pStartupInfo->cbArgs, pStartupInfo->cbEnv));
1769
1770 if ( rc == VERR_BUFFER_OVERFLOW
1771 && cRetries++ < cMaxRetries)
1772 {
1773#define GROW_STR(a_Str, a_cbMax) \
1774 pStartupInfo->psz##a_Str = (char *)RTMemRealloc(pStartupInfo->psz##a_Str, \
1775 RT_MIN(pStartupInfo->cb##a_Str * cGrowthFactor, a_cbMax)); \
1776 AssertPtrBreakStmt(pStartupInfo->psz##a_Str, rc = VERR_NO_MEMORY); \
1777 pStartupInfo->cb##a_Str = RT_MIN(pStartupInfo->cb##a_Str * cGrowthFactor, a_cbMax);
1778
1779 /* We can't tell which parameter doesn't fit, so we have to resize all. */
1780 GROW_STR(Cmd , GUEST_PROC_MAX_CMD_LEN);
1781 GROW_STR(Args, GUEST_PROC_MAX_ARGS_LEN);
1782 GROW_STR(Env, GUEST_PROC_MAX_ENV_LEN);
1783 GROW_STR(Cwd, GUEST_PROC_MAX_CWD_LEN);
1784#undef GROW_STR
1785 LogRel(("VbglR3GuestCtrlProcGetStart: 2 - %Rrc (retry %u, cbCmd=%RU32, cbCwd=%RU32, cbArgs=%RU32, cbEnv=%RU32)\n",
1786 rc, cRetries, pStartupInfo->cbCmd, pStartupInfo->cbCwd, pStartupInfo->cbArgs, pStartupInfo->cbEnv));
1787 LogRel(("g_fVbglR3GuestCtrlHavePeekGetCancel=%RTbool\n", RT_BOOL(g_fVbglR3GuestCtrlHavePeekGetCancel)));
1788 }
1789 else
1790 break;
1791 }
1792 else
1793 {
1794 Msg.context.GetUInt32(&pCtx->uContextID);
1795 Msg.flags.GetUInt32(&pStartupInfo->fFlags);
1796 Msg.num_args.GetUInt32(&pStartupInfo->cArgs);
1797 Msg.num_env.GetUInt32(&pStartupInfo->cEnvVars);
1798 Msg.cb_env.GetUInt32(&pStartupInfo->cbEnv);
1799 if (pCtx->uProtocol < 2)
1800 Msg.u.v1.timeout.GetUInt32(&pStartupInfo->uTimeLimitMS);
1801 else
1802 {
1803 Msg.u.v2.timeout.GetUInt32(&pStartupInfo->uTimeLimitMS);
1804 Msg.u.v2.priority.GetUInt32(&pStartupInfo->uPriority);
1805 Msg.u.v2.num_affinity.GetUInt32(&pStartupInfo->cAffinity);
1806 }
1807 }
1808 } while (( rc == VERR_INTERRUPTED
1809 || rc == VERR_BUFFER_OVERFLOW) && g_fVbglR3GuestCtrlHavePeekGetCancel);
1810
1811 if (RT_SUCCESS(rc))
1812 {
1813 *ppStartupInfo = pStartupInfo;
1814 }
1815 else
1816 VbglR3GuestCtrlProcStartupInfoFree(pStartupInfo);
1817
1818 LogRel(("VbglR3GuestCtrlProcGetStart: Returning %Rrc (retry %u, cbCmd=%RU32, cbArgs=%RU32, cbEnv=%RU32)\n",
1819 rc, cRetries, pStartupInfo->cbCmd, pStartupInfo->cbArgs, pStartupInfo->cbEnv));
1820
1821 LogFlowFuncLeaveRC(rc);
1822 return rc;
1823}
1824
1825/**
1826 * Allocates and gets host data, based on the message ID.
1827 *
1828 * This will block until data becomes available.
1829 *
1830 * @returns VBox status code.
1831 * @param pCtx Guest control command context to use.
1832 * @param puPID Where to return the guest PID to retrieve output from on success.
1833 * @param puHandle Where to return the guest process handle to retrieve output from on success.
1834 * @param pfFlags Where to return the output flags on success.
1835 */
1836VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1837 uint32_t *puPID, uint32_t *puHandle, uint32_t *pfFlags)
1838{
1839 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1840 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1841
1842 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1843 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
1844 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1845
1846 int rc;
1847 do
1848 {
1849 HGCMMsgProcOutput Msg;
1850 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1851 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_GET_OUTPUT);
1852 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1853 VbglHGCMParmUInt32Set(&Msg.handle, 0);
1854 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1855
1856 rc = VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMMsgProcOutput, data));
1857 if (RT_SUCCESS(rc))
1858 {
1859 Msg.context.GetUInt32(&pCtx->uContextID);
1860 Msg.pid.GetUInt32(puPID);
1861 Msg.handle.GetUInt32(puHandle);
1862 Msg.flags.GetUInt32(pfFlags);
1863 }
1864 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1865 return rc;
1866}
1867
1868
1869/**
1870 * Retrieves the input data from host which then gets sent to the started
1871 * process (HOST_EXEC_SET_INPUT).
1872 *
1873 * This will block until data becomes available.
1874 */
1875VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
1876 uint32_t *puPID, uint32_t *pfFlags,
1877 void *pvData, uint32_t cbData,
1878 uint32_t *pcbSize)
1879{
1880 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1881 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
1882
1883 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
1884 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1885 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1886 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
1887
1888 int rc;
1889 do
1890 {
1891 HGCMMsgProcInput Msg;
1892 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1893 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_SET_INPUT);
1894 VbglHGCMParmUInt32Set(&Msg.pid, 0);
1895 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1896 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
1897 VbglHGCMParmUInt32Set(&Msg.size, 0);
1898
1899 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1900 if (RT_SUCCESS(rc))
1901 {
1902 Msg.context.GetUInt32(&pCtx->uContextID);
1903 Msg.pid.GetUInt32(puPID);
1904 Msg.flags.GetUInt32(pfFlags);
1905 Msg.size.GetUInt32(pcbSize);
1906 }
1907 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1908
1909 if ( rc != VERR_TOO_MUCH_DATA
1910 || g_fVbglR3GuestCtrlHavePeekGetCancel)
1911 return rc;
1912 return VERR_BUFFER_OVERFLOW;
1913}
1914
1915
1916#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
1917/**
1918 * Retrieves a HOST_MSG_DIR_CREATE message.
1919 *
1920 * @returns VBox status code.
1921 * @param pCtx Guest control command context to use.
1922 * @param pszPath Where to return the path.
1923 * @param cbPath Size (in bytes) of \a pszPath.
1924 * @param pfMode Where to return the creation mode.
1925 * @param pfFlags Where to return the creation flags (GSTCTL_CREATEDIRECTORY_F_XXX).
1926 */
1927VBGLR3DECL(int) VbglR3GuestCtrlDirGetCreate(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfMode, uint32_t *pfFlags)
1928{
1929 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1930 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
1931
1932 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1933 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1934 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1935 AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
1936
1937 int rc;
1938 do
1939 {
1940 HGCMMsgDirCreate Msg;
1941 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1942 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_CREATE);
1943 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
1944 VbglHGCMParmUInt32Set(&Msg.mode, 0);
1945 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1946
1947 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1948 if (RT_SUCCESS(rc))
1949 {
1950 Msg.context.GetUInt32(&pCtx->uContextID);
1951 Msg.flags.GetUInt32(pfFlags);
1952 Msg.mode.GetUInt32(pfMode);
1953 }
1954
1955 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1956 return rc;
1957}
1958#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
1959
1960
1961/**
1962 * Retrieves a HOST_DIR_REMOVE message.
1963 */
1964VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx,
1965 char *pszPath, uint32_t cbPath,
1966 uint32_t *pfFlags)
1967{
1968 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
1969 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
1970
1971 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1972 AssertReturn(cbPath, VERR_INVALID_PARAMETER);
1973 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
1974
1975 int rc;
1976 do
1977 {
1978 HGCMMsgDirRemove Msg;
1979 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
1980 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_REMOVE);
1981 VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
1982 VbglHGCMParmUInt32Set(&Msg.flags, 0);
1983
1984 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1985 if (RT_SUCCESS(rc))
1986 {
1987 Msg.context.GetUInt32(&pCtx->uContextID);
1988 Msg.flags.GetUInt32(pfFlags);
1989 }
1990 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
1991 return rc;
1992}
1993
1994
1995/**
1996 * Retrieves a HOST_FILE_OPEN message.
1997 */
1998VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
1999 char *pszFileName, uint32_t cbFileName,
2000 char *pszAccess, uint32_t cbAccess,
2001 char *pszDisposition, uint32_t cbDisposition,
2002 char *pszSharing, uint32_t cbSharing,
2003 uint32_t *puCreationMode,
2004 uint64_t *poffAt)
2005{
2006 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2007 AssertReturn(pCtx->uNumParms == 7, VERR_INVALID_PARAMETER);
2008
2009 AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
2010 AssertReturn(cbFileName, VERR_INVALID_PARAMETER);
2011 AssertPtrReturn(pszAccess, VERR_INVALID_POINTER);
2012 AssertReturn(cbAccess, VERR_INVALID_PARAMETER);
2013 AssertPtrReturn(pszDisposition, VERR_INVALID_POINTER);
2014 AssertReturn(cbDisposition, VERR_INVALID_PARAMETER);
2015 AssertPtrReturn(pszSharing, VERR_INVALID_POINTER);
2016 AssertReturn(cbSharing, VERR_INVALID_PARAMETER);
2017 AssertPtrReturn(puCreationMode, VERR_INVALID_POINTER);
2018 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
2019
2020 int rc;
2021 do
2022 {
2023 HGCMMsgFileOpen Msg;
2024 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2025 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_OPEN);
2026 VbglHGCMParmPtrSet(&Msg.filename, pszFileName, cbFileName);
2027 VbglHGCMParmPtrSet(&Msg.openmode, pszAccess, cbAccess);
2028 VbglHGCMParmPtrSet(&Msg.disposition, pszDisposition, cbDisposition);
2029 VbglHGCMParmPtrSet(&Msg.sharing, pszSharing, cbSharing);
2030 VbglHGCMParmUInt32Set(&Msg.creationmode, 0);
2031 VbglHGCMParmUInt64Set(&Msg.offset, 0);
2032
2033 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2034 if (RT_SUCCESS(rc))
2035 {
2036 Msg.context.GetUInt32(&pCtx->uContextID);
2037 Msg.creationmode.GetUInt32(puCreationMode);
2038 Msg.offset.GetUInt64(poffAt);
2039 }
2040 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2041 return rc;
2042}
2043
2044
2045/**
2046 * Retrieves a HOST_FILE_CLOSE message.
2047 */
2048VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
2049{
2050 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2051
2052 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
2053 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2054
2055 int rc;
2056 do
2057 {
2058 HGCMMsgFileClose Msg;
2059 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2060 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_CLOSE);
2061 VbglHGCMParmUInt32Set(&Msg.handle, 0);
2062
2063 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2064 if (RT_SUCCESS(rc))
2065 {
2066 Msg.context.GetUInt32(&pCtx->uContextID);
2067 Msg.handle.GetUInt32(puHandle);
2068 }
2069 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2070 return rc;
2071}
2072
2073
2074/**
2075 * Retrieves a HOST_FILE_READ message.
2076 */
2077VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead)
2078{
2079 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2080
2081 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
2082 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2083 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
2084
2085 int rc;
2086 do
2087 {
2088 HGCMMsgFileRead Msg;
2089 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2090 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ);
2091 VbglHGCMParmUInt32Set(&Msg.handle, 0);
2092 VbglHGCMParmUInt32Set(&Msg.size, 0);
2093
2094 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2095 if (RT_SUCCESS(rc))
2096 {
2097 Msg.context.GetUInt32(&pCtx->uContextID);
2098 Msg.handle.GetUInt32(puHandle);
2099 Msg.size.GetUInt32(puToRead);
2100 }
2101 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2102 return rc;
2103}
2104
2105
2106/**
2107 * Retrieves a HOST_FILE_READ_AT message.
2108 */
2109VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLCMDCTX pCtx,
2110 uint32_t *puHandle, uint32_t *puToRead, uint64_t *poffAt)
2111{
2112 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2113
2114 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
2115 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2116 AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
2117
2118 int rc;
2119 do
2120 {
2121 HGCMMsgFileReadAt Msg;
2122 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2123 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_READ_AT);
2124 VbglHGCMParmUInt32Set(&Msg.handle, 0);
2125 VbglHGCMParmUInt64Set(&Msg.offset, 0);
2126 VbglHGCMParmUInt32Set(&Msg.size, 0);
2127
2128 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2129 if (RT_SUCCESS(rc))
2130 {
2131 Msg.context.GetUInt32(&pCtx->uContextID);
2132 Msg.handle.GetUInt32(puHandle);
2133 Msg.offset.GetUInt64(poffAt);
2134 Msg.size.GetUInt32(puToRead);
2135 }
2136 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2137 return rc;
2138}
2139
2140
2141/**
2142 * Retrieves a HOST_FILE_WRITE message.
2143 */
2144VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
2145 void *pvData, uint32_t cbData, uint32_t *pcbSize)
2146{
2147 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2148
2149 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
2150 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2151 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
2152 AssertReturn(cbData, VERR_INVALID_PARAMETER);
2153 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
2154
2155 int rc;
2156 do
2157 {
2158 HGCMMsgFileWrite Msg;
2159 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2160 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE);
2161 VbglHGCMParmUInt32Set(&Msg.handle, 0);
2162 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
2163 VbglHGCMParmUInt32Set(&Msg.size, 0);
2164
2165 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2166 if (RT_SUCCESS(rc))
2167 {
2168 Msg.context.GetUInt32(&pCtx->uContextID);
2169 Msg.handle.GetUInt32(puHandle);
2170 Msg.size.GetUInt32(pcbSize);
2171 }
2172 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2173
2174 if ( rc != VERR_TOO_MUCH_DATA
2175 || g_fVbglR3GuestCtrlHavePeekGetCancel)
2176 return rc;
2177 return VERR_BUFFER_OVERFLOW;
2178}
2179
2180
2181/**
2182 * Retrieves a HOST_FILE_WRITE_AT message.
2183 */
2184VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle,
2185 void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *poffAt)
2186{
2187 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2188
2189 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
2190 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2191 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
2192 AssertReturn(cbData, VERR_INVALID_PARAMETER);
2193 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
2194
2195 int rc;
2196 do
2197 {
2198 HGCMMsgFileWriteAt Msg;
2199 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2200 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_WRITE_AT);
2201 VbglHGCMParmUInt32Set(&Msg.handle, 0);
2202 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
2203 VbglHGCMParmUInt32Set(&Msg.size, 0);
2204 VbglHGCMParmUInt64Set(&Msg.offset, 0);
2205
2206 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2207 if (RT_SUCCESS(rc))
2208 {
2209 Msg.context.GetUInt32(&pCtx->uContextID);
2210 Msg.handle.GetUInt32(puHandle);
2211 Msg.size.GetUInt32(pcbSize);
2212 Msg.offset.GetUInt64(poffAt);
2213 }
2214 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2215
2216 if ( rc != VERR_TOO_MUCH_DATA
2217 || g_fVbglR3GuestCtrlHavePeekGetCancel)
2218 return rc;
2219 return VERR_BUFFER_OVERFLOW;
2220}
2221
2222
2223/**
2224 * Retrieves a HOST_FILE_SEEK message.
2225 */
2226VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLCMDCTX pCtx,
2227 uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *poffAt)
2228{
2229 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2230
2231 AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
2232 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2233 AssertPtrReturn(puSeekMethod, VERR_INVALID_POINTER);
2234 AssertPtrReturn(poffAt, VERR_INVALID_POINTER);
2235
2236 int rc;
2237 do
2238 {
2239 HGCMMsgFileSeek Msg;
2240 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2241 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_SEEK);
2242 VbglHGCMParmUInt32Set(&Msg.handle, 0);
2243 VbglHGCMParmUInt32Set(&Msg.method, 0);
2244 VbglHGCMParmUInt64Set(&Msg.offset, 0);
2245
2246 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2247 if (RT_SUCCESS(rc))
2248 {
2249 Msg.context.GetUInt32(&pCtx->uContextID);
2250 Msg.handle.GetUInt32(puHandle);
2251 Msg.method.GetUInt32(puSeekMethod);
2252 Msg.offset.GetUInt64(poffAt);
2253 }
2254 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2255 return rc;
2256}
2257
2258
2259/**
2260 * Retrieves a HOST_FILE_TELL message.
2261 */
2262VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
2263{
2264 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2265
2266 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
2267 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2268
2269 int rc;
2270 do
2271 {
2272 HGCMMsgFileTell Msg;
2273 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2274 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_TELL);
2275 VbglHGCMParmUInt32Set(&Msg.handle, 0);
2276
2277 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2278 if (RT_SUCCESS(rc))
2279 {
2280 Msg.context.GetUInt32(&pCtx->uContextID);
2281 Msg.handle.GetUInt32(puHandle);
2282 }
2283 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2284 return rc;
2285}
2286
2287
2288/**
2289 * Retrieves a HOST_FILE_SET_SIZE message.
2290 */
2291VBGLR3DECL(int) VbglR3GuestCtrlFileGetSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint64_t *pcbNew)
2292{
2293 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2294
2295 AssertReturn(pCtx->uNumParms == 3, VERR_INVALID_PARAMETER);
2296 AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
2297 AssertPtrReturn(pcbNew, VERR_INVALID_POINTER);
2298
2299 int rc;
2300 do
2301 {
2302 HGCMMsgFileSetSize Msg;
2303 VBGL_HGCM_HDR_INIT(&Msg.Hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2304 VbglHGCMParmUInt32Set(&Msg.id32Context, HOST_MSG_FILE_SET_SIZE);
2305 VbglHGCMParmUInt32Set(&Msg.id32Handle, 0);
2306 VbglHGCMParmUInt64Set(&Msg.cb64NewSize, 0);
2307
2308 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
2309 if (RT_SUCCESS(rc))
2310 {
2311 Msg.id32Context.GetUInt32(&pCtx->uContextID);
2312 Msg.id32Handle.GetUInt32(puHandle);
2313 Msg.cb64NewSize.GetUInt64(pcbNew);
2314 }
2315 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2316 return rc;
2317}
2318
2319
2320#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
2321VBGLR3DECL(int) VbglR3GuestCtrlFileGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszFileName, uint32_t cbFileName)
2322{
2323 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2324
2325 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
2326 AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
2327 AssertReturn(cbFileName, VERR_INVALID_PARAMETER);
2328
2329 int rc;
2330 do
2331 {
2332 HGCMMsgFileRemove Msg;
2333 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2334 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_REMOVE);
2335 VbglHGCMParmPtrSet(&Msg.filename, pszFileName, cbFileName);
2336
2337 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2338 if (RT_SUCCESS(rc))
2339 {
2340 Msg.context.GetUInt32(&pCtx->uContextID);
2341 }
2342 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2343 return rc;
2344}
2345#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
2346
2347
2348/**
2349 * Retrieves a HOST_EXEC_TERMINATE message.
2350 */
2351VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID)
2352{
2353 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2354
2355 AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
2356 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
2357
2358 int rc;
2359 do
2360 {
2361 HGCMMsgProcTerminate Msg;
2362 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2363 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_TERMINATE);
2364 VbglHGCMParmUInt32Set(&Msg.pid, 0);
2365
2366 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2367 if (RT_SUCCESS(rc))
2368 {
2369 Msg.context.GetUInt32(&pCtx->uContextID);
2370 Msg.pid.GetUInt32(puPID);
2371 }
2372 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2373 return rc;
2374}
2375
2376
2377/**
2378 * Retrieves a HOST_EXEC_WAIT_FOR message.
2379 */
2380VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLCMDCTX pCtx,
2381 uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS)
2382{
2383 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2384
2385 AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
2386 AssertPtrReturn(puPID, VERR_INVALID_POINTER);
2387
2388 int rc;
2389 do
2390 {
2391 HGCMMsgProcWaitFor Msg;
2392 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
2393 VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_EXEC_WAIT_FOR);
2394 VbglHGCMParmUInt32Set(&Msg.pid, 0);
2395 VbglHGCMParmUInt32Set(&Msg.flags, 0);
2396 VbglHGCMParmUInt32Set(&Msg.timeout, 0);
2397
2398 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2399 if (RT_SUCCESS(rc))
2400 {
2401 Msg.context.GetUInt32(&pCtx->uContextID);
2402 Msg.pid.GetUInt32(puPID);
2403 Msg.flags.GetUInt32(puWaitFlags);
2404 Msg.timeout.GetUInt32(puTimeoutMS);
2405 }
2406 } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
2407 return rc;
2408}
2409
2410
2411/*********************************************************************************************************************************
2412 * Directory callbacks *
2413 ********************************************************************************************************************************/
2414
2415#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
2416/**
2417 * Replies to a HOST_MSG_DIR_OPEN message.
2418 *
2419 * @returns VBox status code.
2420 * @param pCtx Guest control command context to use.
2421 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2422 * @param uDirHandle Directory handle of opened directory.
2423 */
2424VBGLR3DECL(int) VbglR3GuestCtrlDirCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uDirHandle)
2425{
2426 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2427
2428 HGCMReplyDirNotify Msg;
2429 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS + 1);
2430 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2431 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_OPEN);
2432 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2433
2434 VbglHGCMParmUInt32Set(&Msg.u.open.handle, uDirHandle);
2435
2436 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u.open));
2437}
2438
2439
2440/**
2441 * Replies to a HOST_MSG_DIR_CLOSE message.
2442 *
2443 * @returns VBox status code.
2444 * @param pCtx Guest control command context to use.
2445 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2446 */
2447VBGLR3DECL(int) VbglR3GuestCtrlDirCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
2448{
2449 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2450
2451 HGCMReplyDirNotify Msg;
2452 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS);
2453 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2454 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_CLOSE);
2455 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2456
2457 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, reply_hdr));
2458}
2459
2460
2461/**
2462 * Replies to a HOST_MSG_DIR_READ message, extended version.
2463 *
2464 * @returns VBox status code.
2465 * @param pCtx Guest control command context to use.
2466 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2467 * @param pEntry Directory entry to send.
2468 * @param cbSize Size (in bytes) of the OFFSET(GSTCTLDIRENTRYEX, szName[pEntry->cbName + 1]).
2469 * See RTDirReadEx() for more information.
2470 * @param pszUser Associated user ID (owner, uid) as a string.
2471 * @param pszGroups Associated user groups as a string.
2472 * Multiple groups are delimited by GSTCTL_DIRENTRY_GROUPS_DELIMITER_STR,
2473 * whereas the first group always is the primary group.
2474 */
2475VBGLR3DECL(int) VbglR3GuestCtrlDirCbReadEx(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLDIRENTRYEX pEntry, uint32_t cbSize,
2476 const char *pszUser, const char *pszGroups)
2477{
2478 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2479
2480 HGCMReplyDirNotify Msg;
2481 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS + 3);
2482 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2483 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_READ);
2484 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2485
2486 VbglHGCMParmPtrSet (&Msg.u.read.entry, pEntry, cbSize);
2487 VbglHGCMParmPtrSetString(&Msg.u.read.user, pszUser);
2488 VbglHGCMParmPtrSetString(&Msg.u.read.groups, pszGroups);
2489
2490 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u.read));
2491}
2492
2493
2494/**
2495 * Replies to a HOST_MSG_DIR_READ message.
2496 *
2497 * @returns VBox status code.
2498 * @param pCtx Guest control command context to use.
2499 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2500 * @param pEntry Directory entry to send.
2501 * @param cbSize Size (in bytes) of the OFFSET(GSTCTLDIRENTRYEX, szName[pEntry->cbName + 1]).
2502 * See RTDirReadEx() for more information.
2503 */
2504VBGLR3DECL(int) VbglR3GuestCtrlDirCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLDIRENTRYEX pEntry, uint32_t cbSize)
2505{
2506 char szIgnored[1] = { 0 };
2507 return VbglR3GuestCtrlDirCbReadEx(pCtx, uRc, pEntry, cbSize, szIgnored /* pszUser */, szIgnored /* pszGroups */);
2508}
2509
2510
2511/**
2512 * Replies to a HOST_MSG_DIR_REWIND message.
2513 *
2514 * @returns VBox status code.
2515 * @param pCtx Guest control command context to use.
2516 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2517 */
2518VBGLR3DECL(int) VbglR3GuestCtrlDirCbRewind(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
2519{
2520 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2521
2522 HGCMReplyDirNotify Msg;
2523 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS);
2524 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2525 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_REWIND);
2526 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2527
2528 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u));
2529}
2530
2531
2532/**
2533 * Replies to a HOST_MSG_DIR_LIST message.
2534 *
2535 * @returns VBox status code.
2536 * @param pCtx Guest control command context to use.
2537 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2538 * @þaram cEntries Number of directory entries to send.
2539 * @param pvBuf Buffer of directory entries to send.
2540 * @param cbBuf Size (in bytes) of \a pvBuf.
2541 */
2542VBGLR3DECL(int) VbglR3GuestCtrlDirCbList(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc,
2543 uint32_t cEntries, void *pvBuf, uint32_t cbBuf)
2544{
2545 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2546
2547 HGCMReplyDirNotify Msg;
2548 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS + 2);
2549 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2550 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_LIST);
2551 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2552
2553 VbglHGCMParmUInt32Set(&Msg.u.list.num_entries, cEntries);
2554 VbglHGCMParmPtrSet(&Msg.u.list.buffer, pvBuf, cbBuf);
2555
2556 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u.list));
2557}
2558#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
2559
2560
2561/*********************************************************************************************************************************
2562 * File callbacks *
2563 ********************************************************************************************************************************/
2564
2565/**
2566 * Replies to a HOST_MSG_FILE_OPEN message.
2567 *
2568 * @returns VBox status code.
2569 * @param pCtx Guest control command context to use.
2570 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2571 * @param uFileHandle File handle of opened file on success.
2572 */
2573VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx,
2574 uint32_t uRc, uint32_t uFileHandle)
2575{
2576 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2577
2578 HGCMReplyFileNotify Msg;
2579 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
2580 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2581 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_OPEN);
2582 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2583 VbglHGCMParmUInt32Set(&Msg.u.open.handle, uFileHandle);
2584
2585 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.open));
2586}
2587
2588
2589/**
2590 * Replies to a HOST_MSG_FILE_CLOSE message.
2591 *
2592 * @returns VBox status code.
2593 * @param pCtx Guest control command context to use.
2594 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2595 */
2596VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx,
2597 uint32_t uRc)
2598{
2599 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2600
2601 HGCMReplyFileNotify Msg;
2602 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
2603 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2604 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_CLOSE);
2605 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2606
2607 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
2608}
2609
2610
2611/**
2612 * Sends an unexpected file handling error to the host.
2613 *
2614 * @returns VBox status code.
2615 * @param pCtx Guest control command context to use.
2616 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2617 */
2618VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
2619{
2620 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2621
2622 HGCMReplyFileNotify Msg;
2623 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 3);
2624 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2625 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_ERROR);
2626 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2627
2628 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSETOF(HGCMReplyFileNotify, u));
2629}
2630
2631
2632/**
2633 * Replies to a HOST_MSG_FILE_READ message.
2634 *
2635 * @returns VBox status code.
2636 * @param pCtx Guest control command context to use.
2637 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2638 * @param pvData Pointer to read file data from guest on success.
2639 * @param cbData Size (in bytes) of read file data from guest on success.
2640 */
2641VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx,
2642 uint32_t uRc,
2643 void *pvData, uint32_t cbData)
2644{
2645 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2646
2647 HGCMReplyFileNotify Msg;
2648 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
2649 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2650 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_READ);
2651 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2652 VbglHGCMParmPtrSet(&Msg.u.read.data, pvData, cbData);
2653
2654 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.read));
2655}
2656
2657
2658/**
2659 * Replies to a HOST_MSG_FILE_READ_AT message.
2660 *
2661 * @returns VBox status code.
2662 * @param pCtx Guest control command context to use.
2663 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2664 * @param pvData Pointer to read file data from guest on success.
2665 * @param cbData Size (in bytes) of read file data from guest on success.
2666 * @param offNew New offset (in bytes) the guest file pointer points at on success.
2667 */
2668VBGLR3DECL(int) VbglR3GuestCtrlFileCbReadOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc,
2669 void *pvData, uint32_t cbData, int64_t offNew)
2670{
2671 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2672
2673 HGCMReplyFileNotify Msg;
2674 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 5);
2675 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2676 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_READ_OFFSET);
2677 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2678 VbglHGCMParmPtrSet(&Msg.u.ReadOffset.pvData, pvData, cbData);
2679 VbglHGCMParmUInt64Set(&Msg.u.ReadOffset.off64New, (uint64_t)offNew);
2680
2681 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.ReadOffset));
2682}
2683
2684
2685/**
2686 * Replies to a HOST_MSG_FILE_WRITE message.
2687 *
2688 * @returns VBox status code.
2689 * @param pCtx Guest control command context to use.
2690 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2691 * @param cbWritten Size (in bytes) of file data successfully written to guest file. Can be partial.
2692 */
2693VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten)
2694{
2695 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2696
2697 HGCMReplyFileNotify Msg;
2698 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
2699 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2700 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_WRITE);
2701 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2702 VbglHGCMParmUInt32Set(&Msg.u.write.written, cbWritten);
2703
2704 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.write));
2705}
2706
2707
2708/**
2709 * Replies to a HOST_MSG_FILE_WRITE_AT message.
2710 *
2711 * @returns VBox status code.
2712 * @param pCtx Guest control command context to use.
2713 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2714 * @param cbWritten Size (in bytes) of file data successfully written to guest file. Can be partial.
2715 * @param offNew New offset (in bytes) the guest file pointer points at on success.
2716 */
2717VBGLR3DECL(int) VbglR3GuestCtrlFileCbWriteOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten, int64_t offNew)
2718{
2719 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2720
2721 HGCMReplyFileNotify Msg;
2722 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 5);
2723 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2724 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_WRITE_OFFSET);
2725 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2726 VbglHGCMParmUInt32Set(&Msg.u.WriteOffset.cb32Written, cbWritten);
2727 VbglHGCMParmUInt64Set(&Msg.u.WriteOffset.off64New, (uint64_t)offNew);
2728
2729 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.WriteOffset));
2730}
2731
2732
2733/**
2734 * Replies to a HOST_MSG_FILE_SEEK message.
2735 *
2736 * @returns VBox status code.
2737 * @param pCtx Guest control command context to use.
2738 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2739 * @param offCurrent New offset (in bytes) the guest file pointer points at on success.
2740 */
2741VBGLR3DECL(int) VbglR3GuestCtrlFileCbSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t offCurrent)
2742{
2743 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2744
2745 HGCMReplyFileNotify Msg;
2746 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
2747 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2748 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_SEEK);
2749 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2750 VbglHGCMParmUInt64Set(&Msg.u.seek.offset, offCurrent);
2751
2752 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.seek));
2753}
2754
2755
2756/**
2757 * Replies to a HOST_MSG_FILE_TELL message.
2758 *
2759 * @returns VBox status code.
2760 * @param pCtx Guest control command context to use.
2761 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2762 * @param offCurrent Current offset (in bytes) the guest file pointer points at on success.
2763 */
2764VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t offCurrent)
2765{
2766 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2767
2768 HGCMReplyFileNotify Msg;
2769 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
2770 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2771 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_TELL);
2772 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2773 VbglHGCMParmUInt64Set(&Msg.u.tell.offset, offCurrent);
2774
2775 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.tell));
2776}
2777
2778
2779/**
2780 * Replies to a HOST_MSG_FILE_SET_SIZE message.
2781 *
2782 * @returns VBox status code.
2783 * @param pCtx Guest control command context to use.
2784 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2785 * @param cbNew New file size (in bytes) of the guest file on success.
2786 */
2787VBGLR3DECL(int) VbglR3GuestCtrlFileCbSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t cbNew)
2788{
2789 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2790
2791 HGCMReplyFileNotify Msg;
2792 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_FILE_NOTIFY, 4);
2793 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2794 VbglHGCMParmUInt32Set(&Msg.type, GUEST_FILE_NOTIFYTYPE_SET_SIZE);
2795 VbglHGCMParmUInt32Set(&Msg.rc, uRc);
2796 VbglHGCMParmUInt64Set(&Msg.u.SetSize.cb64Size, cbNew);
2797
2798 return VbglR3HGCMCall(&Msg.hdr, RT_UOFFSET_AFTER(HGCMReplyFileNotify, u.SetSize));
2799}
2800
2801
2802/*********************************************************************************************************************************
2803 * File system callbacks *
2804 ********************************************************************************************************************************/
2805
2806#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
2807/**
2808 * Replies to a HOST_MSG_FS_OBJ_QUERY_INFO message, extended version.
2809 *
2810 * @returns VBox status code.
2811 * @param pCtx Guest control command context to use.
2812 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2813 * @param pFsObjInfo Guest file system object information to send.
2814 * @param pszUser Associated user ID (owner, uid) as a string.
2815 * @param pszGroups Associated user groups as a string.
2816 * Multiple groups are delimited by GSTCTL_DIRENTRY_GROUPS_DELIMITER_STR,
2817 * whereas the first group always is the primary group.
2818 */
2819VBGLR3DECL(int) VbglR3GuestCtrlFsObjCbQueryInfoEx(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLFSOBJINFO pFsObjInfo,
2820 const char *pszUser, const char *pszGroups)
2821{
2822 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2823 AssertPtrReturn(pFsObjInfo, VERR_INVALID_POINTER);
2824 AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
2825 AssertPtrReturn(pszGroups, VERR_INVALID_POINTER);
2826
2827 HGCMReplyFsNotify Msg;
2828 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_FS_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS + 3);
2829 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2830 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_FS_NOTIFYTYPE_QUERY_OBJ_INFO);
2831 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2832
2833 VbglHGCMParmPtrSet (&Msg.u.queryobjinfo.obj_info, pFsObjInfo, sizeof(GSTCTLFSOBJINFO));
2834 VbglHGCMParmPtrSetString(&Msg.u.queryobjinfo.user, pszUser);
2835 VbglHGCMParmPtrSetString(&Msg.u.queryobjinfo.groups, pszGroups);
2836
2837 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyFsNotify, u.queryobjinfo));
2838}
2839
2840
2841/**
2842 * Replies to a HOST_MSG_FS_OBJ_QUERY_INFO message.
2843 *
2844 * @returns VBox status code.
2845 * @param pCtx Guest control command context to use.
2846 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2847 * @param pFsObjInfo Guest file system object information to send.
2848 */
2849VBGLR3DECL(int) VbglR3GuestCtrlFsObjCbQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLFSOBJINFO pFsObjInfo)
2850{
2851 char szIgnored[1] = { 0 };
2852 return VbglR3GuestCtrlFsObjCbQueryInfoEx(pCtx, uRc, pFsObjInfo, szIgnored /* pszUser */, szIgnored /* pszGroups */);
2853}
2854
2855
2856/**
2857 * Replies to a HOST_MSG_FS_CREATE_TEMP message.
2858 *
2859 * @returns VBox status code.
2860 * @param pCtx Guest control command context to use.
2861 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2862 * @param pszPath Path of created temporary file / directory, if \a uRc marks a success.
2863 * Specify an empty path on failure -- NULL is not allowed!
2864 */
2865VBGLR3DECL(int) VbglR3GuestCtrlFsCbCreateTemp(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, const char *pszPath)
2866{
2867 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2868 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
2869
2870 HGCMReplyFsNotify Msg;
2871 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_FS_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS + 1);
2872 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2873 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_FS_NOTIFYTYPE_CREATE_TEMP);
2874 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2875
2876 VbglHGCMParmPtrSetString(&Msg.u.createtemp.path, pszPath);
2877
2878 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyFsNotify, u.createtemp));
2879}
2880
2881/**
2882 * Replies to a HOST_MSG_FS_QUERY_INFO message.
2883 *
2884 * @returns VBox status code.
2885 * @param pCtx Guest control command context to use.
2886 * @param uRc Guest rc of operation (note: IPRT-style signed int).
2887 * @param pFsInfo File system information to return.
2888 * @param cbFsInfo Size (in bytes) of \a pFsInfo.
2889 */
2890VBGLR3DECL(int) VbglR3GuestCtrlFsCbQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLFSINFO pFsInfo, uint32_t cbFsInfo)
2891{
2892 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2893 AssertPtrReturn(pFsInfo, VERR_INVALID_POINTER);
2894 AssertReturn(cbFsInfo, VERR_INVALID_PARAMETER);
2895
2896 HGCMReplyFsNotify Msg;
2897 VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_FS_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS + 1);
2898 VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
2899 VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_FS_NOTIFYTYPE_QUERY_INFO);
2900 VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
2901
2902 VbglHGCMParmPtrSet(&Msg.u.queryinfo.fs_info, pFsInfo, cbFsInfo);
2903
2904 return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyFsNotify, u.queryinfo));
2905}
2906#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
2907
2908
2909/*********************************************************************************************************************************
2910 * Process callbacks *
2911 ********************************************************************************************************************************/
2912
2913/**
2914 * Callback for reporting a guest process status (along with some other stuff) to the host.
2915 *
2916 * @returns VBox status code.
2917 * @param pCtx Guest control command context to use.
2918 * @param uPID Guest process PID to report status for.
2919 * @param uStatus Status to report. Of type PROC_STS_XXX.
2920 * @param fFlags Additional status flags, depending on the reported status. See RTPROCSTATUS.
2921 * @param pvData Pointer to additional status data. Optional.
2922 * @param cbData Size (in bytes) of additional status data.
2923 */
2924VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx,
2925 uint32_t uPID, uint32_t uStatus, uint32_t fFlags,
2926 void *pvData, uint32_t cbData)
2927{
2928 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2929
2930 HGCMMsgProcStatus Msg;
2931 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_STATUS, 5);
2932 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2933 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
2934 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
2935 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
2936 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
2937
2938 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2939}
2940
2941
2942/**
2943 * Sends output (from stdout/stderr) from a running process.
2944 *
2945 * @returns VBox status code.
2946 * @param pCtx Guest control command context to use.
2947 * @param uPID Guest process PID to report status for.
2948 * @param uHandle Guest process handle the output belong to.
2949 * @param fFlags Additional output flags.
2950 * @param pvData Pointer to actual output data.
2951 * @param cbData Size (in bytes) of output data.
2952 */
2953VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx,
2954 uint32_t uPID,uint32_t uHandle, uint32_t fFlags,
2955 void *pvData, uint32_t cbData)
2956{
2957 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2958
2959 HGCMMsgProcOutput Msg;
2960 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_OUTPUT, 5);
2961 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2962 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
2963 VbglHGCMParmUInt32Set(&Msg.handle, uHandle);
2964 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
2965 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
2966
2967 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2968}
2969
2970
2971/**
2972 * Callback for reporting back the input status of a guest process to the host.
2973 *
2974 * @returns VBox status code.
2975 * @param pCtx Guest control command context to use.
2976 * @param uPID Guest process PID to report status for.
2977 * @param uStatus Status to report. Of type INPUT_STS_XXX.
2978 * @param fFlags Additional input flags.
2979 * @param cbWritten Size (in bytes) of input data handled.
2980 */
2981VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx,
2982 uint32_t uPID, uint32_t uStatus,
2983 uint32_t fFlags, uint32_t cbWritten)
2984{
2985 AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
2986
2987 HGCMMsgProcStatusInput Msg;
2988 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_MSG_EXEC_INPUT_STATUS, 5);
2989 VbglHGCMParmUInt32Set(&Msg.context, pCtx->uContextID);
2990 VbglHGCMParmUInt32Set(&Msg.pid, uPID);
2991 VbglHGCMParmUInt32Set(&Msg.status, uStatus);
2992 VbglHGCMParmUInt32Set(&Msg.flags, fFlags);
2993 VbglHGCMParmUInt32Set(&Msg.written, cbWritten);
2994
2995 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
2996}
2997
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use