VirtualBox

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

Last change on this file since 20542 was 14352, checked in by vboxsync, 16 years 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
File size: 15.5 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#include <iprt/string.h>
40
41/** Everything defined in this file lives in this namespace. */
42namespace guestProp {
43
44/******************************************************************************
45* Typedefs, constants and inlines *
46******************************************************************************/
47
48/** Maximum length for property names */
49enum { MAX_NAME_LEN = 64 };
50/** Maximum length for property values */
51enum { MAX_VALUE_LEN = 128 };
52/** Maximum number of properties per guest */
53enum { MAX_PROPS = 256 };
54/** Maximum size for enumeration patterns */
55enum { MAX_PATTERN_LEN = 1024 };
56/** Maximum number of changes we remember for guest notifications */
57enum { MAX_GUEST_NOTIFICATIONS = 256 };
58
59/**
60 * The guest property flag values which are currently accepted.
61 */
62enum 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 */
78DECLINLINE(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 */
101DECLINLINE(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 */
111enum { 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 */
124DECLINLINE(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 */
174DECLINLINE(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 */
212enum 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 */
252enum 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 */
272typedef 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
286enum
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 */
297typedef 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 */
332typedef 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 */
362typedef 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 */
384typedef 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 */
398typedef 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 */
448typedef 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 repository browser.

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