FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
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/error.h>
26#include <winpr/wlog.h>
27
28#if DEFINE_UNICODE
29
30HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore,
31 WINPR_ATTR_UNUSED unsigned long dwFlags, PWSTR* ppszPathOut)
32{
33 WLog_WARN("TODO", "has known bugs and needs fixing.");
34
35 if (!ppszPathOut)
36 return E_INVALIDARG;
37
38 if (!pszPathIn && !pszMore)
39 return E_INVALIDARG;
40
41 if (!pszMore)
42 return E_FAIL; /* valid but not implemented, see top comment */
43
44 if (!pszPathIn)
45 return E_FAIL; /* valid but not implemented, see top comment */
46
47 const size_t pszPathInLength = _wcslen(pszPathIn);
48 const size_t pszMoreLength = _wcslen(pszMore);
49
50 /* prevent segfaults - the complete implementation below is buggy */
51 if (pszPathInLength < 3)
52 return E_FAIL;
53
54 const BOOL backslashIn =
55 (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
56 const BOOL backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
57
58 if (backslashMore)
59 {
60 if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
61 {
62 const WCHAR colon[] = { ':', '\0' };
63 const size_t pszPathOutLength = sizeof(WCHAR) + pszMoreLength;
64 const size_t sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
65 PWSTR pszPathOut = (PWSTR)calloc(sizeOfBuffer, sizeof(WCHAR));
66
67 if (!pszPathOut)
68 return E_OUTOFMEMORY;
69
70 _wcsncat(pszPathOut, &pszPathIn[0], 1);
71 _wcsncat(pszPathOut, colon, ARRAYSIZE(colon));
72 _wcsncat(pszPathOut, pszMore, pszMoreLength);
73 *ppszPathOut = pszPathOut;
74 return S_OK;
75 }
76 }
77 else
78 {
79 const WCHAR sep[] = CUR_PATH_SEPARATOR_STR;
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, sep, ARRAYSIZE(sep));
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 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 sprintf_s(pszPathOut, sizeOfBuffer, "%s%s", pszPathIn, pszMore);
156 else
157 sprintf_s(pszPathOut, sizeOfBuffer, "%s" CUR_PATH_SEPARATOR_STR "%s", pszPathIn,
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*/