Changeset 29390 in vbox
- Timestamp:
- May 11, 2010 8:11:53 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
r29345 r29390 216 216 217 217 218 /** 219 * Provide information about active users. 220 */ 221 int VBoxServiceVMInfoWriteUsers() 222 { 223 int rc; 224 char szUserList[4096] = {0}; 225 uint32_t cUsersInList = 0; 226 227 #ifdef RT_OS_WINDOWS 228 # ifndef TARGET_NT4 229 PLUID paSessions = NULL; 230 ULONG cSession = 0; 231 NTSTATUS r = 0; 232 233 /* This function can report stale or orphaned interactive logon sessions 234 of already logged off users (especially in Windows 2000). */ 235 r = ::LsaEnumerateLogonSessions(&cSession, &paSessions); 236 VBoxServiceVerbose(3, "Users: Found %ld users.\n", cSession); 237 if (r != STATUS_SUCCESS) 238 { 239 VBoxServiceError("LsaEnumerate failed %lu\n", LsaNtStatusToWinError(r)); 240 return RTErrConvertFromWin32(LsaNtStatusToWinError(r)); 241 } 242 243 PVBOXSERVICEVMINFOPROC paProcs; 244 DWORD cProcs; 245 rc = VBoxServiceVMInfoWinProcessesEnumerate(&paProcs, &cProcs); 246 if (RT_SUCCESS(rc)) 247 { 248 for (ULONG i = 0; i < cSession; i++) 249 { 250 VBOXSERVICEVMINFOUSER UserInfo; 251 if ( VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i]) 252 && VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs)) 253 { 254 if (cUsersInList > 0) 255 strcat(szUserList, ","); 256 257 cUsersInList++; 258 259 char *pszTemp; 260 int rc2 = RTUtf16ToUtf8(UserInfo.wszUser, &pszTemp); 261 if (RT_SUCCESS(rc2)) 262 { 263 strcat(szUserList, pszTemp); 264 RTMemFree(pszTemp); 265 } 266 else 267 strcat(szUserList, "<string-convertion-error>"); 268 } 269 } 270 VBoxServiceVMInfoWinProcessesFree(paProcs); 271 } 272 273 ::LsaFreeReturnBuffer(paSessions); 274 # endif /* TARGET_NT4 */ 275 #elif defined(RT_OS_FREEBSD) 276 /** @todo FreeBSD: Port logged on user info retrival. */ 277 #elif defined(RT_OS_OS2) 278 /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrival. */ 279 #else 280 rc = utmpname(UTMP_FILE); 281 # ifdef RT_OS_SOLARIS 282 if (rc != 1) 283 # else 284 if (rc != 0) 285 # endif 286 { 287 VBoxServiceError("Could not set UTMP file! Error: %ld\n", errno); 288 } 289 setutent(); 290 utmp *ut_user; 291 while ((ut_user = getutent())) 292 { 293 /* Make sure we don't add user names which are not 294 * part of type USER_PROCESS and don't add same users twice. */ 295 if ( ut_user->ut_type == USER_PROCESS 296 && strstr(szUserList, ut_user->ut_user) == NULL) 297 { 298 /** @todo Do we really want to filter out double user names? (Same user logged in twice) 299 * bird: If we do, then we must add checks for buffer overflows here! */ 300 /** @todo r=bird: strstr will filtering out users with similar names. For 301 * example: smith, smithson, joesmith and bobsmith */ 302 if (cUsersInList > 0) 303 strcat(szUserList, ","); 304 strcat(szUserList, ut_user->ut_user); 305 cUsersInList++; 306 } 307 } 308 endutent(); 309 #endif /* !RT_OS_WINDOWS */ 310 311 if (cUsersInList > 0) 312 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", szUserList); 313 else 314 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL); 315 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList); 316 if ( g_cVMInfoLoggedInUsers != cUsersInList 317 || g_cVMInfoLoggedInUsers == UINT32_MAX) 318 { 319 /* 320 * Update this property ONLY if there is a real change from no users to 321 * users or vice versa. The only exception is that the initialization 322 * forces an update, but only once. This ensures consistent property 323 * settings even if the VM aborted previously. 324 */ 325 if (cUsersInList == 0) 326 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "true"); 327 else if (g_cVMInfoLoggedInUsers == 0) 328 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "false"); 329 } 330 g_cVMInfoLoggedInUsers = cUsersInList; 331 332 return VINF_SUCCESS; 333 } 334 335 336 /** 337 * Provide information about the guest network. 338 */ 339 int VBoxServiceVMInfoWriteNetwork() 340 { 341 int cIfacesReport = 0; 342 char szPropPath [FILENAME_MAX]; 343 344 #ifdef RT_OS_WINDOWS 345 SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0); 346 if (sd == SOCKET_ERROR) /* Socket invalid. */ 347 { 348 VBoxServiceError("Failed to get a socket: Error %d\n", WSAGetLastError()); 349 return RTErrConvertFromWin32(WSAGetLastError()); 350 } 351 352 INTERFACE_INFO InterfaceList[20] = {0}; 353 unsigned long nBytesReturned = 0; 354 if (WSAIoctl(sd, 355 SIO_GET_INTERFACE_LIST, 356 0, 357 0, 358 &InterfaceList, 359 sizeof(InterfaceList), 360 &nBytesReturned, 361 0, 362 0) == SOCKET_ERROR) 363 { 364 VBoxServiceError("Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError()); 365 return RTErrConvertFromWin32(WSAGetLastError()); 366 } 367 int cIfacesSystem = nBytesReturned / sizeof(INTERFACE_INFO); 368 369 /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */ 370 for (int i = 0; i < cIfacesSystem; ++i) 371 { 372 sockaddr_in *pAddress; 373 u_long nFlags = 0; 374 if (InterfaceList[i].iiFlags & IFF_LOOPBACK) /* Skip loopback device. */ 375 continue; 376 nFlags = InterfaceList[i].iiFlags; 377 pAddress = (sockaddr_in *)&(InterfaceList[i].iiAddress); 378 Assert(pAddress); 379 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport); 380 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 381 382 pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress); 383 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport); 384 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 385 386 pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask); 387 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport); 388 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 389 390 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport); 391 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, nFlags & IFF_UP ? "Up" : "Down"); 392 cIfacesReport++; 393 } 394 if (sd >= 0) 395 closesocket(sd); 396 #else /* !RT_OS_WINDOWS */ 397 int sd = socket(AF_INET, SOCK_DGRAM, 0); 398 if (sd < 0) 399 { 400 VBoxServiceError("Failed to get a socket: Error %d\n", errno); 401 return RTErrConvertFromErrno(errno); 402 } 403 404 ifconf ifcfg; 405 char buffer[1024] = {0}; 406 ifcfg.ifc_len = sizeof(buffer); 407 ifcfg.ifc_buf = buffer; 408 if (ioctl(sd, SIOCGIFCONF, &ifcfg) < 0) 409 { 410 VBoxServiceError("Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno); 411 return RTErrConvertFromErrno(errno); 412 } 413 414 ifreq* ifrequest = ifcfg.ifc_req; 415 int cIfacesSystem = ifcfg.ifc_len / sizeof(ifreq); 416 417 for (int i = 0; i < cIfacesSystem; ++i) 418 { 419 sockaddr_in *pAddress; 420 if (ioctl(sd, SIOCGIFFLAGS, &ifrequest[i]) < 0) 421 { 422 VBoxServiceError("Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno); 423 close(sd); 424 return RTErrConvertFromErrno(errno); 425 } 426 if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip the loopback device. */ 427 continue; 428 429 bool fIfUp = !!(ifrequest[i].ifr_flags & IFF_UP); 430 pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr); 431 Assert(pAddress); 432 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport); 433 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 434 435 if (ioctl(sd, SIOCGIFBRDADDR, &ifrequest[i]) < 0) 436 { 437 VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno); 438 close(sd); 439 return RTErrConvertFromErrno(errno); 440 } 441 pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr; 442 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport); 443 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 444 445 if (ioctl(sd, SIOCGIFNETMASK, &ifrequest[i]) < 0) 446 { 447 VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno); 448 close(sd); 449 return RTErrConvertFromErrno(errno); 450 } 451 #if defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS) 452 pAddress = (sockaddr_in *)&ifrequest[i].ifr_addr; 453 #else 454 pAddress = (sockaddr_in *)&ifrequest[i].ifr_netmask; 455 #endif 456 457 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport); 458 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 459 460 if (ioctl(sd, SIOCGIFHWADDR, &ifrequest[i]) < 0) 461 { 462 VBoxServiceError("Failed to ioctl(SIOCGIFHWADDR) on socket: Error %d\n", errno); 463 close(sd); 464 return RTErrConvertFromErrno(errno); 465 } 466 467 char szMac[32]; 468 char *pu8Mac = ifrequest[i].ifr_hwaddr.sa_data; 469 RTStrPrintf(szMac, sizeof(szMac), "%02x:%02x:%02x:%02x:%02x:%02x", 470 pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3], pu8Mac[4], pu8Mac[5]); 471 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport); 472 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac); 473 474 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport); 475 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, fIfUp ? "Up" : "Down"); 476 cIfacesReport++; 477 } 478 479 close(sd); 480 481 #endif /* !RT_OS_WINDOWS */ 482 483 /* 484 * This property is a beacon which is _always_ written, even if the network configuration 485 * does not change. If this property is missing, the host assumes that all other GuestInfo 486 * properties are no longer valid. 487 */ 488 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d", 489 cIfacesReport); 490 491 /** @todo r=bird: if cIfacesReport decreased compared to the previous run, zap 492 * the stale data. This can probably be encorporated into the cache. */ 493 494 return VINF_SUCCESS; 495 } 496 497 218 498 /** @copydoc VBOXSERVICE::pfnWorker */ 219 499 DECLCALLBACK(int) VBoxServiceVMInfoWorker(bool volatile *pfShutdown) 220 500 { 221 int rc = VINF_SUCCESS;501 int rc; 222 502 223 503 /* … … 242 522 * Now enter the loop retrieving runtime data continuously. 243 523 */ 244 unsigned cErrors = 0;245 524 for (;;) 246 525 { 247 /** @todo r=bird: split this code up into functions!! */ 248 /* Enumerate logged in users. */ 249 uint32_t cUsersInList = 0; 250 char szUserList[4096] = {0}; 251 252 #ifdef RT_OS_WINDOWS 253 # ifndef TARGET_NT4 254 PLUID paSessions = NULL; 255 ULONG cSession = 0; 256 NTSTATUS r = 0; 257 258 /* This function can report stale or orphaned interactive logon sessions 259 of already logged off users (especially in Windows 2000). */ 260 r = ::LsaEnumerateLogonSessions(&cSession, &paSessions); 261 VBoxServiceVerbose(3, "Users: Found %ld users.\n", cSession); 262 if (r != STATUS_SUCCESS) 263 { 264 VBoxServiceError("LsaEnumerate failed %lu\n", LsaNtStatusToWinError(r)); 265 return 1; 266 } 267 268 PVBOXSERVICEVMINFOPROC paProcs; 269 DWORD cProcs; 270 rc = VBoxServiceVMInfoWinProcessesEnumerate(&paProcs, &cProcs); 271 if (RT_SUCCESS(rc)) 272 { 273 for (ULONG i = 0; i < cSession; i++) 274 { 275 VBOXSERVICEVMINFOUSER UserInfo; 276 if ( VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i]) 277 && VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs)) 278 { 279 if (cUsersInList > 0) 280 strcat(szUserList, ","); 281 282 cUsersInList++; 283 284 char *pszTemp; 285 int rc2 = RTUtf16ToUtf8(UserInfo.wszUser, &pszTemp); 286 if (RT_SUCCESS(rc2)) 287 { 288 strcat(szUserList, pszTemp); 289 RTMemFree(pszTemp); 290 } 291 else 292 strcat(szUserList, "<string-convertion-error>"); 293 } 294 } 295 VBoxServiceVMInfoWinProcessesFree(paProcs); 296 } 297 298 ::LsaFreeReturnBuffer(paSessions); 299 # endif /* TARGET_NT4 */ 300 #elif defined(RT_OS_FREEBSD) 301 /** @todo FreeBSD: Port logged on user info retrival. */ 302 #elif defined(RT_OS_OS2) 303 /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrival. */ 304 #else 305 rc = utmpname(UTMP_FILE); 306 # ifdef RT_OS_SOLARIS 307 if (rc != 1) 308 # else 309 if (rc != 0) 310 # endif 311 { 312 VBoxServiceError("Could not set UTMP file! Error: %ld\n", errno); 313 } 314 setutent(); 315 utmp *ut_user; 316 while ((ut_user = getutent())) 317 { 318 /* Make sure we don't add user names which are not 319 * part of type USER_PROCESS and don't add same users twice. */ 320 if ( ut_user->ut_type == USER_PROCESS 321 && strstr(szUserList, ut_user->ut_user) == NULL) 322 { 323 /** @todo Do we really want to filter out double user names? (Same user logged in twice) 324 * bird: If we do, then we must add checks for buffer overflows here! */ 325 /** @todo r=bird: strstr will filtering out users with similar names. For 326 * example: smith, smithson, joesmith and bobsmith */ 327 if (cUsersInList > 0) 328 strcat(szUserList, ","); 329 strcat(szUserList, ut_user->ut_user); 330 cUsersInList++; 331 } 332 } 333 endutent(); 334 #endif /* !RT_OS_WINDOWS */ 335 336 if (cUsersInList > 0) 337 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", szUserList); 338 else 339 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL); 340 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList); 341 if ( g_cVMInfoLoggedInUsers != cUsersInList 342 || g_cVMInfoLoggedInUsers == UINT32_MAX) 343 { 344 /* 345 * Update this property ONLY if there is a real change from no users to 346 * users or vice versa. The only exception is that the initialization 347 * forces an update, but only once. This ensures consistent property 348 * settings even if the VM aborted previously. 349 */ 350 if (cUsersInList == 0) 351 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "true"); 352 else if (g_cVMInfoLoggedInUsers == 0) 353 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "false"); 354 } 355 g_cVMInfoLoggedInUsers = cUsersInList; 356 357 /* 358 * Get network configuration. 359 */ 360 /** @todo Throw this code into a separate function/module? */ 361 int cInterfaces = 0; 362 #ifdef RT_OS_WINDOWS 363 SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0); 364 if (sd == SOCKET_ERROR) /* Socket invalid. */ 365 { 366 VBoxServiceError("Failed to get a socket: Error %d\n", WSAGetLastError()); 367 return -1; 368 } 369 370 INTERFACE_INFO InterfaceList[20] = {0}; 371 unsigned long nBytesReturned = 0; 372 if (WSAIoctl(sd, 373 SIO_GET_INTERFACE_LIST, 374 0, 375 0, 376 &InterfaceList, 377 sizeof(InterfaceList), 378 &nBytesReturned, 379 0, 380 0) == SOCKET_ERROR) 381 { 382 VBoxServiceError("Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError()); 383 return -1; 384 } 385 cInterfaces = nBytesReturned / sizeof(INTERFACE_INFO); 386 #else 387 int sd = socket(AF_INET, SOCK_DGRAM, 0); 388 if (sd < 0) /* Socket invalid. */ 389 { 390 VBoxServiceError("Failed to get a socket: Error %d\n", errno); 391 return -1; 392 } 393 394 ifconf ifcfg; 395 char buffer[1024] = {0}; 396 ifcfg.ifc_len = sizeof(buffer); 397 ifcfg.ifc_buf = buffer; 398 if (ioctl(sd, SIOCGIFCONF, &ifcfg) < 0) 399 { 400 VBoxServiceError("Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno); 401 return -1; 402 } 403 404 ifreq* ifrequest = ifcfg.ifc_req; 405 ifreq *ifreqitem = NULL; 406 cInterfaces = ifcfg.ifc_len / sizeof(ifreq); 407 #endif 408 char szPropPath [FILENAME_MAX]; 409 int iCurIface = 0; 410 411 /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */ 412 for (int i = 0; i < cInterfaces; ++i) 413 { 414 sockaddr_in *pAddress; 415 u_long nFlags = 0; 416 #ifdef RT_OS_WINDOWS 417 if (InterfaceList[i].iiFlags & IFF_LOOPBACK) /* Skip loopback device. */ 418 continue; 419 nFlags = InterfaceList[i].iiFlags; 420 pAddress = (sockaddr_in *)&(InterfaceList[i].iiAddress); 421 #else 422 if (ioctl(sd, SIOCGIFFLAGS, &ifrequest[i]) < 0) 423 { 424 VBoxServiceError("Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno); 425 return -1; 426 } 427 if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip loopback device. */ 428 continue; 429 nFlags = ifrequest[i].ifr_flags; 430 pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr); 431 #endif 432 Assert(pAddress); 433 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", iCurIface); 434 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 435 436 #ifdef RT_OS_WINDOWS 437 pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress); 438 #else 439 if (ioctl(sd, SIOCGIFBRDADDR, &ifrequest[i]) < 0) 440 { 441 VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno); 442 return -1; 443 } 444 pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr; 445 #endif 446 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", iCurIface); 447 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 448 449 #ifdef RT_OS_WINDOWS 450 pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask); 451 #else 452 if (ioctl(sd, SIOCGIFNETMASK, &ifrequest[i]) < 0) 453 { 454 VBoxServiceError("Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno); 455 return -1; 456 } 457 #if defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS) 458 pAddress = (sockaddr_in *)&ifrequest[i].ifr_addr; 459 #else 460 pAddress = (sockaddr_in *)&ifrequest[i].ifr_netmask; 461 #endif 462 463 #endif 464 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", iCurIface); 465 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr)); 466 467 RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", iCurIface); 468 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, 469 nFlags & IFF_UP ? "Up" : "Down"); 470 iCurIface++; 471 } 472 if (sd >= 0) 473 #ifdef RT_OS_WINDOWS 474 closesocket(sd); 475 #else 476 close(sd); 477 #endif 478 479 /* 480 * This property is a beacon which is _always_ written, even if the network configuration 481 * does not change. If this property is missing, the host assumes that all other GuestInfo 482 * properties are no longer valid. 483 * 484 * cInterfaces also counts in local loopback, but we don't want to report that. 485 */ 486 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d", 487 cInterfaces > 1 ? cInterfaces-1 : 0); 488 489 /** @todo r=bird: if cInterfaces decreased compared to the previous run, zap 490 * the stale data. This can probably be encorporated into the cache. */ 491 526 rc = VBoxServiceVMInfoWriteUsers(); 527 if (RT_FAILURE(rc)) 528 break; 529 530 rc = VBoxServiceVMInfoWriteNetwork(); 531 if (RT_FAILURE(rc)) 532 break; 492 533 493 534 /*
Note:
See TracChangeset
for help on using the changeset viewer.