Skip to content

Commit

Permalink
Create til::env to help with refreshing environment variables (#14839)
Browse files Browse the repository at this point in the history
Adds a helper that replicates how the `RegenerateUserEnvironment()`
method in `shell32.dll` behaves.

* Raises #12516 from the dead.
* Half of #1125

Co-authored-by: Michael Niksa <[email protected]>
  • Loading branch information
ianjoneill and miniksa authored Mar 13, 2023
1 parent fe2220e commit eb871bf
Show file tree
Hide file tree
Showing 6 changed files with 689 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .github/actions/spelling/allow/microsoft.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ appxbundle
appxerror
appxmanifest
ATL
autoexec
backplating
bitmaps
BOMs
COMPUTERNAME
CPLs
cpptools
cppvsdbg
Expand All @@ -26,6 +28,7 @@ dotnetfeed
DTDs
DWINRT
enablewttlogging
HOMESHARE
Intelli
IVisual
libucrt
Expand Down Expand Up @@ -59,6 +62,7 @@ SACLs
segoe
sdkddkver
Shobjidl
sid
Skype
SRW
sxs
Expand All @@ -71,6 +75,7 @@ tdbuildteamid
ucrt
ucrtd
unvirtualized
USERDNSDOMAIN
VCRT
vcruntime
Virtualization
Expand Down
579 changes: 579 additions & 0 deletions src/inc/til/env.h

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions src/til/ut_til/EnvTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "precomp.h"

#include "til/env.h"

using namespace WEX::Common;
using namespace WEX::Logging;
using namespace WEX::TestExecution;

BOOL APIENTRY RegenerateUserEnvironment(void** pNewEnv, BOOL bSetCurrentEnv);

class EnvTests
{
TEST_CLASS(EnvTests);

TEST_METHOD(Construct)
{
til::env environment;
}

TEST_METHOD(Generate)
{
// Be sneaky and pull the method that @eryksun told us about to see if we've effectively recreated it.
wil::unique_hmodule shell32{ LoadLibraryW(L"shell32.dll") };
auto func = GetProcAddressByFunctionDeclaration(shell32.get(), RegenerateUserEnvironment);

// Use a WIL pointer to free it on scope exit.
wil::unique_environstrings_ptr newEnv;
VERIFY_WIN32_BOOL_SUCCEEDED(func((void**)&newEnv, FALSE));

// Parse the string into our environment table.
til::env expected{ newEnv.get() };

// Set up an empty table and tell it to generate the environment with a similar algorithm.
til::env actual;
actual.regenerate();

VERIFY_ARE_EQUAL(expected.as_map().size(), actual.as_map().size());
for (const auto& [expectedKey, expectedValue] : expected.as_map())
{
Log::Comment(String().Format(L"Environment Variable: '%s'", expectedKey.data()));
const auto actualValue = actual.as_map()[expectedKey];
VERIFY_IS_TRUE(actual.as_map().find(expectedKey) != actual.as_map().end());
VERIFY_ARE_EQUAL(expectedValue, actual.as_map()[expectedKey]);
}
}

TEST_METHOD(ToString)
{
til::env environment;
environment.as_map().insert_or_assign(L"A", L"Apple");
environment.as_map().insert_or_assign(L"B", L"Banana");
environment.as_map().insert_or_assign(L"C", L"Cassowary");

wchar_t expectedArray[] = L"A=Apple\0B=Banana\0C=Cassowary\0";

const std::wstring expected{ expectedArray, ARRAYSIZE(expectedArray) };
const auto& actual = environment.to_string();

VERIFY_ARE_EQUAL(expected.size(), actual.size());
for (size_t i = 0; i < expected.size(); ++i)
{
VERIFY_ARE_EQUAL(expected[i], actual[i]);
}
}

TEST_METHOD(TestExpandEnvironmentStrings)
{
{
til::env environment;
environment.as_map().insert_or_assign(L"ENV", L"Bar");

VERIFY_ARE_EQUAL(L"FooBarBaz", environment.expand_environment_strings(L"Foo%ENV%Baz"));
}

{
til::env environment;

VERIFY_ARE_EQUAL(L"Foo%ENV%Baz", environment.expand_environment_strings(L"Foo%ENV%Baz"));
}

{
til::env environment;

VERIFY_ARE_EQUAL(L"Foo%ENV", environment.expand_environment_strings(L"Foo%ENV"));
}
}
};
1 change: 1 addition & 0 deletions src/til/ut_til/sources
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SOURCES = \
CoalesceTests.cpp \
ColorTests.cpp \
EnumSetTests.cpp \
EnvTests.cpp \
HashTests.cpp \
MathTests.cpp \
mutex.cpp \
Expand Down
10 changes: 9 additions & 1 deletion src/til/ut_til/til.unit.tests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<ClCompile Include="CoalesceTests.cpp" />
<ClCompile Include="ColorTests.cpp" />
<ClCompile Include="EnumSetTests.cpp" />
<ClCompile Include="EnvTests.cpp" />
<ClCompile Include="HashTests.cpp" />
<ClCompile Include="MathTests.cpp" />
<ClCompile Include="mutex.cpp" />
Expand All @@ -45,6 +46,7 @@
<ClInclude Include="..\..\inc\til\coalesce.h" />
<ClInclude Include="..\..\inc\til\color.h" />
<ClInclude Include="..\..\inc\til\enumset.h" />
<ClInclude Include="..\..\inc\til\env.h" />
<ClInclude Include="..\..\inc\til\hash.h" />
<ClInclude Include="..\..\inc\til\latch.h" />
<ClInclude Include="..\..\inc\til\math.h" />
Expand Down Expand Up @@ -73,8 +75,14 @@
<AdditionalIncludeDirectories>..;$(SolutionDir)src\inc;$(SolutionDir)src\inc\test;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<!-- subsume fmt, one of our dependencies, into contypes. -->
<ProjectReference Include="..\..\dep\fmt\fmt.vcxproj">
<Project>{6bae5851-50d5-4934-8d5e-30361a8a40f3}</Project>
</ProjectReference>
</ItemGroup>
<!-- Careful reordering these. Some default props (contained in these files) are order sensitive. -->
<Import Project="$(SolutionDir)src\common.build.post.props" />
<Import Project="$(SolutionDir)src\common.build.tests.props" />
<Import Project="$(SolutionDir)src\common.nugetversions.targets" />
</Project>
</Project>
6 changes: 5 additions & 1 deletion src/til/ut_til/til.unit.tests.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<ClCompile Include="string.cpp" />
<ClCompile Include="throttled_func.cpp" />
<ClCompile Include="u8u16convertTests.cpp" />
<ClCompile Include="EnvTests.cpp" />
<ClCompile Include="UnicodeTests.cpp" />
</ItemGroup>
<ItemGroup>
Expand All @@ -51,6 +52,9 @@
<ClInclude Include="..\..\inc\til\enumset.h">
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\til\env.h">
<Filter>inc</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\til\hash.h">
<Filter>inc</Filter>
</ClInclude>
Expand Down Expand Up @@ -120,4 +124,4 @@
<UniqueIdentifier>{7cf29ba4-d33d-4c3b-82e3-ab73e5a79685}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
</Project>

0 comments on commit eb871bf

Please sign in to comment.