20#include <winpr/config.h>
21#include <winpr/version.h>
22#include <winpr/build-config.h>
25#include <winpr/tchar.h>
27#include <winpr/path.h>
28#include <winpr/file.h>
32static const char PATH_SLASH_CHR =
'/';
33static const char PATH_SLASH_STR[] =
"/";
35static const char PATH_BACKSLASH_CHR =
'\\';
36static const char PATH_BACKSLASH_STR[] =
"\\";
39static const WCHAR PATH_SLASH_CHR_W = L
'/';
40static const WCHAR PATH_BACKSLASH_CHR_W = L
'\\';
41static const WCHAR PATH_SLASH_STR_W[] = L
"/";
42static const WCHAR PATH_BACKSLASH_STR_W[] = L
"\\";
44#if defined(__BIG_ENDIAN__)
45static const WCHAR PATH_SLASH_CHR_W = 0x2f00;
46static const WCHAR PATH_BACKSLASH_CHR_W = 0x5c00;
47static const WCHAR PATH_SLASH_STR_W[] = { 0x2f00,
'\0' };
48static const WCHAR PATH_BACKSLASH_STR_W[] = { 0x5c00,
'\0' };
50static const WCHAR PATH_SLASH_CHR_W =
'/';
51static const WCHAR PATH_BACKSLASH_CHR_W =
'\\';
52static const WCHAR PATH_SLASH_STR_W[] = {
'/',
'\0' };
53static const WCHAR PATH_BACKSLASH_STR_W[] = {
'\\',
'\0' };
58#define PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
59#define PATH_SEPARATOR_STR PATH_BACKSLASH_STR
60#define PATH_SEPARATOR_CHR_W PATH_BACKSLASH_CHR_W
61#define PATH_SEPARATOR_STR_W PATH_BACKSLASH_STR_W
63#define PATH_SEPARATOR_CHR PATH_SLASH_CHR
64#define PATH_SEPARATOR_STR PATH_SLASH_STR
65#define PATH_SEPARATOR_CHR_W PATH_SLASH_CHR_W
66#define PATH_SEPARATOR_STR_W PATH_SLASH_STR_W
70#define TAG WINPR_TAG("path")
78#define DEFINE_UNICODE FALSE
79#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
80#define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashA
81#include "include/PathCchAddSeparator.h"
83#undef CUR_PATH_SEPARATOR_CHR
84#undef PATH_CCH_ADD_SEPARATOR
86#define DEFINE_UNICODE TRUE
87#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
88#define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashW
89#include "include/PathCchAddSeparator.h"
91#undef CUR_PATH_SEPARATOR_CHR
92#undef PATH_CCH_ADD_SEPARATOR
96#define DEFINE_UNICODE FALSE
97#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
98#define PATH_CCH_ADD_SEPARATOR PathCchAddSlashA
99#include "include/PathCchAddSeparator.h"
101#undef CUR_PATH_SEPARATOR_CHR
102#undef PATH_CCH_ADD_SEPARATOR
104#define DEFINE_UNICODE TRUE
105#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
106#define PATH_CCH_ADD_SEPARATOR PathCchAddSlashW
107#include "include/PathCchAddSeparator.h"
109#undef CUR_PATH_SEPARATOR_CHR
110#undef PATH_CCH_ADD_SEPARATOR
114#define DEFINE_UNICODE FALSE
115#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
116#define PATH_CCH_ADD_SEPARATOR PathCchAddSeparatorA
117#include "include/PathCchAddSeparator.h"
119#undef CUR_PATH_SEPARATOR_CHR
120#undef PATH_CCH_ADD_SEPARATOR
122#define DEFINE_UNICODE TRUE
123#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
124#define PATH_CCH_ADD_SEPARATOR PathCchAddSeparatorW
125#include "include/PathCchAddSeparator.h"
127#undef CUR_PATH_SEPARATOR_CHR
128#undef PATH_CCH_ADD_SEPARATOR
134HRESULT PathCchRemoveBackslashA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
136 WLog_ERR(TAG,
"not implemented");
140HRESULT PathCchRemoveBackslashW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
142 WLog_ERR(TAG,
"not implemented");
152#define DEFINE_UNICODE FALSE
153#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
154#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExA
155#include "include/PathCchAddSeparatorEx.h"
157#undef CUR_PATH_SEPARATOR_CHR
158#undef PATH_CCH_ADD_SEPARATOR_EX
160#define DEFINE_UNICODE TRUE
161#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
162#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExW
163#include "include/PathCchAddSeparatorEx.h"
165#undef CUR_PATH_SEPARATOR_CHR
166#undef PATH_CCH_ADD_SEPARATOR_EX
170#define DEFINE_UNICODE FALSE
171#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
172#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSlashExA
173#include "include/PathCchAddSeparatorEx.h"
175#undef CUR_PATH_SEPARATOR_CHR
176#undef PATH_CCH_ADD_SEPARATOR_EX
178#define DEFINE_UNICODE TRUE
179#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
180#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSlashExW
181#include "include/PathCchAddSeparatorEx.h"
183#undef CUR_PATH_SEPARATOR_CHR
184#undef PATH_CCH_ADD_SEPARATOR_EX
188#define DEFINE_UNICODE FALSE
189#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
190#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSeparatorExA
191#include "include/PathCchAddSeparatorEx.h"
193#undef CUR_PATH_SEPARATOR_CHR
194#undef PATH_CCH_ADD_SEPARATOR_EX
196#define DEFINE_UNICODE TRUE
197#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
198#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSeparatorExW
199#include "include/PathCchAddSeparatorEx.h"
201#undef CUR_PATH_SEPARATOR_CHR
202#undef PATH_CCH_ADD_SEPARATOR_EX
204HRESULT PathCchRemoveBackslashExA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
205 WINPR_ATTR_UNUSED PSTR* ppszEnd,
206 WINPR_ATTR_UNUSED
size_t* pcchRemaining)
208 WLog_ERR(TAG,
"not implemented");
212HRESULT PathCchRemoveBackslashExW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
213 WINPR_ATTR_UNUSED PWSTR* ppszEnd,
214 WINPR_ATTR_UNUSED
size_t* pcchRemaining)
216 WLog_ERR(TAG,
"not implemented");
226#define DEFINE_UNICODE FALSE
227#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
228#define PATH_CCH_ADD_EXTENSION PathCchAddExtensionA
229#include "include/PathCchAddExtension.h"
231#undef CUR_PATH_SEPARATOR_CHR
232#undef PATH_CCH_ADD_EXTENSION
234#define DEFINE_UNICODE TRUE
235#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
236#define PATH_CCH_ADD_EXTENSION PathCchAddExtensionW
237#include "include/PathCchAddExtension.h"
239#undef CUR_PATH_SEPARATOR_CHR
240#undef PATH_CCH_ADD_EXTENSION
244#define DEFINE_UNICODE FALSE
245#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
246#define PATH_CCH_ADD_EXTENSION UnixPathCchAddExtensionA
247#include "include/PathCchAddExtension.h"
249#undef CUR_PATH_SEPARATOR_CHR
250#undef PATH_CCH_ADD_EXTENSION
252#define DEFINE_UNICODE TRUE
253#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
254#define PATH_CCH_ADD_EXTENSION UnixPathCchAddExtensionW
255#include "include/PathCchAddExtension.h"
257#undef CUR_PATH_SEPARATOR_CHR
258#undef PATH_CCH_ADD_EXTENSION
262#define DEFINE_UNICODE FALSE
263#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
264#define PATH_CCH_ADD_EXTENSION NativePathCchAddExtensionA
265#include "include/PathCchAddExtension.h"
267#undef CUR_PATH_SEPARATOR_CHR
268#undef PATH_CCH_ADD_EXTENSION
270#define DEFINE_UNICODE TRUE
271#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
272#define PATH_CCH_ADD_EXTENSION NativePathCchAddExtensionW
273#include "include/PathCchAddExtension.h"
275#undef CUR_PATH_SEPARATOR_CHR
276#undef PATH_CCH_ADD_EXTENSION
284#define DEFINE_UNICODE FALSE
285#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
286#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR
287#define PATH_CCH_APPEND PathCchAppendA
288#include "include/PathCchAppend.h"
290#undef CUR_PATH_SEPARATOR_CHR
291#undef CUR_PATH_SEPARATOR_STR
292#undef PATH_CCH_APPEND
294#define DEFINE_UNICODE TRUE
295#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
296#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR_W
297#define PATH_CCH_APPEND PathCchAppendW
298#include "include/PathCchAppend.h"
300#undef CUR_PATH_SEPARATOR_CHR
301#undef CUR_PATH_SEPARATOR_STR
302#undef PATH_CCH_APPEND
306#define DEFINE_UNICODE FALSE
307#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
308#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR
309#define PATH_CCH_APPEND UnixPathCchAppendA
310#include "include/PathCchAppend.h"
312#undef CUR_PATH_SEPARATOR_CHR
313#undef CUR_PATH_SEPARATOR_STR
314#undef PATH_CCH_APPEND
316#define DEFINE_UNICODE TRUE
317#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
318#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR_W
319#define PATH_CCH_APPEND UnixPathCchAppendW
320#include "include/PathCchAppend.h"
322#undef CUR_PATH_SEPARATOR_CHR
323#undef CUR_PATH_SEPARATOR_STR
324#undef PATH_CCH_APPEND
328#define DEFINE_UNICODE FALSE
329#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
330#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR
331#define PATH_CCH_APPEND NativePathCchAppendA
332#include "include/PathCchAppend.h"
334#undef CUR_PATH_SEPARATOR_CHR
335#undef CUR_PATH_SEPARATOR_STR
336#undef PATH_CCH_APPEND
338#define DEFINE_UNICODE TRUE
339#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
340#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR_W
341#define PATH_CCH_APPEND NativePathCchAppendW
342#include "include/PathCchAppend.h"
344#undef CUR_PATH_SEPARATOR_CHR
345#undef CUR_PATH_SEPARATOR_STR
346#undef PATH_CCH_APPEND
352HRESULT PathCchAppendExA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
353 WINPR_ATTR_UNUSED PCSTR pszMore, WINPR_ATTR_UNUSED
unsigned long dwFlags)
355 WLog_ERR(TAG,
"not implemented");
359HRESULT PathCchAppendExW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
360 WINPR_ATTR_UNUSED PCWSTR pszMore, WINPR_ATTR_UNUSED
unsigned long dwFlags)
362 WLog_ERR(TAG,
"not implemented");
370HRESULT PathCchCanonicalizeA(WINPR_ATTR_UNUSED PSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
371 WINPR_ATTR_UNUSED PCSTR pszPathIn)
373 WLog_ERR(TAG,
"not implemented");
377HRESULT PathCchCanonicalizeW(WINPR_ATTR_UNUSED PWSTR pszPathOut,
378 WINPR_ATTR_UNUSED
size_t cchPathOut,
379 WINPR_ATTR_UNUSED PCWSTR pszPathIn)
381 WLog_ERR(TAG,
"not implemented");
389HRESULT PathCchCanonicalizeExA(WINPR_ATTR_UNUSED PSTR pszPathOut,
390 WINPR_ATTR_UNUSED
size_t cchPathOut,
391 WINPR_ATTR_UNUSED PCSTR pszPathIn,
392 WINPR_ATTR_UNUSED
unsigned long dwFlags)
394 WLog_ERR(TAG,
"not implemented");
398HRESULT PathCchCanonicalizeExW(WINPR_ATTR_UNUSED PWSTR pszPathOut,
399 WINPR_ATTR_UNUSED
size_t cchPathOut,
400 WINPR_ATTR_UNUSED PCWSTR pszPathIn,
401 WINPR_ATTR_UNUSED
unsigned long dwFlags)
403 WLog_ERR(TAG,
"not implemented");
411HRESULT PathAllocCanonicalizeA(WINPR_ATTR_UNUSED PCSTR pszPathIn,
412 WINPR_ATTR_UNUSED
unsigned long dwFlags,
413 WINPR_ATTR_UNUSED PSTR* ppszPathOut)
415 WLog_ERR(TAG,
"not implemented");
419HRESULT PathAllocCanonicalizeW(WINPR_ATTR_UNUSED PCWSTR pszPathIn,
420 WINPR_ATTR_UNUSED
unsigned long dwFlags,
421 WINPR_ATTR_UNUSED PWSTR* ppszPathOut)
423 WLog_ERR(TAG,
"not implemented");
431HRESULT PathCchCombineA(WINPR_ATTR_UNUSED PSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
432 WINPR_ATTR_UNUSED PCSTR pszPathIn, WINPR_ATTR_UNUSED PCSTR pszMore)
434 WLog_ERR(TAG,
"not implemented");
438HRESULT PathCchCombineW(WINPR_ATTR_UNUSED PWSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
439 WINPR_ATTR_UNUSED PCWSTR pszPathIn, WINPR_ATTR_UNUSED PCWSTR pszMore)
441 WLog_ERR(TAG,
"not implemented");
449HRESULT PathCchCombineExA(WINPR_ATTR_UNUSED PSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
450 WINPR_ATTR_UNUSED PCSTR pszPathIn, WINPR_ATTR_UNUSED PCSTR pszMore,
451 WINPR_ATTR_UNUSED
unsigned long dwFlags)
453 WLog_ERR(TAG,
"not implemented");
457HRESULT PathCchCombineExW(WINPR_ATTR_UNUSED PWSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
458 WINPR_ATTR_UNUSED PCWSTR pszPathIn, WINPR_ATTR_UNUSED PCWSTR pszMore,
459 WINPR_ATTR_UNUSED
unsigned long dwFlags)
461 WLog_ERR(TAG,
"not implemented");
471#define DEFINE_UNICODE FALSE
472#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
473#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR
474#define PATH_ALLOC_COMBINE PathAllocCombineA
475#include "include/PathAllocCombine.h"
477#undef CUR_PATH_SEPARATOR_CHR
478#undef CUR_PATH_SEPARATOR_STR
479#undef PATH_ALLOC_COMBINE
481#define DEFINE_UNICODE TRUE
482#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
483#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR_W
484#define PATH_ALLOC_COMBINE PathAllocCombineW
485#include "include/PathAllocCombine.h"
487#undef CUR_PATH_SEPARATOR_CHR
488#undef CUR_PATH_SEPARATOR_STR
489#undef PATH_ALLOC_COMBINE
493#define DEFINE_UNICODE FALSE
494#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
495#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR
496#define PATH_ALLOC_COMBINE UnixPathAllocCombineA
497#include "include/PathAllocCombine.h"
499#undef CUR_PATH_SEPARATOR_CHR
500#undef CUR_PATH_SEPARATOR_STR
501#undef PATH_ALLOC_COMBINE
503#define DEFINE_UNICODE TRUE
504#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
505#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR_W
506#define PATH_ALLOC_COMBINE UnixPathAllocCombineW
507#include "include/PathAllocCombine.h"
509#undef CUR_PATH_SEPARATOR_CHR
510#undef CUR_PATH_SEPARATOR_STR
511#undef PATH_ALLOC_COMBINE
515#define DEFINE_UNICODE FALSE
516#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
517#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR
518#define PATH_ALLOC_COMBINE NativePathAllocCombineA
519#include "include/PathAllocCombine.h"
521#undef CUR_PATH_SEPARATOR_CHR
522#undef CUR_PATH_SEPARATOR_STR
523#undef PATH_ALLOC_COMBINE
525#define DEFINE_UNICODE TRUE
526#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
527#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR_W
528#define PATH_ALLOC_COMBINE NativePathAllocCombineW
529#include "include/PathAllocCombine.h"
531#undef CUR_PATH_SEPARATOR_CHR
532#undef CUR_PATH_SEPARATOR_STR
533#undef PATH_ALLOC_COMBINE
539HRESULT PathCchFindExtensionA(PCSTR pszPath,
size_t cchPath, PCSTR* ppszExt)
541 const char* p = (
const char*)pszPath;
543 if (!pszPath || !cchPath || !ppszExt)
548 while (*p && --cchPath)
572 if ((*p ==
'\\') || (*p ==
'/') || (*p ==
':'))
581HRESULT PathCchFindExtensionW(WINPR_ATTR_UNUSED PCWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
582 WINPR_ATTR_UNUSED PCWSTR* ppszExt)
584 WLog_ERR(TAG,
"not implemented");
592HRESULT PathCchRenameExtensionA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
593 WINPR_ATTR_UNUSED PCSTR pszExt)
595 WLog_ERR(TAG,
"not implemented");
599HRESULT PathCchRenameExtensionW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
600 WINPR_ATTR_UNUSED PCWSTR pszExt)
602 WLog_ERR(TAG,
"not implemented");
610HRESULT PathCchRemoveExtensionA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
612 WLog_ERR(TAG,
"not implemented");
616HRESULT PathCchRemoveExtensionW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
618 WLog_ERR(TAG,
"not implemented");
626BOOL PathCchIsRootA(WINPR_ATTR_UNUSED PCSTR pszPath)
628 WLog_ERR(TAG,
"not implemented");
632BOOL PathCchIsRootW(WINPR_ATTR_UNUSED PCWSTR pszPath)
634 WLog_ERR(TAG,
"not implemented");
642BOOL PathIsUNCExA(PCSTR pszPath, PCSTR* ppszServer)
647 if ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\'))
649 *ppszServer = &pszPath[2];
656BOOL PathIsUNCExW(PCWSTR pszPath, PCWSTR* ppszServer)
661 if ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\'))
663 *ppszServer = &pszPath[2];
674HRESULT PathCchSkipRootA(WINPR_ATTR_UNUSED PCSTR pszPath, WINPR_ATTR_UNUSED PCSTR* ppszRootEnd)
676 WLog_ERR(TAG,
"not implemented");
680HRESULT PathCchSkipRootW(WINPR_ATTR_UNUSED PCWSTR pszPath, WINPR_ATTR_UNUSED PCWSTR* ppszRootEnd)
682 WLog_ERR(TAG,
"not implemented");
690HRESULT PathCchStripToRootA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
692 WLog_ERR(TAG,
"not implemented");
696HRESULT PathCchStripToRootW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
698 WLog_ERR(TAG,
"not implemented");
706HRESULT PathCchStripPrefixA(PSTR pszPath,
size_t cchPath)
713 if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH)
716 hasPrefix = ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\') && (pszPath[2] ==
'?') &&
717 (pszPath[3] ==
'\\'));
724 if (IsCharAlpha(pszPath[4]) && (pszPath[5] ==
':'))
726 if (memmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4) < 0)
727 return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
733 pszPath[cchPath - 4] = 0;
741HRESULT PathCchStripPrefixW(PWSTR pszPath,
size_t cchPath)
748 if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH)
751 hasPrefix = ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\') && (pszPath[2] ==
'?') &&
752 (pszPath[3] ==
'\\'));
759 const size_t rc = (_wcslen(&pszPath[4]) + 1);
761 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
763 if (IsCharAlphaW(pszPath[4]) && (pszPath[5] == L
':'))
765 if (wmemmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4) < 0)
766 return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
771 pszPath[cchPath - 4] = 0;
783HRESULT PathCchRemoveFileSpecA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
785 WLog_ERR(TAG,
"not implemented");
789HRESULT PathCchRemoveFileSpecW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
791 WLog_ERR(TAG,
"not implemented");
803HRESULT PathCchConvertStyleA(PSTR pszPath,
size_t cchPath,
unsigned long dwFlags)
805 if (dwFlags == PATH_STYLE_WINDOWS)
807 for (
size_t index = 0; index < cchPath; index++)
809 if (pszPath[index] == PATH_SLASH_CHR)
810 pszPath[index] = PATH_BACKSLASH_CHR;
813 else if (dwFlags == PATH_STYLE_UNIX)
815 for (
size_t index = 0; index < cchPath; index++)
817 if (pszPath[index] == PATH_BACKSLASH_CHR)
818 pszPath[index] = PATH_SLASH_CHR;
821 else if (dwFlags == PATH_STYLE_NATIVE)
823 if (PATH_SEPARATOR_CHR == PATH_BACKSLASH_CHR)
827 for (
size_t index = 0; index < cchPath; index++)
829 if (pszPath[index] == PATH_SLASH_CHR)
830 pszPath[index] = PATH_BACKSLASH_CHR;
833 else if (PATH_SEPARATOR_CHR == PATH_SLASH_CHR)
837 for (
size_t index = 0; index < cchPath; index++)
839 if (pszPath[index] == PATH_BACKSLASH_CHR)
840 pszPath[index] = PATH_SLASH_CHR;
858HRESULT PathCchConvertStyleW(PWSTR pszPath,
size_t cchPath,
unsigned long dwFlags)
860 if (dwFlags == PATH_STYLE_WINDOWS)
862 for (
size_t index = 0; index < cchPath; index++)
864 if (pszPath[index] == PATH_SLASH_CHR_W)
865 pszPath[index] = PATH_BACKSLASH_CHR_W;
868 else if (dwFlags == PATH_STYLE_UNIX)
870 for (
size_t index = 0; index < cchPath; index++)
872 if (pszPath[index] == PATH_BACKSLASH_CHR_W)
873 pszPath[index] = PATH_SLASH_CHR_W;
876 else if (dwFlags == PATH_STYLE_NATIVE)
878 if (PATH_SEPARATOR_CHR == PATH_BACKSLASH_CHR_W)
882 for (
size_t index = 0; index < cchPath; index++)
884 if (pszPath[index] == PATH_SLASH_CHR_W)
885 pszPath[index] = PATH_BACKSLASH_CHR_W;
888 else if (PATH_SEPARATOR_CHR == PATH_SLASH_CHR_W)
892 for (
size_t index = 0; index < cchPath; index++)
894 if (pszPath[index] == PATH_BACKSLASH_CHR_W)
895 pszPath[index] = PATH_SLASH_CHR_W;
917char PathGetSeparatorA(
unsigned long dwFlags)
919 if (dwFlags == PATH_STYLE_WINDOWS)
920 return PATH_BACKSLASH_CHR;
921 if (dwFlags == PATH_STYLE_UNIX)
922 return PATH_SLASH_CHR;
924 return PATH_SEPARATOR_CHR;
927WCHAR PathGetSeparatorW(
unsigned long dwFlags)
929 if (dwFlags == PATH_STYLE_WINDOWS)
930 return PATH_BACKSLASH_CHR_W;
931 if (dwFlags == PATH_STYLE_UNIX)
932 return PATH_SLASH_CHR_W;
934 return PATH_SEPARATOR_CHR;
940static const CHAR SharedLibraryExtensionDllA[] =
"dll";
941static const CHAR SharedLibraryExtensionSoA[] =
"so";
942static const CHAR SharedLibraryExtensionDylibA[] =
"dylib";
944static const CHAR SharedLibraryExtensionDotDllA[] =
".dll";
945static const CHAR SharedLibraryExtensionDotSoA[] =
".so";
946static const CHAR SharedLibraryExtensionDotDylibA[] =
".dylib";
947PCSTR PathGetSharedLibraryExtensionA(
unsigned long dwFlags)
949 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT)
951 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
953 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
954 return SharedLibraryExtensionDotDllA;
956 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
957 return SharedLibraryExtensionDotSoA;
959 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
960 return SharedLibraryExtensionDotDylibA;
964 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
965 return SharedLibraryExtensionDllA;
967 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
968 return SharedLibraryExtensionSoA;
970 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
971 return SharedLibraryExtensionDylibA;
975 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
978 return SharedLibraryExtensionDotDllA;
979#elif defined(__APPLE__)
980 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
981 return SharedLibraryExtensionDotSoA;
983 return SharedLibraryExtensionDotDylibA;
985 return SharedLibraryExtensionDotSoA;
991 return SharedLibraryExtensionDllA;
992#elif defined(__APPLE__)
993 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
994 return SharedLibraryExtensionSoA;
996 return SharedLibraryExtensionDylibA;
998 return SharedLibraryExtensionSoA;
1003PCWSTR PathGetSharedLibraryExtensionW(
unsigned long dwFlags)
1005 static WCHAR buffer[6][16] = WINPR_C_ARRAY_INIT;
1006 const WCHAR* SharedLibraryExtensionDotDllW = InitializeConstWCharFromUtf8(
1007 SharedLibraryExtensionDotDllA, buffer[0], ARRAYSIZE(buffer[0]));
1008 const WCHAR* SharedLibraryExtensionDotSoW =
1009 InitializeConstWCharFromUtf8(SharedLibraryExtensionDotSoA, buffer[1], ARRAYSIZE(buffer[1]));
1010 const WCHAR* SharedLibraryExtensionDotDylibW = InitializeConstWCharFromUtf8(
1011 SharedLibraryExtensionDotDylibA, buffer[2], ARRAYSIZE(buffer[2]));
1012 const WCHAR* SharedLibraryExtensionDllW =
1013 InitializeConstWCharFromUtf8(SharedLibraryExtensionDllA, buffer[3], ARRAYSIZE(buffer[3]));
1014 const WCHAR* SharedLibraryExtensionSoW =
1015 InitializeConstWCharFromUtf8(SharedLibraryExtensionSoA, buffer[4], ARRAYSIZE(buffer[4]));
1016 const WCHAR* SharedLibraryExtensionDylibW =
1017 InitializeConstWCharFromUtf8(SharedLibraryExtensionDylibA, buffer[5], ARRAYSIZE(buffer[5]));
1019 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT)
1021 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
1023 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
1024 return SharedLibraryExtensionDotDllW;
1026 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
1027 return SharedLibraryExtensionDotSoW;
1029 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
1030 return SharedLibraryExtensionDotDylibW;
1034 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
1035 return SharedLibraryExtensionDllW;
1037 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
1038 return SharedLibraryExtensionSoW;
1040 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
1041 return SharedLibraryExtensionDylibW;
1045 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
1048 return SharedLibraryExtensionDotDllW;
1049#elif defined(__APPLE__)
1050 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1051 return SharedLibraryExtensionDotSoW;
1053 return SharedLibraryExtensionDotDylibW;
1055 return SharedLibraryExtensionDotSoW;
1061 return SharedLibraryExtensionDllW;
1062#elif defined(__APPLE__)
1063 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1064 return SharedLibraryExtensionSoW;
1066 return SharedLibraryExtensionDylibW;
1068 return SharedLibraryExtensionSoW;
1073const char* GetKnownPathIdString(
int id)
1077 case KNOWN_PATH_HOME:
1078 return "KNOWN_PATH_HOME";
1079 case KNOWN_PATH_TEMP:
1080 return "KNOWN_PATH_TEMP";
1081 case KNOWN_PATH_XDG_DATA_HOME:
1082 return "KNOWN_PATH_XDG_DATA_HOME";
1083 case KNOWN_PATH_XDG_CONFIG_HOME:
1084 return "KNOWN_PATH_XDG_CONFIG_HOME";
1085 case KNOWN_PATH_XDG_CACHE_HOME:
1086 return "KNOWN_PATH_XDG_CACHE_HOME";
1087 case KNOWN_PATH_XDG_RUNTIME_DIR:
1088 return "KNOWN_PATH_XDG_RUNTIME_DIR";
1089 case KNOWN_PATH_SYSTEM_CONFIG_HOME:
1090 return "KNOWN_PATH_SYSTEM_CONFIG_HOME";
1092 return "KNOWN_PATH_UNKNOWN_ID";
1096static char* concat(
const char* path,
size_t pathlen,
const char* name,
size_t namelen)
1098 const size_t strsize = pathlen + namelen + 2;
1099 char* str = calloc(strsize,
sizeof(
char));
1103 winpr_str_append(path, str, strsize,
"");
1104 winpr_str_append(name, str, strsize,
"");
1108BOOL winpr_RemoveDirectory_RecursiveA(LPCSTR lpPathName)
1115 const size_t pathnamelen = strlen(lpPathName);
1116 const size_t path_slash_len = pathnamelen + 3;
1117 char* path_slash = calloc(pathnamelen + 4,
sizeof(
char));
1120 strncat(path_slash, lpPathName, pathnamelen);
1122 const char star[] =
"*";
1123 const HRESULT hr = NativePathCchAppendA(path_slash, path_slash_len, star);
1124 HANDLE dir = INVALID_HANDLE_VALUE;
1130 dir = FindFirstFileA(path_slash, &findFileData);
1132 if (dir == INVALID_HANDLE_VALUE)
1136 path_slash[path_slash_len - 1] =
'\0';
1139 const size_t len = strnlen(findFileData.cFileName, ARRAYSIZE(findFileData.cFileName));
1141 if ((len == 1 && findFileData.cFileName[0] ==
'.') ||
1142 (len == 2 && findFileData.cFileName[0] ==
'.' && findFileData.cFileName[1] ==
'.'))
1147 char* fullpath = concat(path_slash, path_slash_len, findFileData.cFileName, len);
1151 if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1152 ret = winpr_RemoveDirectory_RecursiveA(fullpath);
1155 WINPR_PRAGMA_DIAG_PUSH
1156 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
1157 ret = winpr_DeleteFile(fullpath);
1158 WINPR_PRAGMA_DIAG_POP
1165 }
while (ret && FindNextFileA(dir, &findFileData) != 0);
1170 if (!winpr_RemoveDirectory(lpPathName))
1180BOOL winpr_RemoveDirectory_RecursiveW(LPCWSTR lpPathName)
1182 char* name = ConvertWCharToUtf8Alloc(lpPathName,
nullptr);
1185 const BOOL rc = winpr_RemoveDirectory_RecursiveA(name);
1190char* winpr_GetConfigFilePathVA(BOOL system, WINPR_FORMAT_ARG
const char* filename, va_list ap)
1192 eKnownPathTypes
id = system ? KNOWN_PATH_SYSTEM_CONFIG_HOME : KNOWN_PATH_XDG_CONFIG_HOME;
1193 const char* vendor = winpr_getApplicationDetailsVendor();
1194 const char* product = winpr_getApplicationDetailsProduct();
1195 const SSIZE_T version = winpr_getApplicationDetailsVersion();
1197 if (!vendor || !product)
1200 char* config = GetKnownSubPathV(
id,
"%s", vendor);
1204 char* base =
nullptr;
1206 base = GetCombinedPathV(config,
"%s", product);
1208 base = GetCombinedPathV(config,
"%s%" PRIdz, product, version);
1213 char* path = GetCombinedPathVA(base, filename, ap);
1219char* winpr_GetConfigFilePath(BOOL system,
const char* filename)
1222 return winpr_GetConfigFilePathV(system,
"%s",
"");
1223 return winpr_GetConfigFilePathV(system,
"%s", filename);
1226char* winpr_GetConfigFilePathV(BOOL system,
const char* filename, ...)
1228 va_list ap = WINPR_C_ARRAY_INIT;
1229 va_start(ap, filename);
1230 char* str = winpr_GetConfigFilePathVA(system, filename, ap);