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 ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: Windows Patch API: Compressing a Target Without a Basis (Source) File

  1. 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


  2. 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


+ Reply to Thread