diff --git a/.github/workflows/build-cpp.yml b/.github/workflows/build-cpp.yml
new file mode 100644
index 0000000..a0ec763
--- /dev/null
+++ b/.github/workflows/build-cpp.yml
@@ -0,0 +1,89 @@
+name: Build C++ DLL
+
+# Trigger on version tags (e.g. v1.7.0) or manually
+on:
+ push:
+ tags:
+ - 'v*'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ # ── Build x64 and Win32 release DLLs ─────────────────────────────────────────
+ build:
+ runs-on: windows-2022
+ strategy:
+ matrix:
+ platform: [x64, Win32]
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup MSBuild
+ uses: microsoft/setup-msbuild@v2
+
+ # Override the v120 platform toolset with the VS 2022 toolset (v143).
+ # The rdpwrap C++ source is standard Win32 API code and compiles cleanly
+ # with any modern MSVC version.
+ - name: Build rdpwrap.dll (${{ matrix.platform }})
+ working-directory: src-x86-x64-Fusix
+ run: |
+ msbuild RDPWrap.vcxproj `
+ /p:Configuration=Release `
+ /p:Platform="${{ matrix.platform }}" `
+ /p:PlatformToolset=v143 `
+ /p:WindowsTargetPlatformVersion=10.0
+
+ - name: Upload ${{ matrix.platform }} artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: rdpwrap-dll-${{ matrix.platform }}
+ path: src-x86-x64-Fusix/${{ matrix.platform }}/Release/rdpwrap.dll
+ if-no-files-found: error
+
+ # ── Assemble a GitHub Release from both DLL artifacts ────────────────────────
+ release:
+ needs: build
+ runs-on: ubuntu-latest
+ if: startsWith(github.ref, 'refs/tags/')
+
+ steps:
+ - name: Download x64 artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: rdpwrap-dll-x64
+ path: ./dist/x64
+
+ - name: Download Win32 artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: rdpwrap-dll-Win32
+ path: ./dist/x86
+
+ - name: Rename DLLs for release
+ run: |
+ mv dist/x64/rdpwrap.dll dist/rdpwrap_x64.dll
+ mv dist/x86/rdpwrap.dll dist/rdpwrap_x86.dll
+
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v2
+ with:
+ make_latest: false
+ body: |
+ ## RDP Wrapper DLL – ${{ github.ref_name }}
+
+ Built from `src-x86-x64-Fusix/` with MSVC v143 (VS 2022).
+
+ | File | Architecture |
+ |---|---|
+ | `rdpwrap_x64.dll` | x86-64 (64-bit Windows) |
+ | `rdpwrap_x86.dll` | x86 (32-bit Windows) |
+
+ > Place the appropriate DLL in `C:\Program Files\RDP Wrapper\rdpwrap.dll`
+ > and run `RDPWInst.exe -i` to install.
+ files: |
+ dist/rdpwrap_x64.dll
+ dist/rdpwrap_x86.dll
diff --git a/.github/workflows/publish-ini.yml b/.github/workflows/publish-ini.yml
new file mode 100644
index 0000000..7363bb2
--- /dev/null
+++ b/.github/workflows/publish-ini.yml
@@ -0,0 +1,137 @@
+name: Publish INI and Offset Finder Tools
+
+on:
+ push:
+ branches: [main, master]
+ paths:
+ - 'res/rdpwrap.ini'
+ - '.github/workflows/publish-ini.yml'
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ publish:
+ runs-on: windows-2022
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ # ── Extract the date string used for tagging and the updated field ──────
+ - name: Get release metadata
+ id: meta
+ shell: pwsh
+ run: |
+ $date = Get-Date -Format "yyyy.MM.dd.HHmm"
+ $stamp = Get-Date -Format "yyyy-MM-dd HH:mm UTC"
+
+ # Pull the Updated= line out of the INI to surface in release notes
+ $iniContent = Get-Content res/rdpwrap.ini -Raw
+ $iniDate = if ($iniContent -match 'Updated=([^\r\n]+)') { $Matches[1] } else { 'unknown' }
+
+ echo "date=$date" >> $env:GITHUB_OUTPUT
+ echo "stamp=$stamp" >> $env:GITHUB_OUTPUT
+ echo "inidate=$iniDate" >> $env:GITHUB_OUTPUT
+
+ # ── Download the latest RDPWrapOffsetFinder release zip from llccd ──────
+ - name: Download RDPWrapOffsetFinder
+ id: finder
+ shell: pwsh
+ run: |
+ $zip = "RDPWrapOffsetFinder.zip"
+
+ # Resolve the real latest-release download URL via the GitHub API
+ $apiUrl = "https://api.github.com/repos/llccd/RDPWrapOffsetFinder/releases/latest"
+ $release = Invoke-RestMethod -Uri $apiUrl -Headers @{ "User-Agent" = "rdpwrap-ci" }
+ $asset = $release.assets | Where-Object { $_.name -like "*.zip" } | Select-Object -First 1
+ if (-not $asset) { throw "No zip asset found in latest RDPWrapOffsetFinder release" }
+
+ Write-Host "Downloading $($asset.browser_download_url)"
+ Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $zip
+
+ # Expand the archive
+ Expand-Archive -Path $zip -DestinationPath .\finder -Force
+
+ # Diagnostic: show what we got
+ Write-Host "Zip contents:"
+ Get-ChildItem -Recurse .\finder | Select-Object FullName
+
+ # Helper: find a file by name pattern, preferring arch-specific subdirs
+ function Find-Binary($pattern, $archHint) {
+ $hits = Get-ChildItem -Recurse -Filter $pattern .\finder
+ # prefer paths that contain the arch hint
+ $match = $hits | Where-Object { $_.FullName -match $archHint } | Select-Object -First 1
+ if (-not $match) { $match = $hits | Select-Object -First 1 }
+ return $match
+ }
+
+ $x64exe = Find-Binary "RDPWrapOffsetFinder*.exe" "x64"
+ $x86exe = Find-Binary "RDPWrapOffsetFinder*.exe" "x86|Win32|32"
+ $x64dll = Find-Binary "Zydis*.dll" "x64"
+ $x86dll = Find-Binary "Zydis*.dll" "x86|Win32|32"
+
+ # If only one exe/dll variant exists, use it for both architectures
+ if (-not $x86exe) { $x86exe = $x64exe }
+ if (-not $x86dll) { $x86dll = $x64dll }
+ if (-not $x64exe) { throw "Could not locate RDPWrapOffsetFinder exe in zip" }
+ if (-not $x64dll) { throw "Could not locate Zydis dll in zip" }
+
+ Copy-Item $x64exe.FullName .\RDPWrapOffsetFinder_x64.exe
+ Copy-Item $x86exe.FullName .\RDPWrapOffsetFinder_x86.exe
+ Copy-Item $x64dll.FullName .\Zydis_x64.dll
+ Copy-Item $x86dll.FullName .\Zydis_x86.dll
+
+ Write-Host "Staged binaries:"
+ Get-ChildItem .\RDPWrapOffsetFinder_*.exe, .\Zydis_*.dll |
+ Format-Table Name, Length
+
+ echo "finder_ver=$($release.tag_name)" >> $env:GITHUB_OUTPUT
+
+ # ── Validate the INI has required sections ───────────────────────────────
+ - name: Validate INI
+ shell: pwsh
+ run: |
+ $ini = Get-Content res/rdpwrap.ini -Raw
+ foreach ($section in @('[Main]', '[SLPolicy]', '[PatchCodes]')) {
+ if ($ini -notmatch [regex]::Escape($section)) {
+ throw "INI validation failed: missing required section $section"
+ }
+ }
+ $sectionCount = ([regex]::Matches($ini, '^\[[\d\.]+\]', 'Multiline')).Count
+ Write-Host "INI is valid. Windows-version sections: $sectionCount"
+
+ # ── Create/update a versioned GitHub Release with all assets ─────────────
+ - name: Publish release
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: "ini-${{ steps.meta.outputs.date }}"
+ name: "INI Update ${{ steps.meta.outputs.date }}"
+ make_latest: true
+ body: |
+ ## RDP Wrapper — Automated INI Release
+
+ | Field | Value |
+ |---|---|
+ | INI `Updated` date | `${{ steps.meta.outputs.inidate }}` |
+ | Published | ${{ steps.meta.outputs.stamp }} |
+ | RDPWrapOffsetFinder | ${{ steps.finder.outputs.finder_ver }} |
+
+ ### Assets
+ | File | Purpose |
+ |---|---|
+ | `rdpwrap.ini` | Latest offset database for all known termsrv.dll versions |
+ | `RDPWrapOffsetFinder_x64.exe` | Auto-generates offsets for unknown x64 Windows builds |
+ | `RDPWrapOffsetFinder_x86.exe` | Auto-generates offsets for unknown x86 Windows builds |
+ | `Zydis_x64.dll` / `Zydis_x86.dll` | Required runtime for the offset finder |
+
+ The installer fetches `rdpwrap.ini` from this release automatically.
+ If your termsrv.dll version is not in the INI, the installer downloads the
+ offset finder tools and generates the missing section on-the-fly.
+ files: |
+ res/rdpwrap.ini
+ RDPWrapOffsetFinder_x64.exe
+ RDPWrapOffsetFinder_x86.exe
+ Zydis_x64.dll
+ Zydis_x86.dll
diff --git a/README.md b/README.md
index 837e679..d38bafe 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,15 @@
-# RDP Wrapper Library by Stas'M
+# RDP Wrapper Library
+
+> **Maintained fork** by [@sjackson0109](https://github.com/sjackson0109) — based on the original work by [Stas'M / binarymaster](https://github.com/stascorp/rdpwrap).
[](https://t.me/rdpwrap)
-
-[](https://github.com/stascorp/rdpwrap/releases)
-
-
-
+
+[](https://github.com/sjackson0109/rdpwrap/releases)
+[](https://github.com/sjackson0109/rdpwrap/actions/workflows/publish-ini.yml)
+[](https://github.com/sjackson0109/rdpwrap/actions/workflows/build-cpp.yml)
+
+
+
The goal of this project is to enable Remote Desktop Host support and concurrent RDP sessions on reduced functionality systems for home usage.
@@ -64,21 +68,30 @@ It's recommended to have original termsrv.dll file with the RDP Wrapper installa
- Windows 2000, XP and Server 2003 will not be supported
### Key features:
-- RDP host server on any Windows edition beginning from Vista
+- RDP host server on any Windows edition beginning from Vista through Windows 11
- Console and remote sessions at the same time
- Using the same user simultaneously for local and remote logon (see configuration app)
- Up to [15 concurrent sessions](https://github.com/stascorp/rdpwrap/issues/192) (the actual limitation depends on your hardware and OS version)
- Console and RDP session shadowing (using [Task Manager in Windows 7](http://cdn.freshdesk.com/data/helpdesk/attachments/production/1009641577/original/remote_control.png?1413476051) and lower, and [Remote Desktop Connection in Windows 8](http://woshub.com/rds-shadow-how-to-connect-to-a-user-session-in-windows-server-2012-r2/) and higher)
- Full [multi-monitor support](https://github.com/stascorp/rdpwrap/issues/163) for RDP host
-- ...and if you find a new feature not listed here, [tell us](https://github.com/stascorp/rdpwrap/issues/new) ;)
+- **Automatic INI updates** — the installer fetches the latest `rdpwrap.ini` directly from [GitHub Releases](https://github.com/sjackson0109/rdpwrap/releases/latest), published automatically by CI/CD on every change
+- **Auto-generation of offsets for unknown builds** — if your `termsrv.dll` version is not yet in the INI, the installer downloads [RDPWrapOffsetFinder](https://github.com/llccd/RDPWrapOffsetFinder) and generates the missing section on-the-fly (inspired by [sergiye/rdpWrapper](https://github.com/sergiye/rdpWrapper))
+- ...and if you find a new feature not listed here, [tell us](https://github.com/sjackson0109/rdpwrap/issues/new) ;)
### Porting to other platforms:
- **ARM** for Windows RT (see links below)
- **IA-64** for Itanium-based Windows Server? *Well, I have no idea* :)
### Building the binaries:
-- **x86 Delphi version** can be built with *Embarcadero RAD Studio 2010*
-- **x86/x64 C++ version** can be built with *Microsoft Visual Studio 2013*
+- **x86 Delphi version** (installer, config tool, checker) — requires *Embarcadero RAD Studio 2010* or later; no automated CI yet
+- **x86/x64 C++ version** (`rdpwrap.dll`) — can be built locally with *Visual Studio 2013+*, or automatically via the [Build C++ DLL](.github/workflows/build-cpp.yml) GitHub Actions workflow (uses MSVC v143 / VS 2022) by pushing a `v*` tag
+
+### CI/CD Pipelines:
+
+| Workflow | Trigger | Output |
+|---|---|---|
+| [publish-ini.yml](.github/workflows/publish-ini.yml) | Push to `main`/`master` touching `res/rdpwrap.ini`, or manual | GitHub Release with `rdpwrap.ini`, `RDPWrapOffsetFinder_x64/x86.exe`, `Zydis_x64/x86.dll` |
+| [build-cpp.yml](.github/workflows/build-cpp.yml) | Version tag push (`v*`) | GitHub Release with `rdpwrap_x64.dll` and `rdpwrap_x86.dll` |
[andrewblock]: http://web.archive.org/web/20150810054558/http://andrewblock.net/enable-remote-desktop-on-windows-8-core/
[mydigitallife]: http://forums.mydigitallife.info/threads/55935-RDP-Wrapper-Library-(works-with-Windows-8-1-Basic)
@@ -87,8 +100,14 @@ It's recommended to have original termsrv.dll file with the RDP Wrapper installa
[yt-offsets]: http://www.youtube.com/watch?v=FiD86tmRBtk
### Links:
-- Official GitHub repository:
+- **This fork (maintained):**
+
https://github.com/sjackson0109/rdpwrap/
+- Original upstream repository (archived / unmaintained):
https://github.com/stascorp/rdpwrap/
+- Inspiration for auto-offset generation:
+
[sergiye/rdpWrapper](https://github.com/sergiye/rdpWrapper)
+- Offset finder tool used for auto-generation:
+
[llccd/RDPWrapOffsetFinder](https://github.com/llccd/RDPWrapOffsetFinder)
- Official Telegram chat:
https://t.me/rdpwrap
- Active discussion in the comments here:
@@ -119,7 +138,7 @@ It's recommended to have original termsrv.dll file with the RDP Wrapper installa
> Where can I download the installer or binaries?
-In the [GitHub Releases](https://github.com/stascorp/rdpwrap/releases) section.
+In the [GitHub Releases](https://github.com/sjackson0109/rdpwrap/releases) section.
> Is it legal to use this application?
@@ -131,7 +150,7 @@ Yes, it works in online mode by default. You may disable it by removing `-o` fla
> What is online install mode?
-Online install mode introduced in version 1.6.1. When you installing RDP Wrapper first time using this mode, it will download [latest INI file](https://github.com/stascorp/rdpwrap/blob/master/res/rdpwrap.ini) from GitHub. See [this discussion](https://github.com/stascorp/rdpwrap/issues/132).
+Online install mode was introduced in version 1.6.1. When installing for the first time using this mode, the installer downloads the [latest `rdpwrap.ini`](https://github.com/sjackson0109/rdpwrap/releases/latest/download/rdpwrap.ini) from this repository's GitHub Releases — published automatically by CI/CD whenever `res/rdpwrap.ini` is updated. If your `termsrv.dll` version is not yet listed in the downloaded INI, the installer will additionally download [RDPWrapOffsetFinder](https://github.com/llccd/RDPWrapOffsetFinder) and attempt to auto-generate the missing offsets on the spot.
> What is INI file and why we need it?
@@ -143,11 +162,11 @@ Beginning with version 1.5 the `rdpwrap.dll` is not updated anymore, since all s
> Config Tool shows `[not supported]` and RDP doesn't work. What can I do?
-Make sure you're connected to the Internet and run `update.bat`.
+Make sure you're connected to the Internet and run `update.bat`. This will download the latest INI from GitHub Releases and, if your `termsrv.dll` version is still missing, will automatically run [RDPWrapOffsetFinder](https://github.com/llccd/RDPWrapOffsetFinder) to generate offsets for your specific build.
> Update doesn't help, it still shows `[not supported]`.
-Visit [issues](https://github.com/stascorp/rdpwrap/issues) section, and check whether your `termsrv.dll` build is listed here. If you can't find such issue, create a new — specify your build version for adding to support.
+Check the [issues](https://github.com/sjackson0109/rdpwrap/issues) section to see if your `termsrv.dll` build is mentioned. If not, please open a new issue with your exact build version (shown by the Config Tool). You can also run `RDPWInst.exe -w` from an Administrator command prompt to see the full output of the update and auto-generation steps.
> Why `RDPCheck` doesn't allow to change resolution and other settings?
@@ -168,6 +187,14 @@ Visit [issues](https://github.com/stascorp/rdpwrap/issues) section, and check wh
### Change log:
+#### 2026.03.29
+- Fork maintained by [@sjackson0109](https://github.com/sjackson0109)
+- INI source redirected from unmaintained stascorp upstream to this repository's GitHub Releases
+- **CI/CD pipeline added** — [`publish-ini.yml`](.github/workflows/publish-ini.yml) publishes `rdpwrap.ini` and the `RDPWrapOffsetFinder` tools as release assets on every INI change
+- **CI/CD pipeline added** — [`build-cpp.yml`](.github/workflows/build-cpp.yml) builds `rdpwrap_x64.dll` / `rdpwrap_x86.dll` via MSVC v143 (VS 2022) on version tag push
+- **Auto-offset generation** added to `RDPWInst.dpr` — on install (`-i`) and update (`-w`), if the running `termsrv.dll` version is absent from the INI the installer downloads `RDPWrapOffsetFinder` from release assets and appends the generated `[x.x.xxxxx.xxxxx]` section automatically; inspired by [sergiye/rdpWrapper](https://github.com/sergiye/rdpWrapper)
+- New installer helpers: `DownloadFileToDisk`, `INIHasSection`, `TryAutoGenerateOffsets`
+
#### 2017.12.27
- Version 1.6.2
- Installer updated
diff --git a/src-installer/RDPWInst.dpr b/src-installer/RDPWInst.dpr
index 6c95f3f..f419d82 100644
--- a/src-installer/RDPWInst.dpr
+++ b/src-installer/RDPWInst.dpr
@@ -93,6 +93,7 @@ var
TermServicePID: DWORD;
ShareSvc: Array of String;
sShareSvc: String;
+ TermSrvVerTxt: String; // e.g. '10.0.26100.7623' — set by CheckTermsrvVersion
function SupportedArchitecture: Boolean;
var
@@ -617,7 +618,9 @@ end;
function GitINIFile(var Content: String): Boolean;
const
- URL = 'https://raw.githubusercontent.com/stascorp/rdpwrap/master/res/rdpwrap.ini';
+ // Points to the latest release artifact in the sjackson0109 fork.
+ // The publish-ini CI/CD workflow keeps this asset up to date automatically.
+ URL = 'https://github.com/sjackson0109/rdpwrap/releases/latest/download/rdpwrap.ini';
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
@@ -843,6 +846,138 @@ begin
Result := True;
end;
+{ ──────────────────────────────────────────────────────────────────────────────
+ DownloadFileToDisk
+ Downloads the HTTP/HTTPS resource at URL and saves it to DestPath on disk.
+ Returns True only when the destination file exists and is non-empty.
+────────────────────────────────────────────────────────────────────────────── }
+function DownloadFileToDisk(const URL, DestPath: String): Boolean;
+var
+ NetHandle: HINTERNET;
+ UrlHandle: HINTERNET;
+ FileHandle: THandle;
+ Buf: Array[0..4095] of Byte;
+ BytesRead, BytesWritten: DWORD;
+begin
+ Result := False;
+ NetHandle := InternetOpen('RDP Wrapper', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
+ if not Assigned(NetHandle) then Exit;
+ UrlHandle := InternetOpenUrl(NetHandle, PChar(URL), nil, 0, INTERNET_FLAG_RELOAD, 0);
+ if not Assigned(UrlHandle) then
+ begin
+ InternetCloseHandle(NetHandle);
+ Exit;
+ end;
+ FileHandle := CreateFile(PChar(DestPath), GENERIC_WRITE, 0, nil,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if FileHandle = INVALID_HANDLE_VALUE then
+ begin
+ InternetCloseHandle(UrlHandle);
+ InternetCloseHandle(NetHandle);
+ Exit;
+ end;
+ repeat
+ InternetReadFile(UrlHandle, @Buf[0], SizeOf(Buf), BytesRead);
+ if BytesRead > 0 then
+ WriteFile(FileHandle, Buf[0], BytesRead, BytesWritten, nil);
+ until BytesRead = 0;
+ CloseHandle(FileHandle);
+ InternetCloseHandle(UrlHandle);
+ InternetCloseHandle(NetHandle);
+ Result := FileExists(DestPath);
+end;
+
+{ ──────────────────────────────────────────────────────────────────────────────
+ INIHasSection
+ Returns True when the INI file at INIPath contains [Section].
+────────────────────────────────────────────────────────────────────────────── }
+function INIHasSection(const INIPath, Section: String): Boolean;
+var
+ F: TStringList;
+begin
+ Result := False;
+ if not FileExists(INIPath) then Exit;
+ F := TStringList.Create;
+ try
+ F.LoadFromFile(INIPath);
+ Result := Pos('[' + Section + ']', F.Text) > 0;
+ finally
+ F.Free;
+ end;
+end;
+
+{ ──────────────────────────────────────────────────────────────────────────────
+ TryAutoGenerateOffsets
+ If the current termsrv.dll version (TermSrvVerTxt) is absent from the on-disk
+ rdpwrap.ini, download RDPWrapOffsetFinder + Zydis from the sjackson0109 release
+ assets and run the finder to append the generated section to the INI.
+ This mirrors the approach used by sergiye/rdpWrapper (Wrapper.cs GenerateIniFile).
+────────────────────────────────────────────────────────────────────────────── }
+procedure TryAutoGenerateOffsets;
+const
+ BASE_URL = 'https://github.com/sjackson0109/rdpwrap/releases/latest/download/';
+var
+ TempDir, ExePath, DllPath, INIPath, ArchSuffix, SysCmd: String;
+begin
+ if TermSrvVerTxt = '' then Exit;
+
+ INIPath := ExtractFilePath(ExpandPath(WrapPath)) + 'rdpwrap.ini';
+
+ if INIHasSection(INIPath, TermSrvVerTxt) then
+ begin
+ Writeln('[+] Version ', TermSrvVerTxt, ' is covered in INI.');
+ Exit;
+ end;
+
+ Writeln('[!] Version ', TermSrvVerTxt, ' not found in INI.');
+ Writeln('[*] Attempting automatic offset generation via RDPWrapOffsetFinder...');
+
+ if Arch = 64 then ArchSuffix := '_x64' else ArchSuffix := '_x86';
+
+ TempDir := ExpandPath('%TEMP%') + '\rdpwrapoffset';
+ if not ForceDirectories(TempDir) and not DirectoryExists(TempDir) then
+ begin
+ Writeln('[-] Could not create temp directory. Skipping auto-generation.');
+ Exit;
+ end;
+
+ ExePath := TempDir + '\RDPWrapOffsetFinder.exe';
+ DllPath := TempDir + '\Zydis.dll';
+
+ Writeln('[*] Downloading RDPWrapOffsetFinder', ArchSuffix, '.exe ...');
+ if not DownloadFileToDisk(BASE_URL + 'RDPWrapOffsetFinder' + ArchSuffix + '.exe', ExePath) then
+ begin
+ Writeln('[-] Download failed. The release asset may not yet be published.');
+ Writeln('[!] Run the publish-ini workflow on the sjackson0109/rdpwrap repository,');
+ Writeln('[!] then re-run this installer to enable auto-generation.');
+ Exit;
+ end;
+
+ Writeln('[*] Downloading Zydis', ArchSuffix, '.dll ...');
+ if not DownloadFileToDisk(BASE_URL + 'Zydis' + ArchSuffix + '.dll', DllPath) then
+ begin
+ Writeln('[-] Zydis download failed. Skipping auto-generation.');
+ DeleteFile(ExePath);
+ Exit;
+ end;
+
+ Writeln('[*] Running offset finder for termsrv.dll ', TermSrvVerTxt, ' ...');
+ { Run via cmd.exe so >> redirect to the INI file works correctly. }
+ SysCmd := ExpandPath('%SystemRoot%') + '\System32\cmd.exe';
+ ExecWait('"' + SysCmd + '" /c ""' + ExePath + '" >> "' + INIPath + '""');
+
+ if INIHasSection(INIPath, TermSrvVerTxt) then
+ Writeln('[+] Offsets generated successfully for version ', TermSrvVerTxt)
+ else
+ Writeln('[!] Offset finder ran but [', TermSrvVerTxt, '] was not added.',
+ ' Session may be limited or unstable for this build.');
+
+ { Clean up temporary tool files }
+ DeleteFile(ExePath);
+ DeleteFile(DllPath);
+ RemoveDirectory(PChar(TempDir));
+end;
+
procedure CheckTermsrvVersion;
var
SuppLvl: Byte;
@@ -857,6 +992,7 @@ begin
GetFileVersion(ExpandPath(TermServicePath), FV);
VerTxt := Format('%d.%d.%d.%d',
[FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]);
+ TermSrvVerTxt := VerTxt; // expose globally for TryAutoGenerateOffsets
Writeln('[*] Terminal Services version: ', VerTxt);
if (FV.Version.w.Major = 5) and (FV.Version.w.Minor = 1) then
@@ -1119,6 +1255,15 @@ begin
end;
Str.Free;
+ { After writing updated INI, fill any missing section for the running
+ termsrv.dll. FV/TermSrvVerTxt may not be set in the -w path, so
+ compute the version here before calling TryAutoGenerateOffsets. }
+ GetFileVersion(ExpandPath(TermServicePath), FV);
+ TermSrvVerTxt := Format('%d.%d.%d.%d',
+ [FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build]);
+ Writeln('[*] Checking INI coverage for installed termsrv.dll version...');
+ TryAutoGenerateOffsets;
+
SvcStart(TermService);
Writeln('[+] Update completed.');
@@ -1208,6 +1353,9 @@ begin
Online := (ParamStr(2) = '-o') or (ParamStr(3) = '-o');
ExtractFiles;
+ Writeln('[*] Checking INI coverage for installed termsrv.dll version...');
+ TryAutoGenerateOffsets;
+
Writeln('[*] Configuring service library...');
SetWrapperDll;