summaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/path2utl.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/path2utl.cpp145
1 files changed, 133 insertions, 12 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
index 3c4b2f88..862a743d 100644
--- a/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/path2utl.cpp
@@ -19,6 +19,65 @@
19#define PathExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_PATHUTIL, g, x, s, __VA_ARGS__) 19#define PathExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_PATHUTIL, g, x, s, __VA_ARGS__)
20 20
21 21
22typedef HRESULT(WINAPI* PFN_PATH_ALLOC_CANONICALIZE)(
23 __in LPCWSTR wzSource,
24 __in DWORD dwFlags,
25 __out_z LPWSTR* psczPathOut
26 );
27
28static BOOL vfInitialized = FALSE;
29static HMODULE vhPathApiSet_1_1_0 = NULL;
30static PFN_PATH_ALLOC_CANONICALIZE vpfnPathAllocCanonicalize = NULL;
31static BOOL vfForceFallback = FALSE;
32
33// from PathCch.h
34#ifndef PATHCCH_ALLOW_LONG_PATHS
35#define PATHCCH_ALLOW_LONG_PATHS 0x01
36#endif
37
38static HRESULT Initialize()
39{
40 HRESULT hr = S_OK;
41 DWORD er = ERROR_SUCCESS;
42
43 if (vfInitialized)
44 {
45 ExitFunction();
46 }
47
48 hr = LoadSystemApiSet(L"api-ms-win-core-path-l1-1-0.dll", &vhPathApiSet_1_1_0);
49 if (E_MODNOTFOUND == hr)
50 {
51 hr = E_NOTIMPL;
52 }
53 PathExitOnFailure(hr, "Failed to load api-ms-win-core-path-l1-1-0.dll");
54
55 vpfnPathAllocCanonicalize = reinterpret_cast<PFN_PATH_ALLOC_CANONICALIZE>(::GetProcAddress(vhPathApiSet_1_1_0, "PathAllocCanonicalize"));
56 if (!vpfnPathAllocCanonicalize)
57 {
58 er = ::GetLastError();
59 PathExitWithRootFailure(hr, ERROR_PROC_NOT_FOUND == er ? E_NOTIMPL : HRESULT_FROM_WIN32(er), "Failed to get address of PathAllocCanonicalize.");
60 }
61
62 vfInitialized = TRUE;
63
64LExit:
65 return hr;
66}
67
68
69DAPI_(void) Path2FunctionAllowFallback()
70{
71 vfForceFallback = FALSE;
72}
73
74
75DAPI_(void) Path2FunctionForceFallback()
76{
77 vfForceFallback = TRUE;
78}
79
80
22DAPI_(HRESULT) PathCanonicalizePath( 81DAPI_(HRESULT) PathCanonicalizePath(
23 __in_z LPCWSTR wzPath, 82 __in_z LPCWSTR wzPath,
24 __deref_out_z LPWSTR* psczCanonicalized 83 __deref_out_z LPWSTR* psczCanonicalized
@@ -43,6 +102,37 @@ LExit:
43 return hr; 102 return hr;
44} 103}
45 104
105DAPI_(HRESULT) PathAllocCanonicalizePath(
106 __in_z LPCWSTR wzPath,
107 __in DWORD dwFlags,
108 __deref_out_z LPWSTR* psczCanonicalized
109 )
110{
111 HRESULT hr = S_OK;
112 LPWSTR sczCanonicalizedPath = NULL;
113
114 hr = Initialize();
115 if (E_NOTIMPL == hr || SUCCEEDED(hr) && !vpfnPathAllocCanonicalize)
116 {
117 ExitFunction1(hr = E_NOTIMPL);
118 }
119 PathExitOnFailure(hr, "Failed to initialize path2utl.");
120
121 hr = vpfnPathAllocCanonicalize(wzPath, dwFlags, &sczCanonicalizedPath);
122 PathExitOnFailure(hr, "Failed to canonicalize: %ls", wzPath);
123
124 hr = StrAllocString(psczCanonicalized, sczCanonicalizedPath, 0);
125 PathExitOnFailure(hr, "Failed to copy the canonicalized path.");
126
127LExit:
128 if (sczCanonicalizedPath)
129 {
130 ::LocalFree(sczCanonicalizedPath);
131 }
132
133 return hr;
134}
135
46DAPI_(HRESULT) PathCanonicalizeForComparison( 136DAPI_(HRESULT) PathCanonicalizeForComparison(
47 __in_z LPCWSTR wzPath, 137 __in_z LPCWSTR wzPath,
48 __in DWORD dwCanonicalizeFlags, 138 __in DWORD dwCanonicalizeFlags,
@@ -75,7 +165,19 @@ DAPI_(HRESULT) PathCanonicalizeForComparison(
75 165
76 if (*wzNormalizedPath) 166 if (*wzNormalizedPath)
77 { 167 {
78 hr = PathCanonicalizePath(wzNormalizedPath, psczCanonicalized); 168 if (!vfForceFallback)
169 {
170 hr = PathAllocCanonicalizePath(wzNormalizedPath, PATHCCH_ALLOW_LONG_PATHS, psczCanonicalized);
171 }
172 else
173 {
174 hr = E_NOTIMPL;
175 }
176
177 if (E_NOTIMPL == hr)
178 {
179 hr = PathCanonicalizePath(wzNormalizedPath, psczCanonicalized);
180 }
79 PathExitOnFailure(hr, "Failed to canonicalize: %ls", wzNormalizedPath); 181 PathExitOnFailure(hr, "Failed to canonicalize: %ls", wzNormalizedPath);
80 } 182 }
81 else 183 else
@@ -273,33 +375,52 @@ DAPI_(HRESULT) PathSystemWindowsSubdirectory(
273 ) 375 )
274{ 376{
275 HRESULT hr = S_OK; 377 HRESULT hr = S_OK;
276 WCHAR wzTempPath[MAX_PATH + 1] = { }; 378 LPWSTR sczWindowsPath = NULL;
379 DWORD cchBuffer = MAX_PATH + 1;
277 DWORD cch = 0; 380 DWORD cch = 0;
278 381
279 cch = ::GetSystemWindowsDirectoryW(wzTempPath, countof(wzTempPath)); 382 hr = StrAlloc(&sczWindowsPath, cchBuffer);
280 if (!cch) 383 PathExitOnFailure(hr, "Failed to alloc Windows directory path.");
281 { 384
282 PathExitWithLastError(hr, "Failed to get Windows directory path."); 385 cch = ::GetSystemWindowsDirectoryW(sczWindowsPath, cchBuffer);
283 } 386 PathExitOnNullWithLastError(cch, hr, "Failed to get Windows directory path with default size.");
284 else if (cch >= countof(wzTempPath)) 387
388 cch += 1; // add 1 for null terminator.
389
390 if (cch > cchBuffer)
285 { 391 {
286 PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "Windows directory path too long."); 392 hr = StrAlloc(&sczWindowsPath, cch);
393 PathExitOnFailure(hr, "Failed to realloc Windows directory path.");
394
395 cchBuffer = cch;
396
397 cch = ::GetSystemWindowsDirectoryW(sczWindowsPath, cchBuffer);
398 PathExitOnNullWithLastError(cch, hr, "Failed to get Windows directory path with returned size.");
399
400 cch += 1; // add 1 for null terminator.
401
402 if (cch > cchBuffer)
403 {
404 PathExitWithRootFailure(hr, E_INSUFFICIENT_BUFFER, "Failed to get Windows directory path with returned size.");
405 }
287 } 406 }
288 407
289 if (wzSubdirectory) 408 if (wzSubdirectory)
290 { 409 {
291 hr = PathConcatRelativeToBase(wzTempPath, wzSubdirectory, psczFullPath); 410 hr = PathConcatRelativeToBase(sczWindowsPath, wzSubdirectory, psczFullPath);
292 PathExitOnFailure(hr, "Failed to concat subdirectory on Windows directory path."); 411 PathExitOnFailure(hr, "Failed to concat subdirectory on Windows directory path.");
293 } 412 }
294 else 413 else
295 { 414 {
296 hr = StrAllocString(psczFullPath, wzTempPath, 0); 415 *psczFullPath = sczWindowsPath;
297 PathExitOnFailure(hr, "Failed to copy Windows directory path."); 416 sczWindowsPath = NULL;
298 } 417 }
299 418
300 hr = PathBackslashTerminate(psczFullPath); 419 hr = PathBackslashTerminate(psczFullPath);
301 PathExitOnFailure(hr, "Failed to terminate Windows directory path with backslash."); 420 PathExitOnFailure(hr, "Failed to terminate Windows directory path with backslash.");
302 421
303LExit: 422LExit:
423 ReleaseStr(sczWindowsPath);
424
304 return hr; 425 return hr;
305} 426}