VirtualBox

root/trunk/include/VBox/HostServices/GuestPropertySvc.h

Revision 14352, 15.5 kB (checked in by vboxsync, 2 months ago)

Additions/HGCM: merged code for HGCMCall and HGCMCallTimed, as per todo

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
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 #include <iprt/string.h>
40
41 /** Everything defined in this file lives in this namespace. */
42 namespace guestProp {
43
44 /******************************************************************************
45 * Typedefs, constants and inlines                                             *
46 ******************************************************************************/
47
48 /** Maximum length for property names */
49 enum { MAX_NAME_LEN = 64 };
50 /** Maximum length for property values */
51 enum { MAX_VALUE_LEN = 128 };
52 /** Maximum number of properties per guest */
53 enum { MAX_PROPS = 256 };
54 /** Maximum size for enumeration patterns */
55 enum { MAX_PATTERN_LEN = 1024 };
56 /** Maximum number of changes we remember for guest notifications */
57 enum { MAX_GUEST_NOTIFICATIONS = 256 };
58
59 /**
60  * The guest property flag values which are currently accepted.
61  */
62 enum ePropFlags
63 {
64     NILFLAG     = 0,
65     TRANSIENT   = RT_BIT(1),
66     RDONLYGUEST = RT_BIT(2),
67     RDONLYHOST  = RT_BIT(3),
68     READONLY    = RDONLYGUEST | RDONLYHOST,
69     ALLFLAGS    = TRANSIENT | READONLY
70 };
71
72 /**
73  * Get the name of a flag as a string.
74  * @returns the name, or NULL if fFlag is invalid.
75  * @param   fFlag  the flag.  Must be a value from the ePropFlags enumeration
76  *                 list.
77  */
78 DECLINLINE(const char *) flagName(uint32_t fFlag)
79 {
80     switch(fFlag)
81     {
82         case TRANSIENT:
83             return "TRANSIENT";
84         case RDONLYGUEST:
85             return "RDONLYGUEST";
86         case RDONLYHOST:
87             return "RDONLYHOST";
88         case READONLY:
89             return "READONLY";
90         default:
91             return NULL;
92     }
93 }
94
95 /**
96  * Get the length of a flag name as returned by flagName.
97  * @returns the length, or 0 if fFlag is invalid.
98  * @param   fFlag  the flag.  Must be a value from the ePropFlags enumeration
99  *                 list.
100  */
101 DECLINLINE(size_t) flagNameLen(uint32_t fFlag)
102 {
103     const char *pcszName = flagName(fFlag);
104     return RT_LIKELY(pcszName != NULL) ? strlen(pcszName) : 0;
105 }
106
107 /**
108  * Maximum length for the property flags field.  We only ever return one of
109  * RDONLYGUEST, RDONLYHOST and RDONLY
110  */
111 enum { MAX_FLAGS_LEN =   sizeof("TRANSIENT, RDONLYGUEST") };
112
113 /**
114  * Parse a guest properties flags string for flag names and make sure that
115  * there is no junk text in the string.
116  * @returns  IPRT status code
117  * @returns  VERR_INVALID_PARAM if the flag string is not valid
118  * @param    pcszFlags  the flag string to parse
119  * @param    pfFlags    where to store the parse result.  May not be NULL.
120  * @note     This function is also inline because it must be accessible from
121  *           several modules and it does not seem reasonable to put it into
122  *           its own library.
123  */
124 DECLINLINE(int) validateFlags(const char *pcszFlags, uint32_t *pfFlags)
125 {
126     const static uint32_t sFlagList[] =
127     {
128         TRANSIENT, READONLY, RDONLYGUEST, RDONLYHOST
129     };
130     const char *pcszNext = pcszFlags;
131     int rc = VINF_SUCCESS;
132     uint32_t fFlags = 0;
133     AssertLogRelReturn(VALID_PTR(pfFlags), VERR_INVALID_POINTER);
134     AssertLogRelReturn(VALID_PTR(pcszFlags), VERR_INVALID_POINTER);
135     while (' ' == *pcszNext)
136         ++pcszNext;
137     while ((*pcszNext != '\0') && RT_SUCCESS(rc))
138     {
139         unsigned i = 0;
140         for (; i < RT_ELEMENTS(sFlagList); ++i)
141             if (RTStrNICmp(pcszNext, flagName(sFlagList[i]),
142                            flagNameLen(sFlagList[i])
143                            ) == 0
144                )
145                 break;
146         if (RT_ELEMENTS(sFlagList) == i)
147              rc = VERR_PARSE_ERROR;
148         else
149         {
150             fFlags |= sFlagList[i];
151             pcszNext += flagNameLen(sFlagList[i]);
152             while (' ' == *pcszNext)
153                 ++pcszNext;
154             if (',' == *pcszNext)
155                 ++pcszNext;
156             else if (*pcszNext != '\0')
157                 rc = VERR_PARSE_ERROR;
158             while (' ' == *pcszNext)
159                 ++pcszNext;
160         }
161     }
162     if (RT_SUCCESS(rc))
163         *pfFlags = fFlags;
164     return rc;
165 }
166
167 /**
168  * Write out flags to a string.
169  * @returns  IPRT status code
170  * @param    fFlags    the flags to write out
171  * @param    pszFlags  where to write the flags string.  This must point to
172  *                     a buffer of size (at least) MAX_FLAGS_LEN.
173  */
174 DECLINLINE(int) writeFlags(uint32_t fFlags, char *pszFlags)
175 {
176     const static uint32_t sFlagList[] =
177     {
178         TRANSIENT, READONLY, RDONLYGUEST, RDONLYHOST
179     };
180     char *pszNext = pszFlags;
181     int rc = VINF_SUCCESS;
182     AssertLogRelReturn(VALID_PTR(pszFlags), VERR_INVALID_POINTER);
183     if ((fFlags & ~ALLFLAGS) != NILFLAG)
184         rc = VERR_INVALID_PARAMETER;
185     if (RT_SUCCESS(rc))
186     {
187         unsigned i = 0;
188         for (; i < RT_ELEMENTS(sFlagList); ++i)
189         {
190             if (sFlagList[i] == (fFlags & sFlagList[i]))
191             {
192                 strcpy(pszNext, flagName(sFlagList[i]));
193                 pszNext += flagNameLen(sFlagList[i]);
194                 fFlags &= ~sFlagList[i];
195                 if (fFlags != NILFLAG)
196                 {
197                     strcpy(pszNext, ", ");
198                     pszNext += 2;
199                 }
200             }
201         }
202         *pszNext = '\0';
203         if (fFlags != NILFLAG)
204             rc = VERR_INVALID_PARAMETER;  /* But pszFlags will still be set right. */
205     }
206     return rc;
207 }
208
209 /**
210  * The service functions which are callable by host.
211  */
212 enum eHostFn
213 {
214     /**
215      * Set properties in a block.  The parameters are pointers to
216      * NULL-terminated arrays containing the paramters.  These are, in order,
217      * name, value, timestamp, flags.  Strings are stored as pointers to
218      * mutable utf8 data.  All parameters must be supplied.
219      */
220     SET_PROPS_HOST = 1,
221     /**
222      * Get the value attached to a guest property
223      * The parameter format matches that of GET_PROP.
224      */
225     GET_PROP_HOST = 2,
226     /**
227      * Set the value attached to a guest property
228      * The parameter format matches that of SET_PROP.
229      */
230     SET_PROP_HOST = 3,
231     /**
232      * Set the value attached to a guest property
233      * The parameter format matches that of SET_PROP_VALUE.
234      */
235     SET_PROP_VALUE_HOST = 4,
236     /**
237      * Remove a guest property.
238      * The parameter format matches that of DEL_PROP.
239      */
240     DEL_PROP_HOST = 5,
241     /**
242      * Enumerate guest properties.
243      * The parameter format matches that of ENUM_PROPS.
244      */
245     ENUM_PROPS_HOST = 6
246 };
247
248 /**
249  * The service functions which are called by guest.  The numbers may not change,
250  * so we hardcode them.
251  */
252 enum eGuestFn
253 {
254     /** Get a guest property */
255     GET_PROP = 1,
256     /** Set a guest property */
257     SET_PROP = 2,
258     /** Set just the value of a guest property */
259     SET_PROP_VALUE = 3,
260     /** Delete a guest property */
261     DEL_PROP = 4,
262     /** Enumerate guest properties */
263     ENUM_PROPS = 5,
264     /** Poll for guest notifications */
265     GET_NOTIFICATION = 6
266 };
267
268 /**
269  * Data structure to pass to the service extension callback.  We use this to
270  * notify the host of changes to properties.
271  */
272 typedef struct _HOSTCALLBACKDATA
273 {
274     /** Magic number to identify the structure */
275     uint32_t u32Magic;
276     /** The name of the property that was changed */
277     const char *pcszName;
278     /** The new property value, or NULL if the property was deleted */
279     const char *pcszValue;
280     /** The timestamp of the modification */
281     uint64_t u64Timestamp;
282     /** The flags field of the modified property */
283     const char *pcszFlags;
284 } HOSTCALLBACKDATA, *PHOSTCALLBACKDATA;
285
286 enum
287 {
288     /** Magic number for sanity checking the HOSTCALLBACKDATA structure */
289     HOSTCALLBACKMAGIC = 0x69c87a78
290 };
291
292 /**
293  * HGCM parameter structures.  Packing is explicitly defined as this is a wire format.
294  */
295 #pragma pack (1)
296 /** The guest is requesting the value of a property */
297 typedef struct _GetProperty
298 {
299     VBoxGuestHGCMCallInfo hdr;
300
301     /**
302      * The property name (IN pointer)
303      * This must fit to a number of criteria, namely
304      *  - Only Utf8 strings are allowed
305      *  - Less than or equal to MAX_NAME_LEN bytes in length
306      *  - Zero terminated
307      */
308     HGCMFunctionParameter name;
309
310     /**
311      * The returned string data will be placed here.  (OUT pointer)
312      * This call returns two null-terminated strings which will be placed one
313      * after another: value and flags.
314      */
315     HGCMFunctionParameter buffer;
316
317     /**
318      * The property timestamp.  (OUT uint64_t)
319      */
320     HGCMFunctionParameter timestamp;
321
322     /**
323      * If the buffer provided was large enough this will contain the size of
324      * the returned data.  Otherwise it will contain the size of the buffer
325      * needed to hold the data and VERR_BUFFER_OVERFLOW will be returned.
326      * (OUT uint32_t)
327      */
328     HGCMFunctionParameter size;
329 } GetProperty;
330
331 /** The guest is requesting to change a property */
332 typedef struct _SetProperty
333 {
334     VBoxGuestHGCMCallInfo hdr;
335
336     /**
337      * The property name.  (IN pointer)
338      * This must fit to a number of criteria, namely
339      *  - Only Utf8 strings are allowed
340      *  - Less than or equal to MAX_NAME_LEN bytes in length
341      *  - Zero terminated
342      */
343     HGCMFunctionParameter name;
344
345     /**
346      * The value of the property (IN pointer)
347      * Criteria as for the name parameter, but with length less than or equal to
348      * MAX_VALUE_LEN.
349      */
350     HGCMFunctionParameter value;
351
352     /**
353      * The property flags (IN pointer)
354      * This is a comma-separated list of the format flag=value
355      * The length must be less than or equal to MAX_FLAGS_LEN and only
356      * known flag names and values will be accepted.
357      */
358     HGCMFunctionParameter flags;
359 } SetProperty;
360
361 /** The guest is requesting to change the value of a property */
362 typedef struct _SetPropertyValue
363 {
364     VBoxGuestHGCMCallInfo hdr;
365
366     /**
367      * The property name.  (IN pointer)
368      * This must fit to a number of criteria, namely
369      *  - Only Utf8 strings are allowed
370      *  - Less than or equal to MAX_NAME_LEN bytes in length
371      *  - Zero terminated
372      */
373     HGCMFunctionParameter name;
374
375     /**
376      * The value of the property (IN pointer)
377      * Criteria as for the name parameter, but with length less than or equal to
378      * MAX_VALUE_LEN.
379      */
380     HGCMFunctionParameter value;
381 } SetPropertyValue;
382
383 /** The guest is requesting to remove a property */
384 typedef struct _DelProperty
385 {
386     VBoxGuestHGCMCallInfo hdr;
387
388     /**
389      * The property name.  This must fit to a number of criteria, namely
390      *  - Only Utf8 strings are allowed
391      *  - Less than or equal to MAX_NAME_LEN bytes in length
392      *  - Zero terminated
393      */
394     HGCMFunctionParameter name;
395 } DelProperty;
396
397 /** The guest is requesting to enumerate properties */
398 typedef struct _EnumProperties
399 {
400     VBoxGuestHGCMCallInfo hdr;
401
402     /**
403      * Array of patterns to match the properties against, separated by '|'
404      * characters.  For backwards compatibility, '\0' is also accepted
405      * as a separater.
406      * (IN pointer)
407      * If only a single, empty pattern is given then match all.
408      */
409     HGCMFunctionParameter patterns;
410     /**
411      * On success, null-separated array of strings in which the properties are
412      * returned.  (OUT pointer)
413      * The number of strings in the array is always a multiple of four,
414      * and in sequences of name, value, timestamp (hexadecimal string) and the
415      * flags as a comma-separated list in the format "name=value".  The list
416      * is terminated by an empty string after a "flags" entry (or at the
417      * start).
418      */
419     HGCMFunctionParameter strings;
420     /**
421      * On success, the size of the returned data.  If the buffer provided is
422      * too small, the size of buffer needed.  (OUT uint32_t)
423      */
424     HGCMFunctionParameter size;
425 } EnumProperties;
426
427 /**
428  * The guest is polling for notifications on changes to properties, specifying
429  * a set of patterns to match the names of changed properties against and
430  * optionally the timestamp of the last notification seen.
431  * On success, VINF_SUCCESS will be returned and the buffer will contain
432  * details of a property notification.  If no new notification is available
433  * which matches one of the specified patterns, the call will block until one
434  * is.
435  * If the last notification could not be found by timestamp, VWRN_NOT_FOUND
436  * will be returned and the oldest available notification will be returned.
437  * If a zero timestamp is specified, the call will always wait for a new
438  * notification to arrive.
439  * If the buffer supplied was not large enough to hold the notification,
440  * VERR_BUFFER_OVERFLOW will be returned and the size parameter will contain
441  * the size of the buffer needed.
442  *
443  * The protocol for a guest to obtain notifications is to call
444  * GET_NOTIFICATION in a loop.  On the first call, the ingoing timestamp
445  * parameter should be set to zero.  On subsequent calls, it should be set to
446  * the outgoing timestamp from the previous call.
447  */
448 typedef struct _GetNotification
449 {
450     VBoxGuestHGCMCallInfoTimed hdr;
451
452     /**
453      * A list of patterns to match the guest event name against, separated by
454      * vertical bars (|) (IN pointer)
455      * An empty string means match all.
456      */
457     HGCMFunctionParameter patterns;
458     /**
459      * The timestamp of the last change seen (IN uint64_t)
460      * This may be zero, in which case the oldest available change will be
461      * sent.  If the service does not remember an event matching the
462      * timestamp, then VWRN_NOT_FOUND will be returned, and the guest should
463      * assume that it has missed a certain number of notifications.
464      *
465      * The timestamp of the change being notified of (OUT uint64_t)
466      * Undefined on failure.
467      */
468     HGCMFunctionParameter timestamp;
469
470     /**
471      * The returned data, if any, will be placed here.  (OUT pointer)
472      * This call returns three null-terminated strings which will be placed
473      * one after another: name, value and flags.  For a delete notification,
474      * value and flags will be empty strings.  Undefined on failure.
475      */
476     HGCMFunctionParameter buffer;
477
478     /**
479      * On success, the size of the returned data.  (OUT uint32_t)
480      * On buffer overflow, the size of the buffer needed to hold the data.
481      * Undefined on failure.
482      */
483     HGCMFunctionParameter size;
484 } GetNotification;
485 #pragma pack ()
486
487 } /* namespace guestProp */
488
489 #endif  /* ___VBox_HostService_GuestPropertySvc_h defined */
Note: See TracBrowser for help on using the browser.

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy