/** * RTPathTraverseList callback used by RTProcCreateEx to locate the executable. */ static DECLCALLBACK(int) rtPathFindExec(char const *pchPath, size_t cchPath, void *pvUser1, void *pvUser2) { const char *pszExec = (const char *)pvUser1; char *pszRealExec = (char *)pvUser2; int rc = RTPathJoinEx(pszRealExec, RTPATH_MAX, pchPath, cchPath, pszExec, RTSTR_MAX); if (RT_FAILURE(rc)) return rc; if (!access(pszRealExec, X_OK)) return VINF_SUCCESS; if ( errno == EACCES || errno == EPERM) return RTErrConvertFromErrno(errno); return VERR_TRY_AGAIN; }
/** * Corrects the casing of the final component * * @returns * @param pClient . * @param pszFullPath . * @param pszStartComponent . */ static int vbsfCorrectCasing(SHFLCLIENTDATA *pClient, char *pszFullPath, char *pszStartComponent) { Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent)); AssertReturn((uintptr_t)pszFullPath < (uintptr_t)pszStartComponent - 1U, VERR_INTERNAL_ERROR_2); AssertReturn(pszStartComponent[-1] == RTPATH_DELIMITER, VERR_INTERNAL_ERROR_5); /* * Allocate a buffer that can hold really long file name entries as well as * the initial search pattern. */ size_t cchComponent = strlen(pszStartComponent); size_t cchParentDir = pszStartComponent - pszFullPath; size_t cchFullPath = cchParentDir + cchComponent; Assert(strlen(pszFullPath) == cchFullPath); size_t cbDirEntry = 4096; if (cchFullPath + 4 > cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName)) cbDirEntry = RT_OFFSETOF(RTDIRENTRYEX, szName) + cchFullPath + 4; PRTDIRENTRYEX pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry); if (pDirEntry == NULL) return VERR_NO_MEMORY; /* * Construct the search criteria in the szName member of pDirEntry. */ /** @todo This is quite inefficient, especially for directories with many * files. If any of the typically case sensitive host systems start * supporting opendir wildcard filters, it would make sense to build * one here with '?' for case foldable charaters. */ /** @todo Use RTDirOpen here and drop the whole uncessary path copying? */ int rc = RTPathJoinEx(pDirEntry->szName, cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName), pszFullPath, cchParentDir, RT_STR_TUPLE("*")); AssertRC(rc); if (RT_SUCCESS(rc)) { RTDIR hSearch = NULL; rc = RTDirOpenFiltered(&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT, 0 /*fFlags*/); if (RT_SUCCESS(rc)) { for (;;) { size_t cbDirEntrySize = cbDirEntry; rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient)); if (rc == VERR_NO_MORE_FILES) break; if ( rc != VINF_SUCCESS && rc != VWRN_NO_DIRENT_INFO) { if ( rc == VERR_NO_TRANSLATION || rc == VERR_INVALID_UTF8_ENCODING) continue; AssertMsgFailed(("%Rrc\n", rc)); break; } Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0])); if ( pDirEntry->cbName == cchComponent && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0])) { Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent)); strcpy(pszStartComponent, &pDirEntry->szName[0]); rc = VINF_SUCCESS; break; } } RTDirClose(hSearch); } } if (RT_FAILURE(rc)) Log(("vbsfCorrectCasing %s failed with %Rrc\n", pszStartComponent, rc)); RTMemFree(pDirEntry); return rc; }