/* Implements a normal path search for fname on the paths in env_var. Resolves symlinks, * which is needed to get the right config filename (i#1062). */ drfront_status_t drfront_searchenv(const char *fname, const char *env_var, OUT char *full_path, const size_t full_path_size, OUT bool *ret) { drfront_status_t status_check = DRFRONT_ERROR; size_t size_needed = 0; TCHAR wfname[MAX_PATH]; /* XXX: Not sure what the size for environment variable names should be. * Perhaps we want a drfront_char_to_tchar_size_needed */ TCHAR wenv_var[MAX_PATH]; TCHAR wfull_path[MAX_PATH]; if (full_path == NULL && ret == NULL) return DRFRONT_ERROR_INVALID_PARAMETER; status_check = drfront_char_to_tchar(fname, wfname, BUFFER_SIZE_ELEMENTS(wfname)); if (status_check != DRFRONT_SUCCESS) { *ret = false; return status_check; } status_check = drfront_char_to_tchar(env_var, wenv_var, BUFFER_SIZE_ELEMENTS(wenv_var)); if (status_check != DRFRONT_SUCCESS) { *ret = false; return status_check; } _wsearchenv(wfname, wenv_var, wfull_path); if (wfull_path[0] == L'\0') { *ret = false; return DRFRONT_ERROR; } status_check = drfront_tchar_to_char_size_needed(wfull_path, &size_needed); if (status_check != DRFRONT_SUCCESS) { *ret = false; return status_check; } else if (full_path_size < size_needed) { *ret = true; return DRFRONT_ERROR_INVALID_SIZE; } status_check = drfront_tchar_to_char(wfull_path, full_path, full_path_size); if (status_check != DRFRONT_SUCCESS) { *ret = false; return status_check; } full_path[full_path_size - 1] = '\0'; *ret = true; return DRFRONT_SUCCESS; }
/* always null-terminates */ static void char_to_tchar(const char *str, TCHAR *wbuf, size_t wbuflen/*# elements*/) { drfront_status_t sc = drfront_char_to_tchar(str, wbuf, wbuflen); if (sc != DRFRONT_SUCCESS) fatal("failed (status=%d) to convert UTF-8 to UTF-16", sc); }
drfront_status_t drfront_get_app_full_path(const char *app, OUT char *buf, size_t buflen/*# elements*/) { TCHAR wbuf[MAX_PATH]; TCHAR wapp[MAX_PATH]; drfront_status_t status_check = DRFRONT_ERROR; bool is_dir = false; status_check = drfront_char_to_tchar(app, wapp, BUFFER_SIZE_ELEMENTS(wapp)); if (status_check != DRFRONT_SUCCESS) return status_check; _tsearchenv(wapp, _T("PATH"), wbuf); NULL_TERMINATE_BUFFER(wbuf); status_check = drfront_tchar_to_char(wbuf, buf, buflen); if (status_check != DRFRONT_SUCCESS) return status_check; if (wbuf[0] == _T('\0') || /* DrM-i#1617: we might have a same-name directory on the path */ (drfront_dir_exists(buf, &is_dir) == DRFRONT_SUCCESS && is_dir)) { /* may need to append .exe, FIXME : other executable types */ TCHAR tmp_buf[MAX_PATH]; _sntprintf(tmp_buf, BUFFER_SIZE_ELEMENTS(tmp_buf), _T("%s%s"), wapp, _T(".exe")); NULL_TERMINATE_BUFFER(wbuf); _tsearchenv(tmp_buf, _T("PATH"), wbuf); } if (wbuf[0] == _T('\0')) { /* last try: expand w/ cur dir */ GetFullPathName(wapp, BUFFER_SIZE_ELEMENTS(wbuf), wbuf, NULL); NULL_TERMINATE_BUFFER(wbuf); } status_check = drfront_tchar_to_char(wbuf, buf, buflen); return status_check; }
drfront_status_t drfront_get_env_var(const char *name, OUT char *buf, size_t buflen/*# elements*/) { TCHAR wbuf[MAX_PATH]; /* XXX: Not sure what the size for environment variable names should be. */ TCHAR wname[MAX_PATH]; drfront_status_t res = drfront_char_to_tchar(name, wname, BUFFER_SIZE_ELEMENTS(wname)); if (res != DRFRONT_SUCCESS) return res; if (GetEnvironmentVariable(wname, wbuf, BUFFER_SIZE_ELEMENTS(wbuf)) > 0) { return drfront_tchar_to_char(wbuf, buf, buflen); } return DRFRONT_ERROR; }
/* Semi-compatibility with the Windows CRT _access function. */ drfront_status_t drfront_access(const char *fname, drfront_access_mode_t mode, OUT bool *ret) { int r; int msdn_mode = 00; TCHAR wfname[MAX_PATH]; drfront_status_t status_check = DRFRONT_ERROR; if (ret == NULL) return DRFRONT_ERROR_INVALID_PARAMETER; status_check = drfront_char_to_tchar(fname, wfname, MAX_PATH); if (status_check != DRFRONT_SUCCESS) { *ret = false; return status_check; } /* Translate drfront_access_mode_t to msdn _waccess mode */ if (TEST(mode, DRFRONT_WRITE)) msdn_mode |= 02; if (TEST(mode, DRFRONT_READ)) msdn_mode |= 04; r = _waccess(wfname, msdn_mode); if (r == -1) { *ret = false; if (GetLastError() == EACCES) return DRFRONT_SUCCESS; return DRFRONT_ERROR; } else if (TEST(DRFRONT_WRITE, mode)) { DWORD file_attrs = GetFileAttributes(wfname); if (file_attrs != INVALID_FILE_ATTRIBUTES && TEST(file_attrs, FILE_ATTRIBUTE_DIRECTORY)) { /* We use an actual write try, to avoid failing on a read-only filesystem * (DrMi#1857). */ return drfront_dir_try_writable(fname, ret); } } *ret = true; return DRFRONT_SUCCESS; }
drfront_status_t drfront_get_absolute_path(const char *src, OUT char *buf, size_t buflen/*# elements*/) { TCHAR wsrc[MAX_PATH]; TCHAR wdst[MAX_PATH]; drfront_status_t status_check = DRFRONT_ERROR; int res; status_check = drfront_char_to_tchar(src, wsrc, BUFFER_SIZE_ELEMENTS(wsrc)); if (status_check != DRFRONT_SUCCESS) return status_check; res = GetFullPathName(wsrc, BUFFER_SIZE_ELEMENTS(wdst), wdst, NULL); if (res <= 0) return DRFRONT_ERROR; NULL_TERMINATE_BUFFER(wdst); status_check = drfront_tchar_to_char(wdst, buf, buflen); return status_check; }