Changeset 10797 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
- Timestamp:
- Jul 22, 2008 8:12:42 AM (16 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
r10683 r10797 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, information service. 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, 4 * guest properties. 4 5 */ 5 6 … … 28 29 #include <iprt/assert.h> 29 30 #include <VBox/log.h> 30 #include <VBox/HostServices/ VBoxInfoSvc.h> /* For Save and RetrieveVideoMode */31 #include <VBox/HostServices/GuestPropertySvc.h> 31 32 32 33 #include "VBGLR3Internal.h" 33 34 34 using namespace svcInfo;35 36 /** 37 * Connects to the informationservice.35 using namespace guestProp; 36 37 /** 38 * Connects to the guest property service. 38 39 * 39 40 * @returns VBox status code … … 41 42 * must be passed to all the other calls to the service. 42 43 */ 43 VBGLR3DECL(int) VbglR3 InfoSvcConnect(uint32_t *pu32ClientId)44 VBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId) 44 45 { 45 46 VBoxGuestHGCMConnectInfo Info; … … 47 48 Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing; 48 49 memset(&Info.Loc.u, 0, sizeof(Info.Loc.u)); 49 strcpy(Info.Loc.u.host.achName, "VBox SharedInfoSvc");50 strcpy(Info.Loc.u.host.achName, "VBoxGuestPropSvc"); 50 51 Info.u32ClientID = UINT32_MAX; /* try make valgrid shut up. */ 51 52 … … 62 63 63 64 /** 64 * Disconnect from the informationservice.65 * Disconnect from the guest property service. 65 66 * 66 67 * @returns VBox status code. 67 68 * @param u32ClientId The client id returned by VbglR3InfoSvcConnect(). 68 69 */ 69 VBGLR3DECL(int) VbglR3 InfoSvcDisconnect(uint32_t u32ClientId)70 VBGLR3DECL(int) VbglR3GuestPropDisconnect(uint32_t u32ClientId) 70 71 { 71 72 VBoxGuestHGCMDisconnectInfo Info; … … 81 82 82 83 /** 83 * Write a key value.84 * Write a property value. 84 85 * 85 86 * @returns VBox status code. 86 87 * @param u32ClientId The client id returned by VbglR3InvsSvcConnect(). 87 * @param psz Key The key to save to. Utf888 * @param pszName The property to save to. Utf8 88 89 * @param pszValue The value to store. Utf8. If this is NULL then 89 * the key will be removed. 90 */ 91 VBGLR3DECL(int) VbglR3InfoSvcWriteKey(uint32_t u32ClientId, char *pszKey, char *pszValue) 90 * the property will be removed. 91 * @param pszFlags The flags for the property 92 */ 93 VBGLR3DECL(int) VbglR3GuestPropWrite(uint32_t u32ClientId, char *pszName, char *pszValue, char *pszFlags) 92 94 { 93 95 int rc; … … 95 97 if (pszValue != NULL) 96 98 { 97 Set ConfigKey Msg;99 SetProperty Msg; 98 100 99 101 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 100 102 Msg.hdr.u32ClientID = u32ClientId; 101 Msg.hdr.u32Function = SET_ CONFIG_KEY;103 Msg.hdr.u32Function = SET_PROP_VALUE; 102 104 Msg.hdr.cParms = 2; 103 VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1); 105 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 106 VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1); 107 VbglHGCMParmPtrSet(&Msg.flags, pszFlags, strlen(pszFlags) + 1); 108 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 109 if (RT_SUCCESS(rc)) 110 rc = Msg.hdr.result; 111 } 112 else 113 { 114 DelProperty Msg; 115 116 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 117 Msg.hdr.u32ClientID = u32ClientId; 118 Msg.hdr.u32Function = DEL_PROP; 119 Msg.hdr.cParms = 1; 120 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 121 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 122 if (RT_SUCCESS(rc)) 123 rc = Msg.hdr.result; 124 } 125 return rc; 126 } 127 128 129 /** 130 * Write a property value. 131 * 132 * @returns VBox status code. 133 * @param u32ClientId The client id returned by VbglR3InvsSvcConnect(). 134 * @param pszName The property to save to. Utf8 135 * @param pszValue The value to store. Utf8. If this is NULL then 136 * the property will be removed. 137 * @note if the property already exists and pszValue is not NULL then the 138 * property's flags field will be left unchanged 139 */ 140 VBGLR3DECL(int) VbglR3GuestPropWriteValue(uint32_t u32ClientId, char *pszName, char *pszValue) 141 { 142 int rc; 143 144 if (pszValue != NULL) 145 { 146 SetPropertyValue Msg; 147 148 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 149 Msg.hdr.u32ClientID = u32ClientId; 150 Msg.hdr.u32Function = SET_PROP_VALUE; 151 Msg.hdr.cParms = 2; 152 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 104 153 VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1); 105 154 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); … … 109 158 else 110 159 { 111 Del ConfigKey Msg;160 DelProperty Msg; 112 161 113 162 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 114 163 Msg.hdr.u32ClientID = u32ClientId; 115 Msg.hdr.u32Function = DEL_ CONFIG_KEY;164 Msg.hdr.u32Function = DEL_PROP; 116 165 Msg.hdr.cParms = 1; 117 VbglHGCMParmPtrSet(&Msg. key, pszKey, strlen(pszKey) + 1);166 VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1); 118 167 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 119 168 if (RT_SUCCESS(rc)) … … 125 174 126 175 /** 127 * Retrieve a key value. 128 * 129 * @returns VBox status code. 130 * @retval VINF_SUCCESS on success, pszValue and pcbActual containing valid data. 131 * @retval VERR_BUFFER_OVERFLOW if the buffer is too small, pcbActual will contain 132 * the require buffer size. Note race condition here when retrying wrt 133 * someone updating it. 176 * Retrieve a property. 177 * 178 * @returns VBox status code. 179 * @retval VINF_SUCCESS on success, pszValue, pu64Timestamp and pszFlags 180 * containing valid data. 181 * @retval VERR_BUFFER_OVERFLOW if the scratch buffer @a pcBuf is not large 182 * enough. In this case the size needed will be placed in 183 * @a pcbBufActual if it is not NULL. 134 184 * @retval VERR_NOT_FOUND if the key wasn't found. 135 185 * 136 186 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). 137 * @param pszKey The key to read. Utf8 138 * @param pszValue Where to store the value retrieved. Utf8. 139 * @param cbValue The size of the buffer pszValue points to. 140 * @param pcbActual Where to store the required buffer size if cbValue 141 * is too small. On success this contains the 142 * actual size of the value retrieved. Optional. 143 */ 144 VBGLR3DECL(int) VbglR3InfoSvcReadKey(uint32_t u32ClientId, char *pszKey, 145 char *pszValue, uint32_t cbValue, uint32_t *pcbActual) 146 { 147 GetConfigKey Msg; 187 * @param pszName The value to read. Utf8 188 * @param pcBuf A scratch buffer to store the data retrieved into. 189 * The returned data is only valid for it's lifetime. 190 * @param cbBuf The size of @a pcBuf 191 * @param pszValue Where to store the pointer to the value retrieved. 192 * @param pu64Timestamp Where to store the timestamp. Optional. 193 * @param pszFlags Where to store the pointer to the flags. Optional. 194 * @param pcbBufActual If @a pcBuf is not large enough, the size needed. 195 * Optional. 196 */ 197 VBGLR3DECL(int) VbglR3GuestPropRead(uint32_t u32ClientId, const char *pszName, 198 void *pvBuf, uint32_t cbBuf, 199 char **ppszValue, uint64_t *pu64Timestamp, 200 char **ppszFlags, 201 uint32_t *pcbBufActual) 202 { 203 GetProperty Msg; 148 204 149 205 Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */ 150 206 Msg.hdr.u32ClientID = u32ClientId; 151 Msg.hdr.u32Function = GET_CONFIG_KEY; 152 Msg.hdr.cParms = 3; 153 VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1); 154 VbglHGCMParmPtrSet(&Msg.value, pszValue, cbValue); 207 Msg.hdr.u32Function = GET_PROP; 208 Msg.hdr.cParms = 4; 209 VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName), 210 strlen(pszName) + 1); 211 VbglHGCMParmPtrSet(&Msg.buffer, pvBuf, cbBuf); 212 VbglHGCMParmUInt64Set(&Msg.timestamp, 0); 155 213 VbglHGCMParmUInt32Set(&Msg.size, 0); 156 214 … … 158 216 if (RT_SUCCESS(rc)) 159 217 rc = Msg.hdr.result; 160 uint32_t cbActual; 161 if (RT_SUCCESS(rc) || (VERR_BUFFER_OVERFLOW == rc)) 162 { 163 int rc2 = VbglHGCMParmUInt32Get(&Msg.size, &cbActual); 164 if (RT_SUCCESS(rc2)) 218 if ((VERR_BUFFER_OVERFLOW == rc) && (pcbBufActual != NULL)) 219 { 220 int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual); 221 if (!RT_SUCCESS(rc2)) 222 rc = rc2; 223 } 224 if (RT_SUCCESS(rc) && (pu64Timestamp != NULL)) 225 rc = VbglHGCMParmUInt64Get(&Msg.timestamp, pu64Timestamp); 226 if (RT_SUCCESS(rc)) 227 *ppszValue = reinterpret_cast<char *>(pvBuf); 228 if (RT_SUCCESS(rc) && (ppszFlags != NULL)) 229 { 230 bool found = false; 231 size_t i = 0; 232 char *pcBuf = reinterpret_cast<char *>(pvBuf); 233 for (; i < cbBuf && !found; ++i) 234 if (0 == pcBuf[i]) 235 found = true; 236 if (!found) 237 /* To my mind this is an internal error, but whatever */ 238 rc = VERR_TOO_MUCH_DATA; 239 else 240 *ppszFlags = pcBuf + i; 241 } 242 return rc; 243 } 244 245 246 /** 247 * Retrieve a property value, allocating space for it. 248 * 249 * @returns VBox status code. 250 * @retval VINF_SUCCESS on success, pszValue containing valid data. 251 * @retval VERR_NOT_FOUND if the key wasn't found. 252 * 253 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). 254 * @param pszName The value to read. Utf8 255 * @param ppszValue Where to store the pointer to the value returned. 256 */ 257 VBGLR3DECL(int) VbglR3GuestPropReadValueAlloc(uint32_t u32ClientId, 258 const char *pszName, 259 char **ppszValue) 260 { 261 int rc = VINF_SUCCESS; 262 uint32_t cchBuf = 1024; 263 void *pvBuf = RTMemAlloc(cchBuf); 264 char *pszValue = NULL; 265 if (NULL == pvBuf) 266 rc = VERR_NO_MEMORY; 267 if (RT_SUCCESS(rc)) 268 { 269 rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf, 270 &pszValue, NULL, NULL, &cchBuf); 271 if (VERR_BUFFER_OVERFLOW == rc) 165 272 { 166 if (pcbActual != NULL) 167 *pcbActual = cbActual; 273 /** @todo how should we handle the race condition here? */ 274 pvBuf = RTMemRealloc(pvBuf, cchBuf); 275 if (pvBuf != NULL) 276 rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf, 277 &pszValue, NULL, NULL, NULL); 278 else 279 rc = VERR_NO_MEMORY; 280 if (VERR_BUFFER_OVERFLOW == rc) 281 /* VERR_BUFFER_OVERFLOW has a different meaning here as a 282 * return code */ 283 rc = VERR_TOO_MUCH_DATA; 168 284 } 169 else 170 rc = rc2; 171 } 172 return rc; 173 } 285 } 286 if (RT_SUCCESS(rc)) 287 *ppszValue = pszValue; 288 return rc; 289 } 290 291 /** 292 * Free the memory used by VbglR3GuestPropReadValueAlloc for returning a 293 * value. 294 * 295 * @param pszValue the memory to be freed. NULL pointers will be ignored. 296 */ 297 VBGLR3DECL(void) VbglR3GuestPropReadValueFree(char *pszValue) 298 { 299 RTMemFree(pszValue); 300 } 301 302 303 /** 304 * Retrieve a property value, using a user-provided buffer to store it. 305 * 306 * @returns VBox status code. 307 * @retval VINF_SUCCESS on success, pszValue containing valid data. 308 * @retval VERR_BUFFER_OVERFLOW and the size needed in pcchValueActual if the 309 * buffer provided was too small 310 * @retval VERR_NOT_FOUND if the key wasn't found. 311 * 312 * @note There is a race here between obtaining the size of the buffer 313 * needed to hold the value and the value being updated. 314 * 315 * @param u32ClientId The client id returned by VbglR3ClipboardConnect(). 316 * @param pszName The value to read. Utf8 317 * @param pszValue Where to store the value retrieved. 318 * @param cchValue The size of the buffer pointed to by @a pszValue 319 * @param pcchValueActual Where to store the size of the buffer needed if 320 * the buffer supplied is too small. Optional. 321 */ 322 VBGLR3DECL(int) VbglR3GuestPropReadValue(uint32_t u32ClientId, const char *pszName, 323 char *pszValue, uint32_t cchValue, 324 uint32_t *pcchValueActual) 325 { 326 char *pcBuf = NULL; 327 int rc = VbglR3GuestPropReadValueAlloc(u32ClientId, pszName, &pcBuf); 328 if (RT_SUCCESS(rc)) 329 { 330 uint32_t cchValueActual = strlen(pcBuf) + 1; 331 if (cchValueActual > cchValue) 332 { 333 if (pcchValueActual != NULL) 334 *pcchValueActual = cchValueActual; 335 rc = VERR_BUFFER_OVERFLOW; 336 } 337 if (RT_SUCCESS(rc)) 338 strcpy(pszValue, pcBuf); 339 } 340 VbglR3GuestPropReadValueFree(pcBuf); 341 return rc; 342 }
Note:
See TracChangeset
for help on using the changeset viewer.