/** * Retrieves and clears the user credentials for logging into the guest OS. * * @returns IPRT status value * @param ppszUser Receives pointer of allocated user name string. * The returned pointer must be freed using VbglR3CredentialsDestroy(). * @param ppszPassword Receives pointer of allocated user password string. * The returned pointer must be freed using VbglR3CredentialsDestroy(). * @param ppszDomain Receives pointer of allocated domain name string. * The returned pointer must be freed using VbglR3CredentialsDestroy(). */ VBGLR3DECL(int) VbglR3CredentialsRetrieve(char **ppszUser, char **ppszPassword, char **ppszDomain) { AssertPtrReturn(ppszUser, VERR_INVALID_POINTER); AssertPtrReturn(ppszPassword, VERR_INVALID_POINTER); AssertPtrReturn(ppszDomain, VERR_INVALID_POINTER); VMMDevCredentials Req; RT_ZERO(Req); vmmdevInitRequest((VMMDevRequestHeader*)&Req, VMMDevReq_QueryCredentials); Req.u32Flags |= VMMDEV_CREDENTIALS_READ | VMMDEV_CREDENTIALS_CLEAR; int rc = vbglR3GRPerform(&Req.header); if (RT_SUCCESS(rc)) { rc = RTStrDupEx(ppszUser, Req.szUserName); if (RT_SUCCESS(rc)) { rc = RTStrDupEx(ppszPassword, Req.szPassword); if (RT_SUCCESS(rc)) { rc = RTStrDupEx(ppszDomain, Req.szDomain); if (RT_SUCCESS(rc)) return VINF_SUCCESS; RTStrFree(*ppszPassword); } RTStrFree(*ppszUser); } } return rc; }
USBLIB_DECL(int) USBLibGetClientInfo(char *pszDeviceIdent, char **ppszClientPath, int *pInstance) { LogFlow((USBLIBR3 ":USBLibGetClientInfo pszDeviceIdent=%s ppszClientPath=%p pInstance=%p\n", pszDeviceIdent, ppszClientPath, pInstance)); AssertPtrReturn(pInstance, VERR_INVALID_PARAMETER); AssertPtrReturn(ppszClientPath, VERR_INVALID_PARAMETER); AssertPtrReturn(pszDeviceIdent, VERR_INVALID_PARAMETER); VBOXUSBREQ_CLIENT_INFO Req; bzero(&Req, sizeof(Req)); RTStrPrintf(Req.szDeviceIdent, sizeof(Req.szDeviceIdent), "%s", pszDeviceIdent); int rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_CLIENT_INFO, &Req, sizeof(Req)); if (RT_SUCCESS(rc)) { *pInstance = Req.Instance; rc = RTStrDupEx(ppszClientPath, Req.szClientPath); if (RT_SUCCESS(rc)) return VINF_SUCCESS; LogRel((USBLIBR3 ":USBLibGetClientInfo RTStrDupEx failed! rc=%Rrc szClientPath=%s\n", rc, Req.szClientPath)); } else LogRel((USBLIBR3 ":USBLibGetClientInfo VBOXUSBMON_IOCTL_CLIENTPATH failed! rc=%Rrc\n", rc)); return rc; }
int rtPathFromNativeDup(char **ppszPath, const char *pszNativePath, const char *pszBasePath) { int rc = RTStrValidateEncodingEx(pszNativePath, RTSTR_MAX, 0 /*fFlags*/); if (RT_SUCCESS(rc)) rc = RTStrDupEx(ppszPath, pszNativePath); NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */ return rc; }
int rtPathFromNativeDup(char **ppszPath, const char *pszNativePath, const char *pszBasePath) { /** @todo We must compose the codepoints in the string here. We get file names * in normalization form D so we'll end up with normalization form C * whatever approach we take. */ int rc = RTStrValidateEncodingEx(pszNativePath, RTSTR_MAX, 0 /*fFlags*/); if (RT_SUCCESS(rc)) rc = RTStrDupEx(ppszPath, pszNativePath); NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */ return rc; }
/** * Schedules the setting of a property. * * @returns IPRT status code. * @retval VERR_INVALID_STATE if not a SVN WC file. * @param pState The rewrite state to work on. * @param pszName The name of the property to set. * @param pszValue The value. NULL means deleting it. */ int ScmSvnSetProperty(PSCMRWSTATE pState, const char *pszName, const char *pszValue) { /* * Update any existing entry first. */ size_t i = pState->cSvnPropChanges; while (i-- > 0) if (!strcmp(pState->paSvnPropChanges[i].pszName, pszName)) { if (!pszValue) { RTStrFree(pState->paSvnPropChanges[i].pszValue); pState->paSvnPropChanges[i].pszValue = NULL; } else { char *pszCopy; int rc = RTStrDupEx(&pszCopy, pszValue); if (RT_FAILURE(rc)) return rc; pState->paSvnPropChanges[i].pszValue = pszCopy; } return VINF_SUCCESS; } /* * Insert a new entry. */ i = pState->cSvnPropChanges; if ((i % 32) == 0) { void *pvNew = RTMemRealloc(pState->paSvnPropChanges, (i + 32) * sizeof(SCMSVNPROP)); if (!pvNew) return VERR_NO_MEMORY; pState->paSvnPropChanges = (PSCMSVNPROP)pvNew; } pState->paSvnPropChanges[i].pszName = RTStrDup(pszName); pState->paSvnPropChanges[i].pszValue = pszValue ? RTStrDup(pszValue) : NULL; if ( pState->paSvnPropChanges[i].pszName && (pState->paSvnPropChanges[i].pszValue || !pszValue) ) pState->cSvnPropChanges = i + 1; else { RTStrFree(pState->paSvnPropChanges[i].pszName); pState->paSvnPropChanges[i].pszName = NULL; RTStrFree(pState->paSvnPropChanges[i].pszValue); pState->paSvnPropChanges[i].pszValue = NULL; return VERR_NO_MEMORY; } return VINF_SUCCESS; }
/** * Fallback for VbglR3GetAdditionsVersion. */ static int vbglR3GetAdditionsCompileTimeVersion(char **ppszVer, char **ppszVerEx, char **ppszRev) { int rc = VINF_SUCCESS; if (ppszVer) rc = RTStrDupEx(ppszVer, VBOX_VERSION_STRING_RAW); if (RT_SUCCESS(rc)) { if (ppszVerEx) rc = RTStrDupEx(ppszVerEx, VBOX_VERSION_STRING); if (RT_SUCCESS(rc)) { if (ppszRev) { #if 0 char szRev[64]; RTStrPrintf(szRev, sizeof(szRev), "%d", VBOX_SVN_REV); rc = RTStrDupEx(ppszRev, szRev); #else rc = RTStrDupEx(ppszRev, RT_XSTR(VBOX_SVN_REV)); #endif } if (RT_SUCCESS(rc)) return VINF_SUCCESS; /* bail out: */ } if (ppszVerEx) { RTStrFree(*ppszVerEx); *ppszVerEx = NULL; } } if (ppszVer) { RTStrFree(*ppszVer); *ppszVer = NULL; } return rc; }
int rtPathFromNativeDup(char **ppszPath, const char *pszNativePath, const char *pszBasePath) { int rc = RTOnce(&g_OnceInitPathConv, rtPathConvInitOnce, NULL); if (RT_SUCCESS(rc)) { if (g_fPassthruUtf8 || !*pszNativePath) rc = RTStrDupEx(ppszPath, pszNativePath); else rc = rtStrConvert(pszNativePath, strlen(pszNativePath), g_szFsCodeset, ppszPath, 0, "UTF-8", 2, g_enmFsToUtf8Idx); } NOREF(pszBasePath); /* We don't query the FS for codeset preferences. */ return rc; }
/** * Retrieves the installation path of Guest Additions. * * @returns IPRT status value * @param ppszPath Receives pointer of allocated installation path string. * The returned pointer must be freed using * RTStrFree(). */ VBGLR3DECL(int) VbglR3GetAdditionsInstallationPath(char **ppszPath) { int rc; #ifdef RT_OS_WINDOWS HKEY hKey; rc = vbglR3QueryAdditionsWinStoragePath(&hKey); if (RT_SUCCESS(rc)) { /* Installation directory. */ DWORD dwType; DWORD dwSize = _MAX_PATH * sizeof(char); char *pszTmp = (char*)RTMemAlloc(dwSize + 1); if (pszTmp) { LONG l = RegQueryValueEx(hKey, "InstallDir", NULL, &dwType, (BYTE*)(LPCTSTR)pszTmp, &dwSize); if ((l != ERROR_SUCCESS) && (l != ERROR_FILE_NOT_FOUND)) { rc = RTErrConvertFromNtStatus(l); } else { if (dwType == REG_SZ) rc = RTStrDupEx(ppszPath, pszTmp); else rc = VERR_INVALID_PARAMETER; if (RT_SUCCESS(rc)) { /* Flip slashes. */ for (char *pszTmp2 = ppszPath[0]; *pszTmp2; ++pszTmp2) if (*pszTmp2 == '\\') *pszTmp2 = '/'; } } RTMemFree(pszTmp); } else rc = VERR_NO_MEMORY; rc = vbglR3CloseAdditionsWinStoragePath(hKey); } #else /** @todo implement me */ rc = VERR_NOT_IMPLEMENTED; #endif return rc; }
/** * Worker common to RTManifestSetAttr and RTManifestEntrySetAttr. * * @returns IPRT status code. * @param pEntry Pointer to the entry. * @param pszAttr The name of the attribute to add. * @param pszValue The value string. * @param fType The attribute type type. */ static int rtManifestSetAttrWorker(PRTMANIFESTENTRY pEntry, const char *pszAttr, const char *pszValue, uint32_t fType) { char *pszValueCopy; int rc = RTStrDupEx(&pszValueCopy, pszValue); if (RT_FAILURE(rc)) return rc; /* * Does the attribute exist already? */ AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0); PRTMANIFESTATTR pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(&pEntry->Attributes, pszAttr); if (pAttr) { RTStrFree(pAttr->pszValue); pAttr->pszValue = pszValueCopy; pAttr->fType = fType; } else { size_t cbName = strlen(pszAttr) + 1; pAttr = (PRTMANIFESTATTR)RTMemAllocVar(RT_OFFSETOF(RTMANIFESTATTR, szName[cbName])); if (!pAttr) { RTStrFree(pszValueCopy); return VERR_NO_MEMORY; } memcpy(pAttr->szName, pszAttr, cbName); pAttr->StrCore.pszString = pAttr->szName; pAttr->StrCore.cchString = cbName - 1; pAttr->pszValue = pszValueCopy; pAttr->fType = fType; if (RT_UNLIKELY(!RTStrSpaceInsert(&pEntry->Attributes, &pAttr->StrCore))) { AssertFailed(); RTStrFree(pszValueCopy); RTMemFree(pAttr); return VERR_INTERNAL_ERROR_4; } pEntry->cAttributes++; } return VINF_SUCCESS; }
/** * Retrieves the prefix for a shared folder mount point. If no prefix * is set in the guest properties "sf_" is returned. * * @returns VBox status code. * @param ppszPrefix Where to return the prefix string. This shall be * freed by calling RTStrFree. */ VBGLR3DECL(int) VbglR3SharedFolderGetMountPrefix(char **ppszPrefix) { AssertPtrReturn(ppszPrefix, VERR_INVALID_POINTER); int rc; #ifdef VBOX_WITH_GUEST_PROPS uint32_t u32ClientIdGuestProp; rc = VbglR3GuestPropConnect(&u32ClientIdGuestProp); if (RT_SUCCESS(rc)) { rc = VbglR3GuestPropReadValueAlloc(u32ClientIdGuestProp, "/VirtualBox/GuestAdd/SharedFolders/MountPrefix", ppszPrefix); if (rc == VERR_NOT_FOUND) /* No prefix set? Then set the default. */ { #endif rc = RTStrDupEx(ppszPrefix, "sf_"); #ifdef VBOX_WITH_GUEST_PROPS } VbglR3GuestPropDisconnect(u32ClientIdGuestProp); } #endif return rc; }
/** * Basic API checks. * We'll return if any of these fails. */ static void tst1(void) { RTTestISub("Basics"); char *psz; int rc = VINF_SUCCESS; /* RTStrAlloc */ RTTESTI_CHECK(psz = RTStrAlloc(0)); RTTESTI_CHECK(psz && !*psz); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrAlloc(1)); RTTESTI_CHECK(psz && !*psz); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrAlloc(128)); RTTESTI_CHECK(psz && !*psz); RTStrFree(psz); /* RTStrAllocEx */ psz = (char*)"asdfasdf"; RTTESTI_CHECK_RC(RTStrAllocEx(&psz, 0), VINF_SUCCESS); RTTESTI_CHECK(psz && !*psz); RTStrFree(psz); RTTESTI_CHECK_RC(RTStrAllocEx(&psz, 1), VINF_SUCCESS); RTTESTI_CHECK(psz && !*psz); RTStrFree(psz); RTTESTI_CHECK_RC(RTStrAllocEx(&psz, 128), VINF_SUCCESS); RTTESTI_CHECK(psz && !*psz); RTStrFree(psz); /* RTStrRealloc */ psz = NULL; RTTESTI_CHECK_RC(RTStrRealloc(&psz, 10), VINF_SUCCESS); RTTESTI_CHECK(psz && !psz[0]); RTTESTI_CHECK(psz && !psz[9]); RTStrFree(psz); psz = NULL; RTTESTI_CHECK_RC(RTStrRealloc(&psz, 0), VINF_SUCCESS); RTTESTI_CHECK(!psz); psz = NULL; RTTESTI_CHECK_RC(RTStrRealloc(&psz, 128), VINF_SUCCESS); RTTESTI_CHECK(psz && !psz[0]); RTTESTI_CHECK(psz && !psz[127]); if (psz) { memset(psz, 'a', 127); RTTESTI_CHECK_RC(rc = RTStrRealloc(&psz, 160), VINF_SUCCESS); if (RT_SUCCESS(rc) && psz) { RTTESTI_CHECK(!psz[127]); RTTESTI_CHECK(!psz[159]); RTTESTI_CHECK(ASMMemIsAll8(psz, 127, 'a') == NULL); memset(psz, 'b', 159); RTTESTI_CHECK_RC(rc = RTStrRealloc(&psz, 79), VINF_SUCCESS); if (RT_SUCCESS(rc)) { RTTESTI_CHECK(!psz[78]); RTTESTI_CHECK(ASMMemIsAll8(psz, 78, 'b') == NULL); RTTESTI_CHECK_RC(rc = RTStrRealloc(&psz, 0), VINF_SUCCESS); RTTESTI_CHECK(!psz); } } } RTStrFree(psz); /* RTStrDup */ RTTESTI_CHECK(psz = RTStrDup("")); RTTESTI_CHECK(psz && *psz == '\0'); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrDup("abcdefghijklmnop")); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnop")); RTStrFree(psz); /* RTStrDupEx */ psz = NULL; RTTESTI_CHECK_RC(RTStrDupEx(&psz, ""), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || *psz == '\0'); if (RT_SUCCESS(rc)) RTStrFree(psz); psz = (char*)"asdfasdfasdfasdf"; RTTESTI_CHECK_RC(rc = RTStrDupEx(&psz, "abcdefghijklmnop"), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !RTStrCmp(psz, "abcdefghijklmnop")); if (RT_SUCCESS(rc)) RTStrFree(psz); /* RTStrDupN */ RTTESTI_CHECK(psz = RTStrDupN("abcdefg", 3)); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrDupN("abc", 100000)); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrDupN("abc", 0)); RTTESTI_CHECK(psz && *psz == '\0'); RTStrFree(psz); /* RTStrAAppend */ RTTESTI_CHECK(psz = RTStrDup("abc")); RTTESTI_CHECK_RC(RTStrAAppend(&psz, "def"), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdef")); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrDup("abc")); RTTESTI_CHECK_RC(RTStrAAppend(&psz, ""), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTTESTI_CHECK_RC(RTStrAAppend(&psz, NULL), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTStrFree(psz); psz = NULL; RTTESTI_CHECK_RC(RTStrAAppend(&psz, "xyz"), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "xyz")); RTStrFree(psz); /* RTStrAAppendN */ RTTESTI_CHECK(psz = RTStrDup("abc")); RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "def", 1), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcd")); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrDup("abc")); RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "", 0), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "", RTSTR_MAX), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTTESTI_CHECK_RC(RTStrAAppendN(&psz, NULL, 0), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTStrFree(psz); psz = NULL; RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "abc", 2), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "ab")); RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "cdefghijklm", 1), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abc")); RTTESTI_CHECK_RC(RTStrAAppendN(&psz, "defghijklm", RTSTR_MAX), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklm")); RTStrFree(psz); /* RTStrAAppendExN / RTStrAAppendExNV */ psz = NULL; RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 5, "a", (size_t)1, "bc", (size_t)1, "cdefg", RTSTR_MAX, "hijkl", (size_t)2, "jklmnopqrstuvwxyz", RTSTR_MAX), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz")); RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 0), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz")); RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 2, NULL, (size_t)0, "", (size_t)0), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz")); RTTESTI_CHECK_RC(RTStrAAppendExN(&psz, 1, "-", (size_t)1), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz-")); RTStrFree(psz); /* RTStrATruncate */ psz = NULL; RTTESTI_CHECK_RC(RTStrATruncate(&psz, 0), VINF_SUCCESS); RTTESTI_CHECK(!psz); RTTESTI_CHECK(psz = RTStrDup("")); RTTESTI_CHECK_RC(RTStrATruncate(&psz, 0), VINF_SUCCESS); RTStrFree(psz); RTTESTI_CHECK(psz = RTStrDup("1234567890")); RTTESTI_CHECK_RC(RTStrATruncate(&psz, 5), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "12345")); RTStrFree(psz); psz = NULL; for (uint32_t i = 0; i < 128; i++) RTTESTI_CHECK_RC_RETV(RTStrAAppend(&psz, "abcdefghijklmnopqrstuvwxyz"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTStrATruncate(&psz, sizeof("abcdefghijklmnopqrstuvwxyz") - 1), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdefghijklmnopqrstuvwxyz")); RTTESTI_CHECK_RC(RTStrATruncate(&psz, 6), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "abcdef")); RTTESTI_CHECK_RC(RTStrATruncate(&psz, 1), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "a")); RTTESTI_CHECK_RC(RTStrATruncate(&psz, 0), VINF_SUCCESS); RTTESTI_CHECK(!RTStrCmp(psz, "")); RTStrFree(psz); }
/** * Retrieves the installed Guest Additions version and/or revision. * * @returns IPRT status value * @param ppszVer Receives pointer of allocated raw version string * (major.minor.build). NULL is accepted. The returned * pointer must be freed using RTStrFree().* * @param ppszVerExt Receives pointer of allocated full version string * (raw version + vendor suffix(es)). NULL is * accepted. The returned pointer must be freed using * RTStrFree(). * @param ppszRev Receives pointer of allocated revision string. NULL is * accepted. The returned pointer must be freed using * RTStrFree(). */ VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszVerExt, char **ppszRev) { /* * Zap the return value up front. */ if (ppszVer) *ppszVer = NULL; if (ppszVerExt) *ppszVerExt = NULL; if (ppszRev) *ppszRev = NULL; #ifdef RT_OS_WINDOWS HKEY hKey; int rc = vbglR3QueryAdditionsWinStoragePath(&hKey); if (RT_SUCCESS(rc)) { /* * Version. */ char szTemp[32]; if (ppszVer) { rc = vbglR3QueryRegistryString(hKey, "Version", szTemp, sizeof(szTemp)); if (RT_SUCCESS(rc)) rc = RTStrDupEx(ppszVer, szTemp); } if ( RT_SUCCESS(rc) && ppszVerExt) { rc = vbglR3QueryRegistryString(hKey, "VersionExt", szTemp, sizeof(szTemp)); if (RT_SUCCESS(rc)) rc = RTStrDupEx(ppszVerExt, szTemp); } /* * Revision. */ if ( RT_SUCCESS(rc) && ppszRev) { rc = vbglR3QueryRegistryString(hKey, "Revision", szTemp, sizeof(szTemp)); if (RT_SUCCESS(rc)) rc = RTStrDupEx(ppszRev, szTemp); } int rc2 = vbglR3CloseAdditionsWinStoragePath(hKey); if (RT_SUCCESS(rc)) rc = rc2; /* Clean up allocated strings on error. */ if (RT_FAILURE(rc)) { if (ppszVer) RTStrFree(*ppszVer); if (ppszVerExt) RTStrFree(*ppszVerExt); if (ppszRev) RTStrFree(*ppszRev); } } else { /* * No registry entries found, return the version string compiled * into this binary. */ rc = vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszVerExt, ppszRev); } return rc; #else /* !RT_OS_WINDOWS */ /* * On non-Windows platforms just return the compile-time version string. */ return vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszVerExt, ppszRev); #endif /* !RT_OS_WINDOWS */ }
/** * @interface_method_impl{RTVFSFSSTREAMOPS,pfnNext} */ static DECLCALLBACK(int) rtZipTarFss_Next(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj) { PRTZIPTARFSSTREAM pThis = (PRTZIPTARFSSTREAM)pvThis; /* * Dispense with the current object. */ if (pThis->hVfsCurObj != NIL_RTVFSOBJ) { if (pThis->pCurIosData) { pThis->pCurIosData->fEndOfStream = true; pThis->pCurIosData->offFile = pThis->pCurIosData->cbFile; pThis->pCurIosData = NULL; } RTVfsObjRelease(pThis->hVfsCurObj); pThis->hVfsCurObj = NIL_RTVFSOBJ; } /* * Check if we've already reached the end in some way. */ if (pThis->fEndOfStream) return VERR_EOF; if (pThis->rcFatal != VINF_SUCCESS) return pThis->rcFatal; /* * Make sure the input stream is in the right place. */ RTFOFF offHdr = RTVfsIoStrmTell(pThis->hVfsIos); while ( offHdr >= 0 && offHdr < pThis->offNextHdr) { int rc = RTVfsIoStrmSkip(pThis->hVfsIos, pThis->offNextHdr - offHdr); if (RT_FAILURE(rc)) { /** @todo Ignore if we're at the end of the stream? */ return pThis->rcFatal = rc; } offHdr = RTVfsIoStrmTell(pThis->hVfsIos); } if (offHdr < 0) return pThis->rcFatal = (int)offHdr; if (offHdr > pThis->offNextHdr) return pThis->rcFatal = VERR_INTERNAL_ERROR_3; /* * Consume TAR headers. */ size_t cbHdrs = 0; int rc; do { /* * Read the next header. */ RTZIPTARHDR Hdr; size_t cbRead; rc = RTVfsIoStrmRead(pThis->hVfsIos, &Hdr, sizeof(Hdr), true /*fBlocking*/, &cbRead); if (RT_FAILURE(rc)) return pThis->rcFatal = rc; if (rc == VINF_EOF && cbRead == 0) { pThis->fEndOfStream = true; return rtZipTarReaderIsAtEnd(&pThis->TarReader) ? VERR_EOF : VERR_TAR_UNEXPECTED_EOS; } if (cbRead != sizeof(Hdr)) return pThis->rcFatal = VERR_TAR_UNEXPECTED_EOS; cbHdrs += sizeof(Hdr); /* * Parse the it. */ rc = rtZipTarReaderParseHeader(&pThis->TarReader, &Hdr); if (RT_FAILURE(rc)) return pThis->rcFatal = rc; } while (rtZipTarReaderExpectingMoreHeaders(&pThis->TarReader)); pThis->offNextHdr = offHdr + cbHdrs; /* * Fill an object info structure from the current TAR state. */ RTFSOBJINFO Info; rc = rtZipTarReaderGetFsObjInfo(&pThis->TarReader, &Info); if (RT_FAILURE(rc)) return pThis->rcFatal = rc; /* * Create an object of the appropriate type. */ RTVFSOBJTYPE enmType; RTVFSOBJ hVfsObj; RTFMODE fType = Info.Attr.fMode & RTFS_TYPE_MASK; if (rtZipTarReaderIsHardlink(&pThis->TarReader)) fType = RTFS_TYPE_SYMLINK; switch (fType) { /* * Files are represented by a VFS I/O stream. */ case RTFS_TYPE_FILE: { RTVFSIOSTREAM hVfsIos; PRTZIPTARIOSTREAM pIosData; rc = RTVfsNewIoStream(&g_rtZipTarFssIosOps, sizeof(*pIosData), RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, NIL_RTVFS, NIL_RTVFSLOCK, &hVfsIos, (void **)&pIosData); if (RT_FAILURE(rc)) return pThis->rcFatal = rc; pIosData->BaseObj.offHdr = offHdr; pIosData->BaseObj.pTarReader= &pThis->TarReader; pIosData->BaseObj.ObjInfo = Info; pIosData->cbFile = Info.cbObject; pIosData->offFile = 0; pIosData->cbPadding = (uint32_t)(Info.cbAllocated - Info.cbObject); pIosData->fEndOfStream = false; pIosData->hVfsIos = pThis->hVfsIos; RTVfsIoStrmRetain(pThis->hVfsIos); pThis->pCurIosData = pIosData; pThis->offNextHdr += pIosData->cbFile + pIosData->cbPadding; enmType = RTVFSOBJTYPE_IO_STREAM; hVfsObj = RTVfsObjFromIoStream(hVfsIos); RTVfsIoStrmRelease(hVfsIos); break; } /* * We represent hard links using a symbolic link object. This fits * best with the way TAR stores it and there is currently no better * fitting VFS type alternative. */ case RTFS_TYPE_SYMLINK: { RTVFSSYMLINK hVfsSym; PRTZIPTARBASEOBJ pBaseObjData; rc = RTVfsNewSymlink(&g_rtZipTarFssSymOps, sizeof(*pBaseObjData), NIL_RTVFS, NIL_RTVFSLOCK, &hVfsSym, (void **)&pBaseObjData); if (RT_FAILURE(rc)) return pThis->rcFatal = rc; pBaseObjData->offHdr = offHdr; pBaseObjData->pTarReader= &pThis->TarReader; pBaseObjData->ObjInfo = Info; enmType = RTVFSOBJTYPE_SYMLINK; hVfsObj = RTVfsObjFromSymlink(hVfsSym); RTVfsSymlinkRelease(hVfsSym); break; } /* * All other objects are repesented using a VFS base object since they * carry no data streams (unless some TAR extension implements extended * attributes / alternative streams). */ case RTFS_TYPE_DEV_BLOCK: case RTFS_TYPE_DEV_CHAR: case RTFS_TYPE_DIRECTORY: case RTFS_TYPE_FIFO: { PRTZIPTARBASEOBJ pBaseObjData; rc = RTVfsNewBaseObj(&g_rtZipTarFssBaseObjOps, sizeof(*pBaseObjData), NIL_RTVFS, NIL_RTVFSLOCK, &hVfsObj, (void **)&pBaseObjData); if (RT_FAILURE(rc)) return pThis->rcFatal = rc; pBaseObjData->offHdr = offHdr; pBaseObjData->pTarReader= &pThis->TarReader; pBaseObjData->ObjInfo = Info; enmType = RTVFSOBJTYPE_BASE; break; } default: AssertFailed(); return pThis->rcFatal = VERR_INTERNAL_ERROR_5; } pThis->hVfsCurObj = hVfsObj; /* * Set the return data and we're done. */ if (ppszName) { rc = RTStrDupEx(ppszName, pThis->TarReader.szName); if (RT_FAILURE(rc)) return rc; } if (phVfsObj) { RTVfsObjRetain(hVfsObj); *phVfsObj = hVfsObj; } if (penmType) *penmType = enmType; return VINF_SUCCESS; }
/** * 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; }
/** * Queries the value of an SVN property. * * This will automatically adjust for scheduled changes. * * @returns IPRT status code. * @retval VERR_INVALID_STATE if not a SVN WC file. * @retval VERR_NOT_FOUND if the property wasn't found. * @param pState The rewrite state to work on. * @param pszName The property name. * @param ppszValue Where to return the property value. Free this * using RTStrFree. Optional. */ int ScmSvnQueryProperty(PSCMRWSTATE pState, const char *pszName, char **ppszValue) { /* * Look it up in the scheduled changes. */ size_t i = pState->cSvnPropChanges; while (i-- > 0) if (!strcmp(pState->paSvnPropChanges[i].pszName, pszName)) { const char *pszValue = pState->paSvnPropChanges[i].pszValue; if (!pszValue) return VERR_NOT_FOUND; if (ppszValue) return RTStrDupEx(ppszValue, pszValue); return VINF_SUCCESS; } #ifdef SCM_WITHOUT_LIBSVN int rc; scmSvnFindSvnBinary(pState); if (g_enmSvnVersion < kScmSvnVersion_1_7) { /* * Hack: Read the .svn/props/<file>.svn-work file exists. */ char szPath[RTPATH_MAX]; rc = scmSvnConstructName(pState, ".svn/props/", ".svn-work", szPath); if (RT_SUCCESS(rc) && !RTFileExists(szPath)) rc = scmSvnConstructName(pState, ".svn/prop-base/", ".svn-base", szPath); if (RT_SUCCESS(rc)) { SCMSTREAM Stream; rc = ScmStreamInitForReading(&Stream, szPath); if (RT_SUCCESS(rc)) { /* * The current format is K len\n<name>\nV len\n<value>\n" ... END. */ rc = VERR_NOT_FOUND; size_t const cchName = strlen(pszName); SCMEOL enmEol; size_t cchLine; const char *pchLine; while ((pchLine = ScmStreamGetLine(&Stream, &cchLine, &enmEol)) != NULL) { /* * Parse the 'K num' / 'END' line. */ if ( cchLine == 3 && !memcmp(pchLine, "END", 3)) break; size_t cchKey; if ( cchLine < 3 || pchLine[0] != 'K' || pchLine[1] != ' ' || !scmSvnReadNumber(&pchLine[2], cchLine - 2, &cchKey) || cchKey == 0 || cchKey > 4096) { RTMsgError("%s:%u: Unexpected data '%.*s'\n", szPath, ScmStreamTellLine(&Stream), cchLine, pchLine); rc = VERR_PARSE_ERROR; break; } /* * Match the key and skip to the value line. Don't bother with * names containing EOL markers. */ size_t const offKey = ScmStreamTell(&Stream); bool fMatch = cchName == cchKey; if (fMatch) { pchLine = ScmStreamGetLine(&Stream, &cchLine, &enmEol); if (!pchLine) break; fMatch = cchLine == cchName && !memcmp(pchLine, pszName, cchName); } if (RT_FAILURE(ScmStreamSeekAbsolute(&Stream, offKey + cchKey))) break; if (RT_FAILURE(ScmStreamSeekByLine(&Stream, ScmStreamTellLine(&Stream) + 1))) break; /* * Read and Parse the 'V num' line. */ pchLine = ScmStreamGetLine(&Stream, &cchLine, &enmEol); if (!pchLine) break; size_t cchValue; if ( cchLine < 3 || pchLine[0] != 'V' || pchLine[1] != ' ' || !scmSvnReadNumber(&pchLine[2], cchLine - 2, &cchValue) || cchValue > _1M) { RTMsgError("%s:%u: Unexpected data '%.*s'\n", szPath, ScmStreamTellLine(&Stream), cchLine, pchLine); rc = VERR_PARSE_ERROR; break; } /* * If we have a match, allocate a return buffer and read the * value into it. Otherwise skip this value and continue * searching. */ if (fMatch) { if (!ppszValue) rc = VINF_SUCCESS; else { char *pszValue; rc = RTStrAllocEx(&pszValue, cchValue + 1); if (RT_SUCCESS(rc)) { rc = ScmStreamRead(&Stream, pszValue, cchValue); if (RT_SUCCESS(rc)) *ppszValue = pszValue; else RTStrFree(pszValue); } } break; } if (RT_FAILURE(ScmStreamSeekRelative(&Stream, cchValue))) break; if (RT_FAILURE(ScmStreamSeekByLine(&Stream, ScmStreamTellLine(&Stream) + 1))) break; } if (RT_FAILURE(ScmStreamGetStatus(&Stream))) { rc = ScmStreamGetStatus(&Stream); RTMsgError("%s: stream error %Rrc\n", szPath, rc); } ScmStreamDelete(&Stream); } } if (rc == VERR_FILE_NOT_FOUND) rc = VERR_NOT_FOUND; } else { const char *apszArgs[] = { g_szSvnPath, "propget", "--strict", pszName, pState->pszFilename, NULL }; char *pszValue; rc = scmSvnRunAndGetOutput(pState, apszArgs, false, &pszValue); if (RT_SUCCESS(rc)) { if (pszValue && *pszValue) { if (ppszValue) { *ppszValue = pszValue; pszValue = NULL; } } else rc = VERR_NOT_FOUND; RTStrFree(pszValue); } } return rc; #else NOREF(pState); #endif return VERR_NOT_FOUND; }
/** @copydoc VBOXSERVICE::pfnWorker */ DECLCALLBACK(int) VBoxServiceAutoMountWorker(bool volatile *pfShutdown) { /* * Tell the control thread that it can continue * spawning services. */ RTThreadUserSignal(RTThreadSelf()); uint32_t cMappings; PVBGLR3SHAREDFOLDERMAPPING paMappings; int rc = VbglR3SharedFolderGetMappings(g_SharedFoldersSvcClientID, true /* Only process auto-mounted folders */, &paMappings, &cMappings); if ( RT_SUCCESS(rc) && cMappings) { char *pszMountDir; rc = VbglR3SharedFolderGetMountDir(&pszMountDir); if (rc == VERR_NOT_FOUND) rc = RTStrDupEx(&pszMountDir, VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR); if (RT_SUCCESS(rc)) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount dir set to \"%s\"\n", pszMountDir); char *pszSharePrefix; rc = VbglR3SharedFolderGetMountPrefix(&pszSharePrefix); if (RT_SUCCESS(rc)) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount prefix set to \"%s\"\n", pszSharePrefix); #ifdef USE_VIRTUAL_SHARES /* Check for a fixed/virtual auto-mount share. */ if (VbglR3SharedFolderExists(g_SharedFoldersSvcClientID, "vbsfAutoMount")) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Host supports auto-mount root\n"); } else { #endif VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Got %u shared folder mappings\n", cMappings); rc = VBoxServiceAutoMountProcessMappings(paMappings, cMappings, pszMountDir, pszSharePrefix, g_SharedFoldersSvcClientID); #ifdef USE_VIRTUAL_SHARES } #endif RTStrFree(pszSharePrefix); } /* Mount share prefix. */ else VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mount prefix, rc = %Rrc\n", rc); RTStrFree(pszMountDir); } else VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder directory, rc = %Rrc\n", rc); VbglR3SharedFolderFreeMappings(paMappings); } else if (RT_FAILURE(rc)) VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc); else VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: No shared folder mappings found\n"); /* * Because this thread is a one-timer at the moment we don't want to break/change * the semantics of the main thread's start/stop sub-threads handling. * * This thread exits so fast while doing its own startup in VBoxServiceStartServices() * that this->fShutdown flag is set to true in VBoxServiceThread() before we have the * chance to check for a service failure in VBoxServiceStartServices() to indicate * a VBoxService startup error. * * Therefore *no* service threads are allowed to quit themselves and need to wait * for the pfShutdown flag to be set by the main thread. */ for (;;) { /* Do we need to shutdown? */ if (*pfShutdown) break; /* Let's sleep for a bit and let others run ... */ RTThreadSleep(500); } RTSemEventMultiDestroy(g_AutoMountEvent); g_AutoMountEvent = NIL_RTSEMEVENTMULTI; VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Finished with rc=%Rrc\n", rc); return VINF_SUCCESS; }