VirtualBox

source: vbox/trunk/include/VBox/HostServices/GuestPropertySvc.h@ 13437

Last change on this file since 13437 was 13376, checked in by vboxsync, 16 years ago

HostServices/GuestProperties: use an HGCM service extension instead of the callback type I added

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 11.7 KB
Line 
1/** @file
2 * Guest property service:
3 * Common header for host service and guest clients.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31#ifndef ___VBox_HostService_GuestPropertyService_h
32#define ___VBox_HostService_GuestPropertyService_h
33
34#include <VBox/types.h>
35#include <VBox/VBoxGuest.h>
36#include <VBox/hgcmsvc.h>
37#include <VBox/log.h>
38#include <iprt/assert.h>
39
40#include <string.h>
41
42#ifdef RT_OS_WINDOWS
43# define strncasecmp strnicmp
44#endif
45
46/** Everything defined in this file lives in this namespace. */
47namespace guestProp {
48
49/******************************************************************************
50* Typedefs, constants and inlines *
51******************************************************************************/
52
53/** Maximum length for property names */
54enum { MAX_NAME_LEN = 64 };
55/** Maximum length for property values */
56enum { MAX_VALUE_LEN = 128 };
57/** Maximum number of properties per guest */
58enum { MAX_PROPS = 256 };
59
60/**
61 * The guest property flag values which are currently accepted.
62 */
63enum ePropFlags
64{
65 NILFLAG = 0,
66 TRANSIENT = RT_BIT(1),
67 HOSTWRITE = RT_BIT(2),
68 GUESTWRITE = RT_BIT(3),
69 READONLY = RT_BIT(4)
70};
71
72/**
73 * A structure to map the guest property flag values to names. I know it is
74 * ugly to have constants inline, but it has to be accessible in different
75 * modules and it does not seem reasonable to put it into its own library.
76 */
77const struct
78{
79 /** The flag value */
80 uint32_t fFlag;
81 /** And the name of the flag */
82 const char *pcszName;
83} flagNames[] =
84{
85 { TRANSIENT, "TRANSIENT" },
86 { HOSTWRITE, "HOSTWRITE" },
87 { GUESTWRITE, "GUESTWRITE" },
88 { READONLY, "READONLY" },
89 { NILFLAG, NULL }
90};
91
92/** Maximum length for the property flags field */
93enum { MAX_FLAGS_LEN = sizeof(flagNames[0]) + 2 /* + 2 for ", " */
94 + sizeof(flagNames[1]) + 2
95 + sizeof(flagNames[2]) + 2
96 + sizeof(flagNames[3])
97 };
98
99/**
100 * Parse a guest properties flags string for the flags in flagNames.
101 * @returns IPRT status code
102 * @returns VERR_INVALID_PARAM if the flag string is not valid
103 * @param pcszFlags the flag string to parse
104 * @param pfFlags where to store the parse result. May not be NULL.
105 * @note This function is also inline because it must be accessible from
106 * several modules and it does not seem reasonable to put it into
107 * its own library.
108 */
109DECLINLINE(int) validateFlags(const char *pcszFlags, uint32_t *pfFlags)
110{
111 const char *pcszNext = pcszFlags;
112 int rc = VINF_SUCCESS;
113 uint32_t fFlags = 0;
114 AssertLogRelReturn(VALID_PTR(pfFlags), VERR_INVALID_POINTER);
115 AssertLogRelReturn(VALID_PTR(pcszFlags), VERR_INVALID_POINTER);
116 while (' ' == *pcszNext)
117 ++pcszNext;
118 while ((*pcszNext != '\0') && RT_SUCCESS(rc))
119 {
120 int i = 0;
121 for (; flagNames[i].fFlag != NILFLAG; ++i)
122 if (strncasecmp(pcszNext, flagNames[i].pcszName,
123 strlen(flagNames[i].pcszName)) == 0)
124 break;
125 if (NILFLAG == flagNames[i].fFlag)
126 rc = VERR_INVALID_PARAMETER;
127 else
128 {
129 fFlags |= flagNames[i].fFlag;
130 pcszNext += strlen(flagNames[i].pcszName);
131 }
132 while (' ' == *pcszNext)
133 ++pcszNext;
134 if (',' == *pcszNext)
135 ++pcszNext;
136 while (' ' == *pcszNext)
137 ++pcszNext;
138 }
139 if (RT_SUCCESS(rc))
140 *pfFlags = fFlags;
141 return rc;
142}
143
144/**
145 * Write out flags to a string.
146 * @returns IPRT status code
147 * @param fFlags the flags to write out
148 * @param pszFlags where to write the flags string. This must point to
149 * a buffer of size (at least) MAX_FLAGS_LEN + 1.
150 */
151DECLINLINE(int) writeFlags(uint32_t fFlags, char *pszFlags)
152{
153 char *pszNext = pszFlags;
154 int rc = VINF_SUCCESS;
155 AssertLogRelReturn(VALID_PTR(pszFlags), VERR_INVALID_POINTER);
156 int i = 0;
157 for (; flagNames[i].fFlag != NILFLAG; ++i)
158 {
159 if (fFlags & flagNames[i].fFlag)
160 {
161 strcpy(pszNext, flagNames[i].pcszName);
162 pszNext += strlen(flagNames[i].pcszName);
163 fFlags &= ~flagNames[i].fFlag;
164 if ((flagNames[i + 1].fFlag != NILFLAG) && (fFlags != NILFLAG))
165 {
166 strcpy(pszNext, ", ");
167 pszNext += 2;
168 }
169 }
170 }
171 *pszNext = '\0';
172 if (fFlags != NILFLAG)
173 rc = VERR_INVALID_PARAMETER; /* But pszFlags will still be set right. */
174 return rc;
175}
176
177/*
178 * The service functions which are callable by host.
179 */
180enum eHostFn
181{
182 /** Pass the address of the cfgm node used by the service as a database. */
183 SET_CFGM_NODE = 1,
184 /**
185 * Get the value attached to a guest property
186 * The parameter format matches that of GET_PROP.
187 */
188 GET_PROP_HOST = 2,
189 /**
190 * Set the value attached to a guest property
191 * The parameter format matches that of SET_PROP.
192 */
193 SET_PROP_HOST = 3,
194 /**
195 * Set the value attached to a guest property
196 * The parameter format matches that of SET_PROP_VALUE.
197 */
198 SET_PROP_VALUE_HOST = 4,
199 /**
200 * Remove a guest property.
201 * The parameter format matches that of DEL_PROP.
202 */
203 DEL_PROP_HOST = 5,
204 /**
205 * Enumerate guest properties.
206 * The parameter format matches that of ENUM_PROPS.
207 */
208 ENUM_PROPS_HOST = 6
209};
210
211/**
212 * The service functions which are called by guest. The numbers may not change,
213 * so we hardcode them.
214 */
215enum eGuestFn
216{
217 /** Get a guest property */
218 GET_PROP = 1,
219 /** Set a guest property */
220 SET_PROP = 2,
221 /** Set just the value of a guest property */
222 SET_PROP_VALUE = 3,
223 /** Delete a guest property */
224 DEL_PROP = 4,
225 /** Enumerate guest properties */
226 ENUM_PROPS = 5
227};
228
229/**
230 * Data structure to pass to the service extension callback. We use this to
231 * notify the host of changes to properties.
232 */
233typedef struct _HOSTCALLBACKDATA
234{
235 /** Magic number to identify the structure */
236 uint32_t u32Magic;
237 /** The name of the property that was changed */
238 const char *pcszName;
239 /** The new property value, or NULL if the property was deleted */
240 const char *pcszValue;
241 /** The timestamp of the modification */
242 uint64_t u64Timestamp;
243 /** The flags field of the modified property */
244 const char *pcszFlags;
245} HOSTCALLBACKDATA, *PHOSTCALLBACKDATA;
246
247enum
248{
249 /** Magic number for sanity checking the HOSTCALLBACKDATA structure */
250 HOSTCALLBACKMAGIC = 0x69c87a78
251};
252
253/**
254 * HGCM parameter structures. Packing is explicitly defined as this is a wire format.
255 */
256#pragma pack (1)
257/** The guest is requesting the value of a property */
258typedef struct _GetProperty
259{
260 VBoxGuestHGCMCallInfo hdr;
261
262 /**
263 * The property name (IN pointer)
264 * This must fit to a number of criteria, namely
265 * - Only Utf8 strings are allowed
266 * - Less than or equal to MAX_NAME_LEN bytes in length
267 * - Zero terminated
268 */
269 HGCMFunctionParameter name;
270
271 /**
272 * The returned string data will be placed here. (OUT pointer)
273 * This call returns two null-terminated strings which will be placed one
274 * after another: value and flags.
275 */
276 HGCMFunctionParameter buffer;
277
278 /**
279 * The property timestamp. (OUT uint64_t)
280 */
281
282 HGCMFunctionParameter timestamp;
283
284 /**
285 * If the buffer provided was large enough this will contain the size of
286 * the returned data. Otherwise it will contain the size of the buffer
287 * needed to hold the data and VERR_BUFFER_OVERFLOW will be returned.
288 * (OUT uint32_t)
289 */
290 HGCMFunctionParameter size;
291} GetProperty;
292
293/** The guest is requesting to change a property */
294typedef struct _SetProperty
295{
296 VBoxGuestHGCMCallInfo hdr;
297
298 /**
299 * The property name. (IN pointer)
300 * This must fit to a number of criteria, namely
301 * - Only Utf8 strings are allowed
302 * - Less than or equal to MAX_NAME_LEN bytes in length
303 * - Zero terminated
304 */
305 HGCMFunctionParameter name;
306
307 /**
308 * The value of the property (IN pointer)
309 * Criteria as for the name parameter, but with length less than or equal to
310 * MAX_VALUE_LEN.
311 */
312 HGCMFunctionParameter value;
313
314 /**
315 * The property flags (IN pointer)
316 * This is a comma-separated list of the format flag=value
317 * The length must be less than or equal to MAX_FLAGS_LEN and only
318 * known flag names and values will be accepted.
319 */
320 HGCMFunctionParameter flags;
321} SetProperty;
322
323/** The guest is requesting to change the value of a property */
324typedef struct _SetPropertyValue
325{
326 VBoxGuestHGCMCallInfo hdr;
327
328 /**
329 * The property name. (IN pointer)
330 * This must fit to a number of criteria, namely
331 * - Only Utf8 strings are allowed
332 * - Less than or equal to MAX_NAME_LEN bytes in length
333 * - Zero terminated
334 */
335 HGCMFunctionParameter name;
336
337 /**
338 * The value of the property (IN pointer)
339 * Criteria as for the name parameter, but with length less than or equal to
340 * MAX_VALUE_LEN.
341 */
342 HGCMFunctionParameter value;
343} SetPropertyValue;
344
345/** The guest is requesting to remove a property */
346typedef struct _DelProperty
347{
348 VBoxGuestHGCMCallInfo hdr;
349
350 /**
351 * The property name. This must fit to a number of criteria, namely
352 * - Only Utf8 strings are allowed
353 * - Less than or equal to MAX_NAME_LEN bytes in length
354 * - Zero terminated
355 */
356 HGCMFunctionParameter name;
357} DelProperty;
358
359/** The guest is requesting to enumerate properties */
360typedef struct _EnumProperties
361{
362 VBoxGuestHGCMCallInfo hdr;
363
364 /**
365 * Null-separated array of patterns to match the properties against.
366 * (IN pointer)
367 * If no patterns are given then return all. The list is terminated by an
368 * empty string.
369 */
370 HGCMFunctionParameter patterns;
371 /**
372 * On success, null-separated array of strings in which the properties are
373 * returned. (OUT pointer)
374 * The number of strings in the array is always a multiple of four,
375 * and in sequences of name, value, timestamp (hexadecimal string) and the
376 * flags as a comma-separated list in the format "name=value". The list
377 * is terminated by an empty string after a "flags" entry (or at the
378 * start).
379 */
380 HGCMFunctionParameter strings;
381 /**
382 * On success, the size of the returned data. If the buffer provided is
383 * too small, the size of buffer needed. (OUT uint32_t)
384 */
385 HGCMFunctionParameter size;
386} EnumProperties;
387#pragma pack ()
388
389} /* namespace guestProp */
390
391#endif /* ___VBox_HostService_GuestPropertySvc_h defined */
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