Repository: RetroAchievements/RAIntegration
Pull request #862 (2022-01-27 21:25:11)

make v141_xp not required for regressions
The github hosted regression environment no longer provides access to VS2019. VS2022 doesn't provide v141_xp support. This makes the default builds use v142, but leaves a v141_xp project for doing XP-compatible builds for the release.


Patch:
diff --git a/RA_Integration.sln b/RA_Integration.sln
index 1280a162..beb79f1c 100644
--- a/RA_Integration.sln
+++ b/RA_Integration.sln
@@ -1,7 +1,7 @@
 ﻿
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26403.7
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32106.194
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RA_Integration", "src\RA_Integration.vcxproj", "{825CB292-F069-4B27-82CF-3417746ACDF3}"
 EndProject
@@ -28,6 +28,8 @@ Global
 		Release|x64 = Release|x64
 		ReleaseWithDebug|Win32 = ReleaseWithDebug|Win32
 		ReleaseWithDebug|x64 = ReleaseWithDebug|x64
+		Release-xp|Win32 = Release-xp|Win32
+		Release-xp|x64 = Release-xp|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{825CB292-F069-4B27-82CF-3417746ACDF3}.Analysis|Win32.ActiveCfg = Analysis|Win32
@@ -46,6 +48,10 @@ Global
 		{825CB292-F069-4B27-82CF-3417746ACDF3}.ReleaseWithDebug|Win32.Build.0 = ReleaseWithDebug|Win32
 		{825CB292-F069-4B27-82CF-3417746ACDF3}.ReleaseWithDebug|x64.ActiveCfg = ReleaseWithDebug|x64
 		{825CB292-F069-4B27-82CF-3417746ACDF3}.ReleaseWithDebug|x64.Build.0 = ReleaseWithDebug|x64
+		{825CB292-F069-4B27-82CF-3417746ACDF3}.Release-xp|Win32.ActiveCfg = Release-xp|Win32
+		{825CB292-F069-4B27-82CF-3417746ACDF3}.Release-xp|Win32.Build.0 = Release-xp|Win32
+		{825CB292-F069-4B27-82CF-3417746ACDF3}.Release-xp|x64.ActiveCfg = Release-xp|x64
+		{825CB292-F069-4B27-82CF-3417746ACDF3}.Release-xp|x64.Build.0 = Release-xp|x64
 		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.Analysis|Win32.ActiveCfg = Analysis|Win32
 		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.Analysis|Win32.Build.0 = Analysis|Win32
 		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.Analysis|x64.ActiveCfg = Analysis|x64
@@ -62,6 +68,10 @@ Global
 		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.ReleaseWithDebug|Win32.Build.0 = Release|Win32
 		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.ReleaseWithDebug|x64.ActiveCfg = Release|x64
 		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.ReleaseWithDebug|x64.Build.0 = Release|x64
+		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.Release-xp|Win32.ActiveCfg = Release-xp|Win32
+		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.Release-xp|Win32.Build.0 = Release-xp|Win32
+		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.Release-xp|x64.ActiveCfg = Release-xp|x64
+		{876DEBDF-C7C8-4713-8CEF-EBDEE65306A7}.Release-xp|x64.Build.0 = Release-xp|x64
 		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.Analysis|Win32.ActiveCfg = Release|Win32
 		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.Analysis|Win32.Build.0 = Release|Win32
 		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.Analysis|x64.ActiveCfg = Release|x64
@@ -78,6 +88,10 @@ Global
 		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.ReleaseWithDebug|Win32.Build.0 = Release|Win32
 		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.ReleaseWithDebug|x64.ActiveCfg = Release|x64
 		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.ReleaseWithDebug|x64.Build.0 = Release|x64
+		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.Release-xp|Win32.ActiveCfg = Release|Win32
+		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.Release-xp|Win32.Build.0 = Release|Win32
+		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.Release-xp|x64.ActiveCfg = Release|x64
+		{9D55EBE7-1392-4FA1-A9B9-F022F764CE35}.Release-xp|x64.Build.0 = Release|x64
 		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.Analysis|Win32.ActiveCfg = Release|Win32
 		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.Analysis|x64.ActiveCfg = Release|x64
 		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.Analysis|x64.Build.0 = Release|x64
@@ -93,6 +107,10 @@ Global
 		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.ReleaseWithDebug|Win32.Build.0 = Release|Win32
 		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.ReleaseWithDebug|x64.ActiveCfg = Release|x64
 		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.ReleaseWithDebug|x64.Build.0 = Release|x64
