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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <winpr/crt.h>
25 #include <winpr/heap.h>
26 #include <winpr/tchar.h>
27
28 #include <winpr/path.h>
29
30 #define PATH_SLASH_CHR '/'
31 #define PATH_SLASH_STR "/"
32
33 #define PATH_BACKSLASH_CHR '\\'
34 #define PATH_BACKSLASH_STR "\\"
35
36 #ifdef _WIN32
37 #define PATH_SLASH_STR_W L"/"
38 #define PATH_BACKSLASH_STR_W L"\\"
39 #else
40 #define PATH_SLASH_STR_W "/"
41 #define PATH_BACKSLASH_STR_W "\\"
42 #endif
43
44 #ifdef _WIN32
45 #define PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
46 #define PATH_SEPARATOR_STR PATH_BACKSLASH_STR
47 #define PATH_SEPARATOR_STR_W PATH_BACKSLASH_STR_W
48 #else
49 #define PATH_SEPARATOR_CHR PATH_SLASH_CHR
50 #define PATH_SEPARATOR_STR PATH_SLASH_STR
51 #define PATH_SEPARATOR_STR_W PATH_SLASH_STR_W
52 #endif
53
54 #define SHARED_LIBRARY_EXT_DLL "dll"
55 #define SHARED_LIBRARY_EXT_SO "so"
56 #define SHARED_LIBRARY_EXT_DYLIB "dylib"
57
58 #ifdef _WIN32
59 #define SHARED_LIBRARY_EXT SHARED_LIBRARY_EXT_DLL
60 #elif defined(__APPLE__)
61 #define SHARED_LIBRARY_EXT SHARED_LIBRARY_EXT_DYLIB
62 #else
63 #define SHARED_LIBRARY_EXT SHARED_LIBRARY_EXT_SO
64 #endif
65
66 #include "../log.h"
67 #define TAG WINPR_TAG("path")
68
69 /*
70 * PathCchAddBackslash
71 */
72
73 /* Windows-style Paths */
74
75 #define DEFINE_UNICODE FALSE
76 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
77 #define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashA
78 #include "include/PathCchAddSeparator.c"
79 #undef DEFINE_UNICODE
80 #undef _PATH_SEPARATOR_CHR
81 #undef PATH_CCH_ADD_SEPARATOR
82
83 #define DEFINE_UNICODE TRUE
84 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
85 #define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashW
86 #include "include/PathCchAddSeparator.c"
87 #undef DEFINE_UNICODE
88 #undef _PATH_SEPARATOR_CHR
89 #undef PATH_CCH_ADD_SEPARATOR
90
91 /* Unix-style Paths */
92
93 #define DEFINE_UNICODE FALSE
94 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
95 #define PATH_CCH_ADD_SEPARATOR PathCchAddSlashA
96 #include "include/PathCchAddSeparator.c"
97 #undef DEFINE_UNICODE
98 #undef _PATH_SEPARATOR_CHR
99 #undef PATH_CCH_ADD_SEPARATOR
100
101 #define DEFINE_UNICODE TRUE
102 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
103 #define PATH_CCH_ADD_SEPARATOR PathCchAddSlashW
104 #include "include/PathCchAddSeparator.c"
105 #undef DEFINE_UNICODE
106 #undef _PATH_SEPARATOR_CHR
107 #undef PATH_CCH_ADD_SEPARATOR
108
109 /* Native-style Paths */
110
111 #define DEFINE_UNICODE FALSE
112 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
113 #define PATH_CCH_ADD_SEPARATOR PathCchAddSeparatorA
114 #include "include/PathCchAddSeparator.c"
115 #undef DEFINE_UNICODE
116 #undef _PATH_SEPARATOR_CHR
117 #undef PATH_CCH_ADD_SEPARATOR
118
119 #define DEFINE_UNICODE TRUE
120 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
121 #define PATH_CCH_ADD_SEPARATOR PathCchAddSeparatorW
122 #include "include/PathCchAddSeparator.c"
123 #undef DEFINE_UNICODE
124 #undef _PATH_SEPARATOR_CHR
125 #undef PATH_CCH_ADD_SEPARATOR
126
127 /*
128 * PathCchRemoveBackslash
129 */
130
PathCchRemoveBackslashA(PSTR pszPath,size_t cchPath)131 HRESULT PathCchRemoveBackslashA(PSTR pszPath, size_t cchPath)
132 {
133 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
134 return E_NOTIMPL;
135 }
136
PathCchRemoveBackslashW(PWSTR pszPath,size_t cchPath)137 HRESULT PathCchRemoveBackslashW(PWSTR pszPath, size_t cchPath)
138 {
139 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
140 return E_NOTIMPL;
141 }
142
143 /*
144 * PathCchAddBackslashEx
145 */
146
147 /* Windows-style Paths */
148
149 #define DEFINE_UNICODE FALSE
150 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
151 #define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExA
152 #include "include/PathCchAddSeparatorEx.c"
153 #undef DEFINE_UNICODE
154 #undef _PATH_SEPARATOR_CHR
155 #undef PATH_CCH_ADD_SEPARATOR_EX
156
157 #define DEFINE_UNICODE TRUE
158 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
159 #define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExW
160 #include "include/PathCchAddSeparatorEx.c"
161 #undef DEFINE_UNICODE
162 #undef _PATH_SEPARATOR_CHR
163 #undef PATH_CCH_ADD_SEPARATOR_EX
164
165 /* Unix-style Paths */
166
167 #define DEFINE_UNICODE FALSE
168 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
169 #define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSlashExA
170 #include "include/PathCchAddSeparatorEx.c"
171 #undef DEFINE_UNICODE
172 #undef _PATH_SEPARATOR_CHR
173 #undef PATH_CCH_ADD_SEPARATOR_EX
174
175 #define DEFINE_UNICODE TRUE
176 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
177 #define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSlashExW
178 #include "include/PathCchAddSeparatorEx.c"
179 #undef DEFINE_UNICODE
180 #undef _PATH_SEPARATOR_CHR
181 #undef PATH_CCH_ADD_SEPARATOR_EX
182
183 /* Native-style Paths */
184
185 #define DEFINE_UNICODE FALSE
186 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
187 #define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSeparatorExA
188 #include "include/PathCchAddSeparatorEx.c"
189 #undef DEFINE_UNICODE
190 #undef _PATH_SEPARATOR_CHR
191 #undef PATH_CCH_ADD_SEPARATOR_EX
192
193 #define DEFINE_UNICODE TRUE
194 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
195 #define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSeparatorExW
196 #include "include/PathCchAddSeparatorEx.c"
197 #undef DEFINE_UNICODE
198 #undef _PATH_SEPARATOR_CHR
199 #undef PATH_CCH_ADD_SEPARATOR_EX
200
PathCchRemoveBackslashExA(PSTR pszPath,size_t cchPath,PSTR * ppszEnd,size_t * pcchRemaining)201 HRESULT PathCchRemoveBackslashExA(PSTR pszPath, size_t cchPath, PSTR* ppszEnd,
202 size_t* pcchRemaining)
203 {
204 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
205 return E_NOTIMPL;
206 }
207
PathCchRemoveBackslashExW(PWSTR pszPath,size_t cchPath,PWSTR * ppszEnd,size_t * pcchRemaining)208 HRESULT PathCchRemoveBackslashExW(PWSTR pszPath, size_t cchPath, PWSTR* ppszEnd,
209 size_t* pcchRemaining)
210 {
211 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
212 return E_NOTIMPL;
213 }
214
215 /*
216 * PathCchAddExtension
217 */
218
219 /* Windows-style Paths */
220
221 #define DEFINE_UNICODE FALSE
222 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
223 #define PATH_CCH_ADD_EXTENSION PathCchAddExtensionA
224 #include "include/PathCchAddExtension.c"
225 #undef DEFINE_UNICODE
226 #undef _PATH_SEPARATOR_CHR
227 #undef PATH_CCH_ADD_EXTENSION
228
229 #define DEFINE_UNICODE TRUE
230 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
231 #define PATH_CCH_ADD_EXTENSION PathCchAddExtensionW
232 #include "include/PathCchAddExtension.c"
233 #undef DEFINE_UNICODE
234 #undef _PATH_SEPARATOR_CHR
235 #undef PATH_CCH_ADD_EXTENSION
236
237 /* Unix-style Paths */
238
239 #define DEFINE_UNICODE FALSE
240 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
241 #define PATH_CCH_ADD_EXTENSION UnixPathCchAddExtensionA
242 #include "include/PathCchAddExtension.c"
243 #undef DEFINE_UNICODE
244 #undef _PATH_SEPARATOR_CHR
245 #undef PATH_CCH_ADD_EXTENSION
246
247 #define DEFINE_UNICODE TRUE
248 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
249 #define PATH_CCH_ADD_EXTENSION UnixPathCchAddExtensionW
250 #include "include/PathCchAddExtension.c"
251 #undef DEFINE_UNICODE
252 #undef _PATH_SEPARATOR_CHR
253 #undef PATH_CCH_ADD_EXTENSION
254
255 /* Native-style Paths */
256
257 #define DEFINE_UNICODE FALSE
258 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
259 #define PATH_CCH_ADD_EXTENSION NativePathCchAddExtensionA
260 #include "include/PathCchAddExtension.c"
261 #undef DEFINE_UNICODE
262 #undef _PATH_SEPARATOR_CHR
263 #undef PATH_CCH_ADD_EXTENSION
264
265 #define DEFINE_UNICODE TRUE
266 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
267 #define PATH_CCH_ADD_EXTENSION NativePathCchAddExtensionW
268 #include "include/PathCchAddExtension.c"
269 #undef DEFINE_UNICODE
270 #undef _PATH_SEPARATOR_CHR
271 #undef PATH_CCH_ADD_EXTENSION
272
273 /*
274 * PathCchAppend
275 */
276
277 /* Windows-style Paths */
278
279 #define DEFINE_UNICODE FALSE
280 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
281 #define _PATH_SEPARATOR_STR PATH_BACKSLASH_STR
282 #define PATH_CCH_APPEND PathCchAppendA
283 #include "include/PathCchAppend.c"
284 #undef DEFINE_UNICODE
285 #undef _PATH_SEPARATOR_CHR
286 #undef _PATH_SEPARATOR_STR
287 #undef PATH_CCH_APPEND
288
289 #define DEFINE_UNICODE TRUE
290 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
291 #define _PATH_SEPARATOR_STR PATH_BACKSLASH_STR_W
292 #define PATH_CCH_APPEND PathCchAppendW
293 #include "include/PathCchAppend.c"
294 #undef DEFINE_UNICODE
295 #undef _PATH_SEPARATOR_CHR
296 #undef _PATH_SEPARATOR_STR
297 #undef PATH_CCH_APPEND
298
299 /* Unix-style Paths */
300
301 #define DEFINE_UNICODE FALSE
302 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
303 #define _PATH_SEPARATOR_STR PATH_SLASH_STR
304 #define PATH_CCH_APPEND UnixPathCchAppendA
305 #include "include/PathCchAppend.c"
306 #undef DEFINE_UNICODE
307 #undef _PATH_SEPARATOR_CHR
308 #undef _PATH_SEPARATOR_STR
309 #undef PATH_CCH_APPEND
310
311 #define DEFINE_UNICODE TRUE
312 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
313 #define _PATH_SEPARATOR_STR PATH_SLASH_STR_W
314 #define PATH_CCH_APPEND UnixPathCchAppendW
315 #include "include/PathCchAppend.c"
316 #undef DEFINE_UNICODE
317 #undef _PATH_SEPARATOR_CHR
318 #undef _PATH_SEPARATOR_STR
319 #undef PATH_CCH_APPEND
320
321 /* Native-style Paths */
322
323 #define DEFINE_UNICODE FALSE
324 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
325 #define _PATH_SEPARATOR_STR PATH_SEPARATOR_STR
326 #define PATH_CCH_APPEND NativePathCchAppendA
327 #include "include/PathCchAppend.c"
328 #undef DEFINE_UNICODE
329 #undef _PATH_SEPARATOR_CHR
330 #undef _PATH_SEPARATOR_STR
331 #undef PATH_CCH_APPEND
332
333 #define DEFINE_UNICODE TRUE
334 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
335 #define _PATH_SEPARATOR_STR PATH_SEPARATOR_STR_W
336 #define PATH_CCH_APPEND NativePathCchAppendW
337 #include "include/PathCchAppend.c"
338 #undef DEFINE_UNICODE
339 #undef _PATH_SEPARATOR_CHR
340 #undef _PATH_SEPARATOR_STR
341 #undef PATH_CCH_APPEND
342
343 /*
344 * PathCchAppendEx
345 */
346
PathCchAppendExA(PSTR pszPath,size_t cchPath,PCSTR pszMore,unsigned long dwFlags)347 HRESULT PathCchAppendExA(PSTR pszPath, size_t cchPath, PCSTR pszMore, unsigned long dwFlags)
348 {
349 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
350 return E_NOTIMPL;
351 }
352
PathCchAppendExW(PWSTR pszPath,size_t cchPath,PCWSTR pszMore,unsigned long dwFlags)353 HRESULT PathCchAppendExW(PWSTR pszPath, size_t cchPath, PCWSTR pszMore, unsigned long dwFlags)
354 {
355 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
356 return E_NOTIMPL;
357 }
358
359 /*
360 * PathCchCanonicalize
361 */
362
PathCchCanonicalizeA(PSTR pszPathOut,size_t cchPathOut,PCSTR pszPathIn)363 HRESULT PathCchCanonicalizeA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn)
364 {
365 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
366 return E_NOTIMPL;
367 }
368
PathCchCanonicalizeW(PWSTR pszPathOut,size_t cchPathOut,PCWSTR pszPathIn)369 HRESULT PathCchCanonicalizeW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn)
370 {
371 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
372 return E_NOTIMPL;
373 }
374
375 /*
376 * PathCchCanonicalizeEx
377 */
378
PathCchCanonicalizeExA(PSTR pszPathOut,size_t cchPathOut,PCSTR pszPathIn,unsigned long dwFlags)379 HRESULT PathCchCanonicalizeExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn,
380 unsigned long dwFlags)
381 {
382 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
383 return E_NOTIMPL;
384 }
385
PathCchCanonicalizeExW(PWSTR pszPathOut,size_t cchPathOut,PCWSTR pszPathIn,unsigned long dwFlags)386 HRESULT PathCchCanonicalizeExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn,
387 unsigned long dwFlags)
388 {
389 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
390 return E_NOTIMPL;
391 }
392
393 /*
394 * PathAllocCanonicalize
395 */
396
PathAllocCanonicalizeA(PCSTR pszPathIn,unsigned long dwFlags,PSTR * ppszPathOut)397 HRESULT PathAllocCanonicalizeA(PCSTR pszPathIn, unsigned long dwFlags, PSTR* ppszPathOut)
398 {
399 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
400 return E_NOTIMPL;
401 }
402
PathAllocCanonicalizeW(PCWSTR pszPathIn,unsigned long dwFlags,PWSTR * ppszPathOut)403 HRESULT PathAllocCanonicalizeW(PCWSTR pszPathIn, unsigned long dwFlags, PWSTR* ppszPathOut)
404 {
405 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
406 return E_NOTIMPL;
407 }
408
409 /*
410 * PathCchCombine
411 */
412
PathCchCombineA(PSTR pszPathOut,size_t cchPathOut,PCSTR pszPathIn,PCSTR pszMore)413 HRESULT PathCchCombineA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, PCSTR pszMore)
414 {
415 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
416 return E_NOTIMPL;
417 }
418
PathCchCombineW(PWSTR pszPathOut,size_t cchPathOut,PCWSTR pszPathIn,PCWSTR pszMore)419 HRESULT PathCchCombineW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore)
420 {
421 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
422 return E_NOTIMPL;
423 }
424
425 /*
426 * PathCchCombineEx
427 */
428
PathCchCombineExA(PSTR pszPathOut,size_t cchPathOut,PCSTR pszPathIn,PCSTR pszMore,unsigned long dwFlags)429 HRESULT PathCchCombineExA(PSTR pszPathOut, size_t cchPathOut, PCSTR pszPathIn, PCSTR pszMore,
430 unsigned long dwFlags)
431 {
432 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
433 return E_NOTIMPL;
434 }
435
PathCchCombineExW(PWSTR pszPathOut,size_t cchPathOut,PCWSTR pszPathIn,PCWSTR pszMore,unsigned long dwFlags)436 HRESULT PathCchCombineExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore,
437 unsigned long dwFlags)
438 {
439 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
440 return E_NOTIMPL;
441 }
442
443 /*
444 * PathAllocCombine
445 */
446
447 /* Windows-style Paths */
448
449 #define DEFINE_UNICODE FALSE
450 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
451 #define _PATH_SEPARATOR_STR PATH_BACKSLASH_STR
452 #define PATH_ALLOC_COMBINE PathAllocCombineA
453 #include "include/PathAllocCombine.c"
454 #undef DEFINE_UNICODE
455 #undef _PATH_SEPARATOR_CHR
456 #undef _PATH_SEPARATOR_STR
457 #undef PATH_ALLOC_COMBINE
458
459 #define DEFINE_UNICODE TRUE
460 #define _PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
461 #define _PATH_SEPARATOR_STR PATH_BACKSLASH_STR_W
462 #define PATH_ALLOC_COMBINE PathAllocCombineW
463 #include "include/PathAllocCombine.c"
464 #undef DEFINE_UNICODE
465 #undef _PATH_SEPARATOR_CHR
466 #undef _PATH_SEPARATOR_STR
467 #undef PATH_ALLOC_COMBINE
468
469 /* Unix-style Paths */
470
471 #define DEFINE_UNICODE FALSE
472 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
473 #define _PATH_SEPARATOR_STR PATH_SLASH_STR
474 #define PATH_ALLOC_COMBINE UnixPathAllocCombineA
475 #include "include/PathAllocCombine.c"
476 #undef DEFINE_UNICODE
477 #undef _PATH_SEPARATOR_CHR
478 #undef _PATH_SEPARATOR_STR
479 #undef PATH_ALLOC_COMBINE
480
481 #define DEFINE_UNICODE TRUE
482 #define _PATH_SEPARATOR_CHR PATH_SLASH_CHR
483 #define _PATH_SEPARATOR_STR PATH_SLASH_STR_W
484 #define PATH_ALLOC_COMBINE UnixPathAllocCombineW
485 #include "include/PathAllocCombine.c"
486 #undef DEFINE_UNICODE
487 #undef _PATH_SEPARATOR_CHR
488 #undef _PATH_SEPARATOR_STR
489 #undef PATH_ALLOC_COMBINE
490
491 /* Native-style Paths */
492
493 #define DEFINE_UNICODE FALSE
494 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
495 #define _PATH_SEPARATOR_STR PATH_SEPARATOR_STR
496 #define PATH_ALLOC_COMBINE NativePathAllocCombineA
497 #include "include/PathAllocCombine.c"
498 #undef DEFINE_UNICODE
499 #undef _PATH_SEPARATOR_CHR
500 #undef _PATH_SEPARATOR_STR
501 #undef PATH_ALLOC_COMBINE
502
503 #define DEFINE_UNICODE TRUE
504 #define _PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
505 #define _PATH_SEPARATOR_STR PATH_SEPARATOR_STR_W
506 #define PATH_ALLOC_COMBINE NativePathAllocCombineW
507 #include "include/PathAllocCombine.c"
508 #undef DEFINE_UNICODE
509 #undef _PATH_SEPARATOR_CHR
510 #undef _PATH_SEPARATOR_STR
511 #undef PATH_ALLOC_COMBINE
512
513 /**
514 * PathCchFindExtension
515 */
516
PathCchFindExtensionA(PCSTR pszPath,size_t cchPath,PCSTR * ppszExt)517 HRESULT PathCchFindExtensionA(PCSTR pszPath, size_t cchPath, PCSTR* ppszExt)
518 {
519 char* p = (char*)pszPath;
520
521 if (!pszPath || !cchPath || !ppszExt)
522 return E_INVALIDARG;
523
524 /* find end of string */
525
526 while (*p && --cchPath)
527 {
528 p++;
529 }
530
531 if (*p)
532 {
533 /* pszPath is not null terminated within the cchPath range */
534 return E_INVALIDARG;
535 }
536
537 /* If no extension is found, ppszExt must point to the string's terminating null */
538 *ppszExt = p;
539
540 /* search backwards for '.' */
541
542 while (p > pszPath)
543 {
544 if (*p == '.')
545 {
546 *ppszExt = (PCSTR)p;
547 break;
548 }
549
550 if ((*p == '\\') || (*p == '/') || (*p == ':'))
551 break;
552
553 p--;
554 }
555
556 return S_OK;
557 }
558
PathCchFindExtensionW(PCWSTR pszPath,size_t cchPath,PCWSTR * ppszExt)559 HRESULT PathCchFindExtensionW(PCWSTR pszPath, size_t cchPath, PCWSTR* ppszExt)
560 {
561 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
562 return E_NOTIMPL;
563 }
564
565 /**
566 * PathCchRenameExtension
567 */
568
PathCchRenameExtensionA(PSTR pszPath,size_t cchPath,PCSTR pszExt)569 HRESULT PathCchRenameExtensionA(PSTR pszPath, size_t cchPath, PCSTR pszExt)
570 {
571 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
572 return E_NOTIMPL;
573 }
574
PathCchRenameExtensionW(PWSTR pszPath,size_t cchPath,PCWSTR pszExt)575 HRESULT PathCchRenameExtensionW(PWSTR pszPath, size_t cchPath, PCWSTR pszExt)
576 {
577 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
578 return E_NOTIMPL;
579 }
580
581 /**
582 * PathCchRemoveExtension
583 */
584
PathCchRemoveExtensionA(PSTR pszPath,size_t cchPath)585 HRESULT PathCchRemoveExtensionA(PSTR pszPath, size_t cchPath)
586 {
587 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
588 return E_NOTIMPL;
589 }
590
PathCchRemoveExtensionW(PWSTR pszPath,size_t cchPath)591 HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath)
592 {
593 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
594 return E_NOTIMPL;
595 }
596
597 /**
598 * PathCchIsRoot
599 */
600
PathCchIsRootA(PCSTR pszPath)601 BOOL PathCchIsRootA(PCSTR pszPath)
602 {
603 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
604 return FALSE;
605 }
606
PathCchIsRootW(PCWSTR pszPath)607 BOOL PathCchIsRootW(PCWSTR pszPath)
608 {
609 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
610 return FALSE;
611 }
612
613 /**
614 * PathIsUNCEx
615 */
616
PathIsUNCExA(PCSTR pszPath,PCSTR * ppszServer)617 BOOL PathIsUNCExA(PCSTR pszPath, PCSTR* ppszServer)
618 {
619 if (!pszPath)
620 return FALSE;
621
622 if ((pszPath[0] == '\\') && (pszPath[1] == '\\'))
623 {
624 *ppszServer = &pszPath[2];
625 return TRUE;
626 }
627
628 return FALSE;
629 }
630
PathIsUNCExW(PCWSTR pszPath,PCWSTR * ppszServer)631 BOOL PathIsUNCExW(PCWSTR pszPath, PCWSTR* ppszServer)
632 {
633 if (!pszPath)
634 return FALSE;
635
636 if ((pszPath[0] == '\\') && (pszPath[1] == '\\'))
637 {
638 *ppszServer = &pszPath[2];
639 return TRUE;
640 }
641
642 return FALSE;
643 }
644
645 /**
646 * PathCchSkipRoot
647 */
648
PathCchSkipRootA(PCSTR pszPath,PCSTR * ppszRootEnd)649 HRESULT PathCchSkipRootA(PCSTR pszPath, PCSTR* ppszRootEnd)
650 {
651 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
652 return E_NOTIMPL;
653 }
654
PathCchSkipRootW(PCWSTR pszPath,PCWSTR * ppszRootEnd)655 HRESULT PathCchSkipRootW(PCWSTR pszPath, PCWSTR* ppszRootEnd)
656 {
657 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
658 return E_NOTIMPL;
659 }
660
661 /**
662 * PathCchStripToRoot
663 */
664
PathCchStripToRootA(PSTR pszPath,size_t cchPath)665 HRESULT PathCchStripToRootA(PSTR pszPath, size_t cchPath)
666 {
667 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
668 return E_NOTIMPL;
669 }
670
PathCchStripToRootW(PWSTR pszPath,size_t cchPath)671 HRESULT PathCchStripToRootW(PWSTR pszPath, size_t cchPath)
672 {
673 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
674 return E_NOTIMPL;
675 }
676
677 /**
678 * PathCchStripPrefix
679 */
680
PathCchStripPrefixA(PSTR pszPath,size_t cchPath)681 HRESULT PathCchStripPrefixA(PSTR pszPath, size_t cchPath)
682 {
683 BOOL hasPrefix;
684
685 if (!pszPath)
686 return E_INVALIDARG;
687
688 if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH)
689 return E_INVALIDARG;
690
691 hasPrefix = ((pszPath[0] == '\\') && (pszPath[1] == '\\') && (pszPath[2] == '?') &&
692 (pszPath[3] == '\\'))
693 ? TRUE
694 : FALSE;
695
696 if (hasPrefix)
697 {
698 if (cchPath < 6)
699 return S_FALSE;
700
701 if (IsCharAlpha(pszPath[4]) && (pszPath[5] == ':')) /* like C: */
702 {
703 memmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4);
704 /* since the passed pszPath must not necessarily be null terminated
705 * and we always have enough space after the strip we can always
706 * ensure the null termination of the stripped result
707 */
708 pszPath[cchPath - 4] = 0;
709 return S_OK;
710 }
711 }
712
713 return S_FALSE;
714 }
715
PathCchStripPrefixW(PWSTR pszPath,size_t cchPath)716 HRESULT PathCchStripPrefixW(PWSTR pszPath, size_t cchPath)
717 {
718 BOOL hasPrefix;
719
720 if (!pszPath)
721 return E_INVALIDARG;
722
723 if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH)
724 return E_INVALIDARG;
725
726 hasPrefix = ((pszPath[0] == '\\') && (pszPath[1] == '\\') && (pszPath[2] == '?') &&
727 (pszPath[3] == '\\'))
728 ? TRUE
729 : FALSE;
730
731 if (hasPrefix)
732 {
733 int rc;
734 if (cchPath < 6)
735 return S_FALSE;
736
737 rc = (lstrlenW(&pszPath[4]) + 1);
738 if ((rc < 0) || ((INT64)cchPath < rc))
739 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
740
741 if (IsCharAlphaW(pszPath[4]) && (pszPath[5] == L':')) /* like C: */
742 {
743 wmemmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4);
744 /* since the passed pszPath must not necessarily be null terminated
745 * and we always have enough space after the strip we can always
746 * ensure the null termination of the stripped result
747 */
748 pszPath[cchPath - 4] = 0;
749 return S_OK;
750 }
751 }
752
753 return S_FALSE;
754 }
755
756 /**
757 * PathCchRemoveFileSpec
758 */
759
PathCchRemoveFileSpecA(PSTR pszPath,size_t cchPath)760 HRESULT PathCchRemoveFileSpecA(PSTR pszPath, size_t cchPath)
761 {
762 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
763 return E_NOTIMPL;
764 }
765
PathCchRemoveFileSpecW(PWSTR pszPath,size_t cchPath)766 HRESULT PathCchRemoveFileSpecW(PWSTR pszPath, size_t cchPath)
767 {
768 WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
769 return E_NOTIMPL;
770 }
771
772 /*
773 * Path Portability Functions
774 */
775
776 /**
777 * PathCchConvertStyle
778 */
779
PathCchConvertStyleA(PSTR pszPath,size_t cchPath,unsigned long dwFlags)780 HRESULT PathCchConvertStyleA(PSTR pszPath, size_t cchPath, unsigned long dwFlags)
781 {
782 size_t index;
783
784 if (dwFlags == PATH_STYLE_WINDOWS)
785 {
786 for (index = 0; index < cchPath; index++)
787 {
788 if (pszPath[index] == PATH_SLASH_CHR)
789 pszPath[index] = PATH_BACKSLASH_CHR;
790 }
791 }
792 else if (dwFlags == PATH_STYLE_UNIX)
793 {
794 for (index = 0; index < cchPath; index++)
795 {
796 if (pszPath[index] == PATH_BACKSLASH_CHR)
797 pszPath[index] = PATH_SLASH_CHR;
798 }
799 }
800 else if (dwFlags == PATH_STYLE_NATIVE)
801 {
802 if (PATH_SEPARATOR_CHR == PATH_BACKSLASH_CHR)
803 {
804 /* Unix-style to Windows-style */
805
806 for (index = 0; index < cchPath; index++)
807 {
808 if (pszPath[index] == PATH_SLASH_CHR)
809 pszPath[index] = PATH_BACKSLASH_CHR;
810 }
811 }
812 else if (PATH_SEPARATOR_CHR == PATH_SLASH_CHR)
813 {
814 /* Windows-style to Unix-style */
815
816 for (index = 0; index < cchPath; index++)
817 {
818 if (pszPath[index] == PATH_BACKSLASH_CHR)
819 pszPath[index] = PATH_SLASH_CHR;
820 }
821 }
822 else
823 {
824 /* Unexpected error */
825 return E_FAIL;
826 }
827 }
828 else
829 {
830 /* Gangnam style? */
831 return E_FAIL;
832 }
833
834 return S_OK;
835 }
836
PathCchConvertStyleW(PWSTR pszPath,size_t cchPath,unsigned long dwFlags)837 HRESULT PathCchConvertStyleW(PWSTR pszPath, size_t cchPath, unsigned long dwFlags)
838 {
839 size_t index;
840
841 if (dwFlags == PATH_STYLE_WINDOWS)
842 {
843 for (index = 0; index < cchPath; index++)
844 {
845 if (pszPath[index] == PATH_SLASH_CHR)
846 pszPath[index] = PATH_BACKSLASH_CHR;
847 }
848 }
849 else if (dwFlags == PATH_STYLE_UNIX)
850 {
851 for (index = 0; index < cchPath; index++)
852 {
853 if (pszPath[index] == PATH_BACKSLASH_CHR)
854 pszPath[index] = PATH_SLASH_CHR;
855 }
856 }
857 else if (dwFlags == PATH_STYLE_NATIVE)
858 {
859 if (PATH_SEPARATOR_CHR == PATH_BACKSLASH_CHR)
860 {
861 /* Unix-style to Windows-style */
862
863 for (index = 0; index < cchPath; index++)
864 {
865 if (pszPath[index] == PATH_SLASH_CHR)
866 pszPath[index] = PATH_BACKSLASH_CHR;
867 }
868 }
869 else if (PATH_SEPARATOR_CHR == PATH_SLASH_CHR)
870 {
871 /* Windows-style to Unix-style */
872
873 for (index = 0; index < cchPath; index++)
874 {
875 if (pszPath[index] == PATH_BACKSLASH_CHR)
876 pszPath[index] = PATH_SLASH_CHR;
877 }
878 }
879 else
880 {
881 /* Unexpected error */
882 return E_FAIL;
883 }
884 }
885 else
886 {
887 /* Gangnam style? */
888 return E_FAIL;
889 }
890
891 return S_OK;
892 }
893
894 /**
895 * PathGetSeparator
896 */
897
PathGetSeparatorA(unsigned long dwFlags)898 char PathGetSeparatorA(unsigned long dwFlags)
899 {
900 char separator = PATH_SEPARATOR_CHR;
901
902 if (!dwFlags)
903 dwFlags = PATH_STYLE_NATIVE;
904
905 if (dwFlags == PATH_STYLE_WINDOWS)
906 separator = PATH_SEPARATOR_CHR;
907 else if (dwFlags == PATH_STYLE_UNIX)
908 separator = PATH_SEPARATOR_CHR;
909 else if (dwFlags == PATH_STYLE_NATIVE)
910 separator = PATH_SEPARATOR_CHR;
911
912 return separator;
913 }
914
PathGetSeparatorW(unsigned long dwFlags)915 WCHAR PathGetSeparatorW(unsigned long dwFlags)
916 {
917 WCHAR separator = PATH_SEPARATOR_CHR;
918
919 if (!dwFlags)
920 dwFlags = PATH_STYLE_NATIVE;
921
922 if (dwFlags == PATH_STYLE_WINDOWS)
923 separator = PATH_SEPARATOR_CHR;
924 else if (dwFlags == PATH_STYLE_UNIX)
925 separator = PATH_SEPARATOR_CHR;
926 else if (dwFlags == PATH_STYLE_NATIVE)
927 separator = PATH_SEPARATOR_CHR;
928
929 return separator;
930 }
931
932 /**
933 * PathGetSharedLibraryExtension
934 */
935
936 static const CHAR SharedLibraryExtensionDllA[] = "dll";
937 static const CHAR SharedLibraryExtensionSoA[] = "so";
938 static const CHAR SharedLibraryExtensionDylibA[] = "dylib";
939
940 static const WCHAR SharedLibraryExtensionDllW[] = { 'd', 'l', 'l', '\0' };
941 static const WCHAR SharedLibraryExtensionSoW[] = { 's', 'o', '\0' };
942 static const WCHAR SharedLibraryExtensionDylibW[] = { 'd', 'y', 'l', 'i', 'b', '\0' };
943
944 static const CHAR SharedLibraryExtensionDotDllA[] = ".dll";
945 static const CHAR SharedLibraryExtensionDotSoA[] = ".so";
946 static const CHAR SharedLibraryExtensionDotDylibA[] = ".dylib";
947
948 static const WCHAR SharedLibraryExtensionDotDllW[] = { '.', 'd', 'l', 'l', '\0' };
949 static const WCHAR SharedLibraryExtensionDotSoW[] = { '.', 's', 'o', '\0' };
950 static const WCHAR SharedLibraryExtensionDotDylibW[] = { '.', 'd', 'y', 'l', 'i', 'b', '\0' };
951
PathGetSharedLibraryExtensionA(unsigned long dwFlags)952 PCSTR PathGetSharedLibraryExtensionA(unsigned long dwFlags)
953 {
954 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT)
955 {
956 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
957 {
958 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
959 return SharedLibraryExtensionDotDllA;
960
961 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
962 return SharedLibraryExtensionDotSoA;
963
964 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
965 return SharedLibraryExtensionDotDylibA;
966 }
967 else
968 {
969 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
970 return SharedLibraryExtensionDllA;
971
972 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
973 return SharedLibraryExtensionSoA;
974
975 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
976 return SharedLibraryExtensionDylibA;
977 }
978 }
979
980 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
981 {
982 #ifdef _WIN32
983 return SharedLibraryExtensionDotDllA;
984 #elif defined(__APPLE__)
985 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
986 return SharedLibraryExtensionDotSoA;
987 else
988 return SharedLibraryExtensionDotDylibA;
989 #else
990 return SharedLibraryExtensionDotSoA;
991 #endif
992 }
993 else
994 {
995 #ifdef _WIN32
996 return SharedLibraryExtensionDllA;
997 #elif defined(__APPLE__)
998 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
999 return SharedLibraryExtensionSoA;
1000 else
1001 return SharedLibraryExtensionDylibA;
1002 #else
1003 return SharedLibraryExtensionSoA;
1004 #endif
1005 }
1006
1007 return NULL;
1008 }
1009
PathGetSharedLibraryExtensionW(unsigned long dwFlags)1010 PCWSTR PathGetSharedLibraryExtensionW(unsigned long dwFlags)
1011 {
1012 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT)
1013 {
1014 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
1015 {
1016 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
1017 return SharedLibraryExtensionDotDllW;
1018
1019 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
1020 return SharedLibraryExtensionDotSoW;
1021
1022 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
1023 return SharedLibraryExtensionDotDylibW;
1024 }
1025 else
1026 {
1027 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
1028 return SharedLibraryExtensionDllW;
1029
1030 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
1031 return SharedLibraryExtensionSoW;
1032
1033 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
1034 return SharedLibraryExtensionDylibW;
1035 }
1036 }
1037
1038 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
1039 {
1040 #ifdef _WIN32
1041 return SharedLibraryExtensionDotDllW;
1042 #elif defined(__APPLE__)
1043 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1044 return SharedLibraryExtensionDotSoW;
1045 else
1046 return SharedLibraryExtensionDotDylibW;
1047 #else
1048 return SharedLibraryExtensionDotSoW;
1049 #endif
1050 }
1051 else
1052 {
1053 #ifdef _WIN32
1054 return SharedLibraryExtensionDllW;
1055 #elif defined(__APPLE__)
1056 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1057 return SharedLibraryExtensionSoW;
1058 else
1059 return SharedLibraryExtensionDylibW;
1060 #else
1061 return SharedLibraryExtensionSoW;
1062 #endif
1063 }
1064
1065 return NULL;
1066 }
1067