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>
32#if defined(WITH_RESOURCE_VERSIONING)
36static const char PATH_SLASH_CHR =
'/';
37static const char PATH_SLASH_STR[] =
"/";
39static const char PATH_BACKSLASH_CHR =
'\\';
40static const char PATH_BACKSLASH_STR[] =
"\\";
43static const WCHAR PATH_SLASH_CHR_W = L
'/';
44static const WCHAR PATH_BACKSLASH_CHR_W = L
'\\';
45static const WCHAR PATH_SLASH_STR_W[] = L
"/";
46static const WCHAR PATH_BACKSLASH_STR_W[] = L
"\\";
48#if defined(__BIG_ENDIAN__)
49static const WCHAR PATH_SLASH_CHR_W = 0x2f00;
50static const WCHAR PATH_BACKSLASH_CHR_W = 0x5c00;
51static const WCHAR PATH_SLASH_STR_W[] = { 0x2f00,
'\0' };
52static const WCHAR PATH_BACKSLASH_STR_W[] = { 0x5c00,
'\0' };
54static const WCHAR PATH_SLASH_CHR_W =
'/';
55static const WCHAR PATH_BACKSLASH_CHR_W =
'\\';
56static const WCHAR PATH_SLASH_STR_W[] = {
'/',
'\0' };
57static const WCHAR PATH_BACKSLASH_STR_W[] = {
'\\',
'\0' };
62#define PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
63#define PATH_SEPARATOR_STR PATH_BACKSLASH_STR
64#define PATH_SEPARATOR_CHR_W PATH_BACKSLASH_CHR_W
65#define PATH_SEPARATOR_STR_W PATH_BACKSLASH_STR_W
67#define PATH_SEPARATOR_CHR PATH_SLASH_CHR
68#define PATH_SEPARATOR_STR PATH_SLASH_STR
69#define PATH_SEPARATOR_CHR_W PATH_SLASH_CHR_W
70#define PATH_SEPARATOR_STR_W PATH_SLASH_STR_W
74#define TAG WINPR_TAG("path")
82#define DEFINE_UNICODE FALSE
83#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
84#define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashA
85#include "include/PathCchAddSeparator.h"
87#undef CUR_PATH_SEPARATOR_CHR
88#undef PATH_CCH_ADD_SEPARATOR
90#define DEFINE_UNICODE TRUE
91#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
92#define PATH_CCH_ADD_SEPARATOR PathCchAddBackslashW
93#include "include/PathCchAddSeparator.h"
95#undef CUR_PATH_SEPARATOR_CHR
96#undef PATH_CCH_ADD_SEPARATOR
100#define DEFINE_UNICODE FALSE
101#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
102#define PATH_CCH_ADD_SEPARATOR PathCchAddSlashA
103#include "include/PathCchAddSeparator.h"
105#undef CUR_PATH_SEPARATOR_CHR
106#undef PATH_CCH_ADD_SEPARATOR
108#define DEFINE_UNICODE TRUE
109#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
110#define PATH_CCH_ADD_SEPARATOR PathCchAddSlashW
111#include "include/PathCchAddSeparator.h"
113#undef CUR_PATH_SEPARATOR_CHR
114#undef PATH_CCH_ADD_SEPARATOR
118#define DEFINE_UNICODE FALSE
119#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
120#define PATH_CCH_ADD_SEPARATOR PathCchAddSeparatorA
121#include "include/PathCchAddSeparator.h"
123#undef CUR_PATH_SEPARATOR_CHR
124#undef PATH_CCH_ADD_SEPARATOR
126#define DEFINE_UNICODE TRUE
127#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
128#define PATH_CCH_ADD_SEPARATOR PathCchAddSeparatorW
129#include "include/PathCchAddSeparator.h"
131#undef CUR_PATH_SEPARATOR_CHR
132#undef PATH_CCH_ADD_SEPARATOR
138HRESULT PathCchRemoveBackslashA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
140 WLog_ERR(TAG,
"not implemented");
144HRESULT PathCchRemoveBackslashW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
146 WLog_ERR(TAG,
"not implemented");
156#define DEFINE_UNICODE FALSE
157#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
158#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExA
159#include "include/PathCchAddSeparatorEx.h"
161#undef CUR_PATH_SEPARATOR_CHR
162#undef PATH_CCH_ADD_SEPARATOR_EX
164#define DEFINE_UNICODE TRUE
165#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
166#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddBackslashExW
167#include "include/PathCchAddSeparatorEx.h"
169#undef CUR_PATH_SEPARATOR_CHR
170#undef PATH_CCH_ADD_SEPARATOR_EX
174#define DEFINE_UNICODE FALSE
175#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
176#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSlashExA
177#include "include/PathCchAddSeparatorEx.h"
179#undef CUR_PATH_SEPARATOR_CHR
180#undef PATH_CCH_ADD_SEPARATOR_EX
182#define DEFINE_UNICODE TRUE
183#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
184#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSlashExW
185#include "include/PathCchAddSeparatorEx.h"
187#undef CUR_PATH_SEPARATOR_CHR
188#undef PATH_CCH_ADD_SEPARATOR_EX
192#define DEFINE_UNICODE FALSE
193#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
194#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSeparatorExA
195#include "include/PathCchAddSeparatorEx.h"
197#undef CUR_PATH_SEPARATOR_CHR
198#undef PATH_CCH_ADD_SEPARATOR_EX
200#define DEFINE_UNICODE TRUE
201#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
202#define PATH_CCH_ADD_SEPARATOR_EX PathCchAddSeparatorExW
203#include "include/PathCchAddSeparatorEx.h"
205#undef CUR_PATH_SEPARATOR_CHR
206#undef PATH_CCH_ADD_SEPARATOR_EX
208HRESULT PathCchRemoveBackslashExA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
209 WINPR_ATTR_UNUSED PSTR* ppszEnd,
210 WINPR_ATTR_UNUSED
size_t* pcchRemaining)
212 WLog_ERR(TAG,
"not implemented");
216HRESULT PathCchRemoveBackslashExW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
217 WINPR_ATTR_UNUSED PWSTR* ppszEnd,
218 WINPR_ATTR_UNUSED
size_t* pcchRemaining)
220 WLog_ERR(TAG,
"not implemented");
230#define DEFINE_UNICODE FALSE
231#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
232#define PATH_CCH_ADD_EXTENSION PathCchAddExtensionA
233#include "include/PathCchAddExtension.h"
235#undef CUR_PATH_SEPARATOR_CHR
236#undef PATH_CCH_ADD_EXTENSION
238#define DEFINE_UNICODE TRUE
239#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
240#define PATH_CCH_ADD_EXTENSION PathCchAddExtensionW
241#include "include/PathCchAddExtension.h"
243#undef CUR_PATH_SEPARATOR_CHR
244#undef PATH_CCH_ADD_EXTENSION
248#define DEFINE_UNICODE FALSE
249#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
250#define PATH_CCH_ADD_EXTENSION UnixPathCchAddExtensionA
251#include "include/PathCchAddExtension.h"
253#undef CUR_PATH_SEPARATOR_CHR
254#undef PATH_CCH_ADD_EXTENSION
256#define DEFINE_UNICODE TRUE
257#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
258#define PATH_CCH_ADD_EXTENSION UnixPathCchAddExtensionW
259#include "include/PathCchAddExtension.h"
261#undef CUR_PATH_SEPARATOR_CHR
262#undef PATH_CCH_ADD_EXTENSION
266#define DEFINE_UNICODE FALSE
267#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
268#define PATH_CCH_ADD_EXTENSION NativePathCchAddExtensionA
269#include "include/PathCchAddExtension.h"
271#undef CUR_PATH_SEPARATOR_CHR
272#undef PATH_CCH_ADD_EXTENSION
274#define DEFINE_UNICODE TRUE
275#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
276#define PATH_CCH_ADD_EXTENSION NativePathCchAddExtensionW
277#include "include/PathCchAddExtension.h"
279#undef CUR_PATH_SEPARATOR_CHR
280#undef PATH_CCH_ADD_EXTENSION
288#define DEFINE_UNICODE FALSE
289#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
290#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR
291#define PATH_CCH_APPEND PathCchAppendA
292#include "include/PathCchAppend.h"
294#undef CUR_PATH_SEPARATOR_CHR
295#undef CUR_PATH_SEPARATOR_STR
296#undef PATH_CCH_APPEND
298#define DEFINE_UNICODE TRUE
299#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
300#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR_W
301#define PATH_CCH_APPEND PathCchAppendW
302#include "include/PathCchAppend.h"
304#undef CUR_PATH_SEPARATOR_CHR
305#undef CUR_PATH_SEPARATOR_STR
306#undef PATH_CCH_APPEND
310#define DEFINE_UNICODE FALSE
311#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
312#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR
313#define PATH_CCH_APPEND UnixPathCchAppendA
314#include "include/PathCchAppend.h"
316#undef CUR_PATH_SEPARATOR_CHR
317#undef CUR_PATH_SEPARATOR_STR
318#undef PATH_CCH_APPEND
320#define DEFINE_UNICODE TRUE
321#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
322#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR_W
323#define PATH_CCH_APPEND UnixPathCchAppendW
324#include "include/PathCchAppend.h"
326#undef CUR_PATH_SEPARATOR_CHR
327#undef CUR_PATH_SEPARATOR_STR
328#undef PATH_CCH_APPEND
332#define DEFINE_UNICODE FALSE
333#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
334#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR
335#define PATH_CCH_APPEND NativePathCchAppendA
336#include "include/PathCchAppend.h"
338#undef CUR_PATH_SEPARATOR_CHR
339#undef CUR_PATH_SEPARATOR_STR
340#undef PATH_CCH_APPEND
342#define DEFINE_UNICODE TRUE
343#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
344#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR_W
345#define PATH_CCH_APPEND NativePathCchAppendW
346#include "include/PathCchAppend.h"
348#undef CUR_PATH_SEPARATOR_CHR
349#undef CUR_PATH_SEPARATOR_STR
350#undef PATH_CCH_APPEND
356HRESULT PathCchAppendExA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
357 WINPR_ATTR_UNUSED PCSTR pszMore, WINPR_ATTR_UNUSED
unsigned long dwFlags)
359 WLog_ERR(TAG,
"not implemented");
363HRESULT PathCchAppendExW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
364 WINPR_ATTR_UNUSED PCWSTR pszMore, WINPR_ATTR_UNUSED
unsigned long dwFlags)
366 WLog_ERR(TAG,
"not implemented");
374HRESULT PathCchCanonicalizeA(WINPR_ATTR_UNUSED PSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
375 WINPR_ATTR_UNUSED PCSTR pszPathIn)
377 WLog_ERR(TAG,
"not implemented");
381HRESULT PathCchCanonicalizeW(WINPR_ATTR_UNUSED PWSTR pszPathOut,
382 WINPR_ATTR_UNUSED
size_t cchPathOut,
383 WINPR_ATTR_UNUSED PCWSTR pszPathIn)
385 WLog_ERR(TAG,
"not implemented");
393HRESULT PathCchCanonicalizeExA(WINPR_ATTR_UNUSED PSTR pszPathOut,
394 WINPR_ATTR_UNUSED
size_t cchPathOut,
395 WINPR_ATTR_UNUSED PCSTR pszPathIn,
396 WINPR_ATTR_UNUSED
unsigned long dwFlags)
398 WLog_ERR(TAG,
"not implemented");
402HRESULT PathCchCanonicalizeExW(WINPR_ATTR_UNUSED PWSTR pszPathOut,
403 WINPR_ATTR_UNUSED
size_t cchPathOut,
404 WINPR_ATTR_UNUSED PCWSTR pszPathIn,
405 WINPR_ATTR_UNUSED
unsigned long dwFlags)
407 WLog_ERR(TAG,
"not implemented");
415HRESULT PathAllocCanonicalizeA(WINPR_ATTR_UNUSED PCSTR pszPathIn,
416 WINPR_ATTR_UNUSED
unsigned long dwFlags,
417 WINPR_ATTR_UNUSED PSTR* ppszPathOut)
419 WLog_ERR(TAG,
"not implemented");
423HRESULT PathAllocCanonicalizeW(WINPR_ATTR_UNUSED PCWSTR pszPathIn,
424 WINPR_ATTR_UNUSED
unsigned long dwFlags,
425 WINPR_ATTR_UNUSED PWSTR* ppszPathOut)
427 WLog_ERR(TAG,
"not implemented");
435HRESULT PathCchCombineA(WINPR_ATTR_UNUSED PSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
436 WINPR_ATTR_UNUSED PCSTR pszPathIn, WINPR_ATTR_UNUSED PCSTR pszMore)
438 WLog_ERR(TAG,
"not implemented");
442HRESULT PathCchCombineW(WINPR_ATTR_UNUSED PWSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
443 WINPR_ATTR_UNUSED PCWSTR pszPathIn, WINPR_ATTR_UNUSED PCWSTR pszMore)
445 WLog_ERR(TAG,
"not implemented");
453HRESULT PathCchCombineExA(WINPR_ATTR_UNUSED PSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
454 WINPR_ATTR_UNUSED PCSTR pszPathIn, WINPR_ATTR_UNUSED PCSTR pszMore,
455 WINPR_ATTR_UNUSED
unsigned long dwFlags)
457 WLog_ERR(TAG,
"not implemented");
461HRESULT PathCchCombineExW(WINPR_ATTR_UNUSED PWSTR pszPathOut, WINPR_ATTR_UNUSED
size_t cchPathOut,
462 WINPR_ATTR_UNUSED PCWSTR pszPathIn, WINPR_ATTR_UNUSED PCWSTR pszMore,
463 WINPR_ATTR_UNUSED
unsigned long dwFlags)
465 WLog_ERR(TAG,
"not implemented");
475#define DEFINE_UNICODE FALSE
476#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR
477#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR
478#define PATH_ALLOC_COMBINE PathAllocCombineA
479#include "include/PathAllocCombine.h"
481#undef CUR_PATH_SEPARATOR_CHR
482#undef CUR_PATH_SEPARATOR_STR
483#undef PATH_ALLOC_COMBINE
485#define DEFINE_UNICODE TRUE
486#define CUR_PATH_SEPARATOR_CHR PATH_BACKSLASH_CHR_W
487#define CUR_PATH_SEPARATOR_STR PATH_BACKSLASH_STR_W
488#define PATH_ALLOC_COMBINE PathAllocCombineW
489#include "include/PathAllocCombine.h"
491#undef CUR_PATH_SEPARATOR_CHR
492#undef CUR_PATH_SEPARATOR_STR
493#undef PATH_ALLOC_COMBINE
497#define DEFINE_UNICODE FALSE
498#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR
499#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR
500#define PATH_ALLOC_COMBINE UnixPathAllocCombineA
501#include "include/PathAllocCombine.h"
503#undef CUR_PATH_SEPARATOR_CHR
504#undef CUR_PATH_SEPARATOR_STR
505#undef PATH_ALLOC_COMBINE
507#define DEFINE_UNICODE TRUE
508#define CUR_PATH_SEPARATOR_CHR PATH_SLASH_CHR_W
509#define CUR_PATH_SEPARATOR_STR PATH_SLASH_STR_W
510#define PATH_ALLOC_COMBINE UnixPathAllocCombineW
511#include "include/PathAllocCombine.h"
513#undef CUR_PATH_SEPARATOR_CHR
514#undef CUR_PATH_SEPARATOR_STR
515#undef PATH_ALLOC_COMBINE
519#define DEFINE_UNICODE FALSE
520#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR
521#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR
522#define PATH_ALLOC_COMBINE NativePathAllocCombineA
523#include "include/PathAllocCombine.h"
525#undef CUR_PATH_SEPARATOR_CHR
526#undef CUR_PATH_SEPARATOR_STR
527#undef PATH_ALLOC_COMBINE
529#define DEFINE_UNICODE TRUE
530#define CUR_PATH_SEPARATOR_CHR PATH_SEPARATOR_CHR_W
531#define CUR_PATH_SEPARATOR_STR PATH_SEPARATOR_STR_W
532#define PATH_ALLOC_COMBINE NativePathAllocCombineW
533#include "include/PathAllocCombine.h"
535#undef CUR_PATH_SEPARATOR_CHR
536#undef CUR_PATH_SEPARATOR_STR
537#undef PATH_ALLOC_COMBINE
543HRESULT PathCchFindExtensionA(PCSTR pszPath,
size_t cchPath, PCSTR* ppszExt)
545 const char* p = (
const char*)pszPath;
547 if (!pszPath || !cchPath || !ppszExt)
552 while (*p && --cchPath)
576 if ((*p ==
'\\') || (*p ==
'/') || (*p ==
':'))
585HRESULT PathCchFindExtensionW(WINPR_ATTR_UNUSED PCWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
586 WINPR_ATTR_UNUSED PCWSTR* ppszExt)
588 WLog_ERR(TAG,
"not implemented");
596HRESULT PathCchRenameExtensionA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
597 WINPR_ATTR_UNUSED PCSTR pszExt)
599 WLog_ERR(TAG,
"not implemented");
603HRESULT PathCchRenameExtensionW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath,
604 WINPR_ATTR_UNUSED PCWSTR pszExt)
606 WLog_ERR(TAG,
"not implemented");
614HRESULT PathCchRemoveExtensionA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
616 WLog_ERR(TAG,
"not implemented");
620HRESULT PathCchRemoveExtensionW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
622 WLog_ERR(TAG,
"not implemented");
630BOOL PathCchIsRootA(WINPR_ATTR_UNUSED PCSTR pszPath)
632 WLog_ERR(TAG,
"not implemented");
636BOOL PathCchIsRootW(WINPR_ATTR_UNUSED PCWSTR pszPath)
638 WLog_ERR(TAG,
"not implemented");
646BOOL PathIsUNCExA(PCSTR pszPath, PCSTR* ppszServer)
651 if ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\'))
653 *ppszServer = &pszPath[2];
660BOOL PathIsUNCExW(PCWSTR pszPath, PCWSTR* ppszServer)
665 if ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\'))
667 *ppszServer = &pszPath[2];
678HRESULT PathCchSkipRootA(WINPR_ATTR_UNUSED PCSTR pszPath, WINPR_ATTR_UNUSED PCSTR* ppszRootEnd)
680 WLog_ERR(TAG,
"not implemented");
684HRESULT PathCchSkipRootW(WINPR_ATTR_UNUSED PCWSTR pszPath, WINPR_ATTR_UNUSED PCWSTR* ppszRootEnd)
686 WLog_ERR(TAG,
"not implemented");
694HRESULT PathCchStripToRootA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
696 WLog_ERR(TAG,
"not implemented");
700HRESULT PathCchStripToRootW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
702 WLog_ERR(TAG,
"not implemented");
710HRESULT PathCchStripPrefixA(PSTR pszPath,
size_t cchPath)
717 if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH)
720 hasPrefix = ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\') && (pszPath[2] ==
'?') &&
721 (pszPath[3] ==
'\\'))
730 if (IsCharAlpha(pszPath[4]) && (pszPath[5] ==
':'))
732 memmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4);
737 pszPath[cchPath - 4] = 0;
745HRESULT PathCchStripPrefixW(PWSTR pszPath,
size_t cchPath)
752 if (cchPath < 4 || cchPath > PATHCCH_MAX_CCH)
755 hasPrefix = ((pszPath[0] ==
'\\') && (pszPath[1] ==
'\\') && (pszPath[2] ==
'?') &&
756 (pszPath[3] ==
'\\'))
765 const size_t rc = (_wcslen(&pszPath[4]) + 1);
767 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
769 if (IsCharAlphaW(pszPath[4]) && (pszPath[5] == L
':'))
771 wmemmove_s(pszPath, cchPath, &pszPath[4], cchPath - 4);
776 pszPath[cchPath - 4] = 0;
788HRESULT PathCchRemoveFileSpecA(WINPR_ATTR_UNUSED PSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
790 WLog_ERR(TAG,
"not implemented");
794HRESULT PathCchRemoveFileSpecW(WINPR_ATTR_UNUSED PWSTR pszPath, WINPR_ATTR_UNUSED
size_t cchPath)
796 WLog_ERR(TAG,
"not implemented");
808HRESULT PathCchConvertStyleA(PSTR pszPath,
size_t cchPath,
unsigned long dwFlags)
810 if (dwFlags == PATH_STYLE_WINDOWS)
812 for (
size_t index = 0; index < cchPath; index++)
814 if (pszPath[index] == PATH_SLASH_CHR)
815 pszPath[index] = PATH_BACKSLASH_CHR;
818 else if (dwFlags == PATH_STYLE_UNIX)
820 for (
size_t index = 0; index < cchPath; index++)
822 if (pszPath[index] == PATH_BACKSLASH_CHR)
823 pszPath[index] = PATH_SLASH_CHR;
826 else if (dwFlags == PATH_STYLE_NATIVE)
828 if (PATH_SEPARATOR_CHR == PATH_BACKSLASH_CHR)
832 for (
size_t index = 0; index < cchPath; index++)
834 if (pszPath[index] == PATH_SLASH_CHR)
835 pszPath[index] = PATH_BACKSLASH_CHR;
838 else if (PATH_SEPARATOR_CHR == PATH_SLASH_CHR)
842 for (
size_t index = 0; index < cchPath; index++)
844 if (pszPath[index] == PATH_BACKSLASH_CHR)
845 pszPath[index] = PATH_SLASH_CHR;
863HRESULT PathCchConvertStyleW(PWSTR pszPath,
size_t cchPath,
unsigned long dwFlags)
865 if (dwFlags == PATH_STYLE_WINDOWS)
867 for (
size_t index = 0; index < cchPath; index++)
869 if (pszPath[index] == PATH_SLASH_CHR_W)
870 pszPath[index] = PATH_BACKSLASH_CHR_W;
873 else if (dwFlags == PATH_STYLE_UNIX)
875 for (
size_t index = 0; index < cchPath; index++)
877 if (pszPath[index] == PATH_BACKSLASH_CHR_W)
878 pszPath[index] = PATH_SLASH_CHR_W;
881 else if (dwFlags == PATH_STYLE_NATIVE)
883 if (PATH_SEPARATOR_CHR == PATH_BACKSLASH_CHR_W)
887 for (
size_t index = 0; index < cchPath; index++)
889 if (pszPath[index] == PATH_SLASH_CHR_W)
890 pszPath[index] = PATH_BACKSLASH_CHR_W;
893 else if (PATH_SEPARATOR_CHR == PATH_SLASH_CHR_W)
897 for (
size_t index = 0; index < cchPath; index++)
899 if (pszPath[index] == PATH_BACKSLASH_CHR_W)
900 pszPath[index] = PATH_SLASH_CHR_W;
922char PathGetSeparatorA(
unsigned long dwFlags)
924 char separator = PATH_SEPARATOR_CHR;
927 dwFlags = PATH_STYLE_NATIVE;
929 if (dwFlags == PATH_STYLE_WINDOWS)
930 separator = PATH_SEPARATOR_CHR;
931 else if (dwFlags == PATH_STYLE_UNIX)
932 separator = PATH_SEPARATOR_CHR;
933 else if (dwFlags == PATH_STYLE_NATIVE)
934 separator = PATH_SEPARATOR_CHR;
939WCHAR PathGetSeparatorW(
unsigned long dwFlags)
947 cnv.c[0] = PATH_SEPARATOR_CHR;
951 dwFlags = PATH_STYLE_NATIVE;
953 if (dwFlags == PATH_STYLE_WINDOWS)
954 cnv.c[0] = PATH_SEPARATOR_CHR;
955 else if (dwFlags == PATH_STYLE_UNIX)
956 cnv.c[0] = PATH_SEPARATOR_CHR;
957 else if (dwFlags == PATH_STYLE_NATIVE)
958 cnv.c[0] = PATH_SEPARATOR_CHR;
966static const CHAR SharedLibraryExtensionDllA[] =
"dll";
967static const CHAR SharedLibraryExtensionSoA[] =
"so";
968static const CHAR SharedLibraryExtensionDylibA[] =
"dylib";
970static const CHAR SharedLibraryExtensionDotDllA[] =
".dll";
971static const CHAR SharedLibraryExtensionDotSoA[] =
".so";
972static const CHAR SharedLibraryExtensionDotDylibA[] =
".dylib";
973PCSTR PathGetSharedLibraryExtensionA(
unsigned long dwFlags)
975 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT)
977 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
979 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
980 return SharedLibraryExtensionDotDllA;
982 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
983 return SharedLibraryExtensionDotSoA;
985 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
986 return SharedLibraryExtensionDotDylibA;
990 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
991 return SharedLibraryExtensionDllA;
993 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
994 return SharedLibraryExtensionSoA;
996 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
997 return SharedLibraryExtensionDylibA;
1001 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
1004 return SharedLibraryExtensionDotDllA;
1005#elif defined(__APPLE__)
1006 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1007 return SharedLibraryExtensionDotSoA;
1009 return SharedLibraryExtensionDotDylibA;
1011 return SharedLibraryExtensionDotSoA;
1017 return SharedLibraryExtensionDllA;
1018#elif defined(__APPLE__)
1019 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1020 return SharedLibraryExtensionSoA;
1022 return SharedLibraryExtensionDylibA;
1024 return SharedLibraryExtensionSoA;
1031PCWSTR PathGetSharedLibraryExtensionW(
unsigned long dwFlags)
1033 static WCHAR buffer[6][16] = { 0 };
1034 const WCHAR* SharedLibraryExtensionDotDllW = InitializeConstWCharFromUtf8(
1035 SharedLibraryExtensionDotDllA, buffer[0], ARRAYSIZE(buffer[0]));
1036 const WCHAR* SharedLibraryExtensionDotSoW =
1037 InitializeConstWCharFromUtf8(SharedLibraryExtensionDotSoA, buffer[1], ARRAYSIZE(buffer[1]));
1038 const WCHAR* SharedLibraryExtensionDotDylibW = InitializeConstWCharFromUtf8(
1039 SharedLibraryExtensionDotDylibA, buffer[2], ARRAYSIZE(buffer[2]));
1040 const WCHAR* SharedLibraryExtensionDllW =
1041 InitializeConstWCharFromUtf8(SharedLibraryExtensionDllA, buffer[3], ARRAYSIZE(buffer[3]));
1042 const WCHAR* SharedLibraryExtensionSoW =
1043 InitializeConstWCharFromUtf8(SharedLibraryExtensionSoA, buffer[4], ARRAYSIZE(buffer[4]));
1044 const WCHAR* SharedLibraryExtensionDylibW =
1045 InitializeConstWCharFromUtf8(SharedLibraryExtensionDylibA, buffer[5], ARRAYSIZE(buffer[5]));
1047 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT)
1049 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
1051 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
1052 return SharedLibraryExtensionDotDllW;
1054 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
1055 return SharedLibraryExtensionDotSoW;
1057 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
1058 return SharedLibraryExtensionDotDylibW;
1062 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DLL)
1063 return SharedLibraryExtensionDllW;
1065 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_SO)
1066 return SharedLibraryExtensionSoW;
1068 if (dwFlags & PATH_SHARED_LIB_EXT_EXPLICIT_DYLIB)
1069 return SharedLibraryExtensionDylibW;
1073 if (dwFlags & PATH_SHARED_LIB_EXT_WITH_DOT)
1076 return SharedLibraryExtensionDotDllW;
1077#elif defined(__APPLE__)
1078 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1079 return SharedLibraryExtensionDotSoW;
1081 return SharedLibraryExtensionDotDylibW;
1083 return SharedLibraryExtensionDotSoW;
1089 return SharedLibraryExtensionDllW;
1090#elif defined(__APPLE__)
1091 if (dwFlags & PATH_SHARED_LIB_EXT_APPLE_SO)
1092 return SharedLibraryExtensionSoW;
1094 return SharedLibraryExtensionDylibW;
1096 return SharedLibraryExtensionSoW;
1103const char* GetKnownPathIdString(
int id)
1107 case KNOWN_PATH_HOME:
1108 return "KNOWN_PATH_HOME";
1109 case KNOWN_PATH_TEMP:
1110 return "KNOWN_PATH_TEMP";
1111 case KNOWN_PATH_XDG_DATA_HOME:
1112 return "KNOWN_PATH_XDG_DATA_HOME";
1113 case KNOWN_PATH_XDG_CONFIG_HOME:
1114 return "KNOWN_PATH_XDG_CONFIG_HOME";
1115 case KNOWN_PATH_XDG_CACHE_HOME:
1116 return "KNOWN_PATH_XDG_CACHE_HOME";
1117 case KNOWN_PATH_XDG_RUNTIME_DIR:
1118 return "KNOWN_PATH_XDG_RUNTIME_DIR";
1119 case KNOWN_PATH_SYSTEM_CONFIG_HOME:
1120 return "KNOWN_PATH_SYSTEM_CONFIG_HOME";
1122 return "KNOWN_PATH_UNKNOWN_ID";
1126static char* concat(
const char* path,
size_t pathlen,
const char* name,
size_t namelen)
1128 const size_t strsize = pathlen + namelen + 2;
1129 char* str = calloc(strsize,
sizeof(
char));
1133 winpr_str_append(path, str, strsize,
"");
1134 winpr_str_append(name, str, strsize,
"");
1138BOOL winpr_RemoveDirectory_RecursiveA(LPCSTR lpPathName)
1145 const size_t pathnamelen = strlen(lpPathName);
1146 const size_t path_slash_len = pathnamelen + 3;
1147 char* path_slash = calloc(pathnamelen + 4,
sizeof(
char));
1150 strncat(path_slash, lpPathName, pathnamelen);
1152 const char star[] =
"*";
1153 const HRESULT hr = NativePathCchAppendA(path_slash, path_slash_len, star);
1154 HANDLE dir = INVALID_HANDLE_VALUE;
1160 dir = FindFirstFileA(path_slash, &findFileData);
1162 if (dir == INVALID_HANDLE_VALUE)
1166 path_slash[path_slash_len - 1] =
'\0';
1169 const size_t len = strnlen(findFileData.cFileName, ARRAYSIZE(findFileData.cFileName));
1171 if ((len == 1 && findFileData.cFileName[0] ==
'.') ||
1172 (len == 2 && findFileData.cFileName[0] ==
'.' && findFileData.cFileName[1] ==
'.'))
1177 char* fullpath = concat(path_slash, path_slash_len, findFileData.cFileName, len);
1181 if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1182 ret = winpr_RemoveDirectory_RecursiveA(fullpath);
1185 WINPR_PRAGMA_DIAG_PUSH
1186 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
1187 ret = DeleteFileA(fullpath);
1188 WINPR_PRAGMA_DIAG_POP
1195 }
while (ret && FindNextFileA(dir, &findFileData) != 0);
1200 WINPR_PRAGMA_DIAG_PUSH
1201 WINPR_PRAGMA_DIAG_IGNORED_DEPRECATED_DECL
1202 if (!RemoveDirectoryA(lpPathName))
1204 WINPR_PRAGMA_DIAG_POP
1213BOOL winpr_RemoveDirectory_RecursiveW(LPCWSTR lpPathName)
1215 char* name = ConvertWCharToUtf8Alloc(lpPathName, NULL);
1218 const BOOL rc = winpr_RemoveDirectory_RecursiveA(name);
1223char* winpr_GetConfigFilePathVA(BOOL system, WINPR_FORMAT_ARG
const char* filename, va_list ap)
1225 eKnownPathTypes
id = system ? KNOWN_PATH_SYSTEM_CONFIG_HOME : KNOWN_PATH_XDG_CONFIG_HOME;
1226 const char* vendor = winpr_getApplicationDetailsVendor();
1227 const char* product = winpr_getApplicationDetailsProduct();
1228 const SSIZE_T version = winpr_getApplicationDetailsVersion();
1230 if (!vendor || !product)
1233 char* config = GetKnownSubPathV(
id,
"%s", vendor);
1239 base = GetCombinedPathV(config,
"%s", product);
1241 base = GetCombinedPathV(config,
"%s%" PRIdz, product, version);
1246 char* path = GetCombinedPathVA(base, filename, ap);
1252char* winpr_GetConfigFilePath(BOOL system,
const char* filename)
1255 return winpr_GetConfigFilePathV(system,
"%s",
"");
1256 return winpr_GetConfigFilePathV(system,
"%s", filename);
1259char* winpr_GetConfigFilePathV(BOOL system,
const char* filename, ...)
1262 va_start(ap, filename);
1263 char* str = winpr_GetConfigFilePathVA(system, filename, ap);