FreeRDP
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 
30 HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags,
31  PWSTR* ppszPathOut)
32 {
33  WLog_WARN(TAG, "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 
101 HRESULT PATH_ALLOC_COMBINE(PCSTR pszPathIn, PCSTR pszMore, unsigned long dwFlags, PSTR* ppszPathOut)
102 {
103  WLog_WARN(TAG, "has known bugs and needs fixing.");
104 
105  if (!ppszPathOut)
106  return E_INVALIDARG;
107 
108  if (!pszPathIn && !pszMore)
109  return E_INVALIDARG;
110 
111  if (!pszMore)
112  return E_FAIL; /* valid but not implemented, see top comment */
113 
114  if (!pszPathIn)
115  return E_FAIL; /* valid but not implemented, see top comment */
116 
117  const size_t pszPathInLength = strlen(pszPathIn);
118  const size_t pszMoreLength = strlen(pszMore);
119 
120  /* prevent segfaults - the complete implementation below is buggy */
121  if (pszPathInLength < 3)
122  return E_FAIL;
123 
124  const BOOL backslashIn =
125  (pszPathIn[pszPathInLength - 1] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
126  const BOOL backslashMore = (pszMore[0] == CUR_PATH_SEPARATOR_CHR) ? TRUE : FALSE;
127 
128  if (backslashMore)
129  {
130  if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
131  {
132  const size_t pszPathOutLength = 2 + pszMoreLength;
133  const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
134  PSTR pszPathOut = calloc(sizeOfBuffer, 2);
135 
136  if (!pszPathOut)
137  return E_OUTOFMEMORY;
138 
139  sprintf_s(pszPathOut, sizeOfBuffer, "%c:%s", pszPathIn[0], pszMore);
140  *ppszPathOut = pszPathOut;
141  return S_OK;
142  }
143  }
144  else
145  {
146  const size_t pszPathOutLength = pszPathInLength + pszMoreLength;
147  const size_t sizeOfBuffer = (pszPathOutLength + 1) * 2;
148  PSTR pszPathOut = calloc(sizeOfBuffer, 2);
149 
150  if (!pszPathOut)
151  return E_OUTOFMEMORY;
152 
153  if (backslashIn)
154  sprintf_s(pszPathOut, sizeOfBuffer, "%s%s", pszPathIn, pszMore);
155  else
156  sprintf_s(pszPathOut, sizeOfBuffer, "%s" CUR_PATH_SEPARATOR_STR "%s", pszPathIn,
157  pszMore);
158 
159  *ppszPathOut = pszPathOut;
160  return S_OK;
161  }
162 
163  return E_FAIL;
164 }
165 
166 #endif
167 
168 /*
169 #undef DEFINE_UNICODE
170 #undef CUR_PATH_SEPARATOR_CHR
171 #undef CUR_PATH_SEPARATOR_STR
172 #undef PATH_ALLOC_COMBINE
173 */