Windows Patch API: Compressing a Target Without a Basis (Source) File - Programmer
This is a discussion on Windows Patch API: Compressing a Target Without a Basis (Source) File - Programmer ; According to the following web page
http://msdn.microsoft.com/library/de...bdcapitech.asp
it should be possible to use CreatePatchFile() from MSPATCHC.DLL to
compress an executable (e.g. A.DLL) without supplying a previous
version (a basis or a source file) of the target file to the API ...
-
Windows Patch API: Compressing a Target Without a Basis (Source) File
According to the following web page
http://msdn.microsoft.com/library/de...bdcapitech.asp
it should be possible to use CreatePatchFile() from MSPATCHC.DLL to
compress an executable (e.g. A.DLL) without supplying a previous
version (a basis or a source file) of the target file to the API call.
For example, the following code should create a compressed version of
A.DLL:
BOOL ok = CreatePatchFile(
NULL // LPCSTR OldFileName
, "a.dll" // LPCSTR NewFileName
, "a.patch" // LPCSTR PatchFileName
, PATCH_OPTION_USE_BEST // ULONG OptionFlags
, NULL // PPATCH_OPTION_DATA OptionData
);
Instead, it returns an error and GetLastError() reports error #3: 'The
system cannot find the path specified.'
The offending paragraph titled 'Compressing a Target Without a Basis
File' from the above mentioned web page reads:
"If a Delta Create function is called and the basis file is specified
as NULL (file name string pointer for functions that designate files by
paths) or INVALID_HANDLE_VALUE (handle for functions that designate
files by handles), the output will be a compressed target file that is
not actually a delta."
What am I doing wrong and how to make CreatePatchFile() compress a
target without a basis file? Do I have to pass a specific OptionFlags
value, or supply a specific OptionData structure?
I'm running into a similar problem when trying to decompress a patch
file using ApplyPatchToFile() with OldFileName set to NULL.
Any ideas to the solution of the problem?
Thanks in advance,
Boris
bmazic [at] onetel [dot] com
-
Re: Windows Patch API: Compressing a Target Without a Basis (Source) File
It turns out that you need to supply a name of an empty file instead of
NULL (this is contrary to what is mentioned in the documentation). At
least that's how it works on my system:
Win XP Pro SP2
Depends.exe output for MSPATCHC.DLL & MSPATCHA.DLL:
[ ] MSPATCHC.DLL 03.03.2006 23:20 01.02.2003 10:24 47.616 A
0x0000DCF4 0x0000DCF4 x86 GUI PDB 0x47D50000
Unknown 0x0000F000 Not Loaded 5.2.3760.0 5.2.3760.0
5.2 7.10 5.2 4.0
[ ] MSPATCHA.DLL 04.08.2004 6:00 04.08.2004
9:58 30.208 A 0x00007D17 0x00007D17 x86 GUI
CV 0x600A0000 Unknown 0x0000B000 Not Loaded
5.1.2600.2180 5.1.2600.2180 5.1 7.10 5.1 4.0
The following code illustrates the solution.
---------%<-------------%<--------------------%<-------------%<-----------
#include
#include
#include
#define BASE L"patchapi.exe"
#define EMPTY L"empty.dll"
int main(int argc, wchar_t const* argv[]) {
BOOL ok = 0;
// This works fine
printf("Normal usage: oldfile, newfile, patchfile\n");
ok = CreatePatchFileW(BASE, BASE, BASE L".p", 0, 0);
printf("Create %s [%X]\n", ok ? "+" : "-", GetLastError());
ok = ApplyPatchToFileW(BASE L".p", BASE, BASE L".out", 0);
printf("Apply %s [%X]\n", ok ? "+" : "-", GetLastError());
// This doesn't work at all on my system
printf("Compression only usage: NULL, newfile, patchfile\n");
ok = CreatePatchFileW(NULL, BASE, BASE L".p_n", 0, 0);
printf("Create %s [%X]\n", ok ? "+" : "-", GetLastError());
ok = ApplyPatchToFileW(BASE L".p_n", NULL, BASE L".out_n", 0);
printf("Apply %s [%X]\n", ok ? "+" : "-", GetLastError());
// create an empty file
HANDLE e = CreateFileW(EMPTY, GENERIC_READ | GENERIC_WRITE
, 0, NULL, CREATE_ALWAYS, 0, NULL);
CloseHandle(e);
// This works OK
printf("Compression only usage: EMPTY, newfile, patchfile\n");
ok = CreatePatchFileW(EMPTY, BASE, BASE L".p_e", 0, 0);
printf("Create %s [%X]\n", ok ? "+" : "-", GetLastError());
ok = ApplyPatchToFileW(BASE L".p_e", EMPTY, BASE L".out_e", 0);
printf("Apply %s [%X]\n", ok ? "+" : "-", GetLastError());
return 0;
}
---------%<-------------%<--------------------%<-------------%<-----------
When run, it produces the following output on the console:
---------%<-------------%<--------------------%<-------------%<-----------
Normal usage: oldfile, newfile, patchfile
Create + [0]
Apply + [0]
Compression only usage: NULL, newfile, patchfile
Create - [3]
Apply - [2]
Compression only usage: EMPTY, newfile, patchfile
Create + [0]
Apply + [1E7]
---------%<-------------%<--------------------%<-------------%<-----------
Your mileage may vary.
Boris