Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 1 addition & 1 deletion .pipelines/build-stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ parameters:
- name: targets
type: object
default:
- target: "wsl;libwsl;wslg;wslservice;wslhost;wslrelay;wslinstaller;wslinstall;initramfs;wslserviceproxystub;wslsettings;wslinstallerproxystub;testplugin"
- target: "wsl;libwsl;wslg;wslservice;wslhost;wslrelay;wslinstaller;wslinstall;init;wslserviceproxystub;wslsettings;wslinstallerproxystub;testplugin"
pattern: "wsl.exe,libwsl.dll,wslg.exe,wslservice.exe,wslhost.exe,wslrelay.exe,wslinstaller.exe,wslinstall.dll,wslserviceproxystub.dll,wslsettings/wslsettings.dll,wslsettings/wslsettings.exe,wslinstallerproxystub.dll,wsldevicehost.dll,WSLDVCPlugin.dll,testplugin.dll,wsldeps.dll"
- target: "msixgluepackage"
pattern: "gluepackage.msix"
Expand Down
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ find_nuget_package(Microsoft.WSL.bsdtar BSDTARD /build/native/bin)
find_nuget_package(Microsoft.WSL.LinuxSdk LINUXSDK /)
find_nuget_package(Microsoft.WSL.TestDistro TEST_DISTRO /)
find_nuget_package(Microsoft.WSLg WSLG /build/native/bin)
find_nuget_package(StrawberryPerl PERL /)
find_nuget_package(vswhere VSWHERE /tools)
find_nuget_package(Wix WIX /tools/net6.0/any)

Expand All @@ -92,7 +91,6 @@ find_nuget_package(Microsoft.Windows.SDK.NET.Ref WINDOWS_SDK_DOTNET /)
find_nuget_package(Microsoft.Xaml.Behaviors.WinUI.Managed XAML_BEHAVIORS /)
find_nuget_package(WinUIEx WINUIEX /)

set(BIN2CPIO ${CMAKE_CURRENT_LIST_DIR}/tools/bin2cpio/bin2cpio.pl)
set(WSLG_TS_PLUGIN_DLL "WSLDVCPlugin.dll")

# Default to debug build if unspecified
Expand Down
4 changes: 2 additions & 2 deletions msipackage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ foreach(binary ${WINDOWS_BINARIES})
list(APPEND BINARIES_DEPENDENCIES "${PACKAGE_INPUT_DIR}/${binary}")
endforeach()

