VirtualBox

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

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

Guest Properties (HostServices and Main): redid property flag handling

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 12.6 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/** Maximum size for enumeration patterns */
60enum { MAX_PATTERN_LEN = 1024 };
61
62/**
63 * The guest property flag values which are currently accepted.
64 */
65enum ePropFlags
66{
67 NILFLAG = 0,
68 TRANSIENT = RT_BIT(1),
69 RDONLYGUEST = RT_BIT(2),
70 RDONLYHOST = RT_BIT(3),
71 READONLY = RDONLYGUEST | RDONLYHOST,
72 ALLFLAGS = TRANSIENT | READONLY
73};
74
75/**
76 * Get the name of a flag as a string.
77 * @returns the name, or NULL if fFlag is invalid.
78 * @param fFlag the flag. Must be a value from the ePropFlags enumeration
79 * list.
80 */
81DECLINLINE(const char *) flagName(uint32_t fFlag)
82{
83 switch(fFlag)
84 {
85 case TRANSIENT:
86 return "TRANSIENT";
87 case RDONLYGUEST:
88 return "RDONLYGUEST";
89 case RDONLYHOST:
90 return "RDONLYHOST";
91 case READONLY:
92 return "READONLY";
93 default:
94 return NULL;
95 }
96}
97
98/**
99 * Get the length of a flag name as returned by flagName.
100 * @returns the length, or 0 if fFlag is invalid.
101 * @param fFlag the flag. Must be a value from the ePropFlags enumeration
102 * list.
103 */
104DECLINLINE(size_t) flagNameLen(uint32_t fFlag)
105{
106 const char *pcszName = flagName(fFlag);
107 return RT_LIKELY(pcszName != NULL) ? strlen(pcszName) : 0;
108}
109
110/**
111 * Maximum length for the property flags field. We only ever return one of
112 * RDONLYGUEST, RDONLYHOST and RDONLY
113 */
114enum { MAX_FLAGS_LEN = sizeof("TRANSIENT, RDONLYGUEST") };
115
116/**
117 * Parse a guest properties flags string for flag names and make sure that
118 * there is no junk text in the string.
119 * @returns IPRT status code
120 * @returns VERR_INVALID_PARAM if the flag string is not valid
121 * @param pcszFlags the flag string to parse
122 * @param pfFlags where to store the parse result. May not be NULL.
123 * @note This function is also inline because it must be accessible from
124 * several modules and it does not seem reasonable to put it into
125 * its own library.
126 */
127DECLINLINE(int) validateFlags(const char *pcszFlags, uint32_t *pfFlags)
128{
129 static uint32_t flagList[] =
130 {
131 TRANSIENT, READONLY, RDONLYGUEST, RDONLYHOST
132 };
133 const char *pcszNext = pcszFlags;
134 int rc = VINF_SUCCESS;
135 uint32_t fFlags = 0;
136 AssertLogRelReturn(VALID_PTR(pfFlags), VERR_INVALID_POINTER);
137 AssertLogRelReturn(VALID_PTR(pcszFlags), VERR_INVALID_POINTER);
138 while (' ' == *pcszNext)
139 ++pcszNext;
140 while ((*pcszNext != '\0') && RT_SUCCESS(rc))
141 {
142 unsigned i = 0;
143 for (; i < RT_ELEMENTS(flagList); ++i)
144 if (strncasecmp(pcszNext, flagName(flagList[i]),
145 flagNameLen(flagList[i])
146 ) == 0
147 )
148 break;
149 if (RT_ELEMENTS(flagList) == i)
150 rc = VERR_INVALID_PARAMETER;
151 else
152 {
153 fFlags |= flagList[i];
154 pcszNext += flagNameLen(flagList[i]);
155 while (' ' == *pcszNext)
156 ++pcszNext;
157 if (',' == *pcszNext)
158 ++pcszNext;
159 while (' ' == *pcszNext)
160 ++pcszNext;
161 }
162 }
163 if (RT_SUCCESS(rc))
164 *pfFlags = fFlags;
165 return rc;
166}
167
168/**
169 * Write out flags to a string.
170 * @returns IPRT status code
171 * @param fFlags the flags to write out
172 * @param pszFlags where to write the flags string. This must point to
173 * a buffer of size (at least) MAX_FLAGS_LEN.
174 */
175DECLINLINE(int) writeFlags(uint32_t fFlags, char *pszFlags)
176{
177 static uint32_t flagList[] =
178 {
179 TRANSIENT, READONLY, RDONLYGUEST, RDONLYHOST
180 };
181 char *pszNext = pszFlags;
182 int rc = VINF_SUCCESS;
183 AssertLogRelReturn(VALID_PTR(pszFlags), VERR_INVALID_POINTER);
184 if ((fFlags & ~ALLFLAGS) != NILFLAG)
185 rc = VERR_INVALID_PARAMETER;
186 if (RT_SUCCESS(rc))
187 {
188 unsigned i = 0;
189 for (; i < RT_ELEMENTS(flagList); ++i)
190 {
191 if (fFlags & flagList[i])
192 {
193 strcpy(pszNext, flagName(flagList[i]));
194 pszNext += flagNameLen(flagList[i]);
195 fFlags &= ~flagList[i];
196 if (fFlags != NILFLAG)
197 {
198 strcpy(pszNext, ", ");
199 pszNext += 2;
200 }
201 }
202 }
203 *pszNext = '\0';
204 if (fFlags != NILFLAG)
205 rc = VERR_INVALID_PARAMETER; /* But pszFlags will still be set right. */
206 }
207 return rc;
208}
209
210/*
211 * The service functions which are callable by host.
212 */
213enum eHostFn
214{
215 /** Pass the address of the cfgm node used by the service as a database. */
216 SET_CFGM_NODE = 1,
217 /**
218 * Get the value attached to a guest property
219 * The parameter format matches that of GET_PROP.
220 */
221 GET_PROP_HOST = 2,
222 /**
223 * Set the value attached to a guest property
224 * The parameter format matches that of SET_PROP.
225 */
226 SET_PROP_HOST = 3,
227 /**
228 * Set the value attached to a guest property
229 * The parameter format matches that of SET_PROP_VALUE.
230 */
231 SET_PROP_VALUE_HOST = 4,
232 /**
233 * Remove a guest property.
234 * The parameter format matches that of DEL_PROP.
235 */
236 DEL_PROP_HOST = 5,
237 /**
238 * Enumerate guest properties.
239 * The parameter format matches that of ENUM_PROPS.
240 */
241 ENUM_PROPS_HOST = 6
242};
243
244/**
245 * The service functions which are called by guest. The numbers may not change,
246 * so we hardcode them.
247 */
248enum eGuestFn
249{
250 /** Get a guest property */
251 GET_PROP = 1,
252 /** Set a guest property */
253 SET_PROP = 2,
254 /** Set just the value of a guest property */
255 SET_PROP_VALUE = 3,
256 /** Delete a guest property */
257 DEL_PROP = 4,
258 /** Enumerate guest properties */
259 ENUM_PROPS = 5
260};
261
262/**
263 * Data structure to pass to the service extension callback. We use this to
264 * notify the host of changes to properties.
265 */
266typedef struct _HOSTCALLBACKDATA
267{
268 /** Magic number to identify the structure */
269 uint32_t u32Magic;
270 /** The name of the property that was changed */
271 const char *pcszName;
272 /** The new property value, or NULL if the property was deleted */
273 const char *pcszValue;
274 /** The timestamp of the modification */
275 uint64_t u64Timestamp;
276 /** The flags field of the modified property */
277 const char *pcszFlags;
278} HOSTCALLBACKDATA, *PHOSTCALLBACKDATA;
279
280enum
281{
282 /** Magic number for sanity checking the HOSTCALLBACKDATA structure */
283 HOSTCALLBACKMAGIC = 0x69c87a78
284};
285
286/**
287 * HGCM parameter structures. Packing is explicitly defined as this is a wire format.
288 */
289#pragma pack (1)
290/** The guest is requesting the value of a property */
291typedef struct _GetProperty
292{
293 VBoxGuestHGCMCallInfo hdr;
294
295 /**
296 * The property name (IN pointer)
297 * This must fit to a number of criteria, namely
298 * - Only Utf8 strings are allowed
299 * - Less than or equal to MAX_NAME_LEN bytes in length
300 * - Zero terminated
301 */
302 HGCMFunctionParameter name;
303
304 /**
305 * The returned string data will be placed here. (OUT pointer)
306 * This call returns two null-terminated strings which will be placed one
307 * after another: value and flags.
308 */
309 HGCMFunctionParameter buffer;
310
311 /**
312 * The property timestamp. (OUT uint64_t)
313 */
314
315 HGCMFunctionParameter timestamp;
316
317 /**
318 * If the buffer provided was large enough this will contain the size of
319 * the returned data. Otherwise it will contain the size of the buffer
320 * needed to hold the data and VERR_BUFFER_OVERFLOW will be returned.
321 * (OUT uint32_t)
322 */
323 HGCMFunctionParameter size;
324} GetProperty;
325
326/** The guest is requesting to change a property */
327typedef struct _SetProperty
328{
329 VBoxGuestHGCMCallInfo hdr;
330
331 /**
332 * The property name. (IN pointer)
333 * This must fit to a number of criteria, namely
334 * - Only Utf8 strings are allowed
335 * - Less than or equal to MAX_NAME_LEN bytes in length
336 * - Zero terminated
337 */
338 HGCMFunctionParameter name;
339
340 /**
341 * The value of the property (IN pointer)
342 * Criteria as for the name parameter, but with length less than or equal to
343 * MAX_VALUE_LEN.
344 */
345 HGCMFunctionParameter value;
346
347 /**
348 * The property flags (IN pointer)
349 * This is a comma-separated list of the format flag=value
350 * The length must be less than or equal to MAX_FLAGS_LEN and only
351 * known flag names and values will be accepted.
352 */
353 HGCMFunctionParameter flags;
354} SetProperty;
355
356/** The guest is requesting to change the value of a property */
357typedef struct _SetPropertyValue
358{
359 VBoxGuestHGCMCallInfo hdr;
360
361 /**
362 * The property name. (IN pointer)
363 * This must fit to a number of criteria, namely
364 * - Only Utf8 strings are allowed
365 * - Less than or equal to MAX_NAME_LEN bytes in length
366 * - Zero terminated
367 */
368 HGCMFunctionParameter name;
369
370 /**
371 * The value of the property (IN pointer)
372 * Criteria as for the name parameter, but with length less than or equal to
373 * MAX_VALUE_LEN.
374 */
375 HGCMFunctionParameter value;
376} SetPropertyValue;
377
378/** The guest is requesting to remove a property */
379typedef struct _DelProperty
380{
381 VBoxGuestHGCMCallInfo hdr;
382
383 /**
384 * The property name. This must fit to a number of criteria, namely
385 * - Only Utf8 strings are allowed
386 * - Less than or equal to MAX_NAME_LEN bytes in length
387 * - Zero terminated
388 */
389 HGCMFunctionParameter name;
390} DelProperty;
391
392/** The guest is requesting to enumerate properties */
393typedef struct _EnumProperties
394{
395 VBoxGuestHGCMCallInfo hdr;
396
397 /**
398 * Array of patterns to match the properties against, separated by '|'
399 * characters. For backwards compatibility, '\0' is also accepted
400 * as a separater.
401 * (IN pointer)
402 * If only a single, empty pattern is given then match all.
403 */
404 HGCMFunctionParameter patterns;
405 /**
406 * On success, null-separated array of strings in which the properties are
407 * returned. (OUT pointer)
408 * The number of strings in the array is always a multiple of four,
409 * and in sequences of name, value, timestamp (hexadecimal string) and the
410 * flags as a comma-separated list in the format "name=value". The list
411 * is terminated by an empty string after a "flags" entry (or at the
412 * start).
413 */
414 HGCMFunctionParameter strings;
415 /**
416 * On success, the size of the returned data. If the buffer provided is
417 * too small, the size of buffer needed. (OUT uint32_t)
418 */
419 HGCMFunctionParameter size;
420} EnumProperties;
421#pragma pack ()
422
423} /* namespace guestProp */
424
425#endif /* ___VBox_HostService_GuestPropertySvc_h defined */
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