+		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.Release-xp|Win32.ActiveCfg = Release-xp|Win32
+		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.Release-xp|Win32.Build.0 = Release-xp|Win32
+		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.Release-xp|x64.ActiveCfg = Release-xp|x64
+		{F78C2C8B-55DD-4252-A38F-F4D252D14DF8}.Release-xp|x64.Build.0 = Release-xp|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/src/Exports.cpp b/src/Exports.cpp
index 2136d314..349b3d38 100644
--- a/src/Exports.cpp
+++ b/src/Exports.cpp
@@ -457,7 +457,7 @@ static void ProcessAchievements()
                     {
                         ra::services::ServiceLocator::Get<ra::services::IAudioSystem>().PlayAudioFile(L"Overlay\\lb.wav");
                         auto& pOverlayManager = ra::services::ServiceLocator::GetMutable<ra::ui::viewmodels::OverlayManager>();
-                        const int nPopup = pOverlayManager.QueueMessage(ra::ui::viewmodels::Popup::LeaderboardStarted,
+                        pOverlayManager.QueueMessage(ra::ui::viewmodels::Popup::LeaderboardStarted,
                             L"Leaderboard attempt started", pLeaderboard->GetName(), pLeaderboard->GetDescription());
                     }
 
@@ -501,7 +501,7 @@ static void ProcessAchievements()
                         ra::services::ServiceLocator::Get<ra::services::IAudioSystem>().PlayAudioFile(L"Overlay\\lbcancel.wav");
 
                         auto& pOverlayManager = ra::services::ServiceLocator::GetMutable<ra::ui::viewmodels::OverlayManager>();
-                        const int nPopup = pOverlayManager.QueueMessage(ra::ui::viewmodels::Popup::LeaderboardCanceled,
+                        pOverlayManager.QueueMessage(ra::ui::viewmodels::Popup::LeaderboardCanceled,
                             L"Leaderboard attempt failed", pLeaderboard->GetName(), pLeaderboard->GetDescription());
                     }
 
diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj
index 4bf578a8..76c3cd4e 100644
--- a/src/RA_Integration.vcxproj
+++ b/src/RA_Integration.vcxproj
@@ -17,6 +17,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release-xp|Win32">
+      <Configuration>Release-xp</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release-xp|x64">
+      <Configuration>Release-xp</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="ReleaseWithDebug|Win32">
       <Configuration>ReleaseWithDebug</Configuration>
       <Platform>Win32</Platform>
@@ -63,7 +71,9 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Analysis|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Analysis|x64'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebug|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebug|x64'">Create</PrecompiledHeader>
     </ClCompile>
@@ -354,6 +364,7 @@
     <ResourceCompile Include="RA_Version.rc">
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_DEBUG;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_USING_V110_SDK71_;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">_USING_V110_SDK71_;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
   </ItemGroup>
   <ItemGroup>
@@ -375,12 +386,24 @@
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <PlatformToolset>v141_xp</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <PlatformToolset>v141_xp</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
@@ -388,24 +411,24 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebug|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v141_xp</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebug|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v141_xp</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v141_xp</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v141_xp</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Analysis|Win32'" Label="Configuration">
@@ -425,10 +448,18 @@
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="base.props" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="base.props" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="base.props" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="base.props" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="base.props" />
@@ -493,12 +524,24 @@
     <LinkIncremental>false</LinkIncremental>
     <TargetName>RA_Integration</TargetName>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>RA_Integration</TargetName>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
     <TargetName>RA_Integration</TargetName>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
     <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>RA_Integration</TargetName>
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebug|Win32'">
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
     <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
@@ -523,10 +566,9 @@
       <ShowIncludes>false</ShowIncludes>
       <ConformanceMode>true</ConformanceMode>
       <EnablePREfast>false</EnablePREfast>
-      <AdditionalOptions>/w45045 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
@@ -548,10 +590,9 @@
       <ShowIncludes>false</ShowIncludes>
       <ConformanceMode>true</ConformanceMode>
       <EnablePREfast>false</EnablePREfast>
-      <AdditionalOptions>/w45045 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
@@ -576,7 +617,7 @@
       <TreatWarningAsError>true</TreatWarningAsError>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
@@ -604,7 +645,7 @@
       <TreatWarningAsError>true</TreatWarningAsError>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
@@ -629,10 +670,28 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <ConformanceMode>true</ConformanceMode>
-      <AdditionalOptions>/w45045 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <PreprocessorDefinitions>NDEBUG;RA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>false</GenerateDebugInformation>
@@ -649,10 +708,28 @@
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <ConformanceMode>true</ConformanceMode>
-      <AdditionalOptions>/w45045 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">
+    <ClCompile>
+      <Optimization>Full</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <PreprocessorDefinitions>NDEBUG;RA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>false</GenerateDebugInformation>
@@ -673,7 +750,7 @@
       <LinkTimeCodeGeneration>UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
@@ -694,7 +771,7 @@
       <LinkTimeCodeGeneration>UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>windowscodecs.lib;winmm.lib;Winhttp.lib;user32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
diff --git a/src/RA_Shared.rc b/src/RA_Shared.rc
index 21d80025..cb18360a 100644
--- a/src/RA_Shared.rc
+++ b/src/RA_Shared.rc
@@ -7,7 +7,8 @@
 //
 // Generated from the TEXTINCLUDE 2 resource.
 //
-#include "afxres.h"
+#include "winresrc.h"
+#define IDC_STATIC -1
 
 /////////////////////////////////////////////////////////////////////////////
 #undef APSTUDIO_READONLY_SYMBOLS
@@ -550,7 +551,8 @@ END
 
 2 TEXTINCLUDE 
 BEGIN
-    "#include ""afxres.h""\r\n"
+    "#include ""winresrc.h""\r\n"
+    "#define IDC_STATIC -1"\r\n
     "\0"
 END
 
diff --git a/src/data/context/EmulatorContext.cpp b/src/data/context/EmulatorContext.cpp
index 89b15e32..39875dce 100644
--- a/src/data/context/EmulatorContext.cpp
+++ b/src/data/context/EmulatorContext.cpp
@@ -239,12 +239,14 @@ bool EmulatorContext::ValidateClientVersion(bool& bHardcore)
             sMinimumVersion = response.MinimumVersion;
             nMinimumVersion = ParseVersion(response.MinimumVersion.c_str());
 
+#ifndef RA_UTEST
             const unsigned long long nServerVersion = ParseVersion(m_sLatestVersion.c_str());
             const unsigned long long nLocalVersion = ParseVersion(m_sVersion.c_str());
             RA_LOG_INFO("Client %s date: server %s, current %s",
                    (nLocalVersion >= nServerVersion) ? "up to" : "out of",
                    m_sLatestVersion,
                    m_sVersion);
+#endif
         }
 
         if (m_nEmulatorId == EmulatorID::RA_Gens)
