21 #include <winpr/config.h>
22 #include <winpr/build-config.h>
29 #include <winpr/crt.h>
30 #include <winpr/platform.h>
31 #include <winpr/file.h>
32 #include <winpr/tchar.h>
33 #include <winpr/environment.h>
35 #include <winpr/path.h>
36 #include <winpr/wlog.h>
39 #define TAG WINPR_TAG("path.shell")
42 #include "shell_ios.h"
53 static char* GetPath_XDG_CONFIG_HOME(
void);
54 static char* GetPath_XDG_RUNTIME_DIR(
void);
66 char* GetEnvAlloc(LPCSTR lpName)
72 nSize = GetEnvironmentVariableX(lpName, NULL, 0);
81 nStatus = GetEnvironmentVariableX(lpName, env, nSize);
83 if (nStatus != (nSize - 1))
93 static char* GetPath_HOME(
void)
97 path = GetEnvAlloc(
"UserProfile");
98 #elif defined(__IOS__)
99 path = ios_get_home();
101 path = GetEnvAlloc(
"HOME");
106 static char* GetPath_TEMP(
void)
110 path = GetEnvAlloc(
"TEMP");
111 #elif defined(__IOS__)
112 path = ios_get_temp();
114 path = GetEnvAlloc(
"TMPDIR");
117 path = _strdup(
"/tmp");
123 static char* GetPath_XDG_DATA_HOME(
void)
126 #if defined(WIN32) || defined(__IOS__)
127 path = GetPath_XDG_CONFIG_HOME();
139 path = GetEnvAlloc(
"XDG_DATA_HOME");
144 home = GetPath_HOME();
149 size = strlen(home) + strlen(
"/.local/share") + 1;
150 path = (
char*)malloc(size);
158 (void)sprintf_s(path, size,
"%s%s", home,
"/.local/share");
164 static char* GetPath_XDG_CONFIG_HOME(
void)
167 #if defined(WIN32) && !defined(_UWP)
168 path = calloc(MAX_PATH,
sizeof(
char));
173 if (FAILED(SHGetFolderPathA(0, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)))
179 #elif defined(__IOS__)
180 path = ios_get_data();
192 path = GetEnvAlloc(
"XDG_CONFIG_HOME");
197 home = GetPath_HOME();
200 home = GetPath_TEMP();
205 size = strlen(home) + strlen(
"/.config") + 1;
206 path = (
char*)malloc(size);
214 (void)sprintf_s(path, size,
"%s%s", home,
"/.config");
220 static char* GetPath_SYSTEM_CONFIG_HOME(
void)
223 #if defined(WIN32) && !defined(_UWP)
226 if (FAILED(SHGetKnownFolderPath(&FOLDERID_ProgramData, 0, (HANDLE)-1, &wpath)))
230 path = ConvertWCharToUtf8Alloc(wpath, NULL);
231 CoTaskMemFree(wpath);
233 #elif defined(__IOS__)
234 path = ios_get_data();
236 path = _strdup(WINPR_INSTALL_SYSCONFDIR);
241 static char* GetPath_XDG_CACHE_HOME(
void)
246 char* home = GetPath_XDG_RUNTIME_DIR();
250 path = GetCombinedPath(home,
"cache");
252 if (!winpr_PathFileExists(path))
253 if (!CreateDirectoryA(path, NULL))
259 #elif defined(__IOS__)
260 path = ios_get_cache();
271 path = GetEnvAlloc(
"XDG_CACHE_HOME");
276 char* home = GetPath_HOME();
281 size = strlen(home) + strlen(
"/.cache") + 1;
282 path = (
char*)malloc(size);
290 (void)sprintf_s(path, size,
"%s%s", home,
"/.cache");
296 char* GetPath_XDG_RUNTIME_DIR(
void)
299 #if defined(WIN32) && !defined(_UWP)
300 path = calloc(MAX_PATH,
sizeof(
char));
305 if (FAILED(SHGetFolderPathA(0, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)))
343 path = GetEnvAlloc(
"XDG_RUNTIME_DIR");
349 path = GetPath_TEMP();
353 char* GetKnownPath(eKnownPathTypes
id)
359 case KNOWN_PATH_HOME:
360 path = GetPath_HOME();
363 case KNOWN_PATH_TEMP:
364 path = GetPath_TEMP();
367 case KNOWN_PATH_XDG_DATA_HOME:
368 path = GetPath_XDG_DATA_HOME();
371 case KNOWN_PATH_XDG_CONFIG_HOME:
372 path = GetPath_XDG_CONFIG_HOME();
375 case KNOWN_PATH_XDG_CACHE_HOME:
376 path = GetPath_XDG_CACHE_HOME();
379 case KNOWN_PATH_XDG_RUNTIME_DIR:
380 path = GetPath_XDG_RUNTIME_DIR();
383 case KNOWN_PATH_SYSTEM_CONFIG_HOME:
384 path = GetPath_SYSTEM_CONFIG_HOME();
393 WLog_WARN(TAG,
"Path %s is %p", GetKnownPathIdString(WINPR_ASSERTING_INT_CAST(
int,
id)),
398 char* GetKnownSubPath(eKnownPathTypes
id,
const char* path)
400 char* knownPath = GetKnownPath(
id);
404 char* subPath = GetCombinedPath(knownPath, path);
409 char* GetEnvironmentPath(
char* name)
414 nSize = GetEnvironmentVariableX(name, NULL, 0);
418 env = (LPSTR)malloc(nSize);
423 nStatus = GetEnvironmentVariableX(name, env, nSize);
425 if (nStatus != (nSize - 1))
435 char* GetEnvironmentSubPath(
char* name,
const char* path)
438 char* subpath = NULL;
439 env = GetEnvironmentPath(name);
444 subpath = GetCombinedPath(env, path);
449 char* GetCombinedPath(
const char* basePath,
const char* subPath)
454 char* subPathCpy = NULL;
455 size_t basePathLength = 0;
456 size_t subPathLength = 0;
459 basePathLength = strlen(basePath);
462 subPathLength = strlen(subPath);
464 length = basePathLength + subPathLength + 1;
465 path = (
char*)calloc(1, length + 1);
471 CopyMemory(path, basePath, basePathLength);
473 if (FAILED(PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE)))
479 subPathCpy = _strdup(subPath);
484 if (FAILED(PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE)))
487 status = NativePathCchAppendA(path, length + 1, subPathCpy);
500 BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
504 #elif defined(_WIN32)
505 return (SHCreateDirectoryExA(NULL, path, lpAttributes) == ERROR_SUCCESS);
507 const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
518 if (!path || *path != delim)
523 if (!(dup = _strdup(path)))
527 p = (strlen(dup) > 3) && (dup[1] ==
':') && (dup[2] == delim)) ? &dup[3] : dup;
531 for (
char* p = dup; p;)
534 if ((p = strchr(p + 1, delim)))
537 if (mkdir(dup, 0777) != 0)
553 BOOL PathMakePathW(LPCWSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
557 #elif defined(_WIN32)
558 return (SHCreateDirectoryExW(NULL, path, lpAttributes) == ERROR_SUCCESS);
560 const WCHAR wdelim = PathGetSeparatorW(PATH_STYLE_NATIVE);
561 const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
572 if (!path || *path != wdelim)
577 dup = ConvertWCharToUtf8Alloc(path, NULL);
582 p = (strlen(dup) > 3) && (dup[1] ==
':') && (dup[2] == delim)) ? &dup[3] : dup;
586 for (
char* p = dup; p;)
589 if ((p = strchr(p + 1, delim)))
592 if (mkdir(dup, 0777) != 0)
608 #if !defined(_WIN32) || defined(_UWP)
610 BOOL PathIsRelativeA(LPCSTR pszPath)
615 return pszPath[0] !=
'/';
618 BOOL PathIsRelativeW(LPCWSTR pszPath)
620 LPSTR lpFileNameA = NULL;
626 lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
629 ret = PathIsRelativeA(lpFileNameA);
635 BOOL PathFileExistsA(LPCSTR pszPath)
637 struct stat stat_info;
639 if (stat(pszPath, &stat_info) != 0)
645 BOOL PathFileExistsW(LPCWSTR pszPath)
647 LPSTR lpFileNameA = NULL;
652 lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
656 ret = winpr_PathFileExists(lpFileNameA);
662 BOOL PathIsDirectoryEmptyA(LPCSTR pszPath)
664 struct dirent* dp = NULL;
666 DIR* dir = opendir(pszPath);
671 while ((dp = readdir(dir)) != NULL)
673 if (strcmp(dp->d_name,
".") == 0 || strcmp(dp->d_name,
"..") == 0)
684 BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath)
686 LPSTR lpFileNameA = NULL;
690 lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
693 ret = PathIsDirectoryEmptyA(lpFileNameA);
701 BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
704 return MoveFileA(lpExistingFileName, lpNewFileName);
707 LPWSTR lpExistingFileNameW = NULL;
708 LPWSTR lpNewFileNameW = NULL;
710 if (!lpExistingFileName || !lpNewFileName)
713 lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL);
714 if (!lpExistingFileNameW)
716 lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL);
720 result = MoveFileW(lpExistingFileNameW, lpNewFileNameW);
723 free(lpExistingFileNameW);
724 free(lpNewFileNameW);
729 BOOL winpr_MoveFileEx(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags)
732 return MoveFileExA(lpExistingFileName, lpNewFileName, dwFlags);
735 LPWSTR lpExistingFileNameW = NULL;
736 LPWSTR lpNewFileNameW = NULL;
738 if (!lpExistingFileName || !lpNewFileName)
741 lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL);
742 if (!lpExistingFileNameW)
744 lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL);
748 result = MoveFileExW(lpExistingFileNameW, lpNewFileNameW, dwFlags);
751 free(lpExistingFileNameW);
752 free(lpNewFileNameW);
757 BOOL winpr_DeleteFile(
const char* lpFileName)
760 return DeleteFileA(lpFileName);
762 LPWSTR lpFileNameW = NULL;
767 lpFileNameW = ConvertUtf8ToWCharAlloc(lpFileName, NULL);
772 result = DeleteFileW(lpFileNameW);
780 BOOL winpr_RemoveDirectory(LPCSTR lpPathName)
783 return RemoveDirectoryA(lpPathName);
785 LPWSTR lpPathNameW = NULL;
790 lpPathNameW = ConvertUtf8ToWCharAlloc(lpPathName, NULL);
795 result = RemoveDirectoryW(lpPathNameW);
803 BOOL winpr_PathFileExists(
const char* pszPath)
808 return PathFileExistsA(pszPath);
810 WCHAR* pathW = ConvertUtf8ToWCharAlloc(pszPath, NULL);
816 result = PathFileExistsW(pathW);
823 BOOL winpr_PathMakePath(
const char* path, LPSECURITY_ATTRIBUTES lpAttributes)
828 return PathMakePathA(path, lpAttributes);
830 WCHAR* pathW = ConvertUtf8ToWCharAlloc(path, NULL);
836 result = SHCreateDirectoryExW(NULL, pathW, lpAttributes) == ERROR_SUCCESS;