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, -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(
id), path);
397 char* GetKnownSubPath(eKnownPathTypes
id,
const char* path)
399 char* knownPath = GetKnownPath(
id);
403 char* subPath = GetCombinedPath(knownPath, path);
408 char* GetEnvironmentPath(
char* name)
413 nSize = GetEnvironmentVariableX(name, NULL, 0);
417 env = (LPSTR)malloc(nSize);
422 nStatus = GetEnvironmentVariableX(name, env, nSize);
424 if (nStatus != (nSize - 1))
434 char* GetEnvironmentSubPath(
char* name,
const char* path)
437 char* subpath = NULL;
438 env = GetEnvironmentPath(name);
443 subpath = GetCombinedPath(env, path);
448 char* GetCombinedPath(
const char* basePath,
const char* subPath)
453 char* subPathCpy = NULL;
454 size_t basePathLength = 0;
455 size_t subPathLength = 0;
458 basePathLength = strlen(basePath);
461 subPathLength = strlen(subPath);
463 length = basePathLength + subPathLength + 1;
464 path = (
char*)calloc(1, length + 1);
470 CopyMemory(path, basePath, basePathLength);
472 if (FAILED(PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE)))
478 subPathCpy = _strdup(subPath);
483 if (FAILED(PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE)))
486 status = NativePathCchAppendA(path, length + 1, subPathCpy);
499 BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
503 #elif defined(_WIN32)
504 return (SHCreateDirectoryExA(NULL, path, lpAttributes) == ERROR_SUCCESS);
506 const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
517 if (!path || *path != delim)
522 if (!(dup = _strdup(path)))
526 p = (strlen(dup) > 3) && (dup[1] ==
':') && (dup[2] == delim)) ? &dup[3] : dup;
530 for (
char* p = dup; p;)
533 if ((p = strchr(p + 1, delim)))
536 if (mkdir(dup, 0777) != 0)
552 BOOL PathMakePathW(LPCWSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
556 #elif defined(_WIN32)
557 return (SHCreateDirectoryExW(NULL, path, lpAttributes) == ERROR_SUCCESS);
559 const WCHAR wdelim = PathGetSeparatorW(PATH_STYLE_NATIVE);
560 const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
571 if (!path || *path != wdelim)
576 dup = ConvertWCharToUtf8Alloc(path, NULL);
581 p = (strlen(dup) > 3) && (dup[1] ==
':') && (dup[2] == delim)) ? &dup[3] : dup;
585 for (
char* p = dup; p;)
588 if ((p = strchr(p + 1, delim)))
591 if (mkdir(dup, 0777) != 0)
607 #if !defined(_WIN32) || defined(_UWP)
609 BOOL PathIsRelativeA(LPCSTR pszPath)
614 return pszPath[0] !=
'/';
617 BOOL PathIsRelativeW(LPCWSTR pszPath)
619 LPSTR lpFileNameA = NULL;
625 lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
628 ret = PathIsRelativeA(lpFileNameA);
634 BOOL PathFileExistsA(LPCSTR pszPath)
636 struct stat stat_info;
638 if (stat(pszPath, &stat_info) != 0)
644 BOOL PathFileExistsW(LPCWSTR pszPath)
646 LPSTR lpFileNameA = NULL;
651 lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
655 ret = winpr_PathFileExists(lpFileNameA);
661 BOOL PathIsDirectoryEmptyA(LPCSTR pszPath)
663 struct dirent* dp = NULL;
665 DIR* dir = opendir(pszPath);
670 while ((dp = readdir(dir)) != NULL)
672 if (strcmp(dp->d_name,
".") == 0 || strcmp(dp->d_name,
"..") == 0)
683 BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath)
685 LPSTR lpFileNameA = NULL;
689 lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
692 ret = PathIsDirectoryEmptyA(lpFileNameA);
700 BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
703 return MoveFileA(lpExistingFileName, lpNewFileName);
706 LPWSTR lpExistingFileNameW = NULL;
707 LPWSTR lpNewFileNameW = NULL;
709 if (!lpExistingFileName || !lpNewFileName)
712 lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL);
713 if (!lpExistingFileNameW)
715 lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL);
719 result = MoveFileW(lpExistingFileNameW, lpNewFileNameW);
722 free(lpExistingFileNameW);
723 free(lpNewFileNameW);
728 BOOL winpr_MoveFileEx(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags)
731 return MoveFileExA(lpExistingFileName, lpNewFileName, dwFlags);
734 LPWSTR lpExistingFileNameW = NULL;
735 LPWSTR lpNewFileNameW = NULL;
737 if (!lpExistingFileName || !lpNewFileName)
740 lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL);
741 if (!lpExistingFileNameW)
743 lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL);
747 result = MoveFileExW(lpExistingFileNameW, lpNewFileNameW, dwFlags);
750 free(lpExistingFileNameW);
751 free(lpNewFileNameW);
756 BOOL winpr_DeleteFile(
const char* lpFileName)
759 return DeleteFileA(lpFileName);
761 LPWSTR lpFileNameW = NULL;
766 lpFileNameW = ConvertUtf8ToWCharAlloc(lpFileName, NULL);
771 result = DeleteFileW(lpFileNameW);
779 BOOL winpr_RemoveDirectory(LPCSTR lpPathName)
782 return RemoveDirectoryA(lpPathName);
784 LPWSTR lpPathNameW = NULL;
789 lpPathNameW = ConvertUtf8ToWCharAlloc(lpPathName, NULL);
794 result = RemoveDirectoryW(lpPathNameW);
802 BOOL winpr_PathFileExists(
const char* pszPath)
807 return PathFileExistsA(pszPath);
809 WCHAR* pathW = ConvertUtf8ToWCharAlloc(pszPath, NULL);
815 result = PathFileExistsW(pathW);
822 BOOL winpr_PathMakePath(
const char* path, LPSECURITY_ATTRIBUTES lpAttributes)
827 return PathMakePathA(path, lpAttributes);
829 WCHAR* pathW = ConvertUtf8ToWCharAlloc(path, NULL);
835 result = SHCreateDirectoryExW(NULL, pathW, lpAttributes) == ERROR_SUCCESS;