@@ -607,7 +609,6 @@ bool EmulatorContext::HasInvalidRegions() const noexcept
 
 bool EmulatorContext::IsValidAddress(ra::ByteAddress nAddress) const noexcept
 {
-    const ra::ByteAddress nOriginalAddress = nAddress;
     for (const auto& pBlock : m_vMemoryBlocks)
     {
         if (nAddress < pBlock.size)
diff --git a/src/data/context/GameAssets.cpp b/src/data/context/GameAssets.cpp
index de67fbf9..3268cf30 100644
--- a/src/data/context/GameAssets.cpp
+++ b/src/data/context/GameAssets.cpp
@@ -126,7 +126,7 @@ void GameAssets::ReloadAssets(const std::vector<ra::data::models::AssetModelBase
         BeginUpdate();
         for (auto* pAsset : vAssetsToReload)
         {
-            if (pAsset->GetCategory() != ra::data::models::AssetCategory::Local)
+            if (pAsset != nullptr && pAsset->GetCategory() != ra::data::models::AssetCategory::Local)
                 pAsset->RestoreServerCheckpoint();
         }
         EndUpdate();
@@ -202,7 +202,7 @@ void GameAssets::ReloadAssets(const std::vector<ra::data::models::AssetModelBase
             for (auto pIter = vRemainingAssetsToReload.begin(); pIter != vRemainingAssetsToReload.end(); ++pIter)
             {
                 auto* pAssetToReset = *pIter;
-                if (pAssetToReset->GetID() == nId && pAssetToReset->GetType() == nType)
+                if (pAssetToReset != nullptr && pAssetToReset->GetID() == nId && pAssetToReset->GetType() == nType)
                 {
                     pAsset = pAssetToReset;
                     vRemainingAssetsToReload.erase(pIter);
@@ -261,12 +261,18 @@ void GameAssets::ReloadAssets(const std::vector<ra::data::models::AssetModelBase
 
     // assign IDs for any assets where one was not available
     for (auto* pAsset : vUnnumberedAssets)
-        pAsset->SetID(m_nNextLocalId++);
+    {
+        if (pAsset != nullptr)
+            pAsset->SetID(m_nNextLocalId++);
+    }
 
     // any items still in the source list no longer exist in the file. if the item is on the server,
     // just reset to the server state. otherwise, delete the item.
     for (auto* pAsset : vRemainingAssetsToReload)
     {
+        if (pAsset == nullptr)
+            continue;
+
         if (pAsset->GetCategory() == ra::data::models::AssetCategory::Local)
         {
             for (gsl::index nIndex = gsl::narrow_cast<gsl::index>(Count()) - 1; nIndex >= 0; --nIndex)
diff --git a/src/data/models/AchievementModel.cpp b/src/data/models/AchievementModel.cpp
index 40f85e72..5985b83f 100644
--- a/src/data/models/AchievementModel.cpp
+++ b/src/data/models/AchievementModel.cpp
@@ -251,6 +251,7 @@ bool AchievementModel::Deserialize(ra::Tokenizer& pTokenizer)
         // unquoted trigger requires special parsing because flags also use colons
         const char* pTrigger = pTokenizer.GetPointer(pTokenizer.CurrentPosition());
         const char* pScan = pTrigger;
+        Expects(pScan != nullptr);
         while (*pScan && (*pScan != ':' || strchr("ABCMNOPRTabcmnoprt", pScan[-1]) != nullptr))
             pScan++;
 
diff --git a/src/pch.h b/src/pch.h
index 02ed11f3..7767b580 100644
--- a/src/pch.h
+++ b/src/pch.h
@@ -16,7 +16,9 @@
 #include "windows_nodefines.h"
 #include <ShlObj.h> // CommCtrl
 #include <WindowsX.h>
-#include <atlbase.h> // atldef.h (Windows.h), atlcore.h (tchar.h), Shlwapi.h
+#include <Windows.h>
+#include <tchar.h>
+#include <Shlwapi.h>
 #include <direct.h>
 #include <io.h>
 #include <wincodec.h>
diff --git a/src/services/AchievementRuntime.cpp b/src/services/AchievementRuntime.cpp
index 977df9f0..0a9dc706 100644
--- a/src/services/AchievementRuntime.cpp
+++ b/src/services/AchievementRuntime.cpp
@@ -794,6 +794,7 @@ bool AchievementRuntime::LoadProgressFromFile(const char* sLoadStateFilename)
     for (gsl::index nIndex = 0; nIndex < gsl::narrow_cast<gsl::index>(pGameContext.Assets().Count()); ++nIndex)
     {
         auto* pAsset = pGameContext.Assets().GetItemAt(nIndex);
+        Expects(pAsset != nullptr);
         switch (pAsset->GetType())
         {
             case ra::data::models::AssetType::Achievement:
diff --git a/src/services/SearchResults.cpp b/src/services/SearchResults.cpp
index 88874e92..e1183679 100644
--- a/src/services/SearchResults.cpp
+++ b/src/services/SearchResults.cpp
@@ -1709,7 +1709,6 @@ bool SearchResults::GetBytes(ra::ByteAddress nAddress, unsigned char* pBuffer, s
 {
     if (m_pImpl != nullptr)
     {
-        const unsigned int nPadding = m_pImpl->GetPadding();
         for (auto& block : m_vBlocks)
         {
             if (block.GetFirstAddress() > nAddress)
diff --git a/src/ui/drawing/gdi/ImageRepository.cpp b/src/ui/drawing/gdi/ImageRepository.cpp
index 6604cb3f..f6c108b3 100644
--- a/src/ui/drawing/gdi/ImageRepository.cpp
+++ b/src/ui/drawing/gdi/ImageRepository.cpp
@@ -21,7 +21,7 @@ namespace gdi {
 inline constexpr const char* DefaultBadge{ "00000" };
 inline constexpr const char* DefaultUserPic{ "_User" };
 
-static CComPtr<IWICImagingFactory> g_pIWICFactory;
+static IWICImagingFactory* g_pIWICFactory = nullptr;
 
 bool ImageRepository::Initialize()
 {
@@ -73,7 +73,8 @@ ImageRepository::~ImageRepository() noexcept
         DeleteBitmap(userPic.second.m_hBitmap);
     m_mUserPics.clear();
 
-    g_pIWICFactory.Release();
+    if (g_pIWICFactory != nullptr)
+        g_pIWICFactory->Release();
 
     if (m_bShutdownCOM)
         CoUninitialize();
@@ -264,12 +265,13 @@ HBITMAP ImageRepository::GetDefaultImage(ImageType nType)
     }
 }
 
+GSL_SUPPRESS_F23
 static HRESULT ConvertBitmapSource(_In_ RECT rcDest, _In_ IWICBitmapSource* pOriginalBitmapSource, _Inout_ IWICBitmapSource*& pToRenderBitmapSource)
 {
     pToRenderBitmapSource = nullptr;
 
     // Create a BitmapScaler
-    CComPtr<IWICBitmapScaler> pScaler;
+    IWICBitmapScaler* pScaler = nullptr;
     auto hr = g_pIWICFactory->CreateBitmapScaler(&pScaler);
 
     // Initialize the bitmap scaler from the original bitmap map bits
@@ -284,29 +286,34 @@ static HRESULT ConvertBitmapSource(_In_ RECT rcDest, _In_ IWICBitmapSource* pOri
     // Convert the bitmap into 32bppBGR, a convenient pixel format for GDI rendering 
     if (SUCCEEDED(hr))
     {
-        CComPtr<IWICFormatConverter> pConverter;
+        IWICFormatConverter* pConverter = nullptr;
         hr = g_pIWICFactory->CreateFormatConverter(&pConverter);
 
         // Format convert to 32bppBGR
         if (SUCCEEDED(hr))
         {
-            hr = pConverter->Initialize(static_cast<IWICBitmapSource*>(pScaler), // Input bitmap to convert
+            hr = pConverter->Initialize(pScaler,            // Input bitmap to convert
                 GUID_WICPixelFormat32bppBGR,                // &GUID_WICPixelFormat32bppBGR,
                 WICBitmapDitherTypeNone,                    // Specified dither pattern
                 nullptr,                                    // Specify a particular palette 
-                0.f,                                        // Alpha threshold
+                0.0f,                                       // Alpha threshold
                 WICBitmapPaletteTypeCustom);                // Palette translation type
 
             // Store the converted bitmap as ppToRenderBitmapSource 
             if (SUCCEEDED(hr))
+            {
                 GSL_SUPPRESS_TYPE1
                 pConverter->QueryInterface(IID_IWICBitmapSource, reinterpret_cast<void**>(&pToRenderBitmapSource));
+            }
         }
 
-        pConverter.Release();
+        if (pConverter != nullptr)
+            pConverter->Release();
     }
 
-    pScaler.Release();
+    if (pScaler != nullptr)
+        pScaler->Release();
+
     return hr;
 }
 
@@ -389,13 +396,14 @@ static HRESULT CreateDIBFromBitmapSource(_In_ IWICBitmapSource* pToRenderBitmapS
     return hr;
 }
 
+GSL_SUPPRESS_F23
 HBITMAP ImageRepository::LoadLocalPNG(const std::wstring& sFilename, unsigned int nWidth, unsigned int nHeight)
 {
     if (g_pIWICFactory == nullptr)
         return nullptr;
 
     // Decode the source image to IWICBitmapSource
-    CComPtr<IWICBitmapDecoder> pDecoder;
+    IWICBitmapDecoder* pDecoder = nullptr;
     HRESULT hr = g_pIWICFactory->CreateDecoderFromFilename(ra::Widen(sFilename).c_str(), // Image to be decoded
                                                            nullptr,      // Do not prefer a particular vendor
                                                            GENERIC_READ, // Desired read access to the file
@@ -403,12 +411,12 @@ HBITMAP ImageRepository::LoadLocalPNG(const std::wstring& sFilename, unsigned in
                                                            &pDecoder);                     // Pointer to the decoder
 
     // Retrieve the first frame of the image from the decoder
-    CComPtr<IWICBitmapFrameDecode> pFrame;
+    IWICBitmapFrameDecode* pFrame = nullptr;
     if (SUCCEEDED(hr))
         hr = pDecoder->GetFrame(0, &pFrame);
 
     // Retrieve IWICBitmapSource from the frame
-    CComPtr<IWICBitmapSource> pOriginalBitmapSource;
+    IWICBitmapSource* pOriginalBitmapSource = nullptr;
     if (SUCCEEDED(hr))
     {
         GSL_SUPPRESS_TYPE1
@@ -421,7 +429,7 @@ HBITMAP ImageRepository::LoadLocalPNG(const std::wstring& sFilename, unsigned in
     }
 
     // Scale the original IWICBitmapSource to the client rect size and convert the pixel format
-    CComPtr<IWICBitmapSource> pToRenderBitmapSource;
+    IWICBitmapSource* pToRenderBitmapSource = nullptr;
     if (SUCCEEDED(hr))
         hr = ConvertBitmapSource({0, 0, to_signed(nWidth), to_signed(nHeight)}, pOriginalBitmapSource,
                                  *&pToRenderBitmapSource);
@@ -431,10 +439,17 @@ HBITMAP ImageRepository::LoadLocalPNG(const std::wstring& sFilename, unsigned in
     if (SUCCEEDED(hr))
         hr = CreateDIBFromBitmapSource(pToRenderBitmapSource, hBitmap);
 
-    pToRenderBitmapSource.Release();
-    pOriginalBitmapSource.Release();
-    pFrame.Release();
-    pDecoder.Release();
+    if (pToRenderBitmapSource != nullptr)
+        pToRenderBitmapSource->Release();
+
+    if (pOriginalBitmapSource != nullptr)
+        pOriginalBitmapSource->Release();
+
+    if (pFrame != nullptr)
+        pFrame->Release();
+
+    if (pDecoder != nullptr)
+        pDecoder->Release();
 
     return hBitmap;
 }
@@ -583,6 +598,7 @@ bool ImageRepository::HasReferencedImageChanged(ImageReference& pImage) const
     return (pImage.m_nData != hBitmapBefore);
 }
 
+GSL_SUPPRESS_F23
 bool GDISurfaceFactory::SaveImage(const ISurface& pSurface, const std::wstring& sPath) const
 {
     if (g_pIWICFactory == nullptr)
@@ -596,11 +612,11 @@ bool GDISurfaceFactory::SaveImage(const ISurface& pSurface, const std::wstring&
         return false;
 
     // create a PNG encoder
-    CComPtr<IWICBitmapEncoder> pEncoder;
+    IWICBitmapEncoder* pEncoder = nullptr;
     HRESULT hr = g_pIWICFactory->CreateEncoder(GUID_ContainerFormatPng, nullptr, &pEncoder);
 
     // open the file stream
-    CComPtr<IWICStream> pStream;
+    IWICStream* pStream = nullptr;
     if (SUCCEEDED(hr))
         hr = g_pIWICFactory->CreateStream(&pStream);
 
@@ -611,7 +627,7 @@ bool GDISurfaceFactory::SaveImage(const ISurface& pSurface, const std::wstring&
         hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache);
 
     // convert the image to a WICBitmap
-    CComPtr<IWICBitmapFrameEncode> pFrameEncode;
+    IWICBitmapFrameEncode* pFrameEncode = nullptr;
     if (SUCCEEDED(hr))
         hr = pEncoder->CreateNewFrame(&pFrameEncode, nullptr);
 
@@ -626,7 +642,7 @@ bool GDISurfaceFactory::SaveImage(const ISurface& pSurface, const std::wstring&
     if (SUCCEEDED(hr))
         hr = pFrameEncode->SetPixelFormat(&pixelFormat);
 
-    CComPtr<IWICBitmap> pWicBitmap;
+    IWICBitmap* pWicBitmap = nullptr;
     if (SUCCEEDED(hr))
         hr = g_pIWICFactory->CreateBitmapFromHBITMAP(pGDIBitmapSurface->GetHBitmap(), nullptr, WICBitmapIgnoreAlpha, &pWicBitmap);
 
@@ -643,6 +659,18 @@ bool GDISurfaceFactory::SaveImage(const ISurface& pSurface, const std::wstring&
     if (!SUCCEEDED(hr))
         RA_LOG_WARN("Error %08x saving %s", hr, sPath);
 
+    if (pWicBitmap != nullptr)
+        pWicBitmap->Release();
+
+    if (pFrameEncode != nullptr)
+        pFrameEncode->Release();
+
+    if (pStream != nullptr)
+        pStream->Release();
+
+    if (pEncoder != nullptr)
+        pEncoder->Release();
+
     return SUCCEEDED(hr);
 }
 
diff --git a/src/ui/viewmodels/AssetListViewModel.cpp b/src/ui/viewmodels/AssetListViewModel.cpp
index 0fab0a8a..8180cf44 100644
--- a/src/ui/viewmodels/AssetListViewModel.cpp
+++ b/src/ui/viewmodels/AssetListViewModel.cpp
@@ -134,6 +134,7 @@ void AssetListViewModel::OnDataModelIntValueChanged(gsl::index nIndex, const Int
     {
         const auto& pGameContext = ra::services::ServiceLocator::Get<ra::data::context::GameContext>();
         const auto* pAsset = pGameContext.Assets().GetItemAt(nIndex);
+        Expects(pAsset != nullptr);
         const auto* pAchievement = dynamic_cast<const ra::data::models::AchievementModel*>(pAsset);
         if (pAchievement != nullptr && GetFilteredAssetIndex(*pAsset) >= 0)
         {
@@ -155,6 +156,7 @@ void AssetListViewModel::OnDataModelIntValueChanged(gsl::index nIndex, const Int
         {
             const auto& pGameContext = ra::services::ServiceLocator::Get<ra::data::context::GameContext>();
             const auto* pAsset = pGameContext.Assets().GetItemAt(nIndex);
+            Expects(pAsset != nullptr);
             switch (pAsset->GetType())
             {
                 case ra::data::models::AssetType::Achievement:
@@ -179,7 +181,8 @@ void AssetListViewModel::OnDataModelIntValueChanged(gsl::index nIndex, const Int
             // if KeepActive is selected, set a Triggered achievement back to Waiting
             auto& pGameContext = ra::services::ServiceLocator::GetMutable<ra::data::context::GameContext>();
             auto* pAsset = pGameContext.Assets().GetItemAt(nIndex);
-            pAsset->SetState(ra::data::models::AssetState::Waiting);
+            if (pAsset != nullptr)
+                pAsset->SetState(ra::data::models::AssetState::Waiting);
 
             // SetState is re-entrant - we don't want to do any further processing with the previous new value
             return;
@@ -501,8 +504,6 @@ bool AssetListViewModel::AddOrRemoveFilteredItem(const ra::data::models::AssetMo
     {
         if (nIndex >= 0)
         {
-            const bool bIsSelected = m_vFilteredAssets.GetItemValue(nIndex, AssetSummaryViewModel::IsSelectedProperty);
-
             m_vFilteredAssets.RemoveAt(nIndex);
             return true;
         }
@@ -617,7 +618,6 @@ void AssetListViewModel::DoUpdateButtons()
     bool bHasUnofficial = false;
     bool bHasCore = false;
     bool bHasLocal = false;
-    const bool bHardcore = _RA_HardcoreModeIsActive();
 
     const bool bGameLoaded = (GetGameId() != 0);
     if (!bGameLoaded)
@@ -975,6 +975,9 @@ void AssetListViewModel::SaveSelected()
             std::string sMessage;
             for (const auto* pAsset : vSelectedAssets)
             {
+                if (pAsset == nullptr)
+                    continue;
+
                 if (!sMessage.empty())
                     sMessage.push_back(',');
                 sMessage.append(std::to_string(pAsset->GetID()));
@@ -1028,7 +1031,10 @@ void AssetListViewModel::SaveSelected()
             return;
 
         for (auto* pAsset : vSelectedAssets)
-            pAsset->SetCategory(ra::data::models::AssetCategory::Core);
+        {
+            if (pAsset != nullptr)
+                pAsset->SetCategory(ra::data::models::AssetCategory::Core);
+        }
 
         RA_LOG_INFO("Promoting %u items", vSelectedAssets.size());
         Publish(vSelectedAssets);
@@ -1047,7 +1053,7 @@ void AssetListViewModel::SaveSelected()
 
         for (const auto* pAsset : vSelectedAssets)
         {
-            if (pAsset->GetType() == ra::data::models::AssetType::Leaderboard)
+            if (pAsset != nullptr && pAsset->GetType() == ra::data::models::AssetType::Leaderboard)
             {
                 ra::ui::viewmodels::MessageBoxViewModel::ShowWarningMessage(L"Leaderboards cannot be demoted.");
                 return;
@@ -1063,7 +1069,10 @@ void AssetListViewModel::SaveSelected()
             return;
 
         for (auto* pAsset : vSelectedAssets)
-            pAsset->SetCategory(ra::data::models::AssetCategory::Unofficial);
+        {
+            if (pAsset != nullptr)
+                pAsset->SetCategory(ra::data::models::AssetCategory::Unofficial);
+        }
 
         RA_LOG_INFO("Demoting %u items", vSelectedAssets.size());
         Publish(vSelectedAssets);
@@ -1336,12 +1345,15 @@ void AssetListViewModel::ResetSelected()
         // reset selection, remove "new" items and get the AssetViewModel for the others
         for (auto* pItem : vSelectedAssets)
         {
+            if (pItem == nullptr)
+                continue;
+
             const auto nType = pItem->GetType();
             const auto nId = ra::to_unsigned(pItem->GetId());
             for (gsl::index nIndex = gsl::narrow_cast<gsl::index>(pGameContext.Assets().Count()) - 1; nIndex >= 0; --nIndex)
             {
                 auto* pAsset = pGameContext.Assets().GetItemAt(nIndex);
-                if (pAsset->GetID() == nId && pAsset->GetType() == nType)
+                if (pAsset != nullptr && pAsset->GetID() == nId && pAsset->GetType() == nType)
                 {
                     if (pAsset->GetState() == ra::data::models::AssetState::Primed)
                     {
@@ -1371,6 +1383,9 @@ void AssetListViewModel::ResetSelected()
             std::string sMessage;
             for (const auto* pAsset : vAssetsToReset)
             {
+                if (pAsset == nullptr)
+                    continue;
+
                 if (!sMessage.empty())
                     sMessage.push_back(',');
                 sMessage.append(std::to_string(pAsset->GetID()));
@@ -1482,6 +1497,9 @@ void AssetListViewModel::RevertSelected()
     std::string sMessage;
     for (const auto* pAsset : vAssetsToReset)
     {
+        if (pAsset == nullptr)
+            continue;
+
         if (!sMessage.empty())
             sMessage.push_back(',');
         sMessage.append(std::to_string(pAsset->GetID()));
@@ -1635,6 +1653,9 @@ void AssetListViewModel::CloneSelected()
         std::string sMessage;
         for (const auto* pAsset : vSelectedAssets)
         {
+            if (pAsset == nullptr)
+                continue;
+
             if (!sMessage.empty())
                 sMessage.push_back(',');
             sMessage.append(std::to_string(pAsset->GetID()));
diff --git a/src/ui/viewmodels/MemoryBookmarksViewModel.cpp b/src/ui/viewmodels/MemoryBookmarksViewModel.cpp
index cfe5d707..d58771d4 100644
--- a/src/ui/viewmodels/MemoryBookmarksViewModel.cpp
+++ b/src/ui/viewmodels/MemoryBookmarksViewModel.cpp
@@ -340,7 +340,10 @@ void MemoryBookmarksViewModel::LoadBookmarks(ra::services::TextReader& sBookmark
             {
                 auto* vmBookmark = m_vBookmarks.GetItemAt(nIndex);
                 if (vmBookmark == nullptr)
+                {
                     vmBookmark = &m_vBookmarks.Add();
+                    Ensures(vmBookmark != nullptr);
+                }
                 ++nIndex;
 
                 vmBookmark->BeginInitialization();
diff --git a/src/ui/viewmodels/MemorySearchViewModel.cpp b/src/ui/viewmodels/MemorySearchViewModel.cpp
index ffd05f52..8bbd66aa 100644
--- a/src/ui/viewmodels/MemorySearchViewModel.cpp
+++ b/src/ui/viewmodels/MemorySearchViewModel.cpp
@@ -718,7 +718,10 @@ void MemorySearchViewModel::UpdateResults()
 
         auto* pRow = m_vResults.GetItemAt(nRow);
         if (pRow == nullptr)
+        {
             pRow = &m_vResults.Add();
+            Ensures(pRow != nullptr);
+        }
 
         pRow->nAddress = pResult.nAddress;
 
diff --git a/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp b/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp
index f9fd1abc..8ead492a 100644
--- a/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp
+++ b/src/ui/viewmodels/OverlayLeaderboardsPageViewModel.cpp
@@ -80,6 +80,9 @@ void OverlayLeaderboardsPageViewModel::Refresh()
 
         for (const auto* vmLeaderboard : vActiveLeaderboards)
         {
+            if (vmLeaderboard == nullptr)
+                continue;
+
             auto& pvmLeaderboard = GetNextItem(&nIndex);
             SetLeaderboard(pvmLeaderboard, *vmLeaderboard);
         }
@@ -97,6 +100,9 @@ void OverlayLeaderboardsPageViewModel::Refresh()
 
         for (const auto* vmLeaderboard : vLocalLeaderboards)
         {
+            if (vmLeaderboard == nullptr)
+                continue;
+
             auto& pvmLeaderboard = GetNextItem(&nIndex);
             SetLeaderboard(pvmLeaderboard, *vmLeaderboard);
         }
@@ -114,6 +120,9 @@ void OverlayLeaderboardsPageViewModel::Refresh()
 
         for (const auto* vmLeaderboard : vCoreLeaderboards)
         {
+            if (vmLeaderboard == nullptr)
+                continue;
+
             auto& pvmLeaderboard = GetNextItem(&nIndex);
             SetLeaderboard(pvmLeaderboard, *vmLeaderboard);
         }
@@ -131,6 +140,9 @@ void OverlayLeaderboardsPageViewModel::Refresh()
 
         for (const auto* vmLeaderboard : vUnsupportedLeaderboards)
         {
+            if (vmLeaderboard == nullptr)
+                continue;
+
             auto& pvmLeaderboard = GetNextItem(&nIndex);
             SetLeaderboard(pvmLeaderboard, *vmLeaderboard);
         }
diff --git a/src/ui/viewmodels/ScoreboardViewModel.cpp b/src/ui/viewmodels/ScoreboardViewModel.cpp
index 6c114ce6..96c52fc8 100644
--- a/src/ui/viewmodels/ScoreboardViewModel.cpp
+++ b/src/ui/viewmodels/ScoreboardViewModel.cpp
@@ -37,7 +37,6 @@ void ScoreboardViewModel::BeginAnimation()
     m_fAnimationProgress = 0.0;
 
     const auto& pTheme = ra::services::ServiceLocator::Get<ra::ui::OverlayTheme>();
-    const auto nHeight = CalculateScoreboardHeight(pTheme);
     const auto nWidth = CalculateScoreboardWidth(pTheme);
 
     // bottom margin 10px
diff --git a/src/ui/win32/FileDialog.cpp b/src/ui/win32/FileDialog.cpp
index baa5802c..bdd2f96c 100644
--- a/src/ui/win32/FileDialog.cpp
+++ b/src/ui/win32/FileDialog.cpp
@@ -42,15 +42,16 @@ BrowseCallbackProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ _UNUSED LPARAM lParam, _
     return 0;
 }
 
+GSL_SUPPRESS_F23
 static void ShowFolder(FileDialogViewModel& vmFileDialog, HWND hParentWnd)
 {
-    CComPtr<IFileDialog> pFileDialog;
+    IFileDialog* pFileDialog = nullptr;
     if (SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFileDialog))))
     {
         pFileDialog->SetTitle(vmFileDialog.GetWindowTitle().c_str());
 
         const std::wstring& sInitialLocation = vmFileDialog.GetInitialDirectory();
-        CComPtr<IShellItem> pShellItem;
+        IShellItem* pShellItem = nullptr;
         if (!sInitialLocation.empty())
         {
             LPITEMIDLIST pItemIdList = nullptr;
@@ -60,7 +61,7 @@ static void ShowFolder(FileDialogViewModel& vmFileDialog, HWND hParentWnd)
                 if (SHCreateShellItem(nullptr, nullptr, pItemIdList, &pShellItem) == 0)
                 {
                     pFileDialog->SetFolder(pShellItem);
-                    pShellItem.Release();
+                    pShellItem->Release();
                 }
             }
         }
@@ -70,6 +71,8 @@ static void ShowFolder(FileDialogViewModel& vmFileDialog, HWND hParentWnd)
             pFileDialog->SetOptions(dwOptions | FOS_PICKFOLDERS);
 
         const HRESULT hr = pFileDialog->Show(hParentWnd);
+        pFileDialog->Release();
+
         if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED))
         {
             vmFileDialog.SetDialogResult(ra::ui::DialogResult::Cancel);
@@ -87,7 +90,7 @@ static void ShowFolder(FileDialogViewModel& vmFileDialog, HWND hParentWnd)
                     vmFileDialog.SetDialogResult(ra::ui::DialogResult::OK);
                 }
 
-                pShellItem.Release();
+                pShellItem->Release();
             }
 
             return;
@@ -164,7 +167,7 @@ void FileDialog::Presenter::DoShowModal(ra::ui::WindowViewModelBase& oViewModel,
         if (!sDefaultExtension.empty())
         {
             const wchar_t* pStart = pPair.first.data();
-            while (*pStart)
+            while (pStart != nullptr && *pStart)
             {
                 while (*pStart && *pStart != '.')
                     ++pStart;
@@ -173,6 +176,7 @@ void FileDialog::Presenter::DoShowModal(ra::ui::WindowViewModelBase& oViewModel,
                     break;
 
                 const wchar_t* pEnd = ++pStart;
+                Expects(pEnd != nullptr);
                 while (*pEnd && *pEnd != ';')
                     ++pEnd;
 


Test patch:
diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj
index a05fae75..8406125e 100644
--- a/tests/RA_Integration.Tests.vcxproj
+++ b/tests/RA_Integration.Tests.vcxproj
@@ -17,6 +17,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release-xp|Win32">
+      <Configuration>Release-xp</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release-xp|x64">
+      <Configuration>Release-xp</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
@@ -48,14 +56,14 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v141_xp</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v141_xp</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
@@ -74,6 +82,14 @@
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <PlatformToolset>v141_xp</PlatformToolset>
@@ -82,6 +98,14 @@
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <PlatformToolset>v141_xp</PlatformToolset>
@@ -114,10 +138,18 @@
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="base.props" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="base.props" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="base.props" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="base.props" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
@@ -150,11 +182,21 @@
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Integration\</OutDir>
     <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Integration\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Integration\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Integration\</IntDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Integration\</OutDir>
     <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Integration\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Integration\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Integration\</IntDir>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -258,6 +300,27 @@
       <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
     </PreBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(RA_IncludePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;RA_UTEST;RA_EXPORTS;NDEBUG;RA_V141_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <UseFullPaths>true</UseFullPaths>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <DisableSpecificWarnings>4201</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <PreBuildEvent>
+      <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -279,6 +342,27 @@
       <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
     </PreBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(RA_IncludePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;RA_UTEST;RA_EXPORTS;NDEBUG;RA_V141_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <UseFullPaths>true</UseFullPaths>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <DisableSpecificWarnings>4201</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <PreBuildEvent>
+      <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\src\data\context\GameAssets.cpp" />
     <ClCompile Include="..\src\data\ModelProperty.cpp" />
@@ -308,7 +392,9 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Analysis|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Analysis|x64'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">Create</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="..\src\Exports.cpp" />
     <ClCompile Include="..\src\RA_Json.cpp" />
diff --git a/tests/RA_Interface.Tests.vcxproj b/tests/RA_Interface.Tests.vcxproj
index 785ad811..86d9e3b1 100644
--- a/tests/RA_Interface.Tests.vcxproj
+++ b/tests/RA_Interface.Tests.vcxproj
@@ -9,6 +9,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release-xp|Win32">
+      <Configuration>Release-xp</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release-xp|x64">
+      <Configuration>Release-xp</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
@@ -49,6 +57,14 @@
     <CharacterSet>MultiByte</CharacterSet>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
@@ -57,6 +73,14 @@
     <CharacterSet>MultiByte</CharacterSet>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
@@ -71,9 +95,15 @@
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
@@ -90,11 +120,21 @@
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Interface\</OutDir>
     <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Interface\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Interface\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Interface\</IntDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Interface\</OutDir>
     <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Interface\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\tests\RA_Interface\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\tests\RA_Interface\</IntDir>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -171,7 +211,6 @@
       <UseFullPaths>true</UseFullPaths>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <DisableSpecificWarnings>4201</DisableSpecificWarnings>
-      <AdditionalOptions>/w45045 %(AdditionalOptions)</AdditionalOptions>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <PrecompiledHeaderFile />
@@ -188,6 +227,34 @@
       <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
     </PreBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include\;$(SolutionDir)src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;RA_UTEST;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <UseFullPaths>true</UseFullPaths>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <DisableSpecificWarnings>4201</DisableSpecificWarnings>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>kernel32.lib;user32.lib;Winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <PreBuildEvent>
+      <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -198,7 +265,31 @@
       <UseFullPaths>true</UseFullPaths>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <DisableSpecificWarnings>4201</DisableSpecificWarnings>
-      <AdditionalOptions>/w45045 %(AdditionalOptions)</AdditionalOptions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>
+      </PrecompiledHeaderOutputFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>kernel32.lib;user32.lib;Winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include\;$(SolutionDir)src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;RA_UTEST;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <UseFullPaths>true</UseFullPaths>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <DisableSpecificWarnings>4201</DisableSpecificWarnings>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <PrecompiledHeaderFile>
@@ -235,6 +326,27 @@
       <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
     </PreBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-xp|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>Disabled</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include\;$(SolutionDir)src\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>RA_UTEST;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <UseFullPaths>true</UseFullPaths>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+    <PreBuildEvent>
+      <Command>if not exist "$(SolutionDir)src\RA_BuildVer.h" "$(SolutionDir)RAInterface\MakeBuildVer.bat" "$(SolutionDir)src\RA_BuildVer.h" RAIntegration RA_INTEGRATION</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="RA_Interface_Tests.cpp" />
   </ItemGroup>
diff --git a/tests/RA_UnitTestHelpers.h b/tests/RA_UnitTestHelpers.h
index 3c58d155..ca5538da 100644
--- a/tests/RA_UnitTestHelpers.h
+++ b/tests/RA_UnitTestHelpers.h
@@ -25,10 +25,9 @@ std::wstring ToString<std::chrono::milliseconds>(const std::chrono::milliseconds
     return std::to_wstring(t.count()) + L"ms";
 }
 
-#ifndef RA_ANALYSIS
+#ifdef RA_V141_XP
 // this has to be defined when compiling against v141_xp, but not when compiling against v142.
-// since it's impractical to detect the selected platform toolset, just key off the fact that
-// the Analysis builds have to use the newer toolset.
+// since it's impractical to detect the selected platform toolset, use a compilation flag
 
 template<>
 std::wstring ToString<__int64>(const __int64& t)
diff --git a/tests/data/context/GameContext_Tests.cpp b/tests/data/context/GameContext_Tests.cpp
index 2b82964a..70b58280 100644
--- a/tests/data/context/GameContext_Tests.cpp
+++ b/tests/data/context/GameContext_Tests.cpp
@@ -480,6 +480,7 @@ public:
         // local achievement data for 7 should be merged with server achievement data
         pAch = game.Assets().FindAchievement(7U);
         Assert::IsNotNull(pAch);
+        Ensures(pAch != nullptr);
         Assert::AreEqual(std::wstring(L"Ach2b"), pAch->GetName());
         Assert::AreEqual(std::wstring(L"Desc2b"), pAch->GetDescription());
         Assert::AreEqual(std::wstring(L"Auth2"), pAch->GetAuthor()); // author not merged
@@ -491,6 +492,7 @@ public:
         // no server achievement, assign FirstLocalId
         pAch = game.Assets().FindAchievement(GameAssets::FirstLocalId);
         Assert::IsNotNull(pAch);
+        Ensures(pAch != nullptr);
         Assert::AreEqual(std::wstring(L"Ach3"), pAch->GetName());
         Assert::AreEqual(std::wstring(L"Desc3"), pAch->GetDescription());
         Assert::AreEqual(std::wstring(L"Auth3"), pAch->GetAuthor());
@@ -502,6 +504,7 @@ public:
         // no server achievement, assign next local id
         pAch = game.Assets().FindAchievement(GameAssets::FirstLocalId + 1);
         Assert::IsNotNull(pAch);
+        Ensures(pAch != nullptr);
         Assert::AreEqual(std::wstring(L"Ach4"), pAch->GetName());
         Assert::AreEqual(std::wstring(L"Desc4"), pAch->GetDescription());
         Assert::AreEqual(std::wstring(L"Auth4"), pAch->GetAuthor());
diff --git a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp
index 94b1b4f2..b5ff8072 100644
--- a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp
+++ b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp
@@ -3400,6 +3400,7 @@ public:
     {
         AssetListViewModelHarness vmAssetList;
         const auto* pLocalBadges = vmAssetList.AddLocalBadgesModel();
+        Expects(pLocalBadges != nullptr);
         const std::wstring sLocalBadgeName = L"local\\1234.png";
 
         vmAssetList.SetGameId(22U);
@@ -3687,6 +3688,7 @@ public:
         AssetListViewModelHarness vmAssetList;
         vmAssetList.SetGameId(22U);
         const auto* pLocalBadges = vmAssetList.AddLocalBadgesModel();
+        Expects(pLocalBadges != nullptr);
         vmAssetList.AddAchievement(AssetCategory::Core, 5, L"Test1", L"Desc1", L"12345", "0xH1234=1");
         vmAssetList.AddAchievement(AssetCategory::Core, 7, L"Test2", L"Desc2", L"11111", "0xH1111=1");
         const std::wstring sBadge1 = L"local\\ABCD.png";
@@ -3777,6 +3779,7 @@ public:
         AssetListViewModelHarness vmAssetList;
         vmAssetList.SetGameId(22U);
         const auto* pLocalBadges = vmAssetList.AddLocalBadgesModel();
+        Expects(pLocalBadges != nullptr);
         vmAssetList.AddAchievement(AssetCategory::Core, 5, L"Test1", L"Desc1", L"12345", "0xH1234=1");
         vmAssetList.AddAchievement(AssetCategory::Core, 7, L"Test2", L"Desc2", L"11111", "0xH1111=1");
         const std::wstring sBadge1 = L"local\\ABCD.png";
@@ -4727,6 +4730,7 @@ public:
         const std::wstring sBadge1 = L"local\\ABCD.png";
         const std::wstring sBadge2 = L"local\\EFGH.png";
         const auto* pLocalBadges = vmAssetList.AddLocalBadgesModel();
+        Expects(pLocalBadges != nullptr);
         vmAssetList.AddAchievement(AssetCategory::Local, 5, L"Test1", L"Desc1", sBadge1, "0xH1234=1");
         vmAssetList.AddAchievement(AssetCategory::Local, 7, L"Test2", L"Desc2", sBadge2, "0xH1234=1");