/** * Writes data from the given S/G buffer into the I/O log. * * @returns VBox status code. * @param pIoLogger The I/O logger to use. * @param off The start offset in the log to write to. * @param pSgBuf The S/G buffer to write. * @param cbSgBuf How much data to write. */ static int vddbgIoLogWriteSgBuf(PVDIOLOGGERINT pIoLogger, uint64_t off, PCRTSGBUF pSgBuf, size_t cbSgBuf) { int rc = VINF_SUCCESS; RTSGBUF SgBuf; RTSgBufClone(&SgBuf, pSgBuf); while (cbSgBuf) { void *pvSeg; size_t cbSeg = cbSgBuf; pvSeg = RTSgBufGetNextSegment(&SgBuf, &cbSeg); AssertPtrBreakStmt(pvSeg, rc = VERR_INTERNAL_ERROR); rc = RTFileWriteAt(pIoLogger->hFile, off, pvSeg, cbSeg, NULL); if (RT_FAILURE(rc)) break; cbSgBuf -= cbSeg; off += cbSeg; } return rc; }
/** * Get the list of available shared folders. * * @returns VBox status code. * @param u32ClientId The client id returned by VbglR3SharedFolderConnect(). * @param fAutoMountOnly Flag whether only auto-mounted shared folders * should be reported. * @param ppaMappings Allocated array which will retrieve the mapping info. Needs * to be freed with VbglR3SharedFolderFreeMappings() later. * @param pcMappings The number of mappings returned in @a ppaMappings. */ VBGLR3DECL(int) VbglR3SharedFolderGetMappings(uint32_t u32ClientId, bool fAutoMountOnly, PVBGLR3SHAREDFOLDERMAPPING *ppaMappings, uint32_t *pcMappings) { AssertPtrReturn(pcMappings, VERR_INVALID_PARAMETER); AssertPtrReturn(ppaMappings, VERR_INVALID_PARAMETER); *pcMappings = 0; *ppaMappings = NULL; VBoxSFQueryMappings Msg; Msg.callInfo.result = VERR_WRONG_ORDER; Msg.callInfo.u32ClientID = u32ClientId; Msg.callInfo.u32Function = SHFL_FN_QUERY_MAPPINGS; Msg.callInfo.cParms = 3; /* Set the mapping flags. */ uint32_t u32Flags = 0; /** @todo SHFL_MF_UTF8 is not implemented yet. */ if (fAutoMountOnly) /* We only want the mappings which get auto-mounted. */ u32Flags |= SHFL_MF_AUTOMOUNT; VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); /* * Prepare and get the actual mappings from the host service. */ int rc = VINF_SUCCESS; uint32_t cMappings = 8; /* Should be a good default value. */ uint32_t cbSize = cMappings * sizeof(VBGLR3SHAREDFOLDERMAPPING); VBGLR3SHAREDFOLDERMAPPING *ppaMappingsTemp = (PVBGLR3SHAREDFOLDERMAPPING)RTMemAllocZ(cbSize); if (!ppaMappingsTemp) return VERR_NO_MEMORY; do { VbglHGCMParmUInt32Set(&Msg.numberOfMappings, cMappings); VbglHGCMParmPtrSet(&Msg.mappings, ppaMappingsTemp, cbSize); rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); if (RT_SUCCESS(rc)) { rc = Msg.callInfo.result; if (RT_SUCCESS(rc)) { VbglHGCMParmUInt32Get(&Msg.numberOfMappings, pcMappings); /* Do we have more mappings than we have allocated space for? */ if (rc == VINF_BUFFER_OVERFLOW) { cMappings = *pcMappings; cbSize = cMappings * sizeof(VBGLR3SHAREDFOLDERMAPPING); void *pvNew = RTMemRealloc(ppaMappingsTemp, cbSize); AssertPtrBreakStmt(pvNew, rc = VERR_NO_MEMORY); ppaMappingsTemp = (PVBGLR3SHAREDFOLDERMAPPING)pvNew; } } } } while (rc == VINF_BUFFER_OVERFLOW); if ( RT_FAILURE(rc) || !*pcMappings) { RTMemFree(ppaMappingsTemp); ppaMappingsTemp = NULL; } /* In this case, just return success with 0 mappings */ if ( rc == VERR_INVALID_PARAMETER && fAutoMountOnly) rc = VINF_SUCCESS; *ppaMappings = ppaMappingsTemp; return rc; }
/** * Provide information about active users. */ static int vboxserviceVMInfoWriteUsers(void) { int rc = VINF_SUCCESS; char *pszUserList = NULL; uint32_t cUsersInList = 0; #ifdef RT_OS_WINDOWS # ifndef TARGET_NT4 rc = VBoxServiceVMInfoWinWriteUsers(&pszUserList, &cUsersInList); # else rc = VERR_NOT_IMPLEMENTED; # endif #elif defined(RT_OS_FREEBSD) /** @todo FreeBSD: Port logged on user info retrieval. * However, FreeBSD 9 supports utmpx, so we could use the code * block below (?). */ rc = VERR_NOT_IMPLEMENTED; #elif defined(RT_OS_OS2) /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrieval. */ rc = VERR_NOT_IMPLEMENTED; #else setutxent(); utmpx *ut_user; uint32_t cListSize = 32; /* Allocate a first array to hold 32 users max. */ char **papszUsers = (char **)RTMemAllocZ(cListSize * sizeof(char *)); if (papszUsers == NULL) rc = VERR_NO_MEMORY; /* Process all entries in the utmp file. */ while ( (ut_user = getutxent()) && RT_SUCCESS(rc)) { VBoxServiceVerbose(4, "Found logged in user \"%s\"\n", ut_user->ut_user); if (cUsersInList > cListSize) { cListSize += 32; void *pvNew = RTMemRealloc(papszUsers, cListSize * sizeof(char*)); AssertPtrBreakStmt(pvNew, cListSize -= 32); papszUsers = (char **)pvNew; } /* Make sure we don't add user names which are not * part of type USER_PROCESS. */ if (ut_user->ut_type == USER_PROCESS) { bool fFound = false; for (uint32_t i = 0; i < cUsersInList && !fFound; i++) fFound = strcmp(papszUsers[i], ut_user->ut_user) == 0; if (!fFound) { rc = RTStrDupEx(&papszUsers[cUsersInList], (const char *)ut_user->ut_user); if (RT_FAILURE(rc)) break; cUsersInList++; } } } /* Calc the string length. */ size_t cchUserList = 0; for (uint32_t i = 0; i < cUsersInList; i++) cchUserList += (i != 0) + strlen(papszUsers[i]); /* Build the user list. */ rc = RTStrAllocEx(&pszUserList, cchUserList + 1); if (RT_SUCCESS(rc)) { char *psz = pszUserList; for (uint32_t i = 0; i < cUsersInList; i++) { if (i != 0) *psz++ = ','; size_t cch = strlen(papszUsers[i]); memcpy(psz, papszUsers[i], cch); psz += cch; } *psz = '\0'; } /* Cleanup. */ for (uint32_t i = 0; i < cUsersInList; i++) RTStrFree(papszUsers[i]); RTMemFree(papszUsers); endutxent(); /* Close utmpx file. */ #endif Assert(RT_FAILURE(rc) || cUsersInList == 0 || (pszUserList && *pszUserList)); /* If the user enumeration above failed, reset the user count to 0 except * we didn't have enough memory anymore. In that case we want to preserve * the previous user count in order to not confuse third party tools which * rely on that count. */ if (RT_FAILURE(rc)) { if (rc == VERR_NO_MEMORY) { static int s_iVMInfoBitchedOOM = 0; if (s_iVMInfoBitchedOOM++ < 3) VBoxServiceVerbose(0, "Warning: Not enough memory available to enumerate users! Keeping old value (%u)\n", g_cVMInfoLoggedInUsers); cUsersInList = g_cVMInfoLoggedInUsers; } else cUsersInList = 0; } VBoxServiceVerbose(4, "cUsersInList: %u, pszUserList: %s, rc=%Rrc\n", cUsersInList, pszUserList ? pszUserList : "<NULL>", rc); if (pszUserList && cUsersInList > 0) VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", pszUserList); else VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL); VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList); if (g_cVMInfoLoggedInUsers != cUsersInList) { VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", cUsersInList == 0 ? "true" : "false"); g_cVMInfoLoggedInUsers = cUsersInList; } if (RT_SUCCESS(rc) && pszUserList) RTStrFree(pszUserList); return rc; }