# Extract and verify only the runtime DLLs needed by the 5.5.3 gateway. # No newer APPX engine or gateway is installed. param( [Parameter(Mandatory=$true)][string]$IcuInstaller, [Parameter(Mandatory=$true)][string]$BoostDll, [string]$WorkDirectory='C:\APPX-ODBC-553-Runtime', [string]$GatewayRoot='C:\Program Files (x86)\AppxODBCserver', [switch]$StageOnly ) $ErrorActionPreference='Stop' if(Test-Path $WorkDirectory){throw 'Work directory exists; choose a new one to preserve previous work.'} if((Get-FileHash $IcuInstaller).Hash -ne '48330B0FFED3F69280E87C8C88CCD79CFEBCAD050840B73B2518A27AE7FA6659'){throw 'ICU source must be the verified official APPX 6.2.1 x86 gateway package.'} if((Get-FileHash $BoostDll).Hash -ne 'EA0C12DADBB985198ACD186A18371E6108DEE5BEACB073CAE600666E27AA3B84'){throw 'Boost DLL differs from the verified official Boost 1.71 MSVC 14.2 x86 file.'} $expected=@{ 'icuuc59.dll'='202527621D7E252F29B8826265A8E11848CEE897348FD23D9F6912C0693A30BE' 'icuin59.dll'='91E788C4F85FA07BDBDD34297A1C29B2594BCF9C20E7E3E2C1A109A98DA9C27F' 'icudt59.dll'='B9B0A19A996ADBBD622B1E50B70C07CE3C966A98CC9CB2C81F6E6B45E26E3F0D' 'boost_regex-vc142-mt-x32-1_71.dll'='EA0C12DADBB985198ACD186A18371E6108DEE5BEACB073CAE600666E27AA3B84' } if(-not $StageOnly){ if((Get-FileHash "$GatewayRoot\bin\AppxODBC.exe").Hash -ne '0BBAC6560FEADBF2EC7ACB24FB76F92AF12FE0E21B9D01725E1BECC3C29D0C25'){throw 'Gateway executable differs from the tested 5.5.3 package.'} if((Get-Service 'Appx ODBC Data Gateway Server for Windows').Status -ne 'Stopped'){throw 'Stop the gateway service before copying runtime files.'} } New-Item -ItemType Directory $WorkDirectory | Out-Null Add-Type -AssemblyName System.IO.Compression.FileSystem $bytes=[IO.File]::ReadAllBytes((Resolve-Path $IcuInstaller)) $end=-1 for($i=$bytes.Length-22;$i -ge [Math]::Max(0,$bytes.Length-65557);$i--){ if([BitConverter]::ToUInt32($bytes,$i) -eq 0x06054b50 -and $i+22+[BitConverter]::ToUInt16($bytes,$i+20) -le $bytes.Length){$end=$i;break} } if($end -lt 0){throw 'Verified ZIP directory not found.'} $start=$end-[BitConverter]::ToUInt32($bytes,$end+12)-[BitConverter]::ToUInt32($bytes,$end+16) if($start -lt 0 -or [BitConverter]::ToUInt32($bytes,$start) -ne 0x04034b50){throw 'Verified ZIP boundary differs.'} $payload=Join-Path $WorkDirectory 'runtime-payload.zip' $stream=[IO.File]::Create($payload) try{$stream.Write($bytes,$start,$end+22+[BitConverter]::ToUInt16($bytes,$end+20)-$start)}finally{$stream.Dispose()} $zip=[IO.Compression.ZipFile]::OpenRead($payload) try{ foreach($name in @('icuuc59.dll','icuin59.dll','icudt59.dll')){ $entry=$zip.Entries|Where-Object {$_.Name -eq $name}|Select-Object -First 1 if(-not $entry){throw "Missing runtime: $name"} [IO.Compression.ZipFileExtensions]::ExtractToFile($entry,(Join-Path $WorkDirectory $name),$false) } }finally{$zip.Dispose()} Copy-Item $BoostDll $WorkDirectory foreach($name in $expected.Keys){ $file=Join-Path $WorkDirectory $name if((Get-FileHash $file).Hash -ne $expected[$name]){throw "Runtime hash differs: $name"} } if(-not $StageOnly){ $backup=Join-Path $WorkDirectory 'previous-gateway-files' New-Item -ItemType Directory $backup | Out-Null foreach($name in $expected.Keys){ $target=Join-Path "$GatewayRoot\bin" $name if(Test-Path $target){Copy-Item $target $backup} Copy-Item (Join-Path $WorkDirectory $name) $target } } Get-ChildItem $WorkDirectory -Filter '*.dll' | Get-FileHash -Algorithm SHA256 Write-Host 'Four runtime DLLs verified. Next: start and check the 5.5.3 gateway service.'