VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp@ 38114

Last change on this file since 38114 was 37375, checked in by vboxsync, 14 years ago

GuestCtrl: Added APIs for guest directory enumeration, guest file existence and copy from guest support, some API renaming/cleanup (work in progress).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.0 KB
Line 
1/* $Id: VBoxGuestR3LibGuestCtrl.cpp 37375 2011-06-08 10:51:26Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest control.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <iprt/string.h>
32#include <iprt/mem.h>
33#include <iprt/assert.h>
34#include <iprt/cpp/autores.h>
35#include <iprt/stdarg.h>
36#include <VBox/log.h>
37#include <VBox/HostServices/GuestControlSvc.h>
38
39#include "VBGLR3Internal.h"
40
41
42/*******************************************************************************
43* Structures and Typedefs *
44*******************************************************************************/
45
46using namespace guestControl;
47
48/**
49 * Connects to the guest control service.
50 *
51 * @returns VBox status code
52 * @param pu32ClientId Where to put the client id on success. The client id
53 * must be passed to all the other calls to the service.
54 */
55VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pu32ClientId)
56{
57 VBoxGuestHGCMConnectInfo Info;
58 Info.result = VERR_WRONG_ORDER;
59 Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
60 RT_ZERO(Info.Loc.u);
61 strcpy(Info.Loc.u.host.achName, "VBoxGuestControlSvc");
62 Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */
63
64 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
65 if (RT_SUCCESS(rc))
66 {
67 rc = Info.result;
68 if (RT_SUCCESS(rc))
69 *pu32ClientId = Info.u32ClientID;
70 }
71 return rc;
72}
73
74
75/**
76 * Disconnect from the guest control service.
77 *
78 * @returns VBox status code.
79 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
80 */
81VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId)
82{
83 VBoxGuestHGCMDisconnectInfo Info;
84 Info.result = VERR_WRONG_ORDER;
85 Info.u32ClientID = u32ClientId;
86
87 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
88 if (RT_SUCCESS(rc))
89 rc = Info.result;
90 return rc;
91}
92
93
94/**
95 * Waits until a new host message arrives.
96 * This will block until a message becomes available.
97 *
98 * @returns VBox status code.
99 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
100 * @param puMsg Where to store the message id.
101 * @param puNumParms Where to store the number of parameters which will be received
102 * in a second call to the host.
103 */
104VBGLR3DECL(int) VbglR3GuestCtrlWaitForHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms)
105{
106 AssertPtrReturn(puMsg, VERR_INVALID_PARAMETER);
107 AssertPtrReturn(puNumParms, VERR_INVALID_PARAMETER);
108
109 VBoxGuestCtrlHGCMMsgType Msg;
110
111 Msg.hdr.result = VERR_WRONG_ORDER;
112 Msg.hdr.u32ClientID = u32ClientId;
113 Msg.hdr.u32Function = GUEST_GET_HOST_MSG; /* Tell the host we want our next command. */
114 Msg.hdr.cParms = 2; /* Just peek for the next message! */
115
116 VbglHGCMParmUInt32Set(&Msg.msg, 0);
117 VbglHGCMParmUInt32Set(&Msg.num_parms, 0);
118
119 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
120 if (RT_SUCCESS(rc))
121 {
122 rc = VbglHGCMParmUInt32Get(&Msg.msg, puMsg);
123 if (RT_SUCCESS(rc))
124 rc = VbglHGCMParmUInt32Get(&Msg.num_parms, puNumParms);
125 if (RT_SUCCESS(rc))
126 rc = Msg.hdr.result;
127 /* Ok, so now we know what message type and how much parameters there are. */
128 }
129 return rc;
130}
131
132
133/**
134 * Asks the host to cancel (release) all pending waits which were deferred.
135 *
136 * @returns VBox status code.
137 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
138 */
139VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId)
140{
141 VBoxGuestCtrlHGCMMsgCancelPendingWaits Msg;
142
143 Msg.hdr.result = VERR_WRONG_ORDER;
144 Msg.hdr.u32ClientID = u32ClientId;
145 Msg.hdr.u32Function = GUEST_CANCEL_PENDING_WAITS;
146 Msg.hdr.cParms = 0;
147
148 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
149 if (RT_SUCCESS(rc))
150 {
151 int rc2 = Msg.hdr.result;
152 if (RT_FAILURE(rc2))
153 rc = rc2;
154 }
155 return rc;
156}
157
158
159/**
160 * Closes a formerly opened guest directory.
161 *
162 * @return IPRT status code.
163 ** @todo Docs!
164 */
165VBGLR3DECL(int) VbglR3GuestCtrlGetCmdDirClose(uint32_t u32ClientId, uint32_t uNumParms,
166 uint32_t *puContext, uint32_t *puHandle)
167{
168 AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
169 AssertPtrReturn(puHandle, VERR_INVALID_PARAMETER);
170
171 VBoxGuestCtrlHGCMMsgDirClose Msg;
172
173 Msg.hdr.result = VERR_WRONG_ORDER;
174 Msg.hdr.u32ClientID = u32ClientId;
175 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
176 Msg.hdr.cParms = uNumParms;
177
178 VbglHGCMParmUInt32Set(&Msg.context, 0);
179 VbglHGCMParmUInt32Set(&Msg.handle, 0);
180
181 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
182 if (RT_SUCCESS(rc))
183 {
184 int rc2 = Msg.hdr.result;
185 if (RT_FAILURE(rc2))
186 {
187 rc = rc2;
188 }
189 else
190 {
191 Msg.context.GetUInt32(puContext);
192 Msg.handle.GetUInt32(puHandle);
193 }
194 }
195 return rc;
196}
197
198
199/**
200 * Opens a guest directory for reading.
201 *
202 * @return IPRT status code.
203 ** @todo Docs!
204 */
205VBGLR3DECL(int) VbglR3GuestCtrlGetCmdDirOpen(uint32_t u32ClientId, uint32_t uNumParms,
206 uint32_t *puContext,
207 char *pszDir, uint32_t cbDir,
208 char *pszFilter, uint32_t cbFilter,
209 uint32_t *puFlags,
210 char *pszUser, uint32_t cbUser,
211 char *pszPassword, uint32_t cbPassword)
212{
213 AssertPtrReturn(pszDir, VERR_INVALID_PARAMETER);
214 AssertPtrReturn(pszFilter, VERR_INVALID_PARAMETER);
215 AssertPtrReturn(puFlags, VERR_INVALID_PARAMETER);
216 AssertPtrReturn(pszUser, VERR_INVALID_PARAMETER);
217 AssertPtrReturn(pszPassword, VERR_INVALID_PARAMETER);
218
219 VBoxGuestCtrlHGCMMsgDirOpen Msg;
220
221 Msg.hdr.result = VERR_WRONG_ORDER;
222 Msg.hdr.u32ClientID = u32ClientId;
223 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
224 Msg.hdr.cParms = uNumParms;
225
226 VbglHGCMParmUInt32Set(&Msg.context, 0);
227 VbglHGCMParmPtrSet(&Msg.directory, pszDir, cbDir);
228 VbglHGCMParmPtrSet(&Msg.filter, pszFilter, cbFilter);
229 VbglHGCMParmUInt32Set(&Msg.flags, 0);
230 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
231 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
232
233 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
234 if (RT_SUCCESS(rc))
235 {
236 int rc2 = Msg.hdr.result;
237 if (RT_FAILURE(rc2))
238 {
239 rc = rc2;
240 }
241 else
242 {
243 Msg.context.GetUInt32(puContext);
244 Msg.flags.GetUInt32(puFlags);
245 }
246 }
247 return rc;
248}
249
250
251/**
252 * Opens a guest directory for reading.
253 *
254 * @return IPRT status code.
255 ** @todo Docs!
256 */
257VBGLR3DECL(int) VbglR3GuestCtrlGetCmdDirRead(uint32_t u32ClientId, uint32_t uNumParms,
258 uint32_t *puContext, uint32_t *puHandle)
259{
260 AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
261 AssertPtrReturn(puHandle, VERR_INVALID_PARAMETER);
262
263 VBoxGuestCtrlHGCMMsgDirRead Msg;
264
265 Msg.hdr.result = VERR_WRONG_ORDER;
266 Msg.hdr.u32ClientID = u32ClientId;
267 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
268 Msg.hdr.cParms = uNumParms;
269
270 VbglHGCMParmUInt32Set(&Msg.context, 0);
271 VbglHGCMParmUInt32Set(&Msg.handle, 0);
272
273 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
274 if (RT_SUCCESS(rc))
275 {
276 int rc2 = Msg.hdr.result;
277 if (RT_FAILURE(rc2))
278 {
279 rc = rc2;
280 }
281 else
282 {
283 Msg.context.GetUInt32(puContext);
284 Msg.handle.GetUInt32(puHandle);
285 }
286 }
287 return rc;
288}
289
290
291/**
292 * Allocates and gets host data, based on the message id.
293 *
294 * This will block until data becomes available.
295 *
296 * @returns VBox status code.
297 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
298 * @param uNumParms
299 ** @todo Docs!
300 */
301VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t uNumParms,
302 uint32_t *puContext,
303 char *pszCmd, uint32_t cbCmd,
304 uint32_t *puFlags,
305 char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs,
306 char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars,
307 char *pszUser, uint32_t cbUser,
308 char *pszPassword, uint32_t cbPassword,
309 uint32_t *puTimeLimit)
310{
311 AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
312 AssertPtrReturn(pszCmd, VERR_INVALID_PARAMETER);
313 AssertPtrReturn(puFlags, VERR_INVALID_PARAMETER);
314 AssertPtrReturn(pszArgs, VERR_INVALID_PARAMETER);
315 AssertPtrReturn(puNumArgs, VERR_INVALID_PARAMETER);
316 AssertPtrReturn(pszEnv, VERR_INVALID_PARAMETER);
317 AssertPtrReturn(pcbEnv, VERR_INVALID_PARAMETER);
318 AssertPtrReturn(puNumEnvVars, VERR_INVALID_PARAMETER);
319 AssertPtrReturn(pszUser, VERR_INVALID_PARAMETER);
320 AssertPtrReturn(pszPassword, VERR_INVALID_PARAMETER);
321 AssertPtrReturn(puTimeLimit, VERR_INVALID_PARAMETER);
322
323 VBoxGuestCtrlHGCMMsgExecCmd Msg;
324
325 Msg.hdr.result = VERR_WRONG_ORDER;
326 Msg.hdr.u32ClientID = u32ClientId;
327 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
328 Msg.hdr.cParms = uNumParms;
329
330 VbglHGCMParmUInt32Set(&Msg.context, 0);
331 VbglHGCMParmPtrSet(&Msg.cmd, pszCmd, cbCmd);
332 VbglHGCMParmUInt32Set(&Msg.flags, 0);
333 VbglHGCMParmUInt32Set(&Msg.num_args, 0);
334 VbglHGCMParmPtrSet(&Msg.args, pszArgs, cbArgs);
335 VbglHGCMParmUInt32Set(&Msg.num_env, 0);
336 VbglHGCMParmUInt32Set(&Msg.cb_env, 0);
337 VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv);
338 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
339 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
340 VbglHGCMParmUInt32Set(&Msg.timeout, 0);
341
342 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
343 if (RT_SUCCESS(rc))
344 {
345 int rc2 = Msg.hdr.result;
346 if (RT_FAILURE(rc2))
347 {
348 rc = rc2;
349 }
350 else
351 {
352 Msg.context.GetUInt32(puContext);
353 Msg.flags.GetUInt32(puFlags);
354 Msg.num_args.GetUInt32(puNumArgs);
355 Msg.num_env.GetUInt32(puNumEnvVars);
356 Msg.cb_env.GetUInt32(pcbEnv);
357 Msg.timeout.GetUInt32(puTimeLimit);
358 }
359 }
360 return rc;
361}
362
363
364/**
365 * Allocates and gets host data, based on the message id.
366 *
367 * This will block until data becomes available.
368 *
369 * @returns VBox status code.
370 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
371 * @param uNumParms
372 ** @todo Docs!
373 */
374VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t uNumParms,
375 uint32_t *puContext, uint32_t *puPID,
376 uint32_t *puHandle, uint32_t *puFlags)
377{
378 AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
379 AssertPtrReturn(puPID, VERR_INVALID_PARAMETER);
380 AssertPtrReturn(puHandle, VERR_INVALID_PARAMETER);
381 AssertPtrReturn(puFlags, VERR_INVALID_PARAMETER);
382
383 VBoxGuestCtrlHGCMMsgExecOut Msg;
384
385 Msg.hdr.result = VERR_WRONG_ORDER;
386 Msg.hdr.u32ClientID = u32ClientId;
387 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
388 Msg.hdr.cParms = uNumParms;
389
390 VbglHGCMParmUInt32Set(&Msg.context, 0);
391 VbglHGCMParmUInt32Set(&Msg.pid, 0);
392 VbglHGCMParmUInt32Set(&Msg.handle, 0);
393 VbglHGCMParmUInt32Set(&Msg.flags, 0);
394
395 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
396 if (RT_SUCCESS(rc))
397 {
398 int rc2 = Msg.hdr.result;
399 if (RT_FAILURE(rc2))
400 {
401 rc = rc2;
402 }
403 else
404 {
405 Msg.context.GetUInt32(puContext);
406 Msg.pid.GetUInt32(puPID);
407 Msg.handle.GetUInt32(puHandle);
408 Msg.flags.GetUInt32(puFlags);
409 }
410 }
411 return rc;
412}
413
414
415/**
416 * Retrieves the input data from host which then gets sent to the
417 * started process.
418 *
419 * This will block until data becomes available.
420 *
421 * @returns VBox status code.
422 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
423 * @param uNumParms
424 ** @todo Docs!
425 */
426VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uint32_t uNumParms,
427 uint32_t *puContext, uint32_t *puPID,
428 uint32_t *puFlags,
429 void *pvData, uint32_t cbData,
430 uint32_t *pcbSize)
431{
432 AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
433 AssertPtrReturn(puPID, VERR_INVALID_PARAMETER);
434 AssertPtrReturn(puFlags, VERR_INVALID_PARAMETER);
435 AssertPtrReturn(pvData, VERR_INVALID_PARAMETER);
436 AssertPtrReturn(pcbSize, VERR_INVALID_PARAMETER);
437
438 VBoxGuestCtrlHGCMMsgExecIn Msg;
439
440 Msg.hdr.result = VERR_WRONG_ORDER;
441 Msg.hdr.u32ClientID = u32ClientId;
442 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
443 Msg.hdr.cParms = uNumParms;
444
445 VbglHGCMParmUInt32Set(&Msg.context, 0);
446 VbglHGCMParmUInt32Set(&Msg.pid, 0);
447 VbglHGCMParmUInt32Set(&Msg.flags, 0);
448 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
449 VbglHGCMParmUInt32Set(&Msg.size, 0);
450
451 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
452 if (RT_SUCCESS(rc))
453 {
454 int rc2 = Msg.hdr.result;
455 if (RT_FAILURE(rc2))
456 {
457 rc = rc2;
458 }
459 else
460 {
461 Msg.context.GetUInt32(puContext);
462 Msg.pid.GetUInt32(puPID);
463 Msg.flags.GetUInt32(puFlags);
464 Msg.size.GetUInt32(pcbSize);
465 }
466 }
467 return rc;
468}
469
470
471/**
472 * Reports the process status (along with some other stuff) to the host.
473 *
474 * @returns VBox status code.
475 ** @todo Docs!
476 */
477VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatus(uint32_t u32ClientId,
478 uint32_t u32Context,
479 uint32_t u32PID,
480 uint32_t u32Status,
481 uint32_t u32Flags,
482 void *pvData,
483 uint32_t cbData)
484{
485 VBoxGuestCtrlHGCMMsgExecStatus Msg;
486
487 Msg.hdr.result = VERR_WRONG_ORDER;
488 Msg.hdr.u32ClientID = u32ClientId;
489 Msg.hdr.u32Function = GUEST_EXEC_SEND_STATUS;
490 Msg.hdr.cParms = 5;
491
492 VbglHGCMParmUInt32Set(&Msg.context, u32Context);
493 VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
494 VbglHGCMParmUInt32Set(&Msg.status, u32Status);
495 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
496 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
497
498 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
499 if (RT_SUCCESS(rc))
500 {
501 int rc2 = Msg.hdr.result;
502 if (RT_FAILURE(rc2))
503 rc = rc2;
504 }
505 return rc;
506}
507
508
509/**
510 * Sends output (from stdout/stderr) from a running process.
511 *
512 * @returns VBox status code.
513 ** @todo Docs!
514 */
515VBGLR3DECL(int) VbglR3GuestCtrlExecSendOut(uint32_t u32ClientId,
516 uint32_t u32Context,
517 uint32_t u32PID,
518 uint32_t u32Handle,
519 uint32_t u32Flags,
520 void *pvData,
521 uint32_t cbData)
522{
523 VBoxGuestCtrlHGCMMsgExecOut Msg;
524
525 Msg.hdr.result = VERR_WRONG_ORDER;
526 Msg.hdr.u32ClientID = u32ClientId;
527 Msg.hdr.u32Function = GUEST_EXEC_SEND_OUTPUT;
528 Msg.hdr.cParms = 5;
529
530 VbglHGCMParmUInt32Set(&Msg.context, u32Context);
531 VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
532 VbglHGCMParmUInt32Set(&Msg.handle, u32Handle);
533 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
534 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
535
536 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
537 if (RT_SUCCESS(rc))
538 {
539 int rc2 = Msg.hdr.result;
540 if (RT_FAILURE(rc2))
541 rc = rc2;
542 }
543 return rc;
544}
545
546
547/**
548 * Reports back the input status to the host.
549 *
550 * @returns VBox status code.
551 ** @todo Docs!
552 */
553VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatusIn(uint32_t u32ClientId,
554 uint32_t u32Context,
555 uint32_t u32PID,
556 uint32_t u32Status,
557 uint32_t u32Flags,
558 uint32_t cbWritten)
559{
560 VBoxGuestCtrlHGCMMsgExecStatusIn Msg;
561
562 Msg.hdr.result = VERR_WRONG_ORDER;
563 Msg.hdr.u32ClientID = u32ClientId;
564 Msg.hdr.u32Function = GUEST_EXEC_SEND_INPUT_STATUS;
565 Msg.hdr.cParms = 5;
566
567 VbglHGCMParmUInt32Set(&Msg.context, u32Context);
568 VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
569 VbglHGCMParmUInt32Set(&Msg.status, u32Status);
570 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
571 VbglHGCMParmUInt32Set(&Msg.written, cbWritten);
572
573 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
574 if (RT_SUCCESS(rc))
575 {
576 int rc2 = Msg.hdr.result;
577 if (RT_FAILURE(rc2))
578 rc = rc2;
579 }
580 return rc;
581}
Note: See TracBrowser for help on using the repository browser.

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