VirtualBox

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

Last change on this file since 35517 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

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