Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto eol=lf
*.bat text eol=crlf
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
!/res
!/platform
!/.github
!/packager

!.gitignore
!.gitattributes
!*.cpp
!*.h
!*.sln
Expand All @@ -14,6 +16,7 @@
!*.ico
!*.rc
!*.manifest
!packages.config

!LICENSE
!build.gradle
2 changes: 1 addition & 1 deletion fabric-installer-native-bootstrap.rc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include "src\resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
Expand Down
16 changes: 10 additions & 6 deletions fabric-installer-native-bootstrap.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,32 @@ VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fabric-installer-native-bootstrap", "fabric-installer-native-bootstrap.vcxproj", "{B900FD00-808B-4A95-B40B-9B243B186FF0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "packager", "packager\packager.vcxproj", "{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM64 = Release|ARM64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Debug|ARM64.Build.0 = Debug|ARM64
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Debug|Win32.ActiveCfg = Debug|Win32
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Debug|Win32.Build.0 = Debug|Win32
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Debug|x64.ActiveCfg = Debug|x64
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Debug|x64.Build.0 = Debug|x64
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Release|ARM64.ActiveCfg = Release|ARM64
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Release|ARM64.Build.0 = Release|ARM64
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Release|Win32.ActiveCfg = Release|Win32
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Release|Win32.Build.0 = Release|Win32
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Release|x64.ActiveCfg = Release|x64
{B900FD00-808B-4A95-B40B-9B243B186FF0}.Release|x64.Build.0 = Release|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Debug|ARM64.ActiveCfg = Debug|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Debug|ARM64.Build.0 = Debug|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Debug|x64.ActiveCfg = Debug|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Debug|x64.Build.0 = Debug|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Release|ARM64.ActiveCfg = Release|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Release|ARM64.Build.0 = Release|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Release|x64.ActiveCfg = Release|x64
{A3999EF4-14BF-4910-A6AB-13FB5730F7E6}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
38 changes: 31 additions & 7 deletions fabric-installer-native-bootstrap.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,13 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ControlFlowGuard>false</ControlFlowGuard>
<EnablePREfast>true</EnablePREfast>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
Expand All @@ -154,10 +156,12 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ControlFlowGuard>Guard</ControlFlowGuard>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
Expand All @@ -176,11 +180,13 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ControlFlowGuard>false</ControlFlowGuard>
<EnablePREfast>true</EnablePREfast>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
Expand All @@ -197,11 +203,13 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ControlFlowGuard>false</ControlFlowGuard>
<EnablePREfast>true</EnablePREfast>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
Expand All @@ -221,9 +229,11 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<ControlFlowGuard>Guard</ControlFlowGuard>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
Expand All @@ -245,9 +255,11 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<ControlFlowGuard>Guard</ControlFlowGuard>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
Expand All @@ -261,17 +273,19 @@
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\EmbeddedResource.cpp" />
<ClCompile Include="src\Architecture.cpp" />
<ClCompile Include="src\Bootstrap.cpp" />
<ClCompile Include="src\Logger.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\SystemHelper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\EmbeddedResource.h" />
<ClInclude Include="src\Architecture.h" />
<ClInclude Include="src\Bootstrap.h" />
<ClInclude Include="src\ISystemHelper.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\Logger.h" />
<ClInclude Include="src\SystemHelper.h" />
</ItemGroup>
Expand All @@ -281,7 +295,17 @@
<ItemGroup>
<Image Include="icon.ico" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>
21 changes: 20 additions & 1 deletion fabric-installer-native-bootstrap.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
<ClCompile Include="src\Logger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Architecture.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\EmbeddedResource.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Bootstrap.h">
Expand All @@ -38,12 +44,18 @@
<ClInclude Include="src\SystemHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<ClInclude Include="src\resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Logger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Architecture.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\EmbeddedResource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="fabric-installer-native-bootstrap.rc">
Expand All @@ -55,4 +67,11 @@
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natstepfilter" />
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions packager/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*

!.gitignore
!*.cpp
!*.h
!*.sln
!*.vcxproj
!*.filters
!packages.config
80 changes: 80 additions & 0 deletions packager/packager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <print>
#include <filesystem>
#include <fstream>
#include <wil/resource.h>
#include <Windows.h>

namespace {
constexpr auto IDI_EMBEDDED_JAR = 201;
Copy link

Copilot AI Jul 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resource ID constant IDI_EMBEDDED_JAR is duplicated. It should be defined in the shared resource.h file and included here to avoid magic numbers and maintain consistency.

Copilot uses AI. Check for mistakes.

std::vector<char> readFile(const std::filesystem::path& path) {
wil::unique_hfile file{
::CreateFileW(
path.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr
)
};
THROW_LAST_ERROR_IF_MSG(!file, "CreateFileW");

LARGE_INTEGER fileSize{};
THROW_LAST_ERROR_IF(::GetFileSizeEx(file.get(), &fileSize) == 0);
THROW_WIN32_IF(ERROR_FILE_TOO_LARGE, fileSize.QuadPart > SIZE_MAX);

std::vector<char> buffer(static_cast<size_t>(fileSize.QuadPart));
DWORD bytesRead = 0;
THROW_LAST_ERROR_IF(!::ReadFile(file.get(), buffer.data(), static_cast<DWORD>(buffer.size()), &bytesRead, nullptr));
THROW_WIN32_IF(ERROR_HANDLE_EOF, bytesRead != buffer.size());

return buffer;
}

void updateResource(const std::filesystem::path& exe, const std::vector<char>& data, WORD resourceId) {
HANDLE handle = THROW_LAST_ERROR_IF_NULL(::BeginUpdateResourceW(exe.c_str(), false));

bool success = false;
auto _ = wil::scope_exit([&]() noexcept { ::EndUpdateResourceW(handle, !success); });

auto intResource{ MAKEINTRESOURCE(resourceId) };
THROW_LAST_ERROR_IF(!::UpdateResourceW(handle, RT_RCDATA, intResource, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPVOID)data.data(), static_cast<DWORD>(data.size())));

success = true;
}

void packageInstaller(const std::filesystem::path& bootstrap, const std::filesystem::path& installer) {
THROW_WIN32_IF_MSG(ERROR_FILE_NOT_FOUND, !std::filesystem::exists(bootstrap), "Boostrap not found");
THROW_WIN32_IF_MSG(ERROR_FILE_NOT_FOUND, !std::filesystem::exists(installer), "Installer not found");

auto installerBytes = readFile(installer);
updateResource(bootstrap, installerBytes, IDI_EMBEDDED_JAR);

std::print("Done, {} updated to embed {}\n", bootstrap.string(), installer.string());
}
}

int wmain(int argc, wchar_t* argv[])
{
if (argc != 3) {
std::print("Usage: packager <bootstrap_exe> <embedded_installer>\n");
return 1;
}

std::filesystem::path bootstrap{ argv[1] };
std::filesystem::path installer{ argv[2] };

std::print("Packager: {} Installer: {}\n", bootstrap.string(), installer.string());

try {
packageInstaller(bootstrap, installer);
}
catch (const std::exception& error) {
std::print("Packager failed: {}\n", error.what());
throw;
}

return 0;
}
Loading
Loading