set(LINUX_BINARIES init;initrd.img)
set(LINUX_BINARIES init)
foreach(binary ${LINUX_BINARIES})
list(APPEND BINARIES_DEPENDENCIES "${BIN}/${binary}")
endforeach()
Expand Down Expand Up @@ -52,7 +52,7 @@ add_custom_command(

add_custom_target(msipackage DEPENDS ${OUTPUT_PACKAGE})
set_target_properties(msipackage PROPERTIES EXCLUDE_FROM_ALL FALSE SOURCES ${PACKAGE_WIX_IN})
add_dependencies(msipackage wsl wslg wslservice wslhost wslrelay wslserviceproxystub init initramfs wslinstall msixgluepackage)
add_dependencies(msipackage wsl wslg wslservice wslhost wslrelay wslserviceproxystub init wslinstall msixgluepackage)

if (WSL_BUILD_WSL_SETTINGS)
add_dependencies(msipackage wslsettings libwsl)
Expand Down
28 changes: 25 additions & 3 deletions msipackage/package.wix.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
Comment thread
benhillis marked this conversation as resolved.
Outdated
<Package Name="Windows Subsystem for Linux" Language="1033" InstallerVersion="500" Version="${PACKAGE_VERSION}" Manufacturer="Microsoft Corporation" UpgradeCode="6D5B792B-1EDC-4DE9-8EAD-201B820F8E82" Scope="perMachine" Compressed="${COMPRESS_PACKAGE}">
<MajorUpgrade AllowDowngrades="yes" Disallow="no" />
<MediaTemplate EmbedCab="yes" />
Expand Down Expand Up @@ -261,7 +261,6 @@
<DirectoryRef Id="TOOLSFOLDER">
<Component Id="tools" Guid="F0C8D6BA-1502-41E7-BF72-D93DFA134733" Bitness="always64" UninstallWhenSuperseded="yes">
<File Id="init" Source="${BIN}/init" Checksum="yes" />
<File Id="initrd.img" Source="${BIN}/initrd.img"/>
<File Id="bsdtar" Source="${BSDTARD_SOURCE_DIR}/${TARGET_PLATFORM}/bsdtar"/>

<?if "${WSL_DEV_BINARY_PATH}" = "" ?>
Expand Down Expand Up @@ -461,7 +460,23 @@
Return="check"
Execute="deferred"
/>


<CustomAction Id="CreateInitrd"
Impersonate="no"
BinaryRef="wslinstall.dll"
DllEntry="CreateInitrd"
Return="check"
Execute="deferred"
/>

<CustomAction Id="RemoveInitrd"
Impersonate="no"
BinaryRef="wslinstall.dll"
DllEntry="RemoveInitrd"
Return="check"
Execute="deferred"
/>

<CustomAction Id="RemoveRegistryKeyProtections"
Impersonate="no"
BinaryRef="wslinstall.dll"
Expand Down Expand Up @@ -525,10 +540,17 @@
<!-- This needs to run after the registry is written because this action needs to read the install path -->
<Custom Action="RegisterLspCategories" After="WriteRegistryValues" Condition='((not REMOVE~="ALL") or WIX_UPGRADE_DETECTED) and (not UPGRADINGPRODUCTCODE) and (not SKIPLSP = 1)' />

<!-- Generate initrd.img from the init binary during installation -->
<Custom Action="CreateInitrd" After="RegisterLspCategories" Condition='((not REMOVE~="ALL") or WIX_UPGRADE_DETECTED) and (not UPGRADINGPRODUCTCODE)' />

<!-- This needs to run before the registry is cleared because this action needs to read the install path.
This actions runs on uninstallation and upgrade. -->
<Custom Action="UnregisterLspCategories" Before="RemoveRegistryValues" Condition='(REMOVE~="ALL") and (not UPGRADINGPRODUCTCODE) and (not SKIPLSP = 1)' />

<!-- This needs to run before the registry is cleared because this action needs to read the install path.
This actions runs on uninstallation and upgrade. -->
<Custom Action="RemoveInitrd" Before="UnregisterLspCategories" Condition='(REMOVE~="ALL") and (not UPGRADINGPRODUCTCODE)' />

<?if "${WSL_BUILD_WSL_SETTINGS}" = "true" ?>
<!-- This needs to run before the registry is written because this action calculates registry key names and values -->
<Custom Action="CalculateWslSettingsProtocolIds" Before="WriteRegistryValues" Condition='(not REMOVE~="ALL")' />
Expand Down
1 change: 0 additions & 1 deletion packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
<package id="Microsoft.WSL.TestDistro" version="2.5.7-47" />
<package id="Microsoft.WSLg" version="1.0.73" />
<package id="Microsoft.Xaml.Behaviors.WinUI.Managed" version="3.0.0" />
<package id="StrawberryPerl" version="5.32.1.1" />
<package id="vswhere" version="3.1.7" />
<package id="WinUIEx" version="2.9.0" />
<package id="Wix" version="5.0.2" />
Expand Down
17 changes: 0 additions & 17 deletions src/linux/init/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,4 @@ set(INIT_LIBRARIES ${COMMON_LINUX_LINK_LIBRARIES} netlinkutil plan9 mountutil co
add_linux_executable(init "${SOURCES}" "${HEADERS}" "${INIT_LIBRARIES}")
add_dependencies(init localization)

set(INITRAMFS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/initrd.img)
set(INIT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/init)

# The initramfs depends on both the init target and binary so it doesn't start too early
# (before the symbols are stripped from the init binary)
# but so that it is still rebuilt if the file itself changes.
add_custom_command(
OUTPUT ${INITRAMFS} "${CMAKE_CURRENT_BINARY_DIR}/CmakeFiles/initramfs"
DEPENDS init ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/init
COMMAND ${PERL_SOURCE_DIR}/bin/perl.exe ${BIN2CPIO} ${INIT} ${INITRAMFS}
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/CmakeFiles/initramfs"
VERBATIM
)

add_custom_target(initramfs DEPENDS ${INITRAMFS})

set_target_properties(init PROPERTIES FOLDER linux)
set_target_properties(initramfs PROPERTIES FOLDER linux)
2 changes: 1 addition & 1 deletion src/windows/service/exe/WslCoreVm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void WslCoreVm::Initialize(const GUID& VmId, const wil::shared_handle& UserToken
// Set the install path of the package.
m_installPath = wsl::windows::common::wslutil::GetBasePath();

// Initialize the path to the tools folder.
// Initialize the path to the tools folder which also serves as the default rootfs path.
m_rootFsPath = m_installPath / LXSS_TOOLS_DIRECTORY;

// Store the path of the user profile.
Expand Down
179 changes: 164 additions & 15 deletions src/windows/wslinstall/DllMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ static constexpr auto c_wslSettingsProgIDPropertyName = L"WSLSETTINGSPROGID";
return NOERROR; \
}

#define WSL_INSTALL_LOG(Name, ...) \
{ \
WSL_LOG(Name, __VA_ARGS__); \
WriteInstallLog(std::format("MSI install: {}", Name)); \
}

#ifndef WSL_OFFICIAL_BUILD
void TrustPackageCertificate(LPCWSTR Path)
{
Expand Down Expand Up @@ -519,8 +525,7 @@ extern "C" UINT __stdcall CleanMsixState(MSIHANDLE install)
extern "C" UINT __stdcall DeprovisionMsix(MSIHANDLE install)
try
{
WSL_LOG("DeprovisionMsix");
WriteInstallLog("MSI install: DeprovisionMsix");
WSL_INSTALL_LOG("DeprovisionMsix");

const winrt::Windows::Management::Deployment::PackageManager packageManager;
const auto result = packageManager.DeprovisionPackageForAllUsersAsync(wsl::windows::common::wslutil::c_msixPackageFamilyName).get();
Expand All @@ -543,8 +548,7 @@ catch (...)
extern "C" UINT __stdcall RemoveMsixAsSystem(MSIHANDLE install)
try
{
WSL_LOG("RemoveMsixAsSystem");
WriteInstallLog("MSI install: RemoveMsixAsSystem");
WSL_INSTALL_LOG("RemoveMsixAsSystem");

const winrt::Windows::Management::Deployment::PackageManager packageManager;

Expand Down Expand Up @@ -573,8 +577,7 @@ catch (...)
extern "C" UINT __stdcall RemoveMsixAsUser(MSIHANDLE install)
try
{
WSL_LOG("RemoveMsixAsUser");
WriteInstallLog("MSI install: RemoveMsixAsUser");
WSL_INSTALL_LOG("RemoveMsixAsUser");

const winrt::Windows::Management::Deployment::PackageManager packageManager;

Expand Down Expand Up @@ -643,8 +646,7 @@ wsl::windows::common::filesystem::TempFile ExtractMsix(MSIHANDLE install)
extern "C" UINT __stdcall InstallMsixAsUser(MSIHANDLE install)
try
{
WSL_LOG("InstallMsixAsUser");
WriteInstallLog("MSI install: InstallMsixAsUser");
WSL_INSTALL_LOG("InstallMsixAsUser");

// RegisterPackageByFamilyNameAsync() cannot be run as SYSTEM.
// If this thread runs as SYSTEM, simply skip this step.
Expand Down Expand Up @@ -687,8 +689,7 @@ try
// Release a file handle to the MSIX file so that it can be installed.
msixFile.Handle.reset();

WSL_LOG("InstallMsix", TraceLoggingValue(msixFile.Path.c_str(), "Path"));
WriteInstallLog("MSI install: InstallMsix");
WSL_INSTALL_LOG("InstallMsix", TraceLoggingValue(msixFile.Path.c_str(), "Path"));

winrt::Windows::Management::Deployment::PackageManager packageManager;

Expand Down Expand Up @@ -790,8 +791,7 @@ extern "C" UINT __stdcall WslFinalizeInstallation(MSIHANDLE install)
{
try
{
WSL_LOG("WslFinalizeInstallation");
WriteInstallLog(std::format("MSI install: WslFinalizeInstallation"));
WSL_INSTALL_LOG("WslFinalizeInstallation");
}
CATCH_LOG();

Expand All @@ -801,9 +801,7 @@ extern "C" UINT __stdcall WslFinalizeInstallation(MSIHANDLE install)
extern "C" UINT __stdcall WslValidateInstallation(MSIHANDLE install)
try
{
WSL_LOG("WslValidateInstallation");

WriteInstallLog(std::format("MSI install: WslValidateInstallation"));
WSL_INSTALL_LOG("WslValidateInstallation");

// TODO: Use a more precise version check so we don't install if the Windows build doesn't support lifted.

Expand Down Expand Up @@ -874,6 +872,157 @@ extern "C" UINT __stdcall UnregisterLspCategories(MSIHANDLE install)
return NOERROR;
}

void CreateCpioInitrd(_In_ const std::filesystem::path& SourcePath, _In_ const std::filesystem::path& DestPath)
Comment thread
benhillis marked this conversation as resolved.
Outdated
{
// Open the source init binary
wil::unique_hfile sourceFile{
CreateFileW(SourcePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)};
THROW_LAST_ERROR_IF(!sourceFile);

// Get file size
LARGE_INTEGER fileSize{};
THROW_IF_WIN32_BOOL_FALSE(GetFileSizeEx(sourceFile.get(), &fileSize));
THROW_HR_IF(E_INVALIDARG, fileSize.HighPart != 0); // File too large

const DWORD initSize = fileSize.LowPart;
const auto initDataPadding = (4 - (initSize % 4)) % 4;
wil::unique_hfile destFile{CreateFileW(DestPath.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr)};
THROW_LAST_ERROR_IF(!destFile);

// Clean up the destination file on failure.
auto deleteFile = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] {
destFile.reset();
LOG_IF_WIN32_BOOL_FALSE(DeleteFileW(DestPath.c_str()));
});

auto writeCpioHeader = [&destFile](DWORD fileSize, PCSTR name) {
// CPIO newc header: magic(6) + 13 fields of 8 hex chars each = 110 bytes
constexpr size_t headerSize = 110;
const auto nameLen = strlen(name) + 1;
const auto headerPadding = (4 - ((headerSize + nameLen) % 4)) % 4;

// Get current time for mtime
const auto mtime = static_cast<DWORD>(time(nullptr));
Comment thread
benhillis marked this conversation as resolved.
Outdated

char header[headerSize + 1];
sprintf_s(
Comment thread
benhillis marked this conversation as resolved.
Outdated
header,
"070701" // magic
"%08X" // inode
"%08X" // mode
"%08X" // uid
"%08X" // gid
"%08X" // nlink
"%08X" // mtime
"%08X" // filesize
"%08X" // devmajor
"%08X" // devminor
"%08X" // rdevmajor
"%08X" // rdevminor
"%08X" // namesize
"%08X", // check
0,
(fileSize > 0) ? 0100755 : 0,
0,
0,
(fileSize > 0) ? 1 : 0,
mtime,
fileSize,
0,
0,
0,
0,
static_cast<DWORD>(nameLen),
0);

DWORD bytesWritten;
THROW_IF_WIN32_BOOL_FALSE(WriteFile(destFile.get(), header, headerSize, &bytesWritten, nullptr));

// Write name with null terminator
THROW_IF_WIN32_BOOL_FALSE(WriteFile(destFile.get(), name, static_cast<DWORD>(nameLen), &bytesWritten, nullptr));

// Write padding to align to 4 bytes
if (headerPadding > 0)
{
char padding[4] = {0};
THROW_IF_WIN32_BOOL_FALSE(WriteFile(destFile.get(), padding, static_cast<DWORD>(headerPadding), &bytesWritten, nullptr));
}
};

// Write init file header
writeCpioHeader(initSize, SourcePath.filename().string().c_str());
Comment thread
benhillis marked this conversation as resolved.
Outdated

// Copy file contents
wsl::windows::common::relay::InterruptableRelay(sourceFile.get(), destFile.get(), nullptr, 64 * 1024);

// Write data padding
if (initDataPadding > 0)
{
char padding[4] = {0};
DWORD bytesWritten;
THROW_IF_WIN32_BOOL_FALSE(WriteFile(destFile.get(), padding, static_cast<DWORD>(initDataPadding), &bytesWritten, nullptr));
}

// Write trailer entry (empty file with name "TRAILER!!!")
writeCpioHeader(0, "TRAILER!!!");

// Pad the archive to 512-byte boundary
constexpr DWORD archiveBlockSize = 512;
LARGE_INTEGER currentPos{};
THROW_IF_WIN32_BOOL_FALSE(SetFilePointerEx(destFile.get(), {}, &currentPos, FILE_CURRENT));

const auto archivePadding = (archiveBlockSize - (currentPos.LowPart % archiveBlockSize)) % archiveBlockSize;
if (archivePadding > 0)
{
auto paddingBuffer = std::make_unique<char[]>(archivePadding);
Comment thread
benhillis marked this conversation as resolved.
Outdated
memset(paddingBuffer.get(), 0, archivePadding);
DWORD bytesWritten;
THROW_IF_WIN32_BOOL_FALSE(WriteFile(destFile.get(), paddingBuffer.get(), archivePadding, &bytesWritten, nullptr));
}

deleteFile.release();
}

extern "C" UINT __stdcall CreateInitrd(MSIHANDLE install)
try
{
WSL_INSTALL_LOG("CreateInitrd");

const auto installRoot = wsl::windows::common::wslutil::GetMsiPackagePath();
THROW_HR_IF(E_INVALIDARG, !installRoot.has_value());

const auto toolsPath = std::filesystem::path(installRoot.value()) / LXSS_TOOLS_DIRECTORY;
const auto initPath = toolsPath / L"init";
const auto initrdPath = toolsPath / LXSS_VM_MODE_INITRD_NAME;
CreateCpioInitrd(initPath, initrdPath);

return NOERROR;
Comment thread
benhillis marked this conversation as resolved.
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();

return ERROR_INSTALL_FAILURE;
Comment thread
benhillis marked this conversation as resolved.
}

extern "C" UINT __stdcall RemoveInitrd(MSIHANDLE install)
{
try
{
WSL_INSTALL_LOG("RemoveInitrd");

const auto installRoot = wsl::windows::common::wslutil::GetMsiPackagePath();
THROW_HR_IF(E_INVALIDARG, !installRoot.has_value());

const auto initrdPath = std::filesystem::path(installRoot.value()) / LXSS_TOOLS_DIRECTORY / LXSS_VM_MODE_INITRD_NAME;
THROW_IF_WIN32_BOOL_FALSE(DeleteFileW(initrdPath.c_str()));
}
CATCH_LOG()

// Failures in this method aren't fatal.
return NOERROR;
}

std::wstring GetWslSettingsInstalledExePath(MSIHANDLE install)
{
const auto wslSettingsInstallFolder = GetMsiProperty(install, c_wslSettingsInstalledDirectoryPropertyName);
Expand Down
2 changes: 2 additions & 0 deletions src/windows/wslinstall/wslinstall.def
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ EXPORTS
CleanExplorerState
CleanMsixState
DeprovisionMsix
CreateInitrd
RemoveInitrd
WslValidateInstallation
WslFinalizeInstallation
InstallMsix
Expand Down
Loading