VirtualBox

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

Last change on this file since 68667 was 68667, checked in by vboxsync, 7 years ago

build fix

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