VirtualBox

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

Last change on this file was 102932, checked in by vboxsync, 4 months ago

Guest Properties/HostService: Fixed too strict debug assertions for property name / value length checks, which will happen with old(er) Guest Additions installed. Regression of r150110.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 19.9 KB
RevLine 
[9727]1/** @file
[70064]2 * Guest property service - Common header for host service and guest clients.
[9727]3 */
4
5/*
[98103]6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[9727]7 *
[96407]8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
[9727]10 *
[96407]11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
[11934]24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
[96407]26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
[11934]28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
[96407]32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
[9727]34 */
35
[76558]36#ifndef VBOX_INCLUDED_HostServices_GuestPropertySvc_h
37#define VBOX_INCLUDED_HostServices_GuestPropertySvc_h
[76507]38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
[9727]41
[68660]42#include <VBox/VMMDevCoreTypes.h>
[68656]43#include <VBox/VBoxGuestCoreTypes.h>
[68667]44#include <VBox/log.h>
[76395]45#include <iprt/err.h>
[70060]46#include <iprt/assertcompile.h>
[13928]47#include <iprt/string.h>
[9727]48
49
[95334]50/** Maximum size for property names (including the terminator). */
[70058]51#define GUEST_PROP_MAX_NAME_LEN 64
[95334]52/** Maximum size for property values (including the terminator). */
[95228]53#define GUEST_PROP_MAX_VALUE_LEN 1024
[75992]54/** Maximum number of properties per guest. */
[70058]55#define GUEST_PROP_MAX_PROPS 256
[95334]56/** Maximum size for enumeration patterns (including the terminators). */
[70058]57#define GUEST_PROP_MAX_PATTERN_LEN 1024
[75992]58/** Maximum number of changes we remember for guest notifications. */
[70058]59#define GUEST_PROP_MAX_GUEST_NOTIFICATIONS 256
[75992]60/** Maximum number of current pending waits per client. */
61#define GUEST_PROP_MAX_GUEST_CONCURRENT_WAITS 16
[13293]62
[70058]63
64/** @name GUEST_PROP_F_XXX - The guest property flag values which are currently accepted.
65 * @{
[13293]66 */
[70058]67#define GUEST_PROP_F_NILFLAG UINT32_C(0)
68/** Transient until VM gets shut down. */
69#define GUEST_PROP_F_TRANSIENT RT_BIT_32(1)
70#define GUEST_PROP_F_RDONLYGUEST RT_BIT_32(2)
71#define GUEST_PROP_F_RDONLYHOST RT_BIT_32(3)
72/** Transient until VM gets a reset / restarts.
73 * Implies TRANSIENT. */
74#define GUEST_PROP_F_TRANSRESET RT_BIT_32(4)
75#define GUEST_PROP_F_READONLY (GUEST_PROP_F_RDONLYGUEST | GUEST_PROP_F_RDONLYHOST)
76#define GUEST_PROP_F_ALLFLAGS (GUEST_PROP_F_TRANSIENT | GUEST_PROP_F_READONLY | GUEST_PROP_F_TRANSRESET)
77/** @} */
[13293]78
79/**
[93891]80 * Check that a string fits our criteria for a property name.
81 *
82 * @returns IPRT status code
[95338]83 * @param pszName The string to check, must be valid Utf8
84 * @param cbName The number of bytes @a pszName points to, including the
85 * terminating character.
[93891]86 */
[95338]87DECLINLINE(int) GuestPropValidateName(const char *pszName, size_t cbName)
[93891]88{
[102932]89 if ( cbName < 2 /* Property name is expected to be at least 1 charecter long plus terminating character. */
90 || cbName > GUEST_PROP_MAX_NAME_LEN)
91 return VERR_INVALID_PARAMETER;
[93891]92
93 AssertPtrReturn(pszName, VERR_INVALID_POINTER);
94
95 AssertReturn(memchr(pszName, '*', cbName) == NULL, VERR_INVALID_PARAMETER);
96 AssertReturn(memchr(pszName, '?', cbName) == NULL, VERR_INVALID_PARAMETER);
97 AssertReturn(memchr(pszName, '|', cbName) == NULL, VERR_INVALID_PARAMETER);
98
99 return VINF_SUCCESS;
100}
101
102/**
103 * Check a string fits our criteria for the value of a guest property.
104 *
105 * @returns IPRT status code
[95228]106 * @retval VINF_SUCCESS if guest property value corresponds to all criteria.
107 * @retval VERR_TOO_MUCH_DATA if guest property value size exceeds limits.
108 * @retval VERR_INVALID_PARAMETER if guest property does not correspond to all other criteria.
[95338]109 * @param pszValue The string to check, must be valid utf-8.
110 * @param cbValue The size of of @a pszValue in bytes, including the
111 * terminator.
[93891]112 * @thread HGCM
113 */
[95338]114DECLINLINE(int) GuestPropValidateValue(const char *pszValue, size_t cbValue)
[93891]115{
116 AssertPtrReturn(pszValue, VERR_INVALID_POINTER);
117
118 /* Zero-length values are possible, however buffer should contain terminating character at least. */
119 AssertReturn(cbValue > 0, VERR_INVALID_PARAMETER);
120
[102932]121 if (cbValue > GUEST_PROP_MAX_VALUE_LEN)
122 return VERR_TOO_MUCH_DATA;
123
[93891]124 return VINF_SUCCESS;
125}
126
127/**
[13574]128 * Get the name of a flag as a string.
129 * @returns the name, or NULL if fFlag is invalid.
[70222]130 * @param fFlag The flag, GUEST_PROP_F_XXX.
131 * @param pcchName Where to return the name length.
[13293]132 */
[70222]133DECLINLINE(const char *) GuestPropFlagNameAndLen(uint32_t fFlag, size_t *pcchName)
[13293]134{
[36178]135 switch (fFlag)
[13574]136 {
[70058]137 case GUEST_PROP_F_TRANSIENT:
[70222]138 *pcchName = sizeof("TRANSIENT") - 1;
[13574]139 return "TRANSIENT";
[70058]140 case GUEST_PROP_F_RDONLYGUEST:
[70222]141 *pcchName = sizeof("RDONLYGUEST") - 1;
[13574]142 return "RDONLYGUEST";
[70058]143 case GUEST_PROP_F_RDONLYHOST:
[70222]144 *pcchName = sizeof("RDONLYHOST") - 1;
[13574]145 return "RDONLYHOST";
[70058]146 case GUEST_PROP_F_READONLY:
[70222]147 *pcchName = sizeof("READONLY") - 1;
[13574]148 return "READONLY";
[70058]149 case GUEST_PROP_F_TRANSRESET:
[70222]150 *pcchName = sizeof("TRANSRESET") - 1;
[36219]151 return "TRANSRESET";
[13574]152 default:
[70222]153 *pcchName = 0;
154 return NULL;
[13574]155 }
156}
157
158/**
159 * Maximum length for the property flags field. We only ever return one of
160 * RDONLYGUEST, RDONLYHOST and RDONLY
161 */
[70058]162#define GUEST_PROP_MAX_FLAGS_LEN sizeof("TRANSIENT, RDONLYGUEST, TRANSRESET")
[13293]163
164/**
[13574]165 * Parse a guest properties flags string for flag names and make sure that
166 * there is no junk text in the string.
[70058]167 *
[13293]168 * @returns IPRT status code
[70058]169 * @retval VERR_INVALID_PARAMETER if the flag string is not valid
[13293]170 * @param pcszFlags the flag string to parse
171 * @param pfFlags where to store the parse result. May not be NULL.
172 * @note This function is also inline because it must be accessible from
173 * several modules and it does not seem reasonable to put it into
174 * its own library.
175 */
[70058]176DECLINLINE(int) GuestPropValidateFlags(const char *pcszFlags, uint32_t *pfFlags)
[13293]177{
[24666]178 static const uint32_t s_aFlagList[] =
[13574]179 {
[70058]180 GUEST_PROP_F_TRANSIENT, GUEST_PROP_F_READONLY, GUEST_PROP_F_RDONLYGUEST, GUEST_PROP_F_RDONLYHOST, GUEST_PROP_F_TRANSRESET
[13574]181 };
[13293]182 const char *pcszNext = pcszFlags;
183 int rc = VINF_SUCCESS;
184 uint32_t fFlags = 0;
[90792]185 AssertLogRelReturn(RT_VALID_PTR(pfFlags), VERR_INVALID_POINTER);
[22173]186
187 if (pcszFlags)
[13293]188 {
[70222]189 while (*pcszNext == ' ')
[22173]190 ++pcszNext;
191 while ((*pcszNext != '\0') && RT_SUCCESS(rc))
[13293]192 {
[70222]193 unsigned i;
194 rc = VERR_PARSE_ERROR;
195 for (i = 0; i < RT_ELEMENTS(s_aFlagList); ++i)
196 {
197 size_t cchFlagName;
198 const char *pszFlagName = GuestPropFlagNameAndLen(s_aFlagList[i], &cchFlagName);
[71010]199 if (RTStrNICmpAscii(pcszNext, pszFlagName, cchFlagName) == 0)
[70222]200 {
201 char ch;
202 fFlags |= s_aFlagList[i];
203 pcszNext += cchFlagName;
204 while ((ch = *pcszNext) == ' ')
205 ++pcszNext;
206 rc = VINF_SUCCESS;
207 if (ch == ',')
208 {
209 ++pcszNext;
210 while (*pcszNext == ' ')
211 ++pcszNext;
212 }
213 else if (ch != '\0')
214 rc = VERR_PARSE_ERROR;
[22173]215 break;
[70222]216 }
[22173]217 }
[13293]218 }
219 }
220 if (RT_SUCCESS(rc))
221 *pfFlags = fFlags;
222 return rc;
223}
224
[70058]225
[13293]226/**
227 * Write out flags to a string.
228 * @returns IPRT status code
[70221]229 * @param fFlags the flags to write out
230 * @param pszFlags where to write the flags string. This must point to
[70222]231 * a buffer of size (at least) GUEST_PROP_MAX_FLAGS_LEN.
[13293]232 */
[70221]233DECLINLINE(int) GuestPropWriteFlags(uint32_t fFlags, char *pszFlags)
[13293]234{
[36413]235 /* Putting READONLY before the other RDONLY flags keeps the result short. */
[24666]236 static const uint32_t s_aFlagList[] =
[13574]237 {
[70058]238 GUEST_PROP_F_TRANSIENT, GUEST_PROP_F_READONLY, GUEST_PROP_F_RDONLYGUEST, GUEST_PROP_F_RDONLYHOST, GUEST_PROP_F_TRANSRESET
[13574]239 };
[13293]240 int rc = VINF_SUCCESS;
[36412]241
[90792]242 AssertLogRelReturn(RT_VALID_PTR(pszFlags), VERR_INVALID_POINTER);
[70058]243 if ((fFlags & ~GUEST_PROP_F_ALLFLAGS) == GUEST_PROP_F_NILFLAG)
[13293]244 {
[70221]245 char *pszNext;
[70090]246 unsigned i;
247
[36412]248 /* TRANSRESET implies TRANSIENT. For compatability with old clients we
249 always set TRANSIENT when TRANSRESET appears. */
[70058]250 if (fFlags & GUEST_PROP_F_TRANSRESET)
251 fFlags |= GUEST_PROP_F_TRANSIENT;
[36412]252
[70221]253 pszNext = pszFlags;
[70089]254 for (i = 0; i < RT_ELEMENTS(s_aFlagList); ++i)
[13293]255 {
[24666]256 if (s_aFlagList[i] == (fFlags & s_aFlagList[i]))
[13293]257 {
[70222]258 size_t cchFlagName;
259 const char *pszFlagName = GuestPropFlagNameAndLen(s_aFlagList[i], &cchFlagName);
260 memcpy(pszNext, pszFlagName, cchFlagName);
261 pszNext += cchFlagName;
[24666]262 fFlags &= ~s_aFlagList[i];
[70058]263 if (fFlags != GUEST_PROP_F_NILFLAG)
[70090]264 {
[70222]265 *pszNext++ = ',';
266 *pszNext++ = ' ';
[70090]267 }
[13293]268 }
269 }
[70221]270 *pszNext = '\0';
[36412]271
[70222]272 Assert((uintptr_t)(pszNext - pszFlags) < GUEST_PROP_MAX_FLAGS_LEN);
[70058]273 Assert(fFlags == GUEST_PROP_F_NILFLAG); /* bad s_aFlagList */
[13293]274 }
[36412]275 else
276 rc = VERR_INVALID_PARAMETER;
[13293]277 return rc;
278}
279
[70058]280
281/** @name The service functions which are callable by host.
282 * @{
[9727]283 */
[70058]284/** Set properties in a block.
285 * The parameters are pointers to NULL-terminated arrays containing the
286 * parameters. These are, in order, name, value, timestamp, flags. Strings are
287 * stored as pointers to mutable utf8 data. All parameters must be supplied. */
[70063]288#define GUEST_PROP_FN_HOST_SET_PROPS 1
[70058]289/** Get the value attached to a guest property.
290 * The parameter format matches that of GET_PROP. */
[70063]291#define GUEST_PROP_FN_HOST_GET_PROP 2
[70058]292/** Set the value attached to a guest property.
293 * The parameter format matches that of SET_PROP. */
[70063]294#define GUEST_PROP_FN_HOST_SET_PROP 3
[70058]295/** Set the value attached to a guest property.
296 * The parameter format matches that of SET_PROP_VALUE. */
[70063]297#define GUEST_PROP_FN_HOST_SET_PROP_VALUE 4
[70058]298/** Remove a guest property.
299 * The parameter format matches that of DEL_PROP. */
[70063]300#define GUEST_PROP_FN_HOST_DEL_PROP 5
[70058]301/** Enumerate guest properties.
302 * The parameter format matches that of ENUM_PROPS. */
[70063]303#define GUEST_PROP_FN_HOST_ENUM_PROPS 6
[70058]304/** Set global flags for the service.
305 * Currently RDONLYGUEST is supported. Takes one 32-bit unsigned integer
306 * parameter for the flags. */
[70063]307#define GUEST_PROP_FN_HOST_SET_GLOBAL_FLAGS 7
[70058]308/** @} */
[24703]309
[40767]310
[70058]311/** @name The service functions which are called by guest.
312 *
313 * @note The numbers may not change!
314 * @{
[9727]315 */
[70058]316/** Get a guest property */
317#define GUEST_PROP_FN_GET_PROP 1
318/** Set a guest property */
319#define GUEST_PROP_FN_SET_PROP 2
320/** Set just the value of a guest property */
321#define GUEST_PROP_FN_SET_PROP_VALUE 3
322/** Delete a guest property */
323#define GUEST_PROP_FN_DEL_PROP 4
324/** Enumerate guest properties */
325#define GUEST_PROP_FN_ENUM_PROPS 5
326/** Poll for guest notifications */
327#define GUEST_PROP_FN_GET_NOTIFICATION 6
328/** @} */
[9727]329
[70058]330
[9727]331/**
[70058]332 * Data structure to pass to the service extension callback.
333 * We use this to notify the host of changes to properties.
[13376]334 */
[70058]335typedef struct GUESTPROPHOSTCALLBACKDATA
[13376]336{
[70058]337 /** Magic number to identify the structure (GUESTPROPHOSTCALLBACKDATA_MAGIC). */
338 uint32_t u32Magic;
[13376]339 /** The name of the property that was changed */
[70058]340 const char *pcszName;
[13376]341 /** The new property value, or NULL if the property was deleted */
[70058]342 const char *pcszValue;
[13376]343 /** The timestamp of the modification */
[70058]344 uint64_t u64Timestamp;
[13376]345 /** The flags field of the modified property */
[70058]346 const char *pcszFlags;
347} GUESTPROPHOSTCALLBACKDATA;
348/** Poitner to a data structure to pass to the service extension callback. */
349typedef GUESTPROPHOSTCALLBACKDATA *PGUESTPROPHOSTCALLBACKDATA;
[13376]350
[70058]351/** Magic number for sanity checking the HOSTCALLBACKDATA structure */
352#define GUESTPROPHOSTCALLBACKDATA_MAGIC UINT32_C(0x69c87a78)
[13376]353
354/**
[9727]355 * HGCM parameter structures. Packing is explicitly defined as this is a wire format.
356 */
[10797]357/** The guest is requesting the value of a property */
[70061]358typedef struct GuestPropMsgGetProperty
[9727]359{
[68550]360 VBGLIOCHGCMCALL hdr;
[9727]361
362 /**
[10797]363 * The property name (IN pointer)
[9727]364 * This must fit to a number of criteria, namely
[10797]365 * - Only Utf8 strings are allowed
366 * - Less than or equal to MAX_NAME_LEN bytes in length
[9727]367 * - Zero terminated
368 */
[10797]369 HGCMFunctionParameter name;
[9727]370
371 /**
[10797]372 * The returned string data will be placed here. (OUT pointer)
373 * This call returns two null-terminated strings which will be placed one
374 * after another: value and flags.
[9727]375 */
[10797]376 HGCMFunctionParameter buffer;
[9727]377
378 /**
[10797]379 * The property timestamp. (OUT uint64_t)
380 */
381 HGCMFunctionParameter timestamp;
382
383 /**
384 * If the buffer provided was large enough this will contain the size of
385 * the returned data. Otherwise it will contain the size of the buffer
386 * needed to hold the data and VERR_BUFFER_OVERFLOW will be returned.
[9882]387 * (OUT uint32_t)
[9727]388 */
389 HGCMFunctionParameter size;
[70061]390} GuestPropMsgGetProperty;
391AssertCompileSize(GuestPropMsgGetProperty, 40 + 4 * (ARCH_BITS == 64 ? 16 : 12));
[9727]392
[10797]393/** The guest is requesting to change a property */
[70061]394typedef struct GuestPropMsgSetProperty
[9727]395{
[68550]396 VBGLIOCHGCMCALL hdr;
[9727]397
398 /**
[13159]399 * The property name. (IN pointer)
[10797]400 * This must fit to a number of criteria, namely
401 * - Only Utf8 strings are allowed
402 * - Less than or equal to MAX_NAME_LEN bytes in length
[9727]403 * - Zero terminated
404 */
[10797]405 HGCMFunctionParameter name;
[9727]406
407 /**
[10797]408 * The value of the property (IN pointer)
[13159]409 * Criteria as for the name parameter, but with length less than or equal to
[13995]410 * MAX_VALUE_LEN.
[9727]411 */
412 HGCMFunctionParameter value;
[10003]413
[10797]414 /**
415 * The property flags (IN pointer)
416 * This is a comma-separated list of the format flag=value
[70222]417 * The length must be less than or equal to GUEST_PROP_MAX_FLAGS_LEN and only
[10797]418 * known flag names and values will be accepted.
419 */
420 HGCMFunctionParameter flags;
[70061]421} GuestPropMsgSetProperty;
422AssertCompileSize(GuestPropMsgSetProperty, 40 + 3 * (ARCH_BITS == 64 ? 16 : 12));
[10797]423
424/** The guest is requesting to change the value of a property */
[70061]425typedef struct GuestPropMsgSetPropertyValue
[10003]426{
[68550]427 VBGLIOCHGCMCALL hdr;
[10003]428
429 /**
[13159]430 * The property name. (IN pointer)
[10797]431 * This must fit to a number of criteria, namely
432 * - Only Utf8 strings are allowed
433 * - Less than or equal to MAX_NAME_LEN bytes in length
[10003]434 * - Zero terminated
435 */
[10797]436 HGCMFunctionParameter name;
437
438 /**
439 * The value of the property (IN pointer)
[13159]440 * Criteria as for the name parameter, but with length less than or equal to
[13995]441 * MAX_VALUE_LEN.
[10797]442 */
443 HGCMFunctionParameter value;
[70061]444} GuestPropMsgSetPropertyValue;
445AssertCompileSize(GuestPropMsgSetPropertyValue, 40 + 2 * (ARCH_BITS == 64 ? 16 : 12));
[10797]446
447/** The guest is requesting to remove a property */
[70061]448typedef struct GuestPropMsgDelProperty
[10797]449{
[68550]450 VBGLIOCHGCMCALL hdr;
[10797]451
452 /**
453 * The property name. This must fit to a number of criteria, namely
454 * - Only Utf8 strings are allowed
455 * - Less than or equal to MAX_NAME_LEN bytes in length
456 * - Zero terminated
457 */
458 HGCMFunctionParameter name;
[70061]459} GuestPropMsgDelProperty;
460AssertCompileSize(GuestPropMsgDelProperty, 40 + 1 * (ARCH_BITS == 64 ? 16 : 12));
[10797]461
462/** The guest is requesting to enumerate properties */
[70061]463typedef struct GuestPropMsgEnumProperties
[10797]464{
[68550]465 VBGLIOCHGCMCALL hdr;
[10797]466
467 /**
[13558]468 * Array of patterns to match the properties against, separated by '|'
[25647]469 * characters. For backwards compatibility, '\\0' is also accepted
[13558]470 * as a separater.
[10797]471 * (IN pointer)
[13558]472 * If only a single, empty pattern is given then match all.
[10797]473 */
474 HGCMFunctionParameter patterns;
475 /**
[10929]476 * On success, null-separated array of strings in which the properties are
477 * returned. (OUT pointer)
[10797]478 * The number of strings in the array is always a multiple of four,
479 * and in sequences of name, value, timestamp (hexadecimal string) and the
[10929]480 * flags as a comma-separated list in the format "name=value". The list
[11040]481 * is terminated by an empty string after a "flags" entry (or at the
482 * start).
[10797]483 */
484 HGCMFunctionParameter strings;
[10929]485 /**
486 * On success, the size of the returned data. If the buffer provided is
487 * too small, the size of buffer needed. (OUT uint32_t)
488 */
489 HGCMFunctionParameter size;
[70061]490} GuestPropMsgEnumProperties;
491AssertCompileSize(GuestPropMsgEnumProperties, 40 + 3 * (ARCH_BITS == 64 ? 16 : 12));
[13916]492
493/**
[14104]494 * The guest is polling for notifications on changes to properties, specifying
495 * a set of patterns to match the names of changed properties against and
496 * optionally the timestamp of the last notification seen.
[13916]497 * On success, VINF_SUCCESS will be returned and the buffer will contain
[14104]498 * details of a property notification. If no new notification is available
499 * which matches one of the specified patterns, the call will block until one
500 * is.
[13916]501 * If the last notification could not be found by timestamp, VWRN_NOT_FOUND
502 * will be returned and the oldest available notification will be returned.
[14104]503 * If a zero timestamp is specified, the call will always wait for a new
504 * notification to arrive.
[13916]505 * If the buffer supplied was not large enough to hold the notification,
506 * VERR_BUFFER_OVERFLOW will be returned and the size parameter will contain
507 * the size of the buffer needed.
[13971]508 *
509 * The protocol for a guest to obtain notifications is to call
510 * GET_NOTIFICATION in a loop. On the first call, the ingoing timestamp
511 * parameter should be set to zero. On subsequent calls, it should be set to
[13995]512 * the outgoing timestamp from the previous call.
[13916]513 */
[70061]514typedef struct GuestPropMsgGetNotification
[13916]515{
[68550]516 VBGLIOCHGCMCALL hdr;
[13916]517
518 /**
[14104]519 * A list of patterns to match the guest event name against, separated by
520 * vertical bars (|) (IN pointer)
521 * An empty string means match all.
522 */
523 HGCMFunctionParameter patterns;
524 /**
[13916]525 * The timestamp of the last change seen (IN uint64_t)
526 * This may be zero, in which case the oldest available change will be
527 * sent. If the service does not remember an event matching the
528 * timestamp, then VWRN_NOT_FOUND will be returned, and the guest should
529 * assume that it has missed a certain number of notifications.
530 *
531 * The timestamp of the change being notified of (OUT uint64_t)
[13971]532 * Undefined on failure.
[13916]533 */
534 HGCMFunctionParameter timestamp;
535
536 /**
[13971]537 * The returned data, if any, will be placed here. (OUT pointer)
[13916]538 * This call returns three null-terminated strings which will be placed
539 * one after another: name, value and flags. For a delete notification,
540 * value and flags will be empty strings. Undefined on failure.
541 */
542 HGCMFunctionParameter buffer;
543
544 /**
545 * On success, the size of the returned data. (OUT uint32_t)
546 * On buffer overflow, the size of the buffer needed to hold the data.
547 * Undefined on failure.
548 */
549 HGCMFunctionParameter size;
[70061]550} GuestPropMsgGetNotification;
551AssertCompileSize(GuestPropMsgGetNotification, 40 + 4 * (ARCH_BITS == 64 ? 16 : 12));
[9727]552
553
[76585]554#endif /* !VBOX_INCLUDED_HostServices_GuestPropertySvc_h */
[37980]555
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use