VirtualBox

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

Last change on this file since 28887 was 28887, checked in by vboxsync, 15 years ago

Guest Control/Main: Faster (no polling on guest side), free data on shutdown.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1/* $Id: VBoxGuestR3LibGuestCtrl.cpp 28887 2010-04-29 11:19:17Z 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 valgrid 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 * Gets a host message.
96 *
97 * This will block until a message becomes available.
98 *
99 * @returns VBox status code.
100 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
101 * @param puMsg Where to store the message id.
102 * @param puNumParms Where to store the number of parameters which will be received
103 * in a second call to the host.
104 */
105VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms, uint32_t u32Timeout)
106{
107 AssertPtr(puMsg);
108 AssertPtr(puNumParms);
109
110 VBoxGuestCtrlHGCMMsgType Msg;
111
112 Msg.hdr.result = VERR_WRONG_ORDER;
113 Msg.hdr.u32ClientID = u32ClientId;
114 Msg.hdr.u32Function = GUEST_GET_HOST_MSG; /* Tell the host we want our next command. */
115 Msg.hdr.cParms = 2; /* Just peek for the next message! */
116
117 VbglHGCMParmUInt32Set(&Msg.msg, 0);
118 VbglHGCMParmUInt32Set(&Msg.num_parms, 0);
119
120 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
121 if (RT_SUCCESS(rc))
122 {
123 rc = VbglHGCMParmUInt32Get(&Msg.msg, puMsg);
124 if (RT_SUCCESS(rc))
125 rc = VbglHGCMParmUInt32Get(&Msg.num_parms, puNumParms);
126 if (RT_SUCCESS(rc))
127 rc = Msg.hdr.result;
128 /* Ok, so now we know what message type and how much parameters there are. */
129 }
130 return rc;
131}
132
133
134/**
135 * Allocates and gets host data, based on the message id.
136 *
137 * This will block until data becomes available.
138 *
139 * @returns VBox status code.
140 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
141 * @param uNumParms
142 ** @todo Docs!
143 */
144VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t uNumParms,
145 uint32_t *puContext,
146 char *pszCmd, uint32_t cbCmd,
147 uint32_t *puFlags,
148 char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs,
149 char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars,
150 char *pszStdIn, uint32_t cbStdIn,
151 char *pszStdOut, uint32_t cbStdOut,
152 char *pszStdErr, uint32_t cbStdErr,
153 char *pszUser, uint32_t cbUser,
154 char *pszPassword, uint32_t cbPassword,
155 uint32_t *puTimeLimit)
156{
157 AssertPtr(puContext);
158 AssertPtr(pszCmd);
159 AssertPtr(puFlags);
160 AssertPtr(pszArgs);
161 AssertPtr(puNumArgs);
162 AssertPtr(pszEnv);
163 AssertPtr(pcbEnv);
164 AssertPtr(puNumEnvVars);
165 AssertPtr(pszStdIn);
166 AssertPtr(pszStdOut);
167 AssertPtr(pszStdOut);
168 AssertPtr(pszStdErr);
169 AssertPtr(pszUser);
170 AssertPtr(pszPassword);
171 AssertPtr(puTimeLimit);
172
173 VBoxGuestCtrlHGCMMsgExecCmd Msg;
174
175 Msg.hdr.result = VERR_WRONG_ORDER;
176 Msg.hdr.u32ClientID = u32ClientId;
177 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
178 Msg.hdr.cParms = uNumParms;
179
180 VbglHGCMParmUInt32Set(&Msg.context, 0); /** @todo Put this some header struct! */
181 VbglHGCMParmPtrSet(&Msg.cmd, pszCmd, cbCmd);
182 VbglHGCMParmUInt32Set(&Msg.flags, 0);
183 VbglHGCMParmUInt32Set(&Msg.num_args, 0);
184 VbglHGCMParmPtrSet(&Msg.args, pszArgs, cbArgs);
185 VbglHGCMParmUInt32Set(&Msg.num_env, 0);
186 VbglHGCMParmUInt32Set(&Msg.cb_env, 0);
187 VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv);
188 VbglHGCMParmPtrSet(&Msg.std_in, pszStdIn, cbStdIn);
189 VbglHGCMParmPtrSet(&Msg.std_out, pszStdOut, cbStdOut);
190 VbglHGCMParmPtrSet(&Msg.std_err, pszStdErr, cbStdErr);
191 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
192 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
193 VbglHGCMParmUInt32Set(&Msg.timeout, 0);
194
195 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
196 if (RT_SUCCESS(rc))
197 {
198 int rc2 = Msg.hdr.result;
199 if (RT_FAILURE(rc2))
200 {
201 rc = rc2;
202 }
203 else
204 {
205 Msg.context.GetUInt32(puContext);
206 Msg.flags.GetUInt32(puFlags);
207 Msg.num_args.GetUInt32(puNumArgs);
208 Msg.num_env.GetUInt32(puNumEnvVars);
209 Msg.cb_env.GetUInt32(pcbEnv);
210 Msg.timeout.GetUInt32(puTimeLimit);
211 }
212 }
213 return rc;
214}
215
216
217/**
218 * Allocates and gets host data, based on the message id.
219 *
220 * This will block until data becomes available.
221 *
222 * @returns VBox status code.
223 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
224 * @param uNumParms
225 ** @todo Docs!
226 */
227VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t uNumParms,
228 uint32_t *puContext, uint32_t *puPID,
229 uint32_t *puHandle, uint32_t *puFlags)
230{
231 AssertPtr(puContext);
232 AssertPtr(puPID);
233
234 VBoxGuestCtrlHGCMMsgExecOut Msg;
235
236 Msg.hdr.result = VERR_WRONG_ORDER;
237 Msg.hdr.u32ClientID = u32ClientId;
238 Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
239 Msg.hdr.cParms = uNumParms;
240
241 VbglHGCMParmUInt32Set(&Msg.context, 0); /** @todo Put this some header struct! */
242 VbglHGCMParmUInt32Set(&Msg.pid, 0);
243 VbglHGCMParmUInt32Set(&Msg.handle, 0);
244 VbglHGCMParmUInt32Set(&Msg.flags, 0);
245
246 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
247 if (RT_SUCCESS(rc))
248 {
249 int rc2 = Msg.hdr.result;
250 if (RT_FAILURE(rc2))
251 {
252 rc = rc2;
253 }
254 else
255 {
256 Msg.context.GetUInt32(puContext);
257 Msg.pid.GetUInt32(puPID);
258 Msg.handle.GetUInt32(puHandle);
259 Msg.flags.GetUInt32(puFlags);
260 }
261 }
262 return rc;
263}
264
265
266/**
267 * Reports the process status (along with some other stuff) to the host.
268 *
269 * @returns VBox status code.
270 ** @todo Docs!
271 */
272VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatus(uint32_t u32ClientId,
273 uint32_t u32Context,
274 uint32_t u32PID,
275 uint32_t u32Status,
276 uint32_t u32Flags,
277 void *pvData,
278 uint32_t cbData)
279{
280 VBoxGuestCtrlHGCMMsgExecStatus Msg;
281
282 Msg.hdr.result = VERR_WRONG_ORDER;
283 Msg.hdr.u32ClientID = u32ClientId;
284 Msg.hdr.u32Function = GUEST_EXEC_SEND_STATUS;
285 Msg.hdr.cParms = 5;
286
287 VbglHGCMParmUInt32Set(&Msg.context, u32Context);
288 VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
289 VbglHGCMParmUInt32Set(&Msg.status, u32Status);
290 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
291 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
292
293 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
294 if (RT_SUCCESS(rc))
295 {
296 int rc2 = Msg.hdr.result;
297 if (RT_FAILURE(rc2))
298 rc = rc2;
299 }
300 return rc;
301}
302
303
304/**
305 * Sends output (from stdout/stderr) from a running process.
306 *
307 * @returns VBox status code.
308 ** @todo Docs!
309 */
310VBGLR3DECL(int) VbglR3GuestCtrlExecSendOut(uint32_t u32ClientId,
311 uint32_t u32Context,
312 uint32_t u32PID,
313 uint32_t u32Handle,
314 uint32_t u32Flags,
315 void *pvData,
316 uint32_t cbData)
317{
318 VBoxGuestCtrlHGCMMsgExecOut Msg;
319
320 Msg.hdr.result = VERR_WRONG_ORDER;
321 Msg.hdr.u32ClientID = u32ClientId;
322 Msg.hdr.u32Function = GUEST_EXEC_SEND_OUTPUT;
323 Msg.hdr.cParms = 5;
324
325 VbglHGCMParmUInt32Set(&Msg.context, u32Context);
326 VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
327 VbglHGCMParmUInt32Set(&Msg.handle, u32Handle);
328 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
329 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
330
331 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
332 if (RT_SUCCESS(rc))
333 {
334 int rc2 = Msg.hdr.result;
335 if (RT_FAILURE(rc2))
336 rc = rc2;
337 }
338 return rc;
339}
340
Note: See TracBrowser for help on using the repository browser.

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