/** * WinPR: Windows Portable Runtime * Path Functions * * Copyright 2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef WINPR_PATH_H #define WINPR_PATH_H #include #include #include #include //#define WINPR_HAVE_PATHCCH_H 1 #ifdef WINPR_HAVE_PATHCCH_H #include #else #ifdef __cplusplus extern "C" { #endif #define PATHCCH_ALLOW_LONG_PATHS \ 0x00000001 /* Allow building of \\?\ paths if longer than MAX_PATH */ #define VOLUME_PREFIX _T("\\\\?\\Volume") #define VOLUME_PREFIX_LEN ((sizeof(VOLUME_PREFIX) / sizeof(TCHAR)) - 1) /* * Maximum number of characters we support using the "\\?\" syntax * (0x7FFF + 1 for nullptr terminator) */ #define PATHCCH_MAX_CCH 0x8000 WINPR_API HRESULT PathCchAddBackslashA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchAddBackslashW(PWSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchRemoveBackslashA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchRemoveBackslashW(PWSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchAddBackslashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT PathCchAddBackslashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT PathCchRemoveBackslashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT PathCchRemoveBackslashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT PathCchAddExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt); WINPR_API HRESULT PathCchAddExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt); WINPR_API HRESULT PathCchAppendA(PSTR pszPath, size_t cchPath, PCSTR pszMore); WINPR_API HRESULT PathCchAppendW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore); WINPR_API HRESULT PathCchAppendExA(PSTR pszPath, size_t cchPath, PCSTR pszMore, unsigned long dwFlags); WINPR_API HRESULT PathCchAppendExW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore, unsigned long dwFlags); WINPR_API HRESULT PathCchCanonicalizeA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn); WINPR_API HRESULT PathCchCanonicalizeW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn); WINPR_API HRESULT PathCchCanonicalizeExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, unsigned long dwFlags); WINPR_API HRESULT PathCchCanonicalizeExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, unsigned long dwFlags); WINPR_API HRESULT PathAllocCanonicalizeA(PCSTR pszPathIn, unsigned long dwFlags, PSTR* ppszPathOut); WINPR_API HRESULT PathAllocCanonicalizeW(PCWSTR pszPathIn, unsigned long dwFlags, PWSTR* ppszPathOut); WINPR_API HRESULT PathCchCombineA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, PCSTR pszMore); WINPR_API HRESULT PathCchCombineW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore); WINPR_API HRESULT PathCchCombineExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags); WINPR_API HRESULT PathCchCombineExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags); WINPR_API HRESULT PathAllocCombineA(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags, PSTR* ppszPathOut); WINPR_API HRESULT PathAllocCombineW(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags, PWSTR* ppszPathOut); WINPR_API HRESULT PathCchFindExtensionA(PCSTR pszPath, size_t cchPath, PCSTR* ppszExt); WINPR_API HRESULT PathCchFindExtensionW(PCWSTR pszPath, size_t cchPath, PCWSTR* ppszExt); WINPR_API HRESULT PathCchRenameExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt); WINPR_API HRESULT PathCchRenameExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt); WINPR_API HRESULT PathCchRemoveExtensionA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath); WINPR_API BOOL PathCchIsRootA(PCSTR pszPath); WINPR_API BOOL PathCchIsRootW(PCWSTR pszPath); WINPR_API BOOL PathIsUNCExA(PCSTR pszPath, PCSTR* ppszServer); WINPR_API BOOL PathIsUNCExW(PCWSTR pszPath, PCWSTR* ppszServer); WINPR_API HRESULT PathCchSkipRootA(PCSTR pszPath, PCSTR* ppszRootEnd); WINPR_API HRESULT PathCchSkipRootW(PCWSTR pszPath, PCWSTR* ppszRootEnd); WINPR_API HRESULT PathCchStripToRootA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchStripToRootW(PWSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchStripPrefixA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchStripPrefixW(PWSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchRemoveFileSpecA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchRemoveFileSpecW(PWSTR pszPath, size_t cchPath); #ifdef UNICODE #define PathCchAddBackslash PathCchAddBackslashW #define PathCchRemoveBackslash PathCchRemoveBackslashW #define PathCchAddBackslashEx PathCchAddBackslashExW #define PathCchRemoveBackslashEx PathCchRemoveBackslashExW #define PathCchAddExtension PathCchAddExtensionW #define PathCchAppend PathCchAppendW #define PathCchAppendEx PathCchAppendExW #define PathCchCanonicalize PathCchCanonicalizeW #define PathCchCanonicalizeEx PathCchCanonicalizeExW #define PathAllocCanonicalize PathAllocCanonicalizeW #define PathCchCombine PathCchCombineW #define PathCchCombineEx PathCchCombineExW #define PathAllocCombine PathAllocCombineW #define PathCchFindExtension PathCchFindExtensionW #define PathCchRenameExtension PathCchRenameExtensionW #define PathCchRemoveExtension PathCchRemoveExtensionW #define PathCchIsRoot PathCchIsRootW #define PathIsUNCEx PathIsUNCExW #define PathCchSkipRoot PathCchSkipRootW #define PathCchStripToRoot PathCchStripToRootW #define PathCchStripPrefix PathCchStripPrefixW #define PathCchRemoveFileSpec PathCchRemoveFileSpecW #else #define PathCchAddBackslash PathCchAddBackslashA #define PathCchRemoveBackslash PathCchRemoveBackslashA #define PathCchAddBackslashEx PathCchAddBackslashExA #define PathCchRemoveBackslashEx PathCchRemoveBackslashExA #define PathCchAddExtension PathCchAddExtensionA #define PathCchAppend PathCchAppendA #define PathCchAppendEx PathCchAppendExA #define PathCchCanonicalize PathCchCanonicalizeA #define PathCchCanonicalizeEx PathCchCanonicalizeExA #define PathAllocCanonicalize PathAllocCanonicalizeA #define PathCchCombine PathCchCombineA #define PathCchCombineEx PathCchCombineExA #define PathAllocCombine PathAllocCombineA #define PathCchFindExtension PathCchFindExtensionA #define PathCchRenameExtension PathCchRenameExtensionA #define PathCchRemoveExtension PathCchRemoveExtensionA #define PathCchIsRoot PathCchIsRootA #define PathIsUNCEx PathIsUNCExA #define PathCchSkipRoot PathCchSkipRootA #define PathCchStripToRoot PathCchStripToRootA #define PathCchStripPrefix PathCchStripPrefixA #define PathCchRemoveFileSpec PathCchRemoveFileSpecA #endif /* Unix-style Paths */ WINPR_API HRESULT PathCchAddSlashA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchAddSlashW(PWSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchAddSlashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT PathCchAddSlashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT UnixPathCchAddExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt); WINPR_API HRESULT UnixPathCchAddExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt); WINPR_API HRESULT UnixPathCchAppendA(PSTR pszPath, size_t cchPath, PCSTR pszMore); WINPR_API HRESULT UnixPathCchAppendW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore); WINPR_API HRESULT UnixPathAllocCombineA(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags, PSTR* ppszPathOut); WINPR_API HRESULT UnixPathAllocCombineW(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags, PWSTR* ppszPathOut); #ifdef UNICODE #define PathCchAddSlash PathCchAddSlashW #define PathCchAddSlashEx PathCchAddSlashExW #define UnixPathCchAddExtension UnixPathCchAddExtensionW #define UnixPathCchAppend UnixPathCchAppendW #define UnixPathAllocCombine UnixPathAllocCombineW #else #define PathCchAddSlash PathCchAddSlashA #define PathCchAddSlashEx PathCchAddSlashExA #define UnixPathCchAddExtension UnixPathCchAddExtensionA #define UnixPathCchAppend UnixPathCchAppendA #define UnixPathAllocCombine UnixPathAllocCombineA #endif /* Native-style Paths */ WINPR_API HRESULT PathCchAddSeparatorA(PSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchAddSeparatorW(PWSTR pszPath, size_t cchPath); WINPR_API HRESULT PathCchAddSeparatorExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT PathCchAddSeparatorExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd, size_t* pcchRemaining); WINPR_API HRESULT NativePathCchAddExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt); WINPR_API HRESULT NativePathCchAddExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt); WINPR_API HRESULT NativePathCchAppendA(PSTR pszPath, size_t cchPath, PCSTR pszMore); WINPR_API HRESULT NativePathCchAppendW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore); WINPR_API HRESULT NativePathAllocCombineA(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags, PSTR* ppszPathOut); WINPR_API HRESULT NativePathAllocCombineW(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags, PWSTR* ppszPathOut); #ifdef UNICODE #define PathCchAddSeparator PathCchAddSeparatorW #define PathCchAddSeparatorEx PathCchAddSeparatorExW #define NativePathCchAddExtension NativePathCchAddExtensionW #define NativePathCchAppend NativePathCchAppendW #define NativePathAllocCombine NativePathAllocCombineW #else #define PathCchAddSeparator PathCchAddSeparatorA #define PathCchAddSeparatorEx PathCchAddSeparatorExA #define NativePathCchAddExtension NativePathCchAddExtensionA #define NativePathCchAppend NativePathCchAppendA #define NativePathAllocCombine NativePathAllocCombineA #endif /* Path Portability Functions */ #define PATH_STYLE_WINDOWS 0x00000001 #define PATH_STYLE_UNIX 0x00000002 #define PATH_STYLE_NATIVE 0x00000003 #define PATH_SHARED_LIB_EXT_WITH_DOT 0x00000001 #define PATH_SHARED_LIB_EXT_APPLE_SO 0x00000002 #define PATH_SHARED_LIB_EXT_EXPLICIT 0x80000000 #define PATH_SHARED_LIB_EXT_EXPLICIT_DLL 0x80000001 #define PATH_SHARED_LIB_EXT_EXPLICIT_SO 0x80000002 #define PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB 0x80000003 WINPR_API HRESULT PathCchConvertStyleA(PSTR pszPath, size_t cchPath, unsigned long dwFlags); WINPR_API HRESULT PathCchConvertStyleW(PWSTR pszPath, size_t cchPath, unsigned long dwFlags); WINPR_API char PathGetSeparatorA(unsigned long dwFlags); WINPR_API WCHAR PathGetSeparatorW(unsigned long dwFlags); WINPR_API PCSTR PathGetSharedLibraryExtensionA(unsigned long dwFlags); WINPR_API PCWSTR PathGetSharedLibraryExtensionW(unsigned long dwFlags); #ifdef UNICODE #define PathCchConvertStyle PathCchConvertStyleW #define PathGetSeparator PathGetSeparatorW #define PathGetSharedLibraryExtension PathGetSharedLibraryExtensionW #else #define PathCchConvertStyle PathCchConvertStyleA #define PathGetSeparator PathGetSeparatorW #define PathGetSharedLibraryExtension PathGetSharedLibraryExtensionA #endif #ifdef __cplusplus } #endif #endif /** * Shell Path Functions */ typedef enum { KNOWN_PATH_HOME = 1, KNOWN_PATH_TEMP = 2, KNOWN_PATH_XDG_DATA_HOME = 3, KNOWN_PATH_XDG_CONFIG_HOME = 4, KNOWN_PATH_XDG_CACHE_HOME = 5, KNOWN_PATH_XDG_RUNTIME_DIR = 6, KNOWN_PATH_SYSTEM_CONFIG_HOME = 7 } eKnownPathTypes; #ifdef __cplusplus extern "C" { #endif /** @brief Return the absolute path of a configuration file (the path of the configuration * directory if \b filename is \b nullptr) * * @param system a boolean indicating the configuration base, \b TRUE for system configuration, * \b FALSE for user configuration * @param filename an optional configuration file name to append. * * @return The absolute path of the desired configuration or \b nullptr in case of failure. Use * \b free to clean up the allocated string. * * * @since version 3.9.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_API char* winpr_GetConfigFilePath(BOOL system, const char* filename); /** @brief Get a config file sub path with a formatting argument constructing the filename * * @param system \b TRUE to return a system config path * @param filename The format string to generate the filename. Must not be \b nullptr. Must not * contain any forbidden characters. * * @return A (absolute) configuration file path or \b nullptr in case of failure. * @since version 3.23.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 3) WINPR_API char* winpr_GetConfigFilePathV(BOOL system, WINPR_FORMAT_ARG const char* filename, ...); /** @brief Get a config file sub path with a formatting argument constructing the filename * * @param system \b TRUE to return a system config path * @param filename The format string to generate the filename. Must not be \b nullptr. Must not * contain any forbidden characters. * @param ap The argument list * * @return A (absolute) configuration file path or \b nullptr in case of failure. * @since version 3.23.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 0) WINPR_API char* winpr_GetConfigFilePathVA(BOOL system, WINPR_FORMAT_ARG const char* filename, va_list ap); WINPR_API const char* GetKnownPathIdString(int id); WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_API char* GetKnownPath(eKnownPathTypes id); WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_API char* GetKnownSubPath(eKnownPathTypes id, const char* path); /** @brief Append a path to some existing known path type. * * @param id a \ref eKnownPathTypes known path id * @param path the format string generating the subpath. Must not be \b nullptr * * @return A string of combined \b id path and \b path or \b nullptr in case of an error. * @since version 3.23.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 3) WINPR_API char* GetKnownSubPathV(eKnownPathTypes id, const char* path, ...); /** @brief Append a path to some existing known path type. * * @param id a \ref eKnownPathTypes known path id * @param path the format string generating the subpath. Must not be \b nullptr * @param ap a va_list containing the format string arguments * * @return A string of combined \b basePath and \b path or \b nullptr in case of * an error. * * @version since 3.23.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 0) WINPR_API char* GetKnownSubPathVA(eKnownPathTypes id, const char* path, va_list ap); WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_API char* GetEnvironmentPath(char* name); WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_API char* GetEnvironmentSubPath(char* name, const char* path); /** @brief Append a path to some existing environment name. * * @param name The prefix path to use, must not be \b nullptr * @param path A format string used to generate the path to append. Must not be \b nullptr * * @return A string of combined \b basePath and \b path or \b nullptr in case of an error. * @version since 3.23.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 3) WINPR_API char* GetEnvironmentSubPathV(char* name, WINPR_FORMAT_ARG const char* path, ...); /** @brief Append a path to some existing environment name. * * @param name The prefix path to use, must not be \b nullptr * @param path A format string used to generate the path to append. Must not be \b nullptr * @param ap a va_list containing the format string arguments * * @return A string of combined \b basePath and \b path or \b nullptr in case of an * error. * * @version since 3.23.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 0) WINPR_API char* GetEnvironmentSubPathVA(char* name, WINPR_FORMAT_ARG const char* path, va_list ap); WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_API char* GetCombinedPath(const char* basePath, const char* subPath); /** @brief Append a path to some existing path. A system dependent path separator will be added * automatically. * * @bug before version 3.23.0 the function did not allow subPath to be a format string. * * @param basePath The prefix path to use, must not be \b nullptr * @param subPathFmt A format string used to generate the path to append. Must not be \b * nullptr * * @return A string of combined \b basePath and \b subPathFmt or \b nullptr in case of an * error. */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 3) WINPR_API char* GetCombinedPathV(const char* basePath, WINPR_FORMAT_ARG const char* subPathFmt, ...); /** @brief Append a path to some existing path. A system dependent path separator will be added * automatically. * * @param basePath The prefix path to use, must not be \b nullptr * @param subPathFmt A format string used to generate the path to append. Must not be \b * nullptr * @param ap a va_list containing the format string arguments * * @return A string of combined \b basePath and \b subPathFmt or \b nullptr in case of an * error. * @version since 3.23.0 */ WINPR_ATTR_MALLOC(free, 1) WINPR_ATTR_NODISCARD WINPR_ATTR_FORMAT_ARG(2, 0) WINPR_API char* GetCombinedPathVA(const char* basePath, WINPR_FORMAT_ARG const char* subPathFmt, va_list ap); WINPR_API BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes); WINPR_API BOOL PathMakePathW(LPCWSTR path, LPSECURITY_ATTRIBUTES lpAttributes); #if !defined(_WIN32) || defined(_UWP) WINPR_API BOOL PathIsRelativeA(LPCSTR pszPath); WINPR_API BOOL PathIsRelativeW(LPCWSTR pszPath); WINPR_API BOOL PathFileExistsA(LPCSTR pszPath); WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath); WINPR_API BOOL PathIsDirectoryEmptyA(LPCSTR pszPath); WINPR_API BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath); #ifdef UNICODE #define PathFileExists PathFileExistsW #define PathIsDirectoryEmpty PathIsDirectoryEmptyW #else #define PathFileExists PathFileExistsA #define PathIsDirectoryEmpty PathIsDirectoryEmptyA #endif #endif WINPR_API BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName); WINPR_API BOOL winpr_MoveFileEx(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags); WINPR_API BOOL winpr_DeleteFile(const char* lpFileName); WINPR_API BOOL winpr_RemoveDirectory(LPCSTR lpPathName); WINPR_API BOOL winpr_RemoveDirectory_RecursiveA(LPCSTR lpPathName); WINPR_API BOOL winpr_RemoveDirectory_RecursiveW(LPCWSTR lpPathName); WINPR_API BOOL winpr_PathFileExists(const char* pszPath); WINPR_API BOOL winpr_PathMakePath(const char* path, LPSECURITY_ATTRIBUTES lpAttributes); #ifdef __cplusplus } #endif #ifdef _WIN32 #include #endif #endif /* WINPR_PATH_H */