1 /**
2  * WinPR: Windows Portable Runtime
3  * Path Functions
4  *
5  * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef WINPR_PATH_H
21 #define WINPR_PATH_H
22 
23 #include <winpr/winpr.h>
24 #include <winpr/tchar.h>
25 #include <winpr/error.h>
26 #include <winpr/wtypes.h>
27 
28 //#define HAVE_PATHCCH_H	1
29 
30 #ifdef HAVE_PATHCCH_H
31 
32 #include <Pathcch.h>
33 
34 #else
35 
36 #ifdef __cplusplus
37 extern "C"
38 {
39 #endif
40 
41 #define PATHCCH_ALLOW_LONG_PATHS \
42 	0x00000001 /* Allow building of \\?\ paths if longer than MAX_PATH */
43 
44 #define VOLUME_PREFIX _T("\\\\?\\Volume")
45 #define VOLUME_PREFIX_LEN ((sizeof(VOLUME_PREFIX) / sizeof(TCHAR)) - 1)
46 
47 	/*
48 	 * Maximum number of characters we support using the "\\?\" syntax
49 	 * (0x7FFF + 1 for NULL terminator)
50 	 */
51 
52 #define PATHCCH_MAX_CCH 0x8000
53 
54 	WINPR_API HRESULT PathCchAddBackslashA(PSTR pszPath, size_t cchPath);
55 	WINPR_API HRESULT PathCchAddBackslashW(PWSTR pszPath, size_t cchPath);
56 
57 	WINPR_API HRESULT PathCchRemoveBackslashA(PSTR pszPath, size_t cchPath);
58 	WINPR_API HRESULT PathCchRemoveBackslashW(PWSTR pszPath, size_t cchPath);
59 
60 	WINPR_API HRESULT PathCchAddBackslashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd,
61 	                                         size_t* pcchRemaining);
62 	WINPR_API HRESULT PathCchAddBackslashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd,
63 	                                         size_t* pcchRemaining);
64 
65 	WINPR_API HRESULT PathCchRemoveBackslashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd,
66 	                                            size_t* pcchRemaining);
67 	WINPR_API HRESULT PathCchRemoveBackslashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd,
68 	                                            size_t* pcchRemaining);
69 
70 	WINPR_API HRESULT PathCchAddExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt);
71 	WINPR_API HRESULT PathCchAddExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt);
72 
73 	WINPR_API HRESULT PathCchAppendA(PSTR pszPath, size_t cchPath, PCSTR pszMore);
74 	WINPR_API HRESULT PathCchAppendW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore);
75 
76 	WINPR_API HRESULT PathCchAppendExA(PSTR pszPath, size_t cchPath, PCSTR pszMore,
77 	                                   unsigned long dwFlags);
78 	WINPR_API HRESULT PathCchAppendExW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore,
79 	                                   unsigned long dwFlags);
80 
81 	WINPR_API HRESULT PathCchCanonicalizeA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn);
82 	WINPR_API HRESULT PathCchCanonicalizeW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn);
83 
84 	WINPR_API HRESULT PathCchCanonicalizeExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn,
85 	                                         unsigned long dwFlags);
86 	WINPR_API HRESULT PathCchCanonicalizeExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn,
87 	                                         unsigned long dwFlags);
88 
89 	WINPR_API HRESULT PathAllocCanonicalizeA(PCSTR pszPathIn, unsigned long dwFlags,
90 	                                         PSTR* ppszPathOut);
91 	WINPR_API HRESULT PathAllocCanonicalizeW(PCWSTR pszPathIn, unsigned long dwFlags,
92 	                                         PWSTR* ppszPathOut);
93 
94 	WINPR_API HRESULT PathCchCombineA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn,
95 	                                  PCSTR pszMore);
96 	WINPR_API HRESULT PathCchCombineW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn,
97 	                                  PCWSTR pszMore);
98 
99 	WINPR_API HRESULT PathCchCombineExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn,
100 	                                    PCSTR pszMore, unsigned long dwFlags);
101 	WINPR_API HRESULT PathCchCombineExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn,
102 	                                    PCWSTR pszMore, unsigned long dwFlags);
103 
104 	WINPR_API HRESULT PathAllocCombineA(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags,
105 	                                    PSTR* ppszPathOut);
106 	WINPR_API HRESULT PathAllocCombineW(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags,
107 	                                    PWSTR* ppszPathOut);
108 
109 	WINPR_API HRESULT PathCchFindExtensionA(PCSTR pszPath, size_t cchPath, PCSTR* ppszExt);
110 	WINPR_API HRESULT PathCchFindExtensionW(PCWSTR pszPath, size_t cchPath, PCWSTR* ppszExt);
111 
112 	WINPR_API HRESULT PathCchRenameExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt);
113 	WINPR_API HRESULT PathCchRenameExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt);
114 
115 	WINPR_API HRESULT PathCchRemoveExtensionA(PSTR pszPath, size_t cchPath);
116 	WINPR_API HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath);
117 
118 	WINPR_API BOOL PathCchIsRootA(PCSTR pszPath);
119 	WINPR_API BOOL PathCchIsRootW(PCWSTR pszPath);
120 
121 	WINPR_API BOOL PathIsUNCExA(PCSTR pszPath, PCSTR* ppszServer);
122 	WINPR_API BOOL PathIsUNCExW(PCWSTR pszPath, PCWSTR* ppszServer);
123 
124 	WINPR_API HRESULT PathCchSkipRootA(PCSTR pszPath, PCSTR* ppszRootEnd);
125 	WINPR_API HRESULT PathCchSkipRootW(PCWSTR pszPath, PCWSTR* ppszRootEnd);
126 
127 	WINPR_API HRESULT PathCchStripToRootA(PSTR pszPath, size_t cchPath);
128 	WINPR_API HRESULT PathCchStripToRootW(PWSTR pszPath, size_t cchPath);
129 
130 	WINPR_API HRESULT PathCchStripPrefixA(PSTR pszPath, size_t cchPath);
131 	WINPR_API HRESULT PathCchStripPrefixW(PWSTR pszPath, size_t cchPath);
132 
133 	WINPR_API HRESULT PathCchRemoveFileSpecA(PSTR pszPath, size_t cchPath);
134 	WINPR_API HRESULT PathCchRemoveFileSpecW(PWSTR pszPath, size_t cchPath);
135 
136 #ifdef UNICODE
137 #define PathCchAddBackslash PathCchAddBackslashW
138 #define PathCchRemoveBackslash PathCchRemoveBackslashW
139 #define PathCchAddBackslashEx PathCchAddBackslashExW
140 #define PathCchRemoveBackslashEx PathCchRemoveBackslashExW
141 #define PathCchAddExtension PathCchAddExtensionW
142 #define PathCchAppend PathCchAppendW
143 #define PathCchAppendEx PathCchAppendExW
144 #define PathCchCanonicalize PathCchCanonicalizeW
145 #define PathCchCanonicalizeEx PathCchCanonicalizeExW
146 #define PathAllocCanonicalize PathAllocCanonicalizeW
147 #define PathCchCombine PathCchCombineW
148 #define PathCchCombineEx PathCchCombineExW
149 #define PathAllocCombine PathAllocCombineW
150 #define PathCchFindExtension PathCchFindExtensionW
151 #define PathCchRenameExtension PathCchRenameExtensionW
152 #define PathCchRemoveExtension PathCchRemoveExtensionW
153 #define PathCchIsRoot PathCchIsRootW
154 #define PathIsUNCEx PathIsUNCExW
155 #define PathCchSkipRoot PathCchSkipRootW
156 #define PathCchStripToRoot PathCchStripToRootW
157 #define PathCchStripPrefix PathCchStripPrefixW
158 #define PathCchRemoveFileSpec PathCchRemoveFileSpecW
159 #else
160 #define PathCchAddBackslash PathCchAddBackslashA
161 #define PathCchRemoveBackslash PathCchRemoveBackslashA
162 #define PathCchAddBackslashEx PathCchAddBackslashExA
163 #define PathCchRemoveBackslashEx PathCchRemoveBackslashExA
164 #define PathCchAddExtension PathCchAddExtensionA
165 #define PathCchAppend PathCchAppendA
166 #define PathCchAppendEx PathCchAppendExA
167 #define PathCchCanonicalize PathCchCanonicalizeA
168 #define PathCchCanonicalizeEx PathCchCanonicalizeExA
169 #define PathAllocCanonicalize PathAllocCanonicalizeA
170 #define PathCchCombine PathCchCombineA
171 #define PathCchCombineEx PathCchCombineExA
172 #define PathAllocCombine PathAllocCombineA
173 #define PathCchFindExtension PathCchFindExtensionA
174 #define PathCchRenameExtension PathCchRenameExtensionA
175 #define PathCchRemoveExtension PathCchRemoveExtensionA
176 #define PathCchIsRoot PathCchIsRootA
177 #define PathIsUNCEx PathIsUNCExA
178 #define PathCchSkipRoot PathCchSkipRootA
179 #define PathCchStripToRoot PathCchStripToRootA
180 #define PathCchStripPrefix PathCchStripPrefixA
181 #define PathCchRemoveFileSpec PathCchRemoveFileSpecA
182 #endif
183 
184 	/* Unix-style Paths */
185 
186 	WINPR_API HRESULT PathCchAddSlashA(PSTR pszPath, size_t cchPath);
187 	WINPR_API HRESULT PathCchAddSlashW(PWSTR pszPath, size_t cchPath);
188 
189 	WINPR_API HRESULT PathCchAddSlashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd,
190 	                                     size_t* pcchRemaining);
191 	WINPR_API HRESULT PathCchAddSlashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd,
192 	                                     size_t* pcchRemaining);
193 
194 	WINPR_API HRESULT UnixPathCchAddExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt);
195 	WINPR_API HRESULT UnixPathCchAddExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt);
196 
197 	WINPR_API HRESULT UnixPathCchAppendA(PSTR pszPath, size_t cchPath, PCSTR pszMore);
198 	WINPR_API HRESULT UnixPathCchAppendW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore);
199 
200 	WINPR_API HRESULT UnixPathAllocCombineA(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags,
201 	                                        PSTR* ppszPathOut);
202 	WINPR_API HRESULT UnixPathAllocCombineW(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags,
203 	                                        PWSTR* ppszPathOut);
204 
205 #ifdef UNICODE
206 #define PathCchAddSlash PathCchAddSlashW
207 #define PathCchAddSlashEx PathCchAddSlashExW
208 #define UnixPathCchAddExtension UnixPathCchAddExtensionW
209 #define UnixPathCchAppend UnixPathCchAppendW
210 #define UnixPathAllocCombine UnixPathAllocCombineW
211 #else
212 #define PathCchAddSlash PathCchAddSlashA
213 #define PathCchAddSlashEx PathCchAddSlashExA
214 #define UnixPathCchAddExtension UnixPathCchAddExtensionA
215 #define UnixPathCchAppend UnixPathCchAppendA
216 #define UnixPathAllocCombine UnixPathAllocCombineA
217 #endif
218 
219 	/* Native-style Paths */
220 
221 	WINPR_API HRESULT PathCchAddSeparatorA(PSTR pszPath, size_t cchPath);
222 	WINPR_API HRESULT PathCchAddSeparatorW(PWSTR pszPath, size_t cchPath);
223 
224 	WINPR_API HRESULT PathCchAddSeparatorExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd,
225 	                                         size_t* pcchRemaining);
226 	WINPR_API HRESULT PathCchAddSeparatorExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd,
227 	                                         size_t* pcchRemaining);
228 
229 	WINPR_API HRESULT NativePathCchAddExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt);
230 	WINPR_API HRESULT NativePathCchAddExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt);
231 
232 	WINPR_API HRESULT NativePathCchAppendA(PSTR pszPath, size_t cchPath, PCSTR pszMore);
233 	WINPR_API HRESULT NativePathCchAppendW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore);
234 
235 	WINPR_API HRESULT NativePathAllocCombineA(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags,
236 	                                          PSTR* ppszPathOut);
237 	WINPR_API HRESULT NativePathAllocCombineW(PCWSTR pszPathIn, PCWSTR pszMore,
238 	                                          unsigned long dwFlags, PWSTR* ppszPathOut);
239 
240 #ifdef UNICODE
241 #define PathCchAddSeparator PathCchAddSeparatorW
242 #define PathCchAddSeparatorEx PathCchAddSeparatorExW
243 #define NativePathCchAddExtension NativePathCchAddExtensionW
244 #define NativePathCchAppend NativePathCchAppendW
245 #define NativePathAllocCombine NativePathAllocCombineW
246 #else
247 #define PathCchAddSeparator PathCchAddSeparatorA
248 #define PathCchAddSeparatorEx PathCchAddSeparatorExA
249 #define NativePathCchAddExtension NativePathCchAddExtensionA
250 #define NativePathCchAppend NativePathCchAppendA
251 #define NativePathAllocCombine NativePathAllocCombineA
252 #endif
253 
254 	/* Path Portability Functions */
255 
256 #define PATH_STYLE_WINDOWS 0x00000001
257 #define PATH_STYLE_UNIX 0x00000002
258 #define PATH_STYLE_NATIVE 0x00000003
259 
260 #define PATH_SHARED_LIB_EXT_WITH_DOT 0x00000001
261 #define PATH_SHARED_LIB_EXT_APPLE_SO 0x00000002
262 #define PATH_SHARED_LIB_EXT_EXPLICIT 0x80000000
263 #define PATH_SHARED_LIB_EXT_EXPLICIT_DLL 0x80000001
264 #define PATH_SHARED_LIB_EXT_EXPLICIT_SO 0x80000002
265 #define PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB 0x80000003
266 
267 	WINPR_API HRESULT PathCchConvertStyleA(PSTR pszPath, size_t cchPath, unsigned long dwFlags);
268 	WINPR_API HRESULT PathCchConvertStyleW(PWSTR pszPath, size_t cchPath, unsigned long dwFlags);
269 
270 	WINPR_API char PathGetSeparatorA(unsigned long dwFlags);
271 	WINPR_API WCHAR PathGetSeparatorW(unsigned long dwFlags);
272 
273 	WINPR_API PCSTR PathGetSharedLibraryExtensionA(unsigned long dwFlags);
274 	WINPR_API PCWSTR PathGetSharedLibraryExtensionW(unsigned long dwFlags);
275 
276 #ifdef UNICODE
277 #define PathCchConvertStyle PathCchConvertStyleW
278 #define PathGetSeparator PathGetSeparatorW
279 #define PathGetSharedLibraryExtension PathGetSharedLibraryExtensionW
280 #else
281 #define PathCchConvertStyle PathCchConvertStyleA
282 #define PathGetSeparator PathGetSeparatorW
283 #define PathGetSharedLibraryExtension PathGetSharedLibraryExtensionA
284 #endif
285 
286 #ifdef __cplusplus
287 }
288 #endif
289 
290 #endif
291 
292 /**
293  * Shell Path Functions
294  */
295 
296 #define KNOWN_PATH_HOME 1
297 #define KNOWN_PATH_TEMP 2
298 #define KNOWN_PATH_XDG_DATA_HOME 3
299 #define KNOWN_PATH_XDG_CONFIG_HOME 4
300 #define KNOWN_PATH_XDG_CACHE_HOME 5
301 #define KNOWN_PATH_XDG_RUNTIME_DIR 6
302 
303 #ifdef __cplusplus
304 extern "C"
305 {
306 #endif
307 
308 	WINPR_API char* GetKnownPath(int id);
309 	WINPR_API char* GetKnownSubPath(int id, const char* path);
310 	WINPR_API char* GetEnvironmentPath(char* name);
311 	WINPR_API char* GetEnvironmentSubPath(char* name, const char* path);
312 	WINPR_API char* GetCombinedPath(const char* basePath, const char* subPath);
313 
314 	WINPR_API BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes);
315 
316 #if !defined(_WIN32) || defined(_UWP)
317 
318 	WINPR_API BOOL PathIsRelativeA(LPCSTR pszPath);
319 	WINPR_API BOOL PathIsRelativeW(LPCWSTR pszPath);
320 
321 	WINPR_API BOOL PathFileExistsA(LPCSTR pszPath);
322 	WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath);
323 
324 	WINPR_API BOOL PathIsDirectoryEmptyA(LPCSTR pszPath);
325 	WINPR_API BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath);
326 
327 #ifdef UNICODE
328 #define PathFileExists PathFileExistsW
329 #define PathIsDirectoryEmpty PathIsDirectoryEmptyW
330 #else
331 #define PathFileExists PathFileExistsA
332 #define PathIsDirectoryEmpty PathIsDirectoryEmptyA
333 #endif
334 
335 #endif
336 
337 WINPR_API BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName);
338 WINPR_API BOOL winpr_DeleteFile(const char* lpFileName);
339 WINPR_API BOOL winpr_RemoveDirectory(LPCSTR lpPathName);
340 WINPR_API BOOL winpr_PathFileExists(const char* pszPath);
341 WINPR_API BOOL winpr_PathMakePath(const char* path, LPSECURITY_ATTRIBUTES lpAttributes);
342 
343 #ifdef __cplusplus
344 }
345 #endif
346 
347 #ifdef _WIN32
348 #include <shlwapi.h>
349 #endif
350 
351 #endif /* WINPR_PATH_H */
352