diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/pathutil.cpp')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/pathutil.cpp | 104 |
1 files changed, 74 insertions, 30 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp index 99be003c..a9a19b9f 100644 --- a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp | |||
@@ -157,11 +157,12 @@ DAPI_(HRESULT) PathExpand( | |||
157 | __in DWORD dwResolveFlags | 157 | __in DWORD dwResolveFlags |
158 | ) | 158 | ) |
159 | { | 159 | { |
160 | Assert(wzRelativePath && *wzRelativePath); | 160 | Assert(wzRelativePath); |
161 | 161 | ||
162 | HRESULT hr = S_OK; | 162 | HRESULT hr = S_OK; |
163 | DWORD cch = 0; | 163 | DWORD cch = 0; |
164 | LPWSTR sczExpandedPath = NULL; | 164 | LPWSTR sczExpandedPath = NULL; |
165 | SIZE_T cchWritten = 0; | ||
165 | DWORD cchExpandedPath = 0; | 166 | DWORD cchExpandedPath = 0; |
166 | SIZE_T cbSize = 0; | 167 | SIZE_T cbSize = 0; |
167 | 168 | ||
@@ -221,37 +222,12 @@ DAPI_(HRESULT) PathExpand( | |||
221 | // | 222 | // |
222 | if (dwResolveFlags & PATH_EXPAND_FULLPATH) | 223 | if (dwResolveFlags & PATH_EXPAND_FULLPATH) |
223 | { | 224 | { |
224 | LPWSTR wzFileName = NULL; | ||
225 | LPCWSTR wzPath = sczExpandedPath ? sczExpandedPath : wzRelativePath; | 225 | LPCWSTR wzPath = sczExpandedPath ? sczExpandedPath : wzRelativePath; |
226 | DWORD cchFullPath = max(PATH_GOOD_ENOUGH, cchExpandedPath); | ||
227 | 226 | ||
228 | hr = StrAlloc(&sczFullPath, cchFullPath); | 227 | hr = PathGetFullPathName(wzPath, &sczFullPath, NULL, &cchWritten); |
229 | PathExitOnFailure(hr, "Failed to allocate space for full path."); | 228 | PathExitOnFailure(hr, "Failed to get full path for string: %ls", wzPath); |
230 | |||
231 | cch = ::GetFullPathNameW(wzPath, cchFullPath, sczFullPath, &wzFileName); | ||
232 | if (0 == cch) | ||
233 | { | ||
234 | PathExitWithLastError(hr, "Failed to get full path for string: %ls", wzPath); | ||
235 | } | ||
236 | else if (cchFullPath < cch) | ||
237 | { | ||
238 | cchFullPath = cch < MAX_PATH ? cch : cch + 7; // ensure space for "\\?\UNC" prefix if needed | ||
239 | hr = StrAlloc(&sczFullPath, cchFullPath); | ||
240 | PathExitOnFailure(hr, "Failed to re-allocate more space for full path."); | ||
241 | 229 | ||
242 | cch = ::GetFullPathNameW(wzPath, cchFullPath, sczFullPath, &wzFileName); | 230 | if (MAX_PATH < cchWritten) |
243 | if (0 == cch) | ||
244 | { | ||
245 | PathExitWithLastError(hr, "Failed to get full path for string: %ls", wzPath); | ||
246 | } | ||
247 | else if (cchFullPath < cch) | ||
248 | { | ||
249 | hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); | ||
250 | PathExitOnRootFailure(hr, "Failed to allocate buffer for full path."); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | if (MAX_PATH < cch) | ||
255 | { | 231 | { |
256 | hr = PathPrefix(&sczFullPath); | 232 | hr = PathPrefix(&sczFullPath); |
257 | PathExitOnFailure(hr, "Failed to prefix long path after expanding."); | 233 | PathExitOnFailure(hr, "Failed to prefix long path after expanding."); |
@@ -263,7 +239,7 @@ DAPI_(HRESULT) PathExpand( | |||
263 | sczExpandedPath = NULL; | 239 | sczExpandedPath = NULL; |
264 | } | 240 | } |
265 | 241 | ||
266 | hr = StrAllocString(psczFullPath, sczFullPath? sczFullPath : wzRelativePath, 0); | 242 | hr = StrAllocString(psczFullPath, sczFullPath ? sczFullPath : wzRelativePath, 0); |
267 | PathExitOnFailure(hr, "Failed to copy relative path into full path."); | 243 | PathExitOnFailure(hr, "Failed to copy relative path into full path."); |
268 | 244 | ||
269 | LExit: | 245 | LExit: |
@@ -274,6 +250,74 @@ LExit: | |||
274 | } | 250 | } |
275 | 251 | ||
276 | 252 | ||
253 | DAPI_(HRESULT) PathGetFullPathName( | ||
254 | __in_z LPCWSTR wzPath, | ||
255 | __deref_out_z LPWSTR* psczFullPath, | ||
256 | __inout_z_opt LPCWSTR* pwzFileName, | ||
257 | __out_opt SIZE_T* pcch | ||
258 | ) | ||
259 | { | ||
260 | HRESULT hr = S_OK; | ||
261 | SIZE_T cchMax = 0; | ||
262 | DWORD cchBuffer = 0; | ||
263 | DWORD cch = 0; | ||
264 | DWORD dwAttempts = 0; | ||
265 | const DWORD dwMaxAttempts = 10; | ||
266 | |||
267 | if (!wzPath || !*wzPath) | ||
268 | { | ||
269 | hr = DirGetCurrent(psczFullPath, pcch); | ||
270 | PathExitOnFailure(hr, "Failed to get current directory."); | ||
271 | |||
272 | ExitFunction(); | ||
273 | } | ||
274 | |||
275 | if (*psczFullPath) | ||
276 | { | ||
277 | hr = StrMaxLength(*psczFullPath, &cchMax); | ||
278 | PathExitOnFailure(hr, "Failed to get max length of input buffer."); | ||
279 | |||
280 | cchBuffer = (DWORD)min(DWORD_MAX, cchMax); | ||
281 | } | ||
282 | else | ||
283 | { | ||
284 | cchBuffer = MAX_PATH + 1; | ||
285 | |||
286 | hr = StrAlloc(psczFullPath, cchBuffer); | ||
287 | PathExitOnFailure(hr, "Failed to allocate space for full path."); | ||
288 | } | ||
289 | |||
290 | for (; dwAttempts < dwMaxAttempts; ++dwAttempts) | ||
291 | { | ||
292 | cch = ::GetFullPathNameW(wzPath, cchBuffer, *psczFullPath, const_cast<LPWSTR*>(pwzFileName)); | ||
293 | PathExitOnNullWithLastError(cch, hr, "Failed to get full path for string: %ls", wzPath); | ||
294 | |||
295 | if (cch < cchBuffer) | ||
296 | { | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | hr = StrAlloc(psczFullPath, cch); | ||
301 | PathExitOnFailure(hr, "Failed to reallocate space for full path."); | ||
302 | |||
303 | cchBuffer = cch; | ||
304 | } | ||
305 | |||
306 | if (dwMaxAttempts == dwAttempts) | ||
307 | { | ||
308 | PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "GetFullPathNameW results never converged."); | ||
309 | } | ||
310 | |||
311 | if (pcch) | ||
312 | { | ||
313 | *pcch = cch; | ||
314 | } | ||
315 | |||
316 | LExit: | ||
317 | return hr; | ||
318 | } | ||
319 | |||
320 | |||
277 | DAPI_(HRESULT) PathPrefix( | 321 | DAPI_(HRESULT) PathPrefix( |
278 | __inout LPWSTR *psczFullPath | 322 | __inout LPWSTR *psczFullPath |
279 | ) | 323 | ) |