REG_EXPAND_SZ values are not necessarily a path.
Sean Hall committed
Jun 3, 2022 at 17:49 UTC
266b097c0b0a13dd4934f55f61cad62ffcbb953d
13 files changed
+211
-32
src/libs/dutil/WixToolset.DUtil/dutil.vcxproj
+2
@@ -65,6 +65,7 @@
65
<PrecompiledHeader>Create</PrecompiledHeader>
66
<DisableSpecificWarnings>4091;4458</DisableSpecificWarnings>
67
</ClCompile>
68
+ <ClCompile Include="envutil.cpp" />
69
<ClCompile Include="eseutil.cpp" />
70
<ClCompile Include="file2utl.cpp" />
71
<ClCompile Include="fileutil.cpp" />
@@ -130,6 +131,7 @@
131
<ClInclude Include="inc\dpiutil.h" />
132
<ClInclude Include="inc\dutil.h" />
133
<ClInclude Include="inc\dutilsources.h" />
134
+ <ClInclude Include="inc\envutil.h" />
135
<ClInclude Include="inc\eseutil.h" />
136
<ClInclude Include="inc\fileutil.h" />
137
<ClInclude Include="inc\gdiputil.h" />
src/libs/dutil/WixToolset.DUtil/dutil.vcxproj.filters
+6
@@ -66,6 +66,9 @@
66
<ClCompile Include="dutil.cpp">
67
<Filter>Source Files</Filter>
68
</ClCompile>
69
+ <ClCompile Include="envutil.cpp">
70
+ <Filter>Source Files</Filter>
71
+ </ClCompile>
72
<ClCompile Include="eseutil.cpp">
73
<Filter>Source Files</Filter>
74
</ClCompile>
@@ -251,6 +254,9 @@
254
<ClInclude Include="inc\dutilsources.h">
255
<Filter>Header Files</Filter>
256
</ClInclude>
257
+ <ClInclude Include="inc\envutil.h">
258
+ <Filter>Header Files</Filter>
259
+ </ClInclude>
260
<ClInclude Include="inc\eseutil.h">
261
<Filter>Header Files</Filter>
262
</ClInclude>
src/libs/dutil/WixToolset.DUtil/envutil.cpp
new
+78
@@ -0,0 +1,78 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+#include "precomp.h"
4
+
5
+
6
+// Exit macros
7
+#define EnvExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__)
8
+#define EnvExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__)
9
+#define EnvExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__)
10
+#define EnvExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__)
11
+#define EnvExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__)
12
+#define EnvExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_ENVUTIL, x, e, s, __VA_ARGS__)
13
+#define EnvExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_ENVUTIL, x, s, __VA_ARGS__)
14
+#define EnvExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_ENVUTIL, p, x, e, s, __VA_ARGS__)
15
+#define EnvExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_ENVUTIL, p, x, s, __VA_ARGS__)
16
+#define EnvExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_ENVUTIL, p, x, e, s, __VA_ARGS__)
17
+#define EnvExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_ENVUTIL, p, x, s, __VA_ARGS__)
18
+#define EnvExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_ENVUTIL, e, x, s, __VA_ARGS__)
19
+#define EnvExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_ENVUTIL, g, x, s, __VA_ARGS__)
20
+
21
+#define ENV_GOOD_ENOUGH 64
22
+
23
+DAPI_(HRESULT) EnvExpandEnvironmentStrings(
24
+ __in LPCWSTR wzSource,
25
+ __out LPWSTR* psczExpanded,
26
+ __out_opt SIZE_T* pcchExpanded
27
+ )
28
+{
29
+ HRESULT hr = S_OK;
30
+ DWORD cch = 0;
31
+ DWORD cchExpanded = 0;
32
+ SIZE_T cchMax = 0;
33
+
34
+ if (*psczExpanded)
35
+ {
36
+ hr = StrMaxLength(*psczExpanded, &cchMax);
37
+ EnvExitOnFailure(hr, "Failed to get max length of input buffer.");
38
+
39
+ cchExpanded = (DWORD)min(DWORD_MAX, cchMax);
40
+ }
41
+ else
42
+ {
43
+ cchExpanded = ENV_GOOD_ENOUGH;
44
+
45
+ hr = StrAlloc(psczExpanded, cchExpanded);
46
+ EnvExitOnFailure(hr, "Failed to allocate space for expanded path.");
47
+ }
48
+
49
+ cch = ::ExpandEnvironmentStringsW(wzSource, *psczExpanded, cchExpanded);
50
+ if (!cch)
51
+ {
52
+ EnvExitWithLastError(hr, "Failed to expand environment variables in string: %ls", wzSource);
53
+ }
54
+ else if (cchExpanded < cch)
55
+ {
56
+ cchExpanded = cch;
57
+ hr = StrAlloc(psczExpanded, cchExpanded);
58
+ EnvExitOnFailure(hr, "Failed to re-allocate more space for expanded path.");
59
+
60
+ cch = ::ExpandEnvironmentStringsW(wzSource, *psczExpanded, cchExpanded);
61
+ if (!cch)
62
+ {
63
+ EnvExitWithLastError(hr, "Failed to expand environment variables in string: %ls", wzSource);
64
+ }
65
+ else if (cchExpanded < cch)
66
+ {
67
+ EnvExitWithRootFailure(hr, HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Failed to allocate buffer for expanded string.");
68
+ }
69
+ }
70
+
71
+ if (pcchExpanded)
72
+ {
73
+ *pcchExpanded = cch;
74
+ }
75
+
76
+LExit:
77
+ return hr;
78
+}
src/libs/dutil/WixToolset.DUtil/inc/dutilsources.h
+1
@@ -62,6 +62,7 @@ typedef enum DUTIL_SOURCE
62
DUTIL_SOURCE_XMLUTIL,
63
DUTIL_SOURCE_VERUTIL,
64
DUTIL_SOURCE_WNDUTIL,
65
+ DUTIL_SOURCE_ENVUTIL,
66
67
DUTIL_SOURCE_EXTERNAL = 256,
68
} DUTIL_SOURCE;
src/libs/dutil/WixToolset.DUtil/inc/envutil.h
new
+22
@@ -0,0 +1,22 @@
1
+#pragma once
2
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
3
+
4
+
5
+#ifdef __cplusplus
6
+extern "C" {
7
+#endif
8
+
9
+/********************************************************************
10
+ EnvExpandEnvironmentStrings - Wrapper for ::ExpandEnvironmentStrings.
11
+
12
+ *******************************************************************/
13
+HRESULT DAPI EnvExpandEnvironmentStrings(
14
+ __in LPCWSTR wzSource,
15
+ __out LPWSTR* psczExpanded,
16
+ __out_opt SIZE_T* pcchExpanded
17
+ );
18
+
19
+#ifdef __cplusplus
20
+}
21
+#endif
22
+
src/libs/dutil/WixToolset.DUtil/pathutil.cpp
+2
-31
@@ -181,10 +181,8 @@ DAPI_(HRESULT) PathExpand(
181
Assert(wzRelativePath);
182
183
HRESULT hr = S_OK;
184
- DWORD cch = 0;
184
LPWSTR sczExpandedPath = NULL;
185
SIZE_T cchWritten = 0;
187
- DWORD cchExpandedPath = 0;
186
LPWSTR sczFullPath = NULL;
187
DWORD dwPrefixFlags = 0;
188
@@ -193,35 +191,8 @@ DAPI_(HRESULT) PathExpand(
191
//
192
if (dwResolveFlags & PATH_EXPAND_ENVIRONMENT)
193
{
196
- cchExpandedPath = PATH_GOOD_ENOUGH;
197
-
198
- hr = StrAlloc(&sczExpandedPath, cchExpandedPath);
199
- PathExitOnFailure(hr, "Failed to allocate space for expanded path.");
200
-
201
- cch = ::ExpandEnvironmentStringsW(wzRelativePath, sczExpandedPath, cchExpandedPath);
202
- if (0 == cch)
203
- {
204
- PathExitWithLastError(hr, "Failed to expand environment variables in string: %ls", wzRelativePath);
205
- }
206
- else if (cchExpandedPath < cch)
207
- {
208
- cchExpandedPath = cch;
209
- hr = StrAlloc(&sczExpandedPath, cchExpandedPath);
210
- PathExitOnFailure(hr, "Failed to re-allocate more space for expanded path.");
211
-
212
- cch = ::ExpandEnvironmentStringsW(wzRelativePath, sczExpandedPath, cchExpandedPath);
213
- if (0 == cch)
214
- {
215
- PathExitWithLastError(hr, "Failed to expand environment variables in string: %ls", wzRelativePath);
216
- }
217
- else if (cchExpandedPath < cch)
218
- {
219
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
220
- PathExitOnRootFailure(hr, "Failed to allocate buffer for expanded path.");
221
- }
222
- }
223
-
224
- cchWritten = cch;
194
+ hr = EnvExpandEnvironmentStrings(wzRelativePath, &sczExpandedPath, &cchWritten);
195
+ PathExitOnFailure(hr, "Failed to expand environment variables in string: %ls", wzRelativePath);
196
}
197
198
//
src/libs/dutil/WixToolset.DUtil/precomp.h
+1
@@ -52,6 +52,7 @@
52
#include "cabutil.h"
53
#include "conutil.h"
54
#include "cryputil.h"
55
+#include "envutil.h"
56
#include "eseutil.h"
57
#include "dirutil.h"
58
#include "dlutil.h"
src/libs/dutil/WixToolset.DUtil/regutil.cpp
+1
-1
@@ -444,7 +444,7 @@ DAPI_(HRESULT) RegReadValue(
444
if (fExpand && SUCCEEDED(hr) && REG_EXPAND_SZ == *pdwType)
445
{
446
LPWSTR sczValue = reinterpret_cast<LPWSTR>(*ppbBuffer);
447
- hr = PathExpand(&sczExpand, sczValue, PATH_EXPAND_ENVIRONMENT);
447
+ hr = EnvExpandEnvironmentStrings(sczValue, &sczExpand, NULL);
448
RegExitOnFailure(hr, "Failed to expand registry value: %ls", sczValue);
449
450
*ppbBuffer = reinterpret_cast<LPBYTE>(sczExpand);
src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj
+1
@@ -49,6 +49,7 @@
49
<ClCompile Include="DictUtilTest.cpp" />
50
<ClCompile Include="DirUtilTests.cpp" />
51
<ClCompile Include="DUtilTests.cpp" />
52
+ <ClCompile Include="EnvUtilTests.cpp" />
53
<ClCompile Include="error.cpp" />
54
<ClCompile Include="FileUtilTest.cpp" />
55
<ClCompile Include="GuidUtilTest.cpp" />
src/libs/dutil/test/DUtilUnitTest/DUtilUnitTest.vcxproj.filters
+3
@@ -30,6 +30,9 @@
30
<ClCompile Include="DUtilTests.cpp">
31
<Filter>Source Files</Filter>
32
</ClCompile>
33
+ <ClCompile Include="EnvUtilTests.cpp">
34
+ <Filter>Source Files</Filter>
35
+ </ClCompile>
36
<ClCompile Include="error.cpp">
37
<Filter>Source Files</Filter>
38
</ClCompile>
src/libs/dutil/test/DUtilUnitTest/EnvUtilTests.cpp
new
+50
@@ -0,0 +1,50 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+#include "precomp.h"
4
+
5
+using namespace System;
6
+using namespace Xunit;
7
+using namespace WixBuildTools::TestSupport;
8
+
9
+namespace DutilTests
10
+{
11
+ public ref class EnvUtil
12
+ {
13
+ public:
14
+ [Fact]
15
+ void EnvExpandEnvironmentStringsTest()
16
+ {
17
+ HRESULT hr = S_OK;
18
+ LPWSTR sczExpanded = NULL;
19
+ SIZE_T cchExpanded = 0;
20
+ LPCWSTR wzSimpleString = L"%USERPROFILE%";
21
+ LPCWSTR wzMultipleString = L"%TEMP%;%PATH%";
22
+ LPCWSTR wzLongMultipleString = L"%TEMP%;%PATH%;C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789";
23
+ String^ expandedSimpleString = Environment::ExpandEnvironmentVariables(gcnew String(wzSimpleString));
24
+ String^ expandedMultipleString = Environment::ExpandEnvironmentVariables(gcnew String(wzMultipleString));
25
+ String^ expandedLongMultipleString = Environment::ExpandEnvironmentVariables(gcnew String(wzLongMultipleString));
26
+
27
+ try
28
+ {
29
+ hr = EnvExpandEnvironmentStrings(wzSimpleString, &sczExpanded, &cchExpanded);
30
+ NativeAssert::Succeeded(hr, "Failed to expand simple string.");
31
+ WixAssert::StringEqual(expandedSimpleString, gcnew String(sczExpanded), false);
32
+ NativeAssert::Equal<SIZE_T>(expandedSimpleString->Length + 1, cchExpanded);
33
+
34
+ hr = EnvExpandEnvironmentStrings(wzMultipleString, &sczExpanded, &cchExpanded);
35
+ NativeAssert::Succeeded(hr, "Failed to expand multiple string.");
36
+ WixAssert::StringEqual(expandedMultipleString, gcnew String(sczExpanded), false);
37
+ NativeAssert::Equal<SIZE_T>(expandedMultipleString->Length + 1, cchExpanded);
38
+
39
+ hr = EnvExpandEnvironmentStrings(wzLongMultipleString, &sczExpanded, &cchExpanded);
40
+ NativeAssert::Succeeded(hr, "Failed to expand long multiple string.");
41
+ WixAssert::StringEqual(expandedLongMultipleString, gcnew String(sczExpanded), false);
42
+ NativeAssert::Equal<SIZE_T>(expandedLongMultipleString->Length + 1, cchExpanded);
43
+ }
44
+ finally
45
+ {
46
+ ReleaseStr(sczExpanded);
47
+ }
48
+ }
49
+ };
50
+}
src/libs/dutil/test/DUtilUnitTest/RegUtilTest.cpp
+43
@@ -207,6 +207,49 @@ namespace DutilTests
207
}
208
}
209
210
+ [Fact]
211
+ void RegUtilExpandLongStringValueTest()
212
+ {
213
+ this->ExpandLongStringValueTest();
214
+ }
215
+
216
+ [Fact]
217
+ void RegUtilExpandLongStringValueFallbackTest()
218
+ {
219
+ RegFunctionForceFallback();
220
+ this->ExpandLongStringValueTest();
221
+ }
222
+
223
+ void ExpandLongStringValueTest()
224
+ {
225
+ HRESULT hr = S_OK;
226
+ LPWSTR sczValue = NULL;
227
+ LPCWSTR wzValue = L"%TEMP%;%PATH%;C:\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789\\abcdefghijklomnopqrstuvwxyz0123456789";
228
+ String^ expandedValue = Environment::ExpandEnvironmentVariables(gcnew String(wzValue));
229
+
230
+ try
231
+ {
232
+ this->CreateBaseKey();
233
+
234
+ hr = RegWriteExpandString(hkBase, L"ExpandString", wzValue);
235
+ NativeAssert::Succeeded(hr, "Failed to write expand string value.");
236
+
237
+ hr = RegReadString(hkBase, L"ExpandString", &sczValue);
238
+ NativeAssert::Succeeded(hr, "Failed to read expand string value.");
239
+ WixAssert::StringEqual(expandedValue, gcnew String(sczValue), false);
240
+
241
+ ReleaseNullStr(sczValue);
242
+
243
+ hr = RegReadString(hkBase, L"ExpandString", &sczValue);
244
+ NativeAssert::Succeeded(hr, "Failed to read expand string value.");
245
+ WixAssert::StringEqual(expandedValue, gcnew String(sczValue), false);
246
+ }
247
+ finally
248
+ {
249
+ ReleaseStr(sczValue);
250
+ }
251
+ }
252
+
253
[Fact]
254
void RegUtilNotExpandStringValueTest()
255
{
src/libs/dutil/test/DUtilUnitTest/precomp.h
+1
@@ -15,6 +15,7 @@
15
#include <atomutil.h>
16
#include <dictutil.h>
17
#include <dirutil.h>
18
+#include <envutil.h>
19
#include <fileutil.h>
20
#include <guidutil.h>
21
#include <iniutil.h>