0% found this document useful (0 votes)
29 views2 pages

PSFX

The document contains a PowerShell script that defines functions for handling delta compression and applying patches to files. It includes methods for loading dynamic libraries, processing XML files to extract delta information, and applying those deltas to create updated files. The script also manages file paths and handles potential issues with long file names during the extraction process.

Uploaded by

Pedro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views2 pages

PSFX

The document contains a PowerShell script that defines functions for handling delta compression and applying patches to files. It includes methods for loading dynamic libraries, processing XML files to extract delta information, and applying those deltas to create updated files. The script also manages file paths and handles potential issues with long file names during the extraction process.

Uploaded by

Pedro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 2

@exit /b

:cabpsf:
function Native($DllFile)
{
$Lib = [IO.Path]::GetFileName($DllFile)
$Marshal = [System.Runtime.InteropServices.Marshal]
$Module = [AppDomain]::CurrentDomain.DefineDynamicAssembly((Get-Random),
'Run').DefineDynamicModule((Get-Random))
$Struct = $Module.DefineType('DI', 1048841, [ValueType], 0)
[void]$Struct.DefineField('lpStart', [IntPtr], 6)
[void]$Struct.DefineField('uSize', [UIntPtr], 6)
[void]$Struct.DefineField('Editable', [Boolean], 6)
$DELTA_INPUT = $Struct.CreateType()
$Struct = $Module.DefineType('DO', 1048841, [ValueType], 0)
[void]$Struct.DefineField('lpStart', [IntPtr], 6)
[void]$Struct.DefineField('uSize', [UIntPtr], 6)
$DELTA_OUTPUT = $Struct.CreateType()
$Class = $Module.DefineType('PSFE', 1048961, [Object], 0)
[void]$Class.DefinePInvokeMethod('LoadLibraryW', 'kernel32.dll', 22, 1, [IntPtr],
@([String]), 1, 3).SetImplementationFlags(128)
[void]$Class.DefinePInvokeMethod('ApplyDeltaB', $Lib, 22, 1, [Int32], @([Int64],
[Type]$DELTA_INPUT, [Type]$DELTA_INPUT, [Type]$DELTA_OUTPUT.MakeByRefType()), 1, 3)
[void]$Class.DefinePInvokeMethod('DeltaFree', $Lib, 22, 1, [Int32], @([IntPtr]), 1,
3)
$Win32 = $Class.CreateType()
}
function ApplyDelta($dBuffer, $dFile)
{
$trg = [Activator]::CreateInstance($DELTA_OUTPUT)
$src = [Activator]::CreateInstance($DELTA_INPUT)
$dlt = [Activator]::CreateInstance($DELTA_INPUT)
$dlt.lpStart = $Marshal::AllocHGlobal($dBuffer.Length)
$dlt.uSize = [Activator]::CreateInstance([UIntPtr], @([UInt32]$dBuffer.Length))
$dlt.Editable = $true
$Marshal::Copy($dBuffer, 0, $dlt.lpStart, $dBuffer.Length)
[void]$Win32::ApplyDeltaB(0, $src, $dlt, [ref]$trg)
if ($trg.lpStart -eq [IntPtr]::Zero) {return}
$out = New-Object byte[] $trg.uSize.ToUInt32()
$Marshal::Copy($trg.lpStart, $out, 0, $out.Length)
[IO.File]::WriteAllBytes($dFile, $out)
if ($dlt.lpStart -ne [IntPtr]::Zero) {$Marshal::FreeHGlobal($dlt.lpStart)}
if ($trg.lpStart -ne [IntPtr]::Zero) {[void]$Win32::DeltaFree($trg.lpStart)}
}
function G($DirectoryName)
{
$DeltaList = [ordered] @{}
$doc = New-Object xml
$doc.Load($DirectoryName + "\express.psf.cix.xml")
$child = $doc.FirstChild.NextSibling.FirstChild
while (!$child.LocalName.Equals("Files")) {$child = $child.NextSibling}
$FileList = $child.ChildNodes
foreach ($file in $FileList)
{
$fileChild = $file.FirstChild
while (!$fileChild.LocalName.Equals("Delta")) {$fileChild = $fileChild.NextSibling}
$deltaChild = $fileChild.FirstChild
while (!$deltaChild.LocalName.Equals("Source")) {$deltaChild =
$deltaChild.NextSibling}
$DeltaList[$($file.id)] = @{name=$file.name; time=$file.time;
stype=$deltaChild.type; offset=$deltaChild.offset; length=$deltaChild.length};
}
return $DeltaList
}
function P($CabFile, $DllFile = 'msdelta.dll')
{
if ($DllFile -eq 'msdelta.dll' -and (Test-Path "$env:SystemRoot\System32\
UpdateCompression.dll")) {$DllFile = "$env:SystemRoot\System32\
UpdateCompression.dll"}
. Native($DllFile)
[void]$Win32::LoadLibraryW($DllFile)
$DirectoryName = $CabFile.Substring(0, $CabFile.LastIndexOf('.'))
$PSFFile = $DirectoryName + ".psf"
$null = [IO.Directory]::CreateDirectory($DirectoryName)
$DeltaList = G $DirectoryName
$PSFFileStream = [IO.File]::OpenRead([IO.Path]::GetFullPath($PSFFile))
$cwd = [IO.Path]::GetFullPath($DirectoryName)
[Environment]::CurrentDirectory = $cwd
$null = [IO.Directory]::CreateDirectory("000")
foreach ($DeltaFile in $DeltaList.Values)
{
$FullFileName = $DeltaFile.name
if (Test-Path $FullFileName) {continue}
$ShortFold = [IO.Path]::GetDirectoryName($FullFileName)
$ShortFile = [IO.Path]::GetFileName($FullFileName)
[bool]$UseRobo = (($cwd + '\' + $FullFileName).Length -gt 255) -or (($cwd + '\' +
$ShortFold).Length -gt 248)
if ($UseRobo -eq 0 -and $ShortFold.IndexOf("_") -ne -1) {$null =
[IO.Directory]::CreateDirectory($ShortFold)}
if ($UseRobo -eq 0) {$WhereFile = $FullFileName}
Else {$WhereFile = "000\" + $ShortFile}
try {[void]$PSFFileStream.Seek($DeltaFile.offset, 0)} catch {}
$Buffer = New-Object byte[] $DeltaFile.length
try {[void]$PSFFileStream.Read($Buffer, 0, $DeltaFile.length)} catch {}
$OutputFileStream = [IO.File]::Create($WhereFile)
try {[void]$OutputFileStream.Write($Buffer, 0, $DeltaFile.length)} catch {}
[void]$OutputFileStream.Close()
if ($DeltaFile.stype -eq "PA30" -or $DeltaFile.stype -eq "PA31") {ApplyDelta
$Buffer $WhereFile}
$null = [IO.File]::SetLastWriteTimeUtc($WhereFile,
[DateTime]::FromFileTimeUtc($DeltaFile.time))
if ($UseRobo -eq 0) {continue}
Start-Process robocopy.exe -NoNewWindow -Wait -ArgumentList ('"' + $cwd + '\000' +
'"' + ' ' + '"' + $cwd + '\' + $ShortFold + '"' + ' ' + $ShortFile + ' /MOV /R:1
/W:1 /NS /NC /NFL /NDL /NP /NJH /NJS')
}
[void]$PSFFileStream.Close()
$null = [IO.Directory]::Delete("000", $True)
}
:cabpsf:

You might also like