/** * Adjust the profile environment after forking the child process and changing * the UID. * * @returns IRPT status code. * @param hEnvToUse The environment we're going to use with execve. * @param fFlags The process creation flags. * @param hEnv The environment passed in by the user. */ static int rtProcPosixAdjustProfileEnvFromChild(RTENV hEnvToUse, uint32_t fFlags, RTENV hEnv) { int rc = VINF_SUCCESS; #ifdef RT_OS_DARWIN if ( RT_SUCCESS(rc) && (!(fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) || RTEnvExistEx(hEnv, "TMPDIR")) ) { char szValue[_4K]; size_t cbNeeded = confstr(_CS_DARWIN_USER_TEMP_DIR, szValue, sizeof(szValue)); if (cbNeeded > 0 && cbNeeded < sizeof(szValue)) { char *pszTmp; rc = RTStrCurrentCPToUtf8(&pszTmp, szValue); if (RT_SUCCESS(rc)) { rc = RTEnvSetEx(hEnvToUse, "TMPDIR", pszTmp); RTStrFree(pszTmp); } } else rc = VERR_BUFFER_OVERFLOW; } #endif return rc; }
/** * Internal worker which initializes or re-initializes the * program path, name and directory globals. * * @returns IPRT status code. * @param fFlags Flags, see RTR3INIT_XXX. * @param cArgs Pointer to the argument count. * @param ppapszArgs Pointer to the argument vector pointer. NULL * allowed if @a cArgs is 0. */ static int rtR3InitArgv(uint32_t fFlags, int cArgs, char ***ppapszArgs) { NOREF(fFlags); if (cArgs) { AssertPtr(ppapszArgs); AssertPtr(*ppapszArgs); char **papszOrgArgs = *ppapszArgs; /* * Normally we should only be asked to convert arguments once. If we * are though, it should be the already convered arguments. */ if (g_crtArgs != -1) { AssertReturn( g_crtArgs == cArgs && g_papszrtArgs == papszOrgArgs, VERR_WRONG_ORDER); /* only init once! */ return VINF_SUCCESS; } /* * Convert the arguments. */ char **papszArgs = (char **)RTMemAllocZ((cArgs + 1) * sizeof(char *)); if (!papszArgs) return VERR_NO_MEMORY; for (int i = 0; i < cArgs; i++) { int rc = RTStrCurrentCPToUtf8(&papszArgs[i], papszOrgArgs[i]); if (RT_FAILURE(rc)) { while (i--) RTStrFree(papszArgs[i]); RTMemFree(papszArgs); return rc; } } papszArgs[cArgs] = NULL; g_papszrtOrgArgs = papszOrgArgs; g_papszrtArgs = papszArgs; g_crtArgs = cArgs; *ppapszArgs = papszArgs; } return VINF_SUCCESS; }
RTR3DECL(int) RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser) { AssertPtrReturn(ppszUser, VERR_INVALID_POINTER); int rc; if ( hProcess == NIL_RTPROCESS || hProcess == RTProcSelf()) { /* * Figure a good buffer estimate. */ int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX); if (cbPwdMax <= _1K) cbPwdMax = _1K; else AssertStmt(cbPwdMax <= 32*_1M, cbPwdMax = 32*_1M); char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax); if (pchBuf) { /* * Get the password file entry. */ struct passwd Pwd; struct passwd *pPwd = NULL; rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd); if (!rc) { /* * Convert the name to UTF-8, assuming that we're getting it in the local codeset. */ rc = RTStrCurrentCPToUtf8(ppszUser, pPwd->pw_name); } else rc = RTErrConvertFromErrno(rc); RTMemFree(pchBuf); } else rc = VERR_NO_TMP_MEMORY; } else rc = VERR_NOT_SUPPORTED; return rc; }
/** * Create a very very basic environment for a user. * * @returns IPRT status code. * @param phEnvToUse Where to return the created environment. * @param pszUser The user name for the profile. */ static int rtProcPosixCreateProfileEnv(PRTENV phEnvToUse, const char *pszUser) { struct passwd Pwd; struct passwd *pPwd = NULL; char achBuf[_4K]; int rc; errno = 0; if (pszUser) rc = getpwnam_r(pszUser, &Pwd, achBuf, sizeof(achBuf), &pPwd); else rc = getpwuid_r(getuid(), &Pwd, achBuf, sizeof(achBuf), &pPwd); if (rc == 0 && pPwd) { char *pszDir; rc = RTStrCurrentCPToUtf8(&pszDir, pPwd->pw_dir); if (RT_SUCCESS(rc)) { char *pszShell; rc = RTStrCurrentCPToUtf8(&pszShell, pPwd->pw_shell); if (RT_SUCCESS(rc)) { char *pszUserFree = NULL; if (!pszUser) { rc = RTStrCurrentCPToUtf8(&pszUserFree, pPwd->pw_name); if (RT_SUCCESS(rc)) pszUser = pszUserFree; } if (RT_SUCCESS(rc)) { rc = RTEnvCreate(phEnvToUse); if (RT_SUCCESS(rc)) { RTENV hEnvToUse = *phEnvToUse; rc = RTEnvSetEx(hEnvToUse, "HOME", pszDir); if (RT_SUCCESS(rc)) rc = RTEnvSetEx(hEnvToUse, "SHELL", pszShell); if (RT_SUCCESS(rc)) rc = RTEnvSetEx(hEnvToUse, "USER", pszUser); if (RT_SUCCESS(rc)) rc = RTEnvSetEx(hEnvToUse, "LOGNAME", pszUser); if (RT_SUCCESS(rc)) rc = RTEnvSetEx(hEnvToUse, "PATH", pPwd->pw_uid == 0 ? _PATH_STDPATH : _PATH_DEFPATH); if (RT_SUCCESS(rc)) { RTStrPrintf(achBuf, sizeof(achBuf), "%s/%s", _PATH_MAILDIR, pszUser); rc = RTEnvSetEx(hEnvToUse, "MAIL", achBuf); } #ifdef RT_OS_DARWIN if (RT_SUCCESS(rc) && !pszUserFree) { size_t cbNeeded = confstr(_CS_DARWIN_USER_TEMP_DIR, achBuf, sizeof(achBuf)); if (cbNeeded > 0 && cbNeeded < sizeof(achBuf)) { char *pszTmp; rc = RTStrCurrentCPToUtf8(&pszTmp, achBuf); if (RT_SUCCESS(rc)) { rc = RTEnvSetEx(hEnvToUse, "TMPDIR", pszTmp); RTStrFree(pszTmp); } } else rc = VERR_BUFFER_OVERFLOW; } #endif /** @todo load /etc/environment, /etc/profile.env and ~/.pam_environment? */ if (RT_FAILURE(rc)) RTEnvDestroy(hEnvToUse); } RTStrFree(pszUserFree); } RTStrFree(pszShell); } RTStrFree(pszDir); } } else rc = errno ? RTErrConvertFromErrno(errno) : VERR_ACCESS_DENIED; return rc; }
STDMETHODIMP VBoxDnDDropTarget::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) { RT_NOREF(pt); AssertPtrReturn(pDataObject, E_INVALIDARG); AssertPtrReturn(pdwEffect, E_INVALIDARG); LogFlowFunc(("mFormatEtc.cfFormat=%RI16 (%s), pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n", mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), pDataObject, grfKeyState, pt.x, pt.y)); HRESULT hr = S_OK; if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */ { /* Make sure the data object's data format is still valid. */ hr = pDataObject->QueryGetData(&mFormatEtc); AssertMsg(SUCCEEDED(hr), ("Data format changed to invalid between DragEnter() and Drop(), cfFormat=%RI16 (%s), hr=%Rhrc\n", mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), hr)); } int rc = VINF_SUCCESS; if (SUCCEEDED(hr)) { STGMEDIUM stgMed; hr = pDataObject->GetData(&mFormatEtc, &stgMed); if (SUCCEEDED(hr)) { /* * First stage: Prepare the access to the storage medium. * For now we only support HGLOBAL stuff. */ PVOID pvData = NULL; /** @todo Put this in an own union? */ switch (mFormatEtc.tymed) { case TYMED_HGLOBAL: pvData = GlobalLock(stgMed.hGlobal); if (!pvData) { LogFlowFunc(("Locking HGLOBAL storage failed with %Rrc\n", RTErrConvertFromWin32(GetLastError()))); rc = VERR_INVALID_HANDLE; hr = E_INVALIDARG; /* Set special hr for OLE. */ } break; default: AssertMsgFailed(("Storage medium type %RI32 supported\n", mFormatEtc.tymed)); rc = VERR_NOT_SUPPORTED; hr = DV_E_TYMED; /* Set special hr for OLE. */ break; } if (RT_SUCCESS(rc)) { /* * Second stage: Do the actual copying of the data object's data, * based on the storage medium type. */ switch (mFormatEtc.cfFormat) { case CF_TEXT: /* Fall through is intentional. */ case CF_UNICODETEXT: { AssertPtr(pvData); size_t cbSize = GlobalSize(pvData); LogFlowFunc(("CF_TEXT/CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize)); if (cbSize) { char *pszText = NULL; rc = mFormatEtc.cfFormat == CF_TEXT /* ANSI codepage -> UTF-8 */ ? RTStrCurrentCPToUtf8(&pszText, (char *)pvData) /* Unicode -> UTF-8 */ : RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText); if (RT_SUCCESS(rc)) { AssertPtr(pszText); size_t cbText = strlen(pszText) + 1; /* Include termination. */ mpvData = RTMemDup((void *)pszText, cbText); mcbData = cbText; RTStrFree(pszText); pszText = NULL; } } break; } case CF_HDROP: { AssertPtr(pvData); /* Convert to a string list, separated by \r\n. */ DROPFILES *pDropFiles = (DROPFILES *)pvData; AssertPtr(pDropFiles); bool fUnicode = RT_BOOL(pDropFiles->fWide); /* Get the offset of the file list. */ Assert(pDropFiles->pFiles >= sizeof(DROPFILES)); /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only * will work with the plain storage medium pointer! */ HDROP hDrop = (HDROP)(pvData); /* First, get the file count. */ /** @todo Does this work on Windows 2000 / NT4? */ char *pszFiles = NULL; uint32_t cchFiles = 0; UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */, NULL /* lpszFile */, 0 /* cchFile */); LogFlowFunc(("CF_HDROP got %RU16 file(s)\n", cFiles)); for (UINT i = 0; i < cFiles; i++) { UINT cch = DragQueryFile(hDrop, i /* File index */, NULL /* Query size first */, 0 /* cchFile */); Assert(cch); if (RT_FAILURE(rc)) break; char *pszFile = NULL; /* UTF-8 version. */ UINT cchFile = 0; if (fUnicode) { /* Allocate enough space (including terminator). */ WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cch + 1) * sizeof(WCHAR)); if (pwszFile) { cchFile = DragQueryFileW(hDrop, i /* File index */, pwszFile, cch + 1 /* Include terminator */); AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n", cchFile, cch)); rc = RTUtf16ToUtf8(pwszFile, &pszFile); AssertRC(rc); RTMemFree(pwszFile); } else rc = VERR_NO_MEMORY; } else /* ANSI */ { /* Allocate enough space (including terminator). */ pszFile = (char *)RTMemAlloc((cch + 1) * sizeof(char)); if (pszFile) { cchFile = DragQueryFileA(hDrop, i /* File index */, pszFile, cchFile + 1 /* Include terminator */); AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n", cchFile, cch)); } else rc = VERR_NO_MEMORY; } if (RT_SUCCESS(rc)) { LogFlowFunc(("\tFile: %s (cchFile=%RU32)\n", pszFile, cchFile)); rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFile, cchFile); if (RT_SUCCESS(rc)) cchFiles += cchFile; } if (pszFile) RTStrFree(pszFile); if (RT_FAILURE(rc)) break; /* Add separation between filenames. * Note: Also do this for the last element of the list. */ rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, "\r\n", 2 /* Bytes */); if (RT_SUCCESS(rc)) cchFiles += 2; /* Include \r\n */ } if (RT_SUCCESS(rc)) { cchFiles += 1; /* Add string termination. */ uint32_t cbFiles = cchFiles * sizeof(char); LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n", cFiles, cchFiles, cbFiles, pszFiles)); /* Translate the list into URI elements. */ DnDURIList lstURI; rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles, DNDURILIST_FLAGS_ABSOLUTE_PATHS); if (RT_SUCCESS(rc)) { RTCString strRoot = lstURI.RootToString(); size_t cbRoot = strRoot.length() + 1; /* Include termination */ mpvData = RTMemAlloc(cbRoot); if (mpvData) { memcpy(mpvData, strRoot.c_str(), cbRoot); mcbData = cbRoot; } else rc = VERR_NO_MEMORY; } } LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n", rc, pszFiles, cFiles, cchFiles)); if (pszFiles) RTStrFree(pszFiles); break; } default: /* Note: Should not happen due to the checks done in DragEnter(). */ AssertMsgFailed(("Format of type %RI16 (%s) not supported\n", mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat))); hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */ break; } /* * Third stage: Unlock + release access to the storage medium again. */ switch (mFormatEtc.tymed) { case TYMED_HGLOBAL: GlobalUnlock(stgMed.hGlobal); break; default: AssertMsgFailed(("Really should not happen -- see init stage!\n")); break; } } /* Release storage medium again. */ ReleaseStgMedium(&stgMed); /* Signal waiters. */ mDroppedRc = rc; RTSemEventSignal(hEventDrop); } } if (RT_SUCCESS(rc)) { /* Note: pt is not used since we don't need to differentiate within our * proxy window. */ *pdwEffect = VBoxDnDDropTarget::GetDropEffect(grfKeyState, *pdwEffect); } else *pdwEffect = DROPEFFECT_NONE; if (mpWndParent) mpWndParent->hide(); LogFlowFunc(("Returning with hr=%Rhrc (%Rrc), mFormatEtc.cfFormat=%RI16 (%s), *pdwEffect=%RI32\n", hr, rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), *pdwEffect)); return hr; }
RTDECL(int) RTEnvGetEx(RTENV Env, const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual) { AssertPtrReturn(pszVar, VERR_INVALID_POINTER); AssertPtrNullReturn(pszValue, VERR_INVALID_POINTER); AssertPtrNullReturn(pcchActual, VERR_INVALID_POINTER); AssertReturn(pcchActual || (pszValue && cbValue), VERR_INVALID_PARAMETER); AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME); if (pcchActual) *pcchActual = 0; int rc; if (Env == RTENV_DEFAULT) { #ifdef RTENV_IMPLEMENTS_UTF8_DEFAULT_ENV_API rc = RTEnvGetUtf8(pszVar, pszValue, cbValue, pcchActual); #else /* * Since RTEnvGet isn't UTF-8 clean and actually expects the strings * to be in the current code page (codeset), we'll do the necessary * conversions here. */ char *pszVarOtherCP; rc = RTStrUtf8ToCurrentCP(&pszVarOtherCP, pszVar); if (RT_SUCCESS(rc)) { const char *pszValueOtherCP = RTEnvGet(pszVarOtherCP); RTStrFree(pszVarOtherCP); if (pszValueOtherCP) { char *pszValueUtf8; rc = RTStrCurrentCPToUtf8(&pszValueUtf8, pszValueOtherCP); if (RT_SUCCESS(rc)) { rc = VINF_SUCCESS; size_t cch = strlen(pszValueUtf8); if (pcchActual) *pcchActual = cch; if (pszValue && cbValue) { if (cch < cbValue) memcpy(pszValue, pszValueUtf8, cch + 1); else rc = VERR_BUFFER_OVERFLOW; } RTStrFree(pszValueUtf8); } } else rc = VERR_ENV_VAR_NOT_FOUND; } #endif } else { PRTENVINTERNAL pIntEnv = Env; AssertPtrReturn(pIntEnv, VERR_INVALID_HANDLE); AssertReturn(pIntEnv->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE); RTENV_LOCK(pIntEnv); /* * Locate the first variable and return it to the caller. */ rc = VERR_ENV_VAR_NOT_FOUND; const size_t cchVar = strlen(pszVar); size_t iVar; for (iVar = 0; iVar < pIntEnv->cVars; iVar++) if (!pIntEnv->pfnCompare(pIntEnv->papszEnv[iVar], pszVar, cchVar)) { if (pIntEnv->papszEnv[iVar][cchVar] == '=') { rc = VINF_SUCCESS; const char *pszValueOrg = pIntEnv->papszEnv[iVar] + cchVar + 1; size_t cch = strlen(pszValueOrg); if (pcchActual) *pcchActual = cch; if (pszValue && cbValue) { if (cch < cbValue) memcpy(pszValue, pszValueOrg, cch + 1); else rc = VERR_BUFFER_OVERFLOW; } break; } if (pIntEnv->papszEnv[iVar][cchVar] == '\0') { Assert(pIntEnv->fPutEnvBlock); rc = VERR_ENV_VAR_UNSET; break; } } RTENV_UNLOCK(pIntEnv); } return rc; }
RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone) { /* * Validate input and figure out how many variable to clone and where to get them. */ bool fCaseSensitive = true; bool fPutEnvBlock = false; size_t cVars; const char * const *papszEnv; #ifdef RTENV_HAVE_WENVIRON PCRTUTF16 const * papwszEnv; #endif PRTENVINTERNAL pIntEnvToClone; AssertPtrReturn(pEnv, VERR_INVALID_POINTER); if (EnvToClone == RTENV_DEFAULT) { cVars = 0; pIntEnvToClone = NULL; #ifdef RTENV_HAVE_WENVIRON papszEnv = NULL; papwszEnv = (PCRTUTF16 * const)_wenviron; if (!papwszEnv) { _wgetenv(L"Path"); /* Force the CRT to initalize it. */ papwszEnv = (PCRTUTF16 * const)_wenviron; } if (papwszEnv) while (papwszEnv[cVars]) cVars++; #else papszEnv = rtEnvDefault(); if (papszEnv) while (papszEnv[cVars]) cVars++; #endif #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) /* DOS systems was case insensitive. A prime example is the 'Path' variable on windows which turns into the 'PATH' variable. */ fCaseSensitive = false; #endif } else { pIntEnvToClone = EnvToClone; AssertPtrReturn(pIntEnvToClone, VERR_INVALID_HANDLE); AssertReturn(pIntEnvToClone->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE); RTENV_LOCK(pIntEnvToClone); fPutEnvBlock = pIntEnvToClone->fPutEnvBlock; papszEnv = pIntEnvToClone->papszEnv; cVars = pIntEnvToClone->cVars; } /* * Create the duplicate. */ PRTENVINTERNAL pIntEnv; int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */, fCaseSensitive, fPutEnvBlock); if (RT_SUCCESS(rc)) { pIntEnv->cVars = cVars; pIntEnv->papszEnv[pIntEnv->cVars] = NULL; if (EnvToClone == RTENV_DEFAULT) { /* ASSUMES the default environment is in the current codepage. */ size_t iDst = 0; for (size_t iSrc = 0; iSrc < cVars; iSrc++) { #ifdef RTENV_HAVE_WENVIRON int rc2 = RTUtf16ToUtf8(papwszEnv[iSrc], &pIntEnv->papszEnv[iDst]); #else int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]); #endif if (RT_SUCCESS(rc2)) { /* Make sure it contains an '='. */ iDst++; if (strchr(pIntEnv->papszEnv[iDst - 1], '=')) continue; rc2 = RTStrAAppend(&pIntEnv->papszEnv[iDst - 1], "="); if (RT_SUCCESS(rc2)) continue; } else if (rc2 == VERR_NO_TRANSLATION) { rc = VWRN_ENV_NOT_FULLY_TRANSLATED; continue; } /* failed fatally. */ pIntEnv->cVars = iDst; RTEnvDestroy(pIntEnv); return rc2; } pIntEnv->cVars = iDst; } else { for (size_t iVar = 0; iVar < cVars; iVar++) { char *pszVar = RTStrDup(papszEnv[iVar]); if (RT_UNLIKELY(!pszVar)) { RTENV_UNLOCK(pIntEnvToClone); pIntEnv->cVars = iVar; RTEnvDestroy(pIntEnv); return VERR_NO_STR_MEMORY; } pIntEnv->papszEnv[iVar] = pszVar; } } /* done */ *pEnv = pIntEnv; } if (pIntEnvToClone) RTENV_UNLOCK(pIntEnvToClone); return rc; }
void GetInterfaceNameByIID(const GUID &aIID, BSTR *aName) { Assert(aName); if (!aName) return; *aName = NULL; #if !defined(VBOX_WITH_XPCOM) LONG rc; LPOLESTR iidStr = NULL; if (StringFromIID(aIID, &iidStr) == S_OK) { HKEY ifaceKey; rc = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface", 0, KEY_QUERY_VALUE, &ifaceKey); if (rc == ERROR_SUCCESS) { HKEY iidKey; rc = RegOpenKeyExW(ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey); if (rc == ERROR_SUCCESS) { /* determine the size and type */ DWORD sz, type; rc = RegQueryValueExW(iidKey, NULL, NULL, &type, NULL, &sz); if (rc == ERROR_SUCCESS && type == REG_SZ) { /* query the value to BSTR */ *aName = SysAllocStringLen(NULL, (sz + 1) / sizeof(TCHAR) + 1); rc = RegQueryValueExW(iidKey, NULL, NULL, NULL, (LPBYTE) *aName, &sz); if (rc != ERROR_SUCCESS) { SysFreeString(*aName); aName = NULL; } } RegCloseKey(iidKey); } RegCloseKey(ifaceKey); } CoTaskMemFree(iidStr); } #else /* !defined (VBOX_WITH_XPCOM) */ nsresult rv; nsCOMPtr<nsIInterfaceInfoManager> iim = do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIInterfaceInfo> iinfo; rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo)); if (NS_SUCCEEDED(rv)) { const char *iname = NULL; iinfo->GetNameShared(&iname); char *utf8IName = NULL; if (RT_SUCCESS(RTStrCurrentCPToUtf8(&utf8IName, iname))) { PRTUTF16 utf16IName = NULL; if (RT_SUCCESS(RTStrToUtf16(utf8IName, &utf16IName))) { *aName = SysAllocString((OLECHAR *) utf16IName); RTUtf16Free(utf16IName); } RTStrFree(utf8IName); } } } #endif /* !defined (VBOX_WITH_XPCOM) */ }
RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser, size_t *pcbUser) { AssertReturn( (pszUser && cbUser > 0) || (!pszUser && !cbUser), VERR_INVALID_PARAMETER); AssertReturn(pcbUser || pszUser, VERR_INVALID_PARAMETER); int rc; if ( hProcess == NIL_RTPROCESS || hProcess == RTProcSelf()) { /* * Figure a good buffer estimate. */ int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX); if (cbPwdMax <= _1K) cbPwdMax = _1K; else AssertStmt(cbPwdMax <= 32*_1M, cbPwdMax = 32*_1M); char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax); if (pchBuf) { /* * Get the password file entry. */ struct passwd Pwd; struct passwd *pPwd = NULL; rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd); if (!rc) { /* * Convert the name to UTF-8, assuming that we're getting it in the local codeset. */ /** @todo This isn't exactly optimal... the current codeset/page conversion * stuff never was. Should optimize that for UTF-8 and ASCII one day. * And also optimize for avoiding heap. */ char *pszTmp = NULL; rc = RTStrCurrentCPToUtf8(&pszTmp, pPwd->pw_name); if (RT_SUCCESS(rc)) { size_t cbTmp = strlen(pszTmp) + 1; if (pcbUser) *pcbUser = cbTmp; if (cbTmp <= cbUser) { memcpy(pszUser, pszTmp, cbTmp); rc = VINF_SUCCESS; } else rc = VERR_BUFFER_OVERFLOW; RTStrFree(pszTmp); } } else rc = RTErrConvertFromErrno(rc); RTMemFree(pchBuf); } else rc = VERR_NO_TMP_MEMORY; } else rc = VERR_NOT_SUPPORTED; return rc; }
/** * Internal worker which initializes or re-initializes the * program path, name and directory globals. * * @returns IPRT status code. * @param fFlags Flags, see RTR3INIT_XXX. * @param cArgs Pointer to the argument count. * @param ppapszArgs Pointer to the argument vector pointer. NULL * allowed if @a cArgs is 0. */ static int rtR3InitArgv(uint32_t fFlags, int cArgs, char ***ppapszArgs) { NOREF(fFlags); if (cArgs) { AssertPtr(ppapszArgs); AssertPtr(*ppapszArgs); char **papszOrgArgs = *ppapszArgs; /* * Normally we should only be asked to convert arguments once. If we * are though, it should be the already convered arguments. */ if (g_crtArgs != -1) { AssertReturn( g_crtArgs == cArgs && g_papszrtArgs == papszOrgArgs, VERR_WRONG_ORDER); /* only init once! */ return VINF_SUCCESS; } if (!(fFlags & RTR3INIT_FLAGS_UTF8_ARGV)) { /* * Convert the arguments. */ char **papszArgs = (char **)RTMemAllocZ((cArgs + 1) * sizeof(char *)); if (!papszArgs) return VERR_NO_MEMORY; #ifdef RT_OS_WINDOWS /* HACK ALERT! Try convert from unicode versions if possible. Unfortunately for us, __wargv is only initialized if we have a unicode main function. So, we have to use CommandLineToArgvW to get something similar. It should do the same conversion... :-) */ int cArgsW = -1; PWSTR *papwszArgs = NULL; if ( papszOrgArgs == __argv && cArgs == __argc && (papwszArgs = CommandLineToArgvW(GetCommandLineW(), &cArgsW)) != NULL ) { AssertMsg(cArgsW == cArgs, ("%d vs %d\n", cArgsW, cArgs)); for (int i = 0; i < cArgs; i++) { int rc = RTUtf16ToUtf8(papwszArgs[i], &papszArgs[i]); if (RT_FAILURE(rc)) { while (i--) RTStrFree(papszArgs[i]); RTMemFree(papszArgs); LocalFree(papwszArgs); return rc; } } LocalFree(papwszArgs); } else #endif { for (int i = 0; i < cArgs; i++) { int rc = RTStrCurrentCPToUtf8(&papszArgs[i], papszOrgArgs[i]); if (RT_FAILURE(rc)) { while (i--) RTStrFree(papszArgs[i]); RTMemFree(papszArgs); return rc; } } } papszArgs[cArgs] = NULL; g_papszrtOrgArgs = papszOrgArgs; g_papszrtArgs = papszArgs; g_crtArgs = cArgs; *ppapszArgs = papszArgs; } else { /* * The arguments are already UTF-8, no conversion needed. */ g_papszrtOrgArgs = papszOrgArgs; g_papszrtArgs = papszOrgArgs; g_crtArgs = cArgs; } } return VINF_SUCCESS; }
RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone) { /* * Validate input and figure out how many variable to clone and where to get them. */ size_t cVars; const char * const *papszEnv; PRTENVINTERNAL pIntEnvToClone; AssertPtrReturn(pEnv, VERR_INVALID_POINTER); if (EnvToClone == RTENV_DEFAULT) { pIntEnvToClone = NULL; papszEnv = rtEnvDefault(); cVars = 0; if (papszEnv) while (papszEnv[cVars]) cVars++; } else { pIntEnvToClone = EnvToClone; AssertPtrReturn(pIntEnvToClone, VERR_INVALID_HANDLE); AssertReturn(pIntEnvToClone->u32Magic == RTENV_MAGIC, VERR_INVALID_HANDLE); RTENV_LOCK(pIntEnvToClone); papszEnv = pIntEnvToClone->papszEnv; cVars = pIntEnvToClone->cVars; } /* * Create the duplicate. */ PRTENVINTERNAL pIntEnv; int rc = rtEnvCreate(&pIntEnv, cVars + 1 /* NULL */); if (RT_SUCCESS(rc)) { pIntEnv->cVars = cVars; pIntEnv->papszEnv[pIntEnv->cVars] = NULL; if (EnvToClone == RTENV_DEFAULT) { /* ASSUMES the default environment is in the current codepage. */ size_t iDst = 0; for (size_t iSrc = 0; iSrc < cVars; iSrc++) { int rc2 = RTStrCurrentCPToUtf8(&pIntEnv->papszEnv[iDst], papszEnv[iSrc]); if (RT_SUCCESS(rc2)) iDst++; else if (rc2 == VERR_NO_TRANSLATION) rc = VWRN_ENV_NOT_FULLY_TRANSLATED; else { pIntEnv->cVars = iDst; RTEnvDestroy(pIntEnv); return rc2; } } pIntEnv->cVars = iDst; } else { for (size_t iVar = 0; iVar < cVars; iVar++) { char *pszVar = RTStrDup(papszEnv[iVar]); if (RT_UNLIKELY(!pszVar)) { RTENV_UNLOCK(pIntEnvToClone); pIntEnv->cVars = iVar; RTEnvDestroy(pIntEnv); return VERR_NO_STR_MEMORY; } pIntEnv->papszEnv[iVar] = pszVar; } } /* done */ *pEnv = pIntEnv; } if (pIntEnvToClone) RTENV_UNLOCK(pIntEnvToClone); return rc; }