From 4da671fd9f25a45e99fb1d278407b95388c77214 Mon Sep 17 00:00:00 2001 From: Frans van Dorsselaer <17404029+dorssel@users.noreply.github.com> Date: Sun, 28 Jan 2024 12:57:59 +0100 Subject: [PATCH] Refactor DIFx - remove deprecated DIFx - add driver custom actions --- .gitattributes | 7 ++ .github/workflows/build-installer.yml | 6 ++ .github/workflows/codeql-analysis.yml | 16 ++- CustomActions/CPPLINT.cfg | 9 ++ CustomActions/CustomActions.def | 9 ++ CustomActions/CustomActions.vcxproj | 97 ++++++++++++++++++ CustomActions/CustomActions.vcxproj.filters | 39 ++++++++ CustomActions/actions.cpp | 103 ++++++++++++++++++++ CustomActions/dllmain.cpp | 16 +++ CustomActions/stdafx.cpp | 5 + CustomActions/stdafx.h | 23 +++++ Directory.Build.props | 4 +- Directory.Packages.props | 1 - Installer/Drivers.wxs | 21 ++-- Installer/Installer.wixproj | 3 - Installer/PowerShell.wxs | 4 +- Installer/Server.wxs | 27 ++++- Installer/UserInterface.wxs | 9 +- Installer/WSL.wxs | 18 +++- Installer/dummy.ico | Bin 0 -> 2238 bytes Installer/dummy.ico.license | 3 + UnitTests/UnitTests.csproj | 4 +- Usbipd.PowerShell/Usbipd.PowerShell.csproj | 4 +- Usbipd/Usbipd.csproj | 4 +- usbipd-win.sln | 6 ++ 25 files changed, 391 insertions(+), 47 deletions(-) create mode 100644 CustomActions/CPPLINT.cfg create mode 100644 CustomActions/CustomActions.def create mode 100644 CustomActions/CustomActions.vcxproj create mode 100644 CustomActions/CustomActions.vcxproj.filters create mode 100644 CustomActions/actions.cpp create mode 100644 CustomActions/dllmain.cpp create mode 100644 CustomActions/stdafx.cpp create mode 100644 CustomActions/stdafx.h create mode 100644 Installer/dummy.ico create mode 100644 Installer/dummy.ico.license diff --git a/.gitattributes b/.gitattributes index f7447c1..688dfcb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -22,9 +22,16 @@ *.cs text eol=crlf *.props text +*.vcxproj text +*.filters text +*.cpp text +*.h text +*.def text + *.wixproj text *.wxs text *.xslt text +*.ico binary *.png binary *.xcf binary diff --git a/.github/workflows/build-installer.yml b/.github/workflows/build-installer.yml index 7ba39ca..ae355eb 100644 --- a/.github/workflows/build-installer.yml +++ b/.github/workflows/build-installer.yml @@ -59,6 +59,12 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1 + + - name: Build (CustomActions) + run: msbuild -p:Configuration=Release CustomActions + - name: Build (Installer) run: dotnet build --configuration Release Installer diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7814dd7..6fad7f9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,13 +62,10 @@ jobs: # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main - - name: Setup .NET - uses: actions/setup-dotnet@v4 - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 + # - name: Autobuild + # uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -81,5 +78,14 @@ jobs: # make bootstrap # make release + - name: Setup .NET + uses: actions/setup-dotnet@v4 + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: dotnet build --configuration Release --no-restore + - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 diff --git a/CustomActions/CPPLINT.cfg b/CustomActions/CPPLINT.cfg new file mode 100644 index 0000000..da4743a --- /dev/null +++ b/CustomActions/CPPLINT.cfg @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2024 Frans van Dorsselaer +# +# SPDX-License-Identifier: GPL-3.0-only + +set noparent +linelength=160 + +# incompatible with pre-compiled headers +filter=-build/include_subdir diff --git a/CustomActions/CustomActions.def b/CustomActions/CustomActions.def new file mode 100644 index 0000000..16d4209 --- /dev/null +++ b/CustomActions/CustomActions.def @@ -0,0 +1,9 @@ +; SPDX-FileCopyrightText: 2024 Frans van Dorsselaer +; +; SPDX-License-Identifier: GPL-3.0-only + +LIBRARY + +EXPORTS + InstallDrivers + UninstallDrivers diff --git a/CustomActions/CustomActions.vcxproj b/CustomActions/CustomActions.vcxproj new file mode 100644 index 0000000..e174ec6 --- /dev/null +++ b/CustomActions/CustomActions.vcxproj @@ -0,0 +1,97 @@ + + + + + + Release + x64 + + + + 17.0 + Win32Proj + {cbc206bd-0e45-4514-b148-9035c7459268} + CustomActions + 10.0 + + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + false + false + bin\$(Platform)\$(Configuration)\ + obj\$(Platform)\$(Configuration)\ + + + + Level3 + true + true + true + NDEBUG;CUSTOMACTIONS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + MultiThreaded + stdcpp20 + stdc17 + MinSpace + Size + true + None + + + Windows + true + true + false + CustomActions.def + true + 10.0 + + + + false + + UseLinkTimeCodeGeneration + + + + /NOIMPLIB /NOEXP %(AdditionalOptions) + + + + + + + + + + Create + + + + + + + + + \ No newline at end of file diff --git a/CustomActions/CustomActions.vcxproj.filters b/CustomActions/CustomActions.vcxproj.filters new file mode 100644 index 0000000..5189d10 --- /dev/null +++ b/CustomActions/CustomActions.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/CustomActions/actions.cpp b/CustomActions/actions.cpp new file mode 100644 index 0000000..3632801 --- /dev/null +++ b/CustomActions/actions.cpp @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2024 Frans van Dorsselaer +// +// SPDX-License-Identifier: GPL-3.0-only + +#include "stdafx.h" + +using std::wstring; + + +static void log(MSIHANDLE hInstall, wstring fmt, ...) { + auto hRecord = MsiCreateRecord(0); + if (!hRecord) { + return; + } + va_list ap; + va_start(ap, fmt); + va_list ap_copy; + va_copy(ap_copy, ap); + size_t len = _vscwprintf(fmt.c_str(), ap_copy); + va_end(ap_copy); + wstring message; + message.resize(len); + vswprintf_s(message.data(), len + 1, fmt.c_str(), ap); + va_end(ap); + MsiRecordSetString(hRecord, 0, (L"CustomActions: " + message).c_str()); + MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRecord); + MsiCloseHandle(hRecord); +} + + +static void require_reboot(MSIHANDLE hInstall) { + log(hInstall, L"Requesting reboot"); + // This is what WixCheckRebootRequired looks for after InstallFinalize. + GlobalAddAtom(L"WcaDeferredActionRequiresReboot"); +} + + +static wstring get_property(MSIHANDLE hInstall, const wstring& name) { + DWORD valueSize = 0; + if (MsiGetProperty(hInstall, name.c_str(), (LPWSTR)L"", &valueSize) != ERROR_MORE_DATA) { + return wstring(); + } + ++valueSize; // add NUL + auto value = std::make_unique(valueSize); + if (MsiGetProperty(hInstall, name.c_str(), value.get(), &valueSize) != ERROR_SUCCESS) { + return wstring(); + } + return wstring(value.get(), valueSize); +} + + +// This action must run deferred, between InstallFiles and InstallFinalize. +UINT __stdcall InstallDrivers(MSIHANDLE hInstall) { + auto data = get_property(hInstall, L"CustomActionData"); + BOOL request_reboot = FALSE; + { + BOOL need_reboot = FALSE; + log(hInstall, L"Installing VBoxUSBMon"); + if (!DiInstallDriver(NULL, (data + L"Drivers\\VBoxUSBMon\\VBoxUSBMon.inf").c_str(), DIIRFLAG_FORCE_INF, &need_reboot)) { + log(hInstall, L"ERROR installing VBoxUSBMon: 0x%08x", GetLastError()); + return ERROR_INSTALL_FAILURE; + } + request_reboot |= need_reboot; + } + { + BOOL need_reboot = FALSE; + log(hInstall, L"Installing VBoxUSB"); + if (!DiInstallDriver(NULL, (data + L"Drivers\\VBoxUSB\\VBoxUSB.inf").c_str(), DIIRFLAG_FORCE_INF, &need_reboot)) { + log(hInstall, L"ERROR installing VBoxUSB: 0x%08x", GetLastError()); + return ERROR_INSTALL_FAILURE; + } + request_reboot |= need_reboot; + } + if (request_reboot) { + require_reboot(hInstall); + } + return ERROR_SUCCESS; +} + + +// This action must run deferred, between InstallFiles and InstallFinalize. +UINT __stdcall UninstallDrivers(MSIHANDLE hInstall) { + auto data = get_property(hInstall, L"CustomActionData"); + { + BOOL need_reboot = FALSE; + log(hInstall, L"Uninstalling VBoxUSB"); + if (!DiUninstallDriver(NULL, (data + L"Drivers\\VBoxUSB\\VBoxUSB.inf").c_str(), 0, &need_reboot)) { + log(hInstall, L"ERROR uninstalling VBoxUSB: 0x%08x", GetLastError()); + // continue + } + // ignore need_reboot + } + { + BOOL need_reboot = FALSE; + log(hInstall, L"Uninstalling VBoxUSBMon"); + if (!DiUninstallDriver(NULL, (data + L"Drivers\\VBoxUSBMon\\VBoxUSBMon.inf").c_str(), 0, &need_reboot)) { + log(hInstall, L"ERROR uninstalling VBoxUSBMon: 0x%08x", GetLastError()); + // continue + } + // ignore need_reboot + } + return ERROR_SUCCESS; +} diff --git a/CustomActions/dllmain.cpp b/CustomActions/dllmain.cpp new file mode 100644 index 0000000..dcfc61f --- /dev/null +++ b/CustomActions/dllmain.cpp @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2024 Frans van Dorsselaer +// +// SPDX-License-Identifier: GPL-3.0-only + +#include "stdafx.h" + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} diff --git a/CustomActions/stdafx.cpp b/CustomActions/stdafx.cpp new file mode 100644 index 0000000..d2f4c93 --- /dev/null +++ b/CustomActions/stdafx.cpp @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: 2024 Frans van Dorsselaer +// +// SPDX-License-Identifier: GPL-3.0-only + +#include "stdafx.h" diff --git a/CustomActions/stdafx.h b/CustomActions/stdafx.h new file mode 100644 index 0000000..8a5d3a9 --- /dev/null +++ b/CustomActions/stdafx.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2024 Frans van Dorsselaer +// +// SPDX-License-Identifier: GPL-3.0-only + +#pragma once + +#include +#include +#include + +// Target Windows 10 or newer (including Windows Server 2019) only +#define WINVER 0x0A00 +#define _WIN32_WINNT 0x0A00 + +#define WIN32_LEAN_AND_MEAN + +// Windows Header Files +#include +#include +#include +#pragma comment(lib, "msi.lib") +#include +#pragma comment(lib, "newdev.lib") diff --git a/Directory.Build.props b/Directory.Build.props index 2aaf636..7e641e4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -62,9 +62,7 @@ SPDX-License-Identifier: GPL-3.0-only - - all - + diff --git a/Directory.Packages.props b/Directory.Packages.props index fb24bb9..24bd6b1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -18,7 +18,6 @@ SPDX-License-Identifier: GPL-3.0-only - diff --git a/Installer/Drivers.wxs b/Installer/Drivers.wxs index 7e73d80..3f9e58d 100644 --- a/Installer/Drivers.wxs +++ b/Installer/Drivers.wxs @@ -4,10 +4,7 @@ SPDX-FileCopyrightText: 2020 Frans van Dorsselaer SPDX-License-Identifier: GPL-3.0-only --> - + @@ -16,7 +13,7 @@ SPDX-License-Identifier: GPL-3.0-only - + @@ -24,14 +21,13 @@ SPDX-License-Identifier: GPL-3.0-only - + - + - - + @@ -40,14 +36,13 @@ SPDX-License-Identifier: GPL-3.0-only - + - + - - + diff --git a/Installer/Installer.wixproj b/Installer/Installer.wixproj index 2f02095..c8cc571 100644 --- a/Installer/Installer.wixproj +++ b/Installer/Installer.wixproj @@ -12,12 +12,9 @@ SPDX-License-Identifier: GPL-3.0-only ..\Usbipd\bin\publish ..\Usbipd.PowerShell\bin\$(Configuration)\netstandard2.0 PublishDir=$(PublishDir);PowerShellDir=$(PowerShellDir);DriversDir=..\Drivers;Year=$([System.DateTime]::UtcNow.ToString("yyyy")) - - 1130 true - diff --git a/Installer/PowerShell.wxs b/Installer/PowerShell.wxs index 4d13285..05ffc08 100644 --- a/Installer/PowerShell.wxs +++ b/Installer/PowerShell.wxs @@ -13,10 +13,10 @@ SPDX-License-Identifier: GPL-3.0-only - + - + diff --git a/Installer/Server.wxs b/Installer/Server.wxs index 4e9eb2e..4f049bb 100644 --- a/Installer/Server.wxs +++ b/Installer/Server.wxs @@ -16,7 +16,7 @@ SPDX-License-Identifier: GPL-3.0-only and firewall rule do not use the '-win' postfix. --> - + - + + + - + + + + + + + + + + - + + + - + + + + + diff --git a/Installer/UserInterface.wxs b/Installer/UserInterface.wxs index edb7f8d..5966f83 100644 --- a/Installer/UserInterface.wxs +++ b/Installer/UserInterface.wxs @@ -89,6 +89,13 @@ SPDX-License-Identifier: GPL-3.0-only --> + + + @@ -532,7 +539,7 @@ Published under the terms of the <a href="https://www.gnu.org/licenses/g - + - + diff --git a/Installer/dummy.ico b/Installer/dummy.ico new file mode 100644 index 0000000000000000000000000000000000000000..0485efe5cd74d4c4040db3e09d498210da3af168 GIT binary patch literal 2238 zcmZQzU<5)11qLACU|7Myz#s->X#lYT5IX=dBTyU+SRfRbWCW5R3gGWPPGz6#@0>Cn0Kmh>onV; - - all - + diff --git a/Usbipd.PowerShell/Usbipd.PowerShell.csproj b/Usbipd.PowerShell/Usbipd.PowerShell.csproj index 03020f9..c12ecd4 100644 --- a/Usbipd.PowerShell/Usbipd.PowerShell.csproj +++ b/Usbipd.PowerShell/Usbipd.PowerShell.csproj @@ -11,9 +11,7 @@ SPDX-License-Identifier: GPL-3.0-only - - all - + diff --git a/Usbipd/Usbipd.csproj b/Usbipd/Usbipd.csproj index af5801a..34c4a18 100644 --- a/Usbipd/Usbipd.csproj +++ b/Usbipd/Usbipd.csproj @@ -27,9 +27,7 @@ SPDX-License-Identifier: GPL-3.0-only - - all - + diff --git a/usbipd-win.sln b/usbipd-win.sln index 009ff61..1d94f5c 100644 --- a/usbipd-win.sln +++ b/usbipd-win.sln @@ -25,6 +25,7 @@ Project("{B7DD6F7E-DEF8-4E67-B5B7-07EF123DB6F0}") = "Installer", "Installer\Inst ProjectSection(ProjectDependencies) = postProject {3C3ED2C8-54D0-48D4-8BF4-78220D4A9E20} = {3C3ED2C8-54D0-48D4-8BF4-78220D4A9E20} {5CE75792-6F4F-4B16-83E6-29052C6E0D8D} = {5CE75792-6F4F-4B16-83E6-29052C6E0D8D} + {CBC206BD-0E45-4514-B148-9035C7459268} = {CBC206BD-0E45-4514-B148-9035C7459268} EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "UnitTests\UnitTests.csproj", "{03DA15B4-7F40-4EF3-814B-9050C7A671B5}" @@ -35,6 +36,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Usbipd.Automation", "Usbipd EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UsbIds", "UsbIds\UsbIds.csproj", "{FC600539-9D82-4822-B2A0-7157D166A444}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CustomActions", "CustomActions\CustomActions.vcxproj", "{CBC206BD-0E45-4514-B148-9035C7459268}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -63,6 +66,9 @@ Global {FC600539-9D82-4822-B2A0-7157D166A444}.Debug|x64.Build.0 = Debug|Any CPU {FC600539-9D82-4822-B2A0-7157D166A444}.Release|x64.ActiveCfg = Release|Any CPU {FC600539-9D82-4822-B2A0-7157D166A444}.Release|x64.Build.0 = Release|Any CPU + {CBC206BD-0E45-4514-B148-9035C7459268}.Debug|x64.ActiveCfg = Release|x64 + {CBC206BD-0E45-4514-B148-9035C7459268}.Debug|x64.Build.0 = Release|x64 + {CBC206BD-0E45-4514-B148-9035C7459268}.Release|x64.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE