FreeRDP
Loading...
Searching...
No Matches
PathAllocCombine.h
1
2/*
3#define DEFINE_UNICODE FALSE
4#define CUR_PATH_SEPARATOR_CHR '\\'
5#define CUR_PATH_SEPARATOR_STR "\\"
6#define PATH_ALLOC_COMBINE PathAllocCombineA
7*/
8
21#include <stdlib.h>
22#include <string.h>
23
24#include <winpr/wtypes.h>
25#include <winpr/string.h>
26#include <winpr/error.h>
27#include <winpr/wlog.h>
28
29#if DEFINE_UNICODE
30
31HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore,
32 WINPR_ATTR_UNUSED unsigned long dwFlags, PWSTR* ppszPathOut)
33{
34 WLog_WARN("TODO", "has known bugs and needs fixing.");
35
36 if (!ppszPathOut)
37 return E_INVALIDARG;
38
39 if (!pszPathIn && !pszMore)
40 return E_INVALIDARG;
41
42 if (!pszMore)
43 return E_FAIL; /* valid but not implemented, see top comment */
44
45 if (!pszPathIn)
46 return E_FAIL; /* valid but not implemented, see top comment */
47
48 const size_t pszPathInLength = _wcslen(pszPathIn);
49 const size_t pszMoreLength = _wcslen(pszMore);
50
51 /* prevent segfaults - the complete implementation below is buggy */
52 if (pszPathInLength < 3)
53 return E_FAIL;
54
55 const BOOL backslashIn =
56 (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
57 const BOOL backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
58
59 if (backslashMore)
60 {
61 if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
62 {
63 const WCHAR colon[] = { ':', '\0' };
64 const size_t pszPathOutLength = sizeof(WCHAR) + pszMoreLength;
65 const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
66 PWSTR pszPathOut = (PWSTR)calloc(sizeOfBuffer, sizeof(WCHAR));
67
68 if (!pszPathOut)
69 return E_OUTOFMEMORY;
70
71 _wcsncat(pszPathOut, &pszPathIn[0], 1);
72 _wcsncat(pszPathOut, colon, ARRAYSIZE(colon));
73 _wcsncat(pszPathOut, pszMore, pszMoreLength);
74 *ppszPathOut = pszPathOut;
75 return S_OK;
76 }
77 }
78 else
79 {
80 const size_t pszPathOutLength = pszPathInLength + pszMoreLength;
81 const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
82 PWSTR pszPathOut = (PWSTR)calloc(sizeOfBuffer, 2);
83
84 if (!pszPathOut)
85 return E_OUTOFMEMORY;
86
87 _wcsncat(pszPathOut, pszPathIn, pszPathInLength);
88 if (!backslashIn)
89 _wcsncat(pszPathOut, CUR_PATH_SEPARATOR_STR, ARRAYSIZE(CUR_PATH_SEPARATOR_STR));
90 _wcsncat(pszPathOut, pszMore, pszMoreLength);
91
92 *ppszPathOut = pszPathOut;
93 return S_OK;
94 }
95
96 return E_FAIL;
97}
98
99#else
100
101HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, WINPR_ATTR_UNUSED unsigned long dwFlags,
102 PSTR* ppszPathOut)
103{
104 WLog_WARN("TODO", "has known bugs and needs fixing.");
105
106 if (!ppszPathOut)
107 return E_INVALIDARG;
108
109 if (!pszPathIn && !pszMore)
110 return E_INVALIDARG;
111
112 if (!pszMore)
113 return E_FAIL; /* valid but not implemented, see top comment */
114
115 if (!pszPathIn)
116 return E_FAIL; /* valid but not implemented, see top comment */
117
118 const size_t pszPathInLength = strlen(pszPathIn);
119 const size_t pszMoreLength = strlen(pszMore);
120
121 /* prevent segfaults - the complete implementation below is buggy */
122 if (pszPathInLength < 3)
123 return E_FAIL;
124
125 const BOOL backslashIn =
126 (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
127 const BOOL backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
128
129 if (backslashMore)
130 {
131 if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
132 {
133 const size_t pszPathOutLength = 2 + pszMoreLength;
134 const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
135 PSTR pszPathOut = calloc(sizeOfBuffer, 2);
136
137 if (!pszPathOut)
138 return E_OUTOFMEMORY;
139
140 (void)sprintf_s(pszPathOut, sizeOfBuffer, "%c:%s", pszPathIn[0], pszMore);
141 *ppszPathOut = pszPathOut;
142 return S_OK;
143 }
144 }
145 else
146 {
147 const size_t pszPathOutLength = pszPathInLength + pszMoreLength;
148 const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
149 PSTR pszPathOut = calloc(sizeOfBuffer, 2);
150
151 if (!pszPathOut)
152 return E_OUTOFMEMORY;
153
154 if (backslashIn)
155 (void)sprintf_s(pszPathOut, sizeOfBuffer, "%s%s", pszPathIn, pszMore);
156 else
157 (void)sprintf_s(pszPathOut, sizeOfBuffer, "%s%s%s", pszPathIn, CUR_PATH_SEPARATOR_STR,
158 pszMore);
159
160 *ppszPathOut = pszPathOut;
161 return S_OK;
162 }
163
164 return E_FAIL;
165}
166
167#endif
168
169/*
170#undef DEFINE_UNICODE
171#undef CUR_PATH_SEPARATOR_CHR
172#undef CUR_PATH_SEPARATOR_STR
173#undef PATH_ALLOC_COMBINE
174*/