Skip to content

Instantly share code, notes, and snippets.

@sevaa
Created October 18, 2019 14:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sevaa/a49457319946379b60e885f6b5a9f5ca to your computer and use it in GitHub Desktop.
Save sevaa/a49457319946379b60e885f6b5a9f5ca to your computer and use it in GitHub Desktop.
C# wrapper around MSDelta's ApplyDeltaB API
class Delta
{
[StructLayout(LayoutKind.Sequential)]
private struct DELTA_INPUT
{
public IntPtr lpcStart;
public UIntPtr uSize;
[MarshalAs(UnmanagedType.Bool)]
public bool Editable;
}
[StructLayout(LayoutKind.Sequential)]
private struct DELTA_OUTPUT
{
public IntPtr lpcStart;
public UIntPtr uSize;
}
[Flags]
private enum DELTA_FLAG_TYPE : long
{
None = 0,
AllowPa19 = 1
}
[DllImport("msdelta.dll", SetLastError = true)]
private static extern bool ApplyDeltaB(DELTA_FLAG_TYPE ApplyFlags, DELTA_INPUT Source, DELTA_INPUT Delta, out DELTA_OUTPUT lpTarget);
[DllImport("msdelta.dll", SetLastError = true)]
private static extern bool DeltaFree(IntPtr lpMemory);
static public byte[] ApplyDelta(byte[] Orig, byte[] Delta)
{
DELTA_INPUT hOrig = new DELTA_INPUT() { lpcStart = IntPtr.Zero, uSize = new UIntPtr((uint)Orig.Length), Editable = true },
hDelta = new DELTA_INPUT() { lpcStart = IntPtr.Zero, uSize = new UIntPtr((uint)Delta.Length), Editable = true };
DELTA_OUTPUT hResult = new DELTA_OUTPUT() { lpcStart = IntPtr.Zero, uSize = UIntPtr.Zero };
try
{
hOrig.lpcStart = Marshal.AllocHGlobal(Orig.Length);
Marshal.Copy(Orig, 0, hOrig.lpcStart, Orig.Length);
hDelta.lpcStart = Marshal.AllocHGlobal(Delta.Length);
Marshal.Copy(Delta, 0, hDelta.lpcStart, Delta.Length);
if (!ApplyDeltaB(DELTA_FLAG_TYPE.AllowPa19, hOrig, hDelta, out hResult))
throw new Win32Exception(Marshal.GetLastWin32Error());
byte[] Result = new byte[hResult.uSize.ToUInt32()];
Marshal.Copy(hResult.lpcStart, Result, 0, Result.Length);
return Result;
}
finally
{
if (hOrig.lpcStart != IntPtr.Zero)
Marshal.FreeHGlobal(hOrig.lpcStart);
if (hDelta.lpcStart != IntPtr.Zero)
Marshal.FreeHGlobal(hDelta.lpcStart);
if (hResult.lpcStart != IntPtr.Zero)
DeltaFree(hResult.lpcStart);
}
}
}
@sevaa
Copy link
Author

sevaa commented Oct 18, 2019

@sevaa
Copy link
Author

sevaa commented May 4, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment