- Timestamp:
- Dec 11, 2012 5:06:02 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 82626
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.cpp
r33540 r44097 5 5 6 6 /* 7 * Copyright (C) 2009-201 0Oracle Corporation7 * Copyright (C) 2009-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 48 48 * on success. Optional. 49 49 */ 50 int VBoxServiceReadProp(uint32_t u32ClientId, const char *pszPropName, char **ppszValue, char **ppszFlags, uint64_t *puTimestamp) 51 { 50 int VBoxServiceReadProp(uint32_t u32ClientId, const char *pszPropName, 51 char **ppszValue, char **ppszFlags, uint64_t *puTimestamp) 52 { 53 AssertPtrReturn(pszPropName, VERR_INVALID_POINTER); 54 AssertPtrReturn(ppszValue, VERR_INVALID_POINTER); 55 52 56 uint32_t cbBuf = _1K; 53 57 void *pvBuf = NULL; … … 122 126 * 123 127 */ 124 int VBoxServiceReadPropUInt32(uint32_t u32ClientId, const char *pszPropName, uint32_t *pu32, uint32_t u32Min, uint32_t u32Max) 128 int VBoxServiceReadPropUInt32(uint32_t u32ClientId, const char *pszPropName, 129 uint32_t *pu32, uint32_t u32Min, uint32_t u32Max) 125 130 { 126 131 char *pszValue; 127 132 int rc = VBoxServiceReadProp(u32ClientId, pszPropName, &pszValue, 128 NULL /* ppszFlags */, NULL /* puTimestamp */);133 NULL /* ppszFlags */, NULL /* puTimestamp */); 129 134 if (RT_SUCCESS(rc)) 130 135 { 131 AssertPtr(pu32);132 136 char *pszNext; 133 137 rc = RTStrToUInt32Ex(pszValue, &pszNext, 0, pu32); … … 140 144 RTStrFree(pszValue); 141 145 } 146 return rc; 147 } 148 149 150 /** 151 * Reads a guest property from the host side. 152 * 153 * @returns VBox status code, fully bitched. 154 * 155 * @param u32ClientId The HGCM client ID for the guest property session. 156 * @param pszPropName The property name. 157 * @param fReadOnly Whether or not this property needs to be read only 158 * by the guest side. Otherwise VERR_ACCESS_DENIED will 159 * be returned. 160 * @param ppszValue Where to return the value. This is always set 161 * to NULL. Free it using RTStrFree(). 162 * @param ppszFlags Where to return the value flags. Free it 163 * using RTStrFree(). Optional. 164 * @param puTimestamp Where to return the timestamp. This is only set 165 * on success. Optional. 166 */ 167 int VBoxServiceReadHostProp(uint32_t u32ClientId, const char *pszPropName, bool fReadOnly, 168 char **ppszValue, char **ppszFlags, uint64_t *puTimestamp) 169 { 170 char *pszFlags; 171 int rc = VBoxServiceReadProp(u32ClientId, pszPropName, ppszValue, &pszFlags, puTimestamp); 172 if (RT_SUCCESS(rc)) 173 { 174 /* Check security bits. */ 175 if ( fReadOnly /* Do we except a guest read-only property */ 176 && !RTStrStr(pszFlags, "RDONLYGUEST")) 177 { 178 /* If we want a property which is read-only on the guest 179 * and it is *not* marked as such, deny access! */ 180 rc = VERR_ACCESS_DENIED; 181 } 182 183 if (ppszFlags) 184 *ppszFlags = pszFlags; 185 else 186 RTStrFree(pszFlags); 187 } 188 142 189 return rc; 143 190 } -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceUtils.h
r28800 r44097 5 5 6 6 /* 7 * Copyright (C) 2009 Oracle Corporation7 * Copyright (C) 2009-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 int VBoxServiceReadProp(uint32_t u32ClientId, const char *pszPropName, char **ppszValue, char **ppszFlags, uint64_t *puTimestamp); 25 25 int VBoxServiceReadPropUInt32(uint32_t u32ClientId, const char *pszPropName, uint32_t *pu32, uint32_t u32Min, uint32_t u32Max); 26 int VBoxServiceReadHostProp(uint32_t u32ClientId, const char *pszPropName, bool fReadOnly, char **ppszValue, char **ppszFlags, uint64_t *puTimestamp); 26 27 int VBoxServiceWritePropF(uint32_t u32ClientId, const char *pszName, const char *pszValueFormat, ...); 27 28 #endif -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
r44073 r44097 72 72 73 73 74 /** Structure containing information about a location awarness 75 * client provided by the host. */ 76 /** @todo Move this (and functions) into VbglR3. */ 77 typedef struct VBOXSERVICELACLIENTINFO 78 { 79 uint32_t uID; 80 char *pszName; 81 char *pszLocation; 82 char *pszDomain; 83 bool fAttached; 84 uint64_t uAttachedTS; 85 } VBOXSERVICELACLIENTINFO, *PVBOXSERVICELACLIENTINFO; 86 87 74 88 /******************************************************************************* 75 89 * Global Variables * … … 87 101 /** The VM session ID. Changes whenever the VM is restored or reset. */ 88 102 static uint64_t g_idVMInfoSession; 103 /** The last attached locartion awareness (LA) client timestamp. */ 104 static uint64_t g_LAClientAttachedTS = 0; 105 /** The current LA client info. */ 106 static VBOXSERVICELACLIENTINFO g_LAClientInfo; 89 107 90 108 … … 92 110 * Defines * 93 111 *******************************************************************************/ 112 static const char *g_pszLAActiveClient = "/VirtualBox/HostInfo/VRDP/ActiveClient"; 113 94 114 #ifdef VBOX_WITH_DBUS 95 115 /** ConsoleKit defines (taken from 0.4.5). */ … … 153 173 g_cMsVMInfoInterval = g_DefaultInterval * 1000; 154 174 if (!g_cMsVMInfoInterval) 155 g_cMsVMInfoInterval = 10 * 1000; 175 { 176 /* Set it to 5s by default for location awareness checks. */ 177 g_cMsVMInfoInterval = 5 * 1000; 178 } 156 179 157 180 int rc = RTSemEventMultiCreate(&g_hVMInfoEvent); … … 161 184 /* The status code is ignored as this information is not available with VBox < 3.2.10. */ 162 185 186 /* Initialize the LA client object. */ 187 RT_ZERO(g_LAClientInfo); 188 163 189 rc = VbglR3GuestPropConnect(&g_uVMInfoGuestPropSvcClientID); 164 190 if (RT_SUCCESS(rc)) 165 VBoxServiceVerbose(3, " VMInfo:Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID);191 VBoxServiceVerbose(3, "Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID); 166 192 else 167 193 { … … 170 196 if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */ 171 197 { 172 VBoxServiceVerbose(0, " VMInfo:Guest property service is not available, disabling the service\n");198 VBoxServiceVerbose(0, "Guest property service is not available, disabling the service\n"); 173 199 rc = VERR_SERVICE_DISABLED; 174 200 } 175 201 else 176 VBoxServiceError(" VMInfo:Failed to connect to the guest property service! Error: %Rrc\n", rc);202 VBoxServiceError("Failed to connect to the guest property service! Error: %Rrc\n", rc); 177 203 RTSemEventMultiDestroy(g_hVMInfoEvent); 178 204 g_hVMInfoEvent = NIL_RTSEMEVENTMULTI; … … 196 222 } 197 223 return rc; 224 } 225 226 227 /** 228 * Retrieves a specifiy client LA property. 229 * 230 * @return IPRT status code. 231 * @param uClientID LA client ID to retrieve property for. 232 * @param pszProperty Property (without path) to retrieve. 233 * @param ppszValue Where to store value of property. 234 * @param puTimestamp Timestamp of property to retrieve. Optional. 235 */ 236 static int vboxServiceGetLAClientValue(uint32_t uClientID, const char *pszProperty, 237 char **ppszValue, uint64_t *puTimestamp) 238 { 239 AssertReturn(uClientID, VERR_INVALID_PARAMETER); 240 AssertPtrReturn(pszProperty, VERR_INVALID_POINTER); 241 242 int rc; 243 244 char pszClientPath[255]; 245 if (RTStrPrintf(pszClientPath, sizeof(pszClientPath), 246 "/VirtualBox/HostInfo/VRDP/Client/%RU32/%s", uClientID, pszProperty)) 247 { 248 rc = VBoxServiceReadHostProp(g_uVMInfoGuestPropSvcClientID, pszClientPath, true /* Read only */, 249 ppszValue, NULL /* Flags */, puTimestamp); 250 } 251 else 252 rc = VERR_NO_MEMORY; 253 254 return rc; 255 } 256 257 258 /** 259 * Retrieves LA client information. On success the returned structure will have allocated 260 * objects which need to be free'd with vboxServiceFreeLAClientInfo. 261 * 262 * @return IPRT status code. 263 * @param uClientID Client ID to retrieve information for. 264 * @param pClient Pointer where to store the client information. 265 */ 266 static int vboxServiceGetLAClientInfo(uint32_t uClientID, PVBOXSERVICELACLIENTINFO pClient) 267 { 268 AssertReturn(uClientID, VERR_INVALID_PARAMETER); 269 AssertPtrReturn(pClient, VERR_INVALID_POINTER); 270 271 int rc = vboxServiceGetLAClientValue(uClientID, "Name", &pClient->pszName, 272 NULL /* Timestamp */); 273 if (RT_SUCCESS(rc)) 274 { 275 char *pszAttach; 276 rc = vboxServiceGetLAClientValue(uClientID, "Attach", &pszAttach, 277 &pClient->uAttachedTS); 278 if (RT_SUCCESS(rc)) 279 { 280 AssertPtr(pszAttach); 281 pClient->fAttached = !RTStrICmp(pszAttach, "1") ? true : false; 282 283 RTStrFree(pszAttach); 284 } 285 } 286 if (RT_SUCCESS(rc)) 287 rc = vboxServiceGetLAClientValue(uClientID, "Location", &pClient->pszLocation, 288 NULL /* Timestamp */); 289 if (RT_SUCCESS(rc)) 290 rc = vboxServiceGetLAClientValue(uClientID, "Domain", &pClient->pszDomain, 291 NULL /* Timestamp */); 292 if (RT_SUCCESS(rc)) 293 pClient->uID = uClientID; 294 295 return rc; 296 } 297 298 299 /** 300 * Frees all allocated LA client information of a structure. 301 * 302 * @param pClient Pointer to client information structure to free. 303 */ 304 static void vboxServiceFreeLAClientInfo(PVBOXSERVICELACLIENTINFO pClient) 305 { 306 if (pClient) 307 { 308 if (pClient->pszName) 309 RTStrFree(pClient->pszName); 310 if (pClient->pszLocation) 311 RTStrFree(pClient->pszLocation); 312 if (pClient->pszDomain) 313 RTStrFree(pClient->pszDomain); 314 315 pClient = NULL; 316 } 198 317 } 199 318 … … 433 552 } 434 553 435 VBoxServiceVerbose(4, "ConsoleKit: session '%s' is %s\n", 554 VBoxServiceVerbose(4, "ConsoleKit: session '%s' is %s\n", 436 555 *ppszCurSession, fActive ? "active" : "not active"); 437 556 … … 613 732 if (RT_FAILURE(rc)) 614 733 { 615 VBoxServiceError(" VMInfo:Error writing logged on users list, rc=%Rrc\n", rc);734 VBoxServiceError("Error writing logged on users list, rc=%Rrc\n", rc); 616 735 cUsersInList = 0; /* Reset user count on error. */ 617 736 } … … 620 739 if (RT_FAILURE(rc)) 621 740 { 622 VBoxServiceError(" VMInfo:Error writing logged on users count, rc=%Rrc\n", rc);741 VBoxServiceError("Error writing logged on users count, rc=%Rrc\n", rc); 623 742 cUsersInList = 0; /* Reset user count on error. */ 624 743 } … … 629 748 cUsersInList == 0 ? "true" : "false"); 630 749 if (RT_FAILURE(rc)) 631 VBoxServiceError(" VMInfo:Error writing no logged in users beacon, rc=%Rrc\n", rc);750 VBoxServiceError("Error writing no logged in users beacon, rc=%Rrc\n", rc); 632 751 g_cVMInfoLoggedInUsers = cUsersInList; 633 752 } … … 1066 1185 break; 1067 1186 1187 /* Whether to wait for event semaphore or not. */ 1188 bool fWait = true; 1189 1190 /* Check for location awareness. This most likely only 1191 * works with VBox (latest) 4.1 and up. */ 1192 1193 /* Check for new connection. */ 1194 char *pszLAClientID; 1195 int rc2 = VBoxServiceReadHostProp(g_uVMInfoGuestPropSvcClientID, g_pszLAActiveClient, true /* Read only */, 1196 &pszLAClientID, NULL /* Flags */, NULL /* Timestamp */); 1197 if (RT_SUCCESS(rc2)) 1198 { 1199 if (RTStrICmp(pszLAClientID, "0")) /* Is a client connected? */ 1200 { 1201 uint32_t uLAClientID = RTStrToInt32(pszLAClientID); 1202 uint64_t uLAClientAttachedTS; 1203 1204 /* Peek at "Attach" value to figure out if hotdesking happened. */ 1205 char *pszAttach = NULL; 1206 rc2 = vboxServiceGetLAClientValue(uLAClientID, "Attach", &pszAttach, 1207 &uLAClientAttachedTS); 1208 1209 if ( RT_SUCCESS(rc2) 1210 && ( !g_LAClientAttachedTS 1211 || (g_LAClientAttachedTS != uLAClientAttachedTS))) 1212 { 1213 vboxServiceFreeLAClientInfo(&g_LAClientInfo); 1214 1215 /* Note: There is a race between setting the guest properties by the host and getting them by 1216 * the guest. */ 1217 rc2 = vboxServiceGetLAClientInfo(uLAClientID, &g_LAClientInfo); 1218 if (RT_SUCCESS(rc2)) 1219 { 1220 VBoxServiceVerbose(1, "VRDP: Hotdesk client %s with ID=%RU32, Name=%s, Domain=%s\n", 1221 /* If g_LAClientAttachedTS is 0 this means there already was an active 1222 * hotdesk session when VBoxService started. */ 1223 !g_LAClientAttachedTS ? "already active" : g_LAClientInfo.fAttached ? "connected" : "disconnected", 1224 uLAClientID, g_LAClientInfo.pszName, g_LAClientInfo.pszDomain); 1225 1226 g_LAClientAttachedTS = g_LAClientInfo.uAttachedTS; 1227 1228 /* Don't wait for event semaphore below anymore because we now know that the client 1229 * changed. This means we need to iterate all VM information again immediately. */ 1230 fWait = false; 1231 } 1232 else 1233 { 1234 static int s_iBitchedAboutLAClientInfo = 0; 1235 if (s_iBitchedAboutLAClientInfo++ < 10) 1236 VBoxServiceError("Error getting active location awareness client info, rc=%Rrc\n", rc2); 1237 } 1238 } 1239 else if (RT_FAILURE(rc2)) 1240 VBoxServiceError("Error getting attached value of location awareness client %RU32, rc=%Rrc\n", 1241 uLAClientID, rc2); 1242 if (pszAttach) 1243 RTStrFree(pszAttach); 1244 } 1245 else 1246 { 1247 VBoxServiceVerbose(1, "VRDP: UTTSC disconnected from VRDP server\n"); 1248 vboxServiceFreeLAClientInfo(&g_LAClientInfo); 1249 } 1250 1251 RTStrFree(pszLAClientID); 1252 } 1253 else 1254 { 1255 static int s_iBitchedAboutLAClient = 0; 1256 if ( (rc2 != VERR_NOT_FOUND) /* No location awareness installed, skip. */ 1257 && s_iBitchedAboutLAClient++ < 3) 1258 VBoxServiceError("VRDP: Querying connected location awareness client failed with rc=%Rrc\n", rc2); 1259 } 1260 1068 1261 /* 1069 1262 * Flush all properties if we were restored. … … 1073 1266 if (idNewSession != g_idVMInfoSession) 1074 1267 { 1075 VBoxServiceVerbose(3, " VMInfo:The VM session ID changed, flushing all properties\n");1268 VBoxServiceVerbose(3, "The VM session ID changed, flushing all properties\n"); 1076 1269 vboxserviceVMInfoWriteFixedProperties(); 1077 1270 VBoxServicePropCacheFlush(&g_VMInfoPropCache); … … 1087 1280 if (*pfShutdown) 1088 1281 break; 1089 int rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval); 1282 if (fWait) 1283 rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval); 1090 1284 if (*pfShutdown) 1091 1285 break; 1092 1286 if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2)) 1093 1287 { 1094 VBoxServiceError(" VMInfo:RTSemEventMultiWait failed; rc2=%Rrc\n", rc2);1288 VBoxServiceError("RTSemEventMultiWait failed; rc2=%Rrc\n", rc2); 1095 1289 rc = rc2; 1096 1290 break; … … 1101 1295 rc2 = RTSemEventMultiReset(g_hVMInfoEvent); 1102 1296 if (RT_FAILURE(rc2)) 1103 rc2 = VBoxServiceError(" VMInfo:RTSemEventMultiReset failed; rc2=%Rrc\n", rc2);1297 rc2 = VBoxServiceError("RTSemEventMultiReset failed; rc2=%Rrc\n", rc2); 1104 1298 } 1105 1299 } … … 1140 1334 int rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat)); 1141 1335 1336 /* Destroy LA client info. */ 1337 vboxServiceFreeLAClientInfo(&g_LAClientInfo); 1338 1142 1339 /* Destroy property cache. */ 1143 1340 VBoxServicePropCacheDestroy(&g_VMInfoPropCache); … … 1146 1343 rc = VbglR3GuestPropDisconnect(g_uVMInfoGuestPropSvcClientID); 1147 1344 if (RT_FAILURE(rc)) 1148 VBoxServiceError(" VMInfo:Failed to disconnect from guest property service! Error: %Rrc\n", rc);1345 VBoxServiceError("Failed to disconnect from guest property service! Error: %Rrc\n", rc); 1149 1346 g_uVMInfoGuestPropSvcClientID = 0; 1150 1347
Note:
See TracChangeset
for help on using the changeset viewer.