Sweden-Number/dlls/mspatcha/tests/apply_patch.c

815 lines
55 KiB
C

/*
* Unit tests for Patch API functions
*
* Copyright (c) 2019 Conor McCarthy
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
*
* Without mspatchc.dll, the inability to create test patch files under Wine
* limits testing to the supplied small files.
*/
#include "wine/test.h"
#include "windef.h"
#include "winerror.h"
#include "patchapi.h"
static BOOL (WINAPI *pApplyPatchToFileA)(LPCSTR, LPCSTR, LPCSTR, ULONG);
static BOOL (WINAPI *pApplyPatchToFileByHandles)(HANDLE, HANDLE, HANDLE, ULONG);
static BOOL (WINAPI *pApplyPatchToFileExA)(LPCSTR, LPCSTR, LPCSTR, ULONG, PPATCH_PROGRESS_CALLBACK, PVOID);
static BOOL (WINAPI *pApplyPatchToFileByHandlesEx)(HANDLE, HANDLE, HANDLE, ULONG, PPATCH_PROGRESS_CALLBACK, PVOID);
static BOOL (WINAPI *pApplyPatchToFileByBuffers)(PBYTE, ULONG, PBYTE, ULONG, PBYTE*, ULONG, ULONG*, FILETIME*, ULONG, PPATCH_PROGRESS_CALLBACK, PVOID);
static BOOL (WINAPI *pTestApplyPatchToFileA)(LPCSTR, LPCSTR, ULONG);
static BOOL (WINAPI *pTestApplyPatchToFileByHandles)(HANDLE, HANDLE, ULONG);
static BOOL (WINAPI *pTestApplyPatchToFileByBuffers)(PBYTE, ULONG, PBYTE, ULONG, ULONG*, ULONG);
static DWORD (WINAPI *pGetVersion)(void) = NULL;
static DWORD win_version = 0x601;
static BOOL init_function_pointers(void)
{
HMODULE kernel32;
HMODULE mspatcha = LoadLibraryA("mspatcha.dll");
if (!mspatcha)
{
win_skip("mspatcha.dll not found\n");
return FALSE;
}
pApplyPatchToFileA = (void *)GetProcAddress(mspatcha, "ApplyPatchToFileA");
pApplyPatchToFileExA = (void *)GetProcAddress(mspatcha, "ApplyPatchToFileExA");
pApplyPatchToFileByHandles = (void *)GetProcAddress(mspatcha, "ApplyPatchToFileByHandles");
pApplyPatchToFileByBuffers = (void *)GetProcAddress(mspatcha, "ApplyPatchToFileByBuffers");
pApplyPatchToFileByHandlesEx = (void *)GetProcAddress(mspatcha, "ApplyPatchToFileByHandlesEx");
pTestApplyPatchToFileA = (void *)GetProcAddress(mspatcha, "TestApplyPatchToFileA");
pTestApplyPatchToFileByHandles = (void *)GetProcAddress(mspatcha, "TestApplyPatchToFileByHandles");
pTestApplyPatchToFileByBuffers = (void *)GetProcAddress(mspatcha, "TestApplyPatchToFileByBuffers");
kernel32 = GetModuleHandleA("kernel32.dll");
if (kernel32)
{
pGetVersion = (void *)GetProcAddress(kernel32, "GetVersion");
if (pGetVersion)
{
win_version = pGetVersion() & 0xFFFF;
win_version = ((win_version & 0xFF) << 8) | (win_version >> 8);
}
}
return TRUE;
}
#define TWO_FILES_RANGES_SIZE 1023
/* BYTE* arguments to ApplyPatchToFileByBuffers() are not const even for input */
static BYTE old_two_files_ranges_0[] = {
0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x4E,0x3F,0x3D,0x35,
0x4D,0x32,0x31,0x51,0x30,0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,
0x35,0x33,0x33,0x31,0x30,0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,
0x48,0x3B,0x47,0x3E,0x33,0x3E,0x30,0x37,0x31,0x35,0x3F,0x4B,0x47,0x39,0x35,0x53,0x32,0x34,0x30,0x37,0x30,0x48,0x30,0x34,0x53,0x36,0x33,0x31,0x31,0x34,0x40,0x35,
0x37,0x30,0x69,0x4A,0x3F,0x32,0x32,0x30,0x3A,0x39,0x40,0x54,0x31,0x32,0x30,0x3C,0x39,0xE8,0x30,0x34,0x32,0x39,0x4D,0x35,0x45,0x32,0x34,0x30,0x35,0x32,0x33,0x41,
0x33,0x30,0x64,0x30,0x46,0x3E,0x32,0x32,0x39,0x33,0x33,0x62,0x34,0x3D,0x38,0x3A,0x39,0x32,0x32,0x34,0x38,0x50,0x39,0x39,0x44,0x36,0x45,0x38,0x40,0x47,0x3F,0x4B,
0x3D,0x38,0x33,0x30,0x35,0x33,0x35,0x46,0x31,0x5B,0x4B,0x40,0x49,0x3F,0x3F,0x4B,0x3D,0x38,0x33,0x3D,0x70,0x34,0x42,0x32,0x61,0x36,0x4D,0x36,0x3F,0x30,0x35,0x36,
0x37,0x30,0x31,0x31,0x34,0x36,0x3C,0x32,0x3E,0x33,0x34,0x38,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x33,0x30,0x34,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,
0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x40,0x38,0x4A,0x39,0x33,0x42,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0xE8,0xAA,0x01,0x00,0x00,0x49,0x3F,
0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0xE8,0x8C,0x01,0x00,0x00,0x32,0x31,0x51,0x30,0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,
0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,0x35,0x33,0x33,0x31,0x30,0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,
0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,0x48,0x3B,0x47,0x3E,0x33,0x3E,0x30,0x37,0x31,0x35,0x3F,0x4B,0x47,0x39,0x35,0x53,
0x32,0x34,0x30,0x37,0x30,0x48,0x30,0x34,0x53,0x36,0x4F,0x31,0x38,0x32,0x52,0x44,0x37,0x3D,0x4C,0x33,0x38,0x36,0x57,0x30,0x35,0x3C,0x32,0x33,0xE8,0x98,0xFE,0xFF,
0xFF,0x4D,0x31,0x31,0x33,0x32,0x36,0x32,0x32,0x31,0x39,0x35,0x5B,0x31,0x38,0x30,0x35,0x3C,0x3C,0x34,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,
0x38,0xE8,0x28,0x01,0x00,0x00,0x31,0x32,0x34,0x38,0x49,0x31,0x40,0x31,0x41,0x31,0x3F,0x36,0x30,0x3E,0x3B,0x36,0x3A,0x45,0x32,0x50,0x3C,0x45,0x3D,0x31,0x31,0x3C,
0x3A,0x3A,0x46,0x4A,0x3F,0x36,0x33,0x43,0x3C,0x3D,0x32,0x37,0x36,0x3B,0x3E,0x36,0x40,0x32,0x39,0x51,0x31,0x33,0x32,0x36,0x44,0x31,0x35,0x34,0x3A,0x32,0x37,0x3D,
0x33,0x48,0x45,0x31,0x31,0x30,0x3A,0x31,0x39,0x31,0x37,0x32,0x35,0x35,0x3B,0x35,0x35,0x48,0x38,0x33,0x61,0x40,0x36,0x33,0x36,0x39,0x30,0x30,0x3C,0x36,0x56,0x3D,
0xE8,0x12,0xFF,0xFF,0xFF,0x3C,0x3D,0x33,0x45,0xE8,0x32,0x3D,0x3F,0x37,0x35,0x37,0xE8,0x7E,0x00,0x00,0x00,0x34,0x31,0x30,0x34,0x31,0x30,0x32,0x30,0x41,0x35,0x31,
0x44,0x3C,0x31,0x3A,0x4F,0x42,0x34,0x34,0x47,0x41,0x36,0x41,0x32,0x32,0x35,0x3A,0x41,0x37,0x32,0x43,0x31,0x38,0x40,0x3D,0x34,0x33,0x35,0x30,0x3F,0x35,0x32,0x36,
0x31,0x35,0x30,0x33,0x49,0x41,0x33,0x37,0x44,0x35,0x3B,0x3C,0x32,0x33,0x4D,0x33,0x32,0xE8,0xE9,0xFF,0xFF,0xFF,0x33,0x38,0x49,0x3F,0x3C,0x32,0x33,0x4D,0x33,0x32,
0x38,0x3D,0x31,0x55,0x33,0x37,0x3C,0x30,0x3B,0x35,0x3D,0x4F,0x42,0x4F,0x33,0x33,0x3A,0x4D,0x35,0x34,0xE8,0x62,0xFF,0xFF,0xFF,0x31,0x33,0x5E,0x33,0x52,0x51,0x3E,
0x31,0x41,0x34,0x40,0x44,0x3F,0x30,0x52,0x33,0x35,0x36,0x3D,0x3F,0x37,0x41,0x44,0x33,0x39,0x34,0x39,0x30,0x33,0x31,0x37,0x41,0x46,0x3C,0x3A,0xE8,0x30,0x3C,0x3B,
0x48,0x36,0x32,0x33,0x33,0x36,0x3A,0x42,0x43,0x43,0x30,0x37,0x35,0x30,0x4B,0x46,0x4B,0x3C,0x54,0x36,0x3F,0x32,0x31,0x3D,0x3B,0x34,0x30,0x3E,0x32,0x34,0x4C,0x3F,
0x30,0x41,0x32,0x43,0x30,0x36,0x33,0x41,0x36,0x35,0x31,0x30,0x47,0x38,0x31,0x35,0xE8,0x89,0xFF,0xFF,0xFF,0xFF,0xFF,0x32,0x52,0x32,0x32,0x50,0x39,0x3D,0x37,0x4E,
0x33,0x34,0x30,0x4E,0x3A,0x49,0x35,0x37,0x37,0x33,0x44,0x36,0x32,0x3A,0x50,0x3A,0x32,0x34,0x36,0x3D,0x36,0x34,0x3C,0x4C,0x32,0x45,0x38,0x39,0x33,0x33,0x35,0x33,
0x32,0x33,0x3D,0x38,0x38,0x32,0x37,0x32,0x42,0x32,0x36,0x40,0x57,0x34,0x33,0x33,0x4F,0x4D,0x42,0x39,0x34,0x30,0x3A,0x31,0x33,0x45,0x48,0x46,0x35,0x42,0x3D,0x38,
0x3B,0x33,0x34,0x33,0x3F,0x38,0x37,0x4B,0x36,0x33,0x30,0x43,0x42,0x38,0x31,0x4B,0x40,0x4D,0x3F,0x56,0x41,0x33,0x41,0x36,0x3A,0x31,0x4F,0x36,0x44,0x33,0x45,0x34,
0x4B,0x37,0x46,0x34,0x36,0x3F,0x30,0x3B,0x36,0x39,0x36,0x3B,0x34,0xE8,0x4D,0xFF,0xFF,0xFF,0x39,0x34,0x3D,0x38,0x3D,0x34,0x31,0x31,0x37,0x33,0x30,0x32,0x38,0x34,
0x38,0x39,0x35,0x33,0x30,0x34,0x4B,0xE8,0x37,0xFF,0xFF,0xFF,0x33,0x32,0x3A,0x31,0x3B,0x36,0x3A,0x44,0x31,0x57,0x33,0x3E,0x3E,0x33,0x3C,0x32,0x33,0x4D,0x33,0x32,
0x44,0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x4E,0x3F,0x3D,0x35,0x4D,0x32,0x31,0x51,0x30,0x35,
0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,0x35,0x33,0x33,0x31,0x30,0x40,
0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,0x48,0x3B,0x47,0x3E };
static BYTE old_two_files_ranges_1[] = {
0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x4E,0x3F,0x3D,0x35,
0x4D,0x32,0x31,0x51,0x30,0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,
0x35,0x33,0x33,0x31,0x30,0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,
0x48,0x3B,0x47,0x3E,0x33,0x3E,0x30,0x37,0x31,0x35,0x3F,0x4B,0x47,0x39,0x35,0x53,0x32,0x34,0x30,0x37,0x30,0x48,0x30,0x34,0x53,0x36,0x33,0x31,0x31,0x34,0x40,0x35,
0x37,0x30,0x69,0x4A,0x3F,0x32,0x32,0x30,0x3A,0x39,0x40,0x54,0x31,0x32,0x30,0x3C,0x39,0xE8,0x30,0x34,0x32,0x39,0x4D,0x35,0x45,0x32,0x34,0x30,0x35,0x32,0x33,0x41,
0x33,0x30,0x64,0x30,0x46,0x3E,0x32,0x32,0x39,0x33,0x33,0x62,0x34,0x3D,0x38,0x3A,0x39,0x32,0x32,0x34,0x38,0x50,0x39,0x39,0x44,0x36,0x45,0x38,0x40,0x47,0x3F,0x4B,
0x3D,0x38,0x33,0x30,0x35,0x33,0x35,0x46,0x31,0x5B,0x4B,0x40,0x49,0x3F,0x3F,0x4B,0x3D,0x38,0x33,0x3D,0x70,0x34,0x42,0x32,0x61,0x36,0x4D,0x36,0x3F,0x30,0x35,0x36,
0x37,0x30,0x31,0x31,0x34,0x36,0x3C,0x32,0x3E,0x33,0x34,0x38,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x33,0x30,0x34,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,
0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x40,0x38,0x4A,0x39,0x33,0x42,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0xE8,0xAA,0x01,0x00,0x00,0x49,0x3F,
0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0xE8,0x8C,0x01,0x00,0x00,0x32,0x31,0x51,0x30,0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,
0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,0x35,0x33,0x33,0x31,0x30,0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,
0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,0x48,0x3B,0x47,0x3E,0x33,0x3E,0x30,0x37,0x31,0x35,0x3F,0x4B,0x47,0x39,0x35,
0x53,0x32,0x34,0x30,0x37,0x30,0x48,0x30,0x34,0x53,0x36,0x4F,0x31,0x38,0x32,0x52,0x44,0x37,0x3D,0x4C,0x33,0x38,0x36,0x57,0x30,0x35,0x3C,0x32,0x33,0xE8,0x98,0xFE,
0xFF,0xFF,0x4D,0x31,0x31,0x33,0x32,0x36,0x32,0x4A,0x32,0x31,0x39,0x35,0x5B,0x31,0x38,0x30,0x35,0x3C,0x3C,0x34,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,
0x5B,0x33,0x38,0xE8,0x28,0x01,0x00,0x00,0x31,0x32,0x34,0x38,0x49,0x31,0x40,0x31,0x41,0x31,0x3F,0x36,0x30,0x3E,0x3B,0x36,0x3A,0x45,0x32,0x50,0x3C,0x45,0x3D,0x31,
0x31,0x3C,0x3A,0x3A,0x46,0x4A,0x3F,0x36,0x33,0x43,0x3C,0x3D,0x32,0x37,0x36,0x3B,0x3E,0x36,0x40,0x32,0x39,0x51,0x31,0x33,0x32,0x36,0x44,0x31,0x35,0x34,0x3A,0x32,
0x37,0x3D,0x33,0x48,0x45,0x31,0x31,0x30,0x3A,0x31,0x39,0x31,0x37,0x32,0x35,0x35,0x3B,0x35,0x35,0x48,0x38,0x33,0x61,0x40,0x36,0x33,0x36,0x39,0x30,0x30,0x3C,0x36,
0x56,0x3D,0xE8,0x12,0xFF,0xFF,0xFF,0x3C,0x3D,0x33,0x45,0xE8,0x32,0x3D,0x3F,0x37,0x35,0x37,0xE8,0x7E,0x00,0x00,0x00,0x34,0x31,0x30,0x34,0x31,0x30,0x32,0x30,0x41,
0x35,0x31,0x44,0x3C,0x31,0x3A,0x4F,0x42,0x34,0x34,0x47,0x41,0x36,0x41,0x32,0x32,0x35,0x3A,0x41,0x37,0x32,0x43,0x31,0x38,0x40,0x3D,0x34,0x33,0x35,0x30,0x3F,0x35,
0x32,0x36,0x31,0x35,0x30,0x33,0x49,0x41,0x33,0x37,0x44,0x35,0x3B,0x3C,0x32,0x33,0x4D,0x33,0x32,0xE8,0xE9,0xFF,0xFF,0xFF,0x33,0x38,0x49,0x3F,0x3C,0x32,0x33,0x4D,
0x33,0x32,0x38,0x3D,0x31,0x55,0x33,0x37,0x3C,0x30,0x3B,0x35,0x3D,0x4F,0x42,0x4F,0x33,0x33,0x3A,0x4D,0x35,0x34,0xE8,0x62,0xFF,0xFF,0xFF,0x31,0x33,0x5E,0x33,0x52,
0x51,0x3E,0x31,0x41,0x34,0x40,0x44,0x3F,0x30,0x52,0x33,0x35,0x36,0x3D,0x3F,0x37,0x41,0x44,0x33,0x39,0x34,0x39,0x30,0x33,0x31,0x37,0x41,0x46,0x3C,0x3A,0xE8,0x30,
0x3C,0x3B,0x48,0x36,0x32,0x33,0x33,0x36,0x3A,0x42,0x43,0x43,0x30,0x37,0x35,0x30,0x4B,0x46,0x4B,0x3C,0x54,0x36,0x3F,0x32,0x31,0x3D,0x3B,0x34,0x30,0x3E,0x32,0x34,
0x4C,0x3F,0x30,0x41,0x32,0x43,0x30,0x36,0x33,0x41,0x36,0x35,0x31,0x30,0x47,0x38,0x31,0x35,0xE8,0x89,0xFF,0xFF,0xFF,0xFF,0xFF,0x32,0x52,0x32,0x32,0x50,0x39,0x3D,
0x37,0x4E,0x33,0x34,0x30,0x4E,0x3A,0x49,0x35,0x37,0x37,0x33,0x44,0x36,0x32,0x3A,0x50,0x3A,0x32,0x34,0x36,0x3D,0x36,0x34,0x3C,0x4C,0x32,0x45,0x38,0x39,0x33,0x33,
0x35,0x33,0x32,0x33,0x3D,0x38,0x38,0x32,0x37,0x32,0x42,0x32,0x36,0x40,0x57,0x34,0x33,0x33,0x4F,0x4D,0x42,0x39,0x34,0x30,0x3A,0x31,0x33,0x45,0x48,0x46,0x35,0x42,
0x3D,0x38,0x3B,0x33,0x34,0x33,0x3F,0x38,0x37,0x4B,0x36,0x33,0x30,0x43,0x42,0x38,0x31,0x4B,0x40,0x4D,0x3F,0x56,0x41,0x33,0x41,0x36,0x3A,0x31,0x4F,0x36,0x44,0x33,
0x45,0x34,0x4B,0x37,0x46,0x34,0x36,0x3F,0x30,0x3B,0x36,0x39,0x36,0x3B,0x34,0xE8,0x4D,0xFF,0xFF,0xFF,0x39,0x34,0x3D,0x38,0x3D,0x34,0x31,0x31,0x37,0x33,0x30,0x32,
0x38,0x34,0x38,0x39,0x35,0x33,0x30,0x34,0x4B,0xE8,0x37,0xFF,0xFF,0xFF,0x33,0x32,0x3A,0x31,0x3B,0x36,0x3A,0x44,0x31,0x57,0x33,0x3E,0x3E,0x33,0x3C,0x32,0x33,0x4D,
0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x4E,0x3F,0x3D,0x35,0x4D,0x32,0x31,0x51,
0x30,0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,0x35,0x33,0x33,0x31,
0x30,0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,0x48,0x3B,0x47,0x3E };
static BYTE patch_two_files_ranges[] = {
0x50,0x41,0x31,0x39,0x02,0x00,0xC4,0x00,0xC5,0xA5,0xBA,0x5C,0x7F,0x87,0xEC,0x96,0x45,0xA3,0x02,0xC1,0x0F,0x64,0x44,0xAC,0x14,0x1E,0x86,0x81,0x52,0x83,0x81,0x0E,
0x85,0x81,0x40,0x81,0x81,0x03,0x83,0x81,0x5F,0x88,0x81,0xF4,0x81,0x4C,0x81,0x81,0x16,0x84,0x81,0x7B,0x83,0x81,0x36,0x84,0x81,0x18,0x82,0x81,0x61,0x83,0x81,0x3D,
0x87,0x81,0x7C,0x8B,0x81,0x0C,0x81,0x81,0x02,0x89,0x81,0x63,0x83,0x81,0x5F,0x84,0x81,0x3D,0x86,0x81,0x14,0x14,0x83,0x80,0x81,0x34,0x84,0x80,0x81,0x13,0x81,0x80,
0x81,0x5A,0x88,0x80,0x81,0x39,0x81,0x80,0x81,0x22,0x81,0x80,0x81,0x09,0x81,0x80,0x81,0x5B,0x82,0x80,0x81,0x07,0x89,0x80,0x81,0x50,0x88,0x80,0x81,0x34,0x82,0x80,
0x81,0x60,0x84,0x80,0x81,0xE5,0x80,0x81,0x2A,0x86,0x80,0x81,0x00,0x81,0x80,0x81,0x12,0x83,0x80,0x81,0x4B,0x8C,0x80,0x81,0x05,0x82,0x80,0x81,0x6C,0x82,0x80,0x81,
0x01,0x82,0x80,0x81,0x80,0x06,0x81,0x81,0x64,0xB1,0x64,0x3C,0x14,0xA6,0x81,0x8C,0x81,0xA4,0x81,0xAB,0x81,0xAD,0x81,0xA3,0x81,0x83,0x81,0xA4,0x81,0xAE,0x81,0x96,
0x81,0xB0,0x81,0xA6,0x81,0xBE,0x81,0xB0,0x81,0x0F,0x81,0x81,0x85,0x81,0x83,0x81,0xA9,0x81,0xBB,0x81,0xB4,0x81,0x14,0x14,0x83,0x80,0x81,0x34,0x84,0x80,0x81,0x12,
0x81,0x81,0x81,0x58,0x88,0xC1,0x81,0x38,0x81,0x80,0x81,0x23,0x81,0xC1,0x81,0x08,0x81,0x80,0x81,0x5A,0x82,0xC1,0x81,0x05,0x89,0x81,0x81,0x4F,0x88,0x80,0x81,0x33,
0x82,0x81,0x81,0x60,0x84,0x81,0x81,0xE4,0x80,0x81,0x29,0x86,0x81,0x81,0x01,0x81,0x80,0x81,0x13,0x83,0xC1,0x81,0x4C,0x8C,0x80,0x81,0x06,0x82,0xC1,0x81,0x6D,0x82,
0x80,0x81,0x00,0x82,0x81,0x81,0x80,0x14,0x81,0x84,0x00,0x00,0x10,0xF1,0x3F,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x40,0x0E,0x04,0x4E,0xBF,0x18,0xD2,0x42,0x96,0xBF,
0xB1,0xFF,0xFF,0x95,0xFF,0x00,0x04,0x00,0x00,0x00,0x00,0x41,0x91,0x10,0x41,0x95,0x18,0x17,0xF4,0xE2,0xBB,0x33,0xE2,0x70,0x69,0x2D,0x54,0xA0,0xF5,0xFF,0xCE,0x10,
0x7C,0x00,0x00,0x00,0x00,0x32,0x00,0x04,0x50,0x18,0x50,0xD0,0x34,0x17,0xB8,0x05,0xAE,0x82,0xC0,0xE5,0x42,0xF0,0x5B,0xFF,0x6F,0x6F,0xEF,0x9D,0xFF,0x6A,0xF0,0x01,
0xE8,0xE5,0xD2,0x53,0x48,0x04,0x71,0xC0,0x86,0x1D,0x78,0x9E,0x71,0x3E,0x19,0xAC,0xDC,0x74,0x80,0x96,0x16,0xC1,0xE2,0xE3,0x14,0xA1,0xC3,0xAF,0x58,0xF8,0xDF,0x52,
0xAB,0xAD,0x5D,0xF5,0xB3,0x5E,0x9B,0x81,0x33,0x6C,0xE7,0x01,0x99,0x3E,0x33,0x92,0x00,0x00,0x10,0xF2,0x3F,0x00,0x00,0x00,0x00,0x22,0x05,0x00,0x05,0x0F,0x43,0x9E,
0xED,0x20,0xA2,0x51,0x44,0x88,0x4B,0xFE,0x5D,0xDB,0x63,0x63,0xFA,0x22,0x82,0x00,0x00,0x00,0x00,0x4A,0x00,0xC0,0xC0,0x0F,0x86,0xFE,0x42,0xFB,0x42,0x64,0x75,0x04,
0x2C,0x97,0xB8,0xE9,0x12,0x4B,0x5D,0x7C,0x7F,0x00,0x10,0x00,0x00,0x00,0x00,0x50,0x23,0x40,0x05,0x9A,0x29,0x98,0x36,0x08,0xBE,0x61,0xCF,0x15,0xA1,0x5D,0xF1,0xFF,
0xFE,0xF6,0x7F,0xEF,0xB8,0x0A,0x80,0x7F,0x25,0xBD,0x06,0x16,0x4F,0xF3,0x9A,0xEC,0xE3,0x22,0x76,0xC9,0xCE,0x64,0x48,0xDB,0xF9,0xC7,0x3B,0x95,0x91,0xDB,0xBA,0x7A,
0xF9,0xD4,0x0D,0x0A,0x0C,0x40,0x7C,0x56,0x1E,0x8A,0x4D,0x78,0x4D,0x47,0x3F,0x8F,0x0D,0xDB,0x67,0xEB,0x90,0x61,0x4D,0x1E,0x3B,0x79,0x88,0x9D,0xE8,0xB4,0x78,0x8F,
0xDC,0x00,0x80,0xCD,0xCA,0xAE,0x3C };
static BYTE patch_header_only[] = {
0x50,0x41,0x31,0x39,0x02,0x00,0xC4,0x00,0xC5,0xA5,0xBA,0x5C,0x7F,0x87,0xEC,0x96,0x45,0xA3,0x02,0xC1,0x0F,0x64,0x44,0xAC,0x14,0x1E,0x86,0x81,0x52,0x83,0x81,0x0E,
0x85,0x81,0x40,0x81,0x81,0x03,0x83,0x81,0x5F,0x88,0x81,0xF4,0x81,0x4C,0x81,0x81,0x16,0x84,0x81,0x7B,0x83,0x81,0x36,0x84,0x81,0x18,0x82,0x81,0x61,0x83,0x81,0x3D,
0x87,0x81,0x7C,0x8B,0x81,0x0C,0x81,0x81,0x02,0x89,0x81,0x63,0x83,0x81,0x5F,0x84,0x81,0x3D,0x86,0x81,0x14,0x14,0x83,0x80,0x81,0x34,0x84,0x80,0x81,0x13,0x81,0x80,
0x81,0x5A,0x88,0x80,0x81,0x39,0x81,0x80,0x81,0x22,0x81,0x80,0x81,0x09,0x81,0x80,0x81,0x5B,0x82,0x80,0x81,0x07,0x89,0x80,0x81,0x50,0x88,0x80,0x81,0x34,0x82,0x80,
0x81,0x60,0x84,0x80,0x81,0xE5,0x80,0x81,0x2A,0x86,0x80,0x81,0x00,0x81,0x80,0x81,0x12,0x83,0x80,0x81,0x4B,0x8C,0x80,0x81,0x05,0x82,0x80,0x81,0x6C,0x82,0x80,0x81,
0x01,0x82,0x80,0x81,0x80,0x06,0x81,0x81,0x64,0xB1,0x64,0x3C,0x14,0xA6,0x81,0x8C,0x81,0xA4,0x81,0xAB,0x81,0xAD,0x81,0xA3,0x81,0x83,0x81,0xA4,0x81,0xAE,0x81,0x96,
0x81,0xB0,0x81,0xA6,0x81,0xBE,0x81,0xB0,0x81,0x0F,0x81,0x81,0x85,0x81,0x83,0x81,0xA9,0x81,0xBB,0x81,0xB4,0x81,0x14,0x14,0x83,0x80,0x81,0x34,0x84,0x80,0x81,0x12,
0x81,0x81,0x81,0x58,0x88,0xC1,0x81,0x38,0x81,0x80,0x81,0x23,0x81,0xC1,0x81,0x08,0x81,0x80,0x81,0x5A,0x82,0xC1,0x81,0x05,0x89,0x81,0x81,0x4F,0x88,0x80,0x81,0x33,
0x82,0x81,0x81,0x60,0x84,0x81,0x81,0xE4,0x80,0x81,0x29,0x86,0x81,0x81,0x01,0x81,0x80,0x81,0x13,0x83,0xC1,0x81,0x4C,0x8C,0x80,0x81,0x06,0x82,0xC1,0x81,0x6D,0x82,
0x80,0x81,0x00,0x82,0x81,0x81,0x80,0x14,0x81,0x83,0x6F,0xB5,0x1B };
static BYTE windows_output_0[] = {
0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x4E,0x3F,0x3D,0x35,
0x4D,0x32,0x31,0x51,0x30,0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,
0x35,0x33,0x33,0x31,0x30,0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,
0x48,0x3B,0x47,0x3E,0x33,0x3E,0x30,0x37,0x31,0x35,0x3F,0x4B,0x47,0x39,0x35,0x53,0x32,0x34,0x30,0x37,0x30,0x48,0x30,0x34,0x53,0x36,0x33,0x31,0x31,0x34,0x40,0x35,
0x37,0x30,0x69,0x4A,0x3F,0x32,0x32,0x30,0x3A,0x39,0x40,0x54,0x31,0x32,0x30,0x3C,0x39,0xE8,0x30,0x34,0x32,0x39,0x4D,0x35,0x45,0x32,0x34,0x30,0x35,0x32,0x33,0x41,
0x33,0x30,0x64,0x30,0x46,0x3E,0x32,0x32,0x39,0x33,0x33,0x62,0x34,0x3D,0x38,0x3A,0x39,0x32,0x32,0x34,0x38,0x50,0x39,0x39,0x44,0x36,0x45,0x38,0x40,0x47,0x3F,0x4B,
0x3D,0x38,0x33,0x30,0x35,0x33,0x35,0x46,0x31,0x5B,0x4B,0x40,0x49,0x3F,0x3F,0x4B,0x3D,0x38,0x33,0x3D,0x70,0x34,0x42,0x32,0x61,0x36,0x4D,0x36,0x3F,0x30,0x35,0x36,
0x37,0x30,0x31,0x31,0x34,0x36,0x3C,0x32,0x3E,0x33,0x34,0x38,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x33,0x30,0x34,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,
0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x40,0x38,0x4A,0x39,0x33,0x42,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0xE8,0xAA,0x01,0x00,0x00,0x49,0x3F,
0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0xE8,0x8C,0x01,0x00,0x00,0x32,0x31,0x51,0x30,0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,
0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,0x35,0x33,0x33,0x31,0x30,0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,
0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x33,0x33,0x48,0x36,0x37,0x32,0x48,0x3B,0x47,0x3E,0x33,0x3E,0x30,0x37,0x31,0x35,0x3F,0x4B,0x47,0x39,0x35,
0x53,0x32,0x34,0x30,0x37,0x30,0x48,0x30,0x34,0x53,0x36,0x4F,0x31,0x38,0x32,0x52,0x44,0x37,0x3D,0x4C,0x33,0x38,0x36,0x57,0x30,0x35,0x3C,0x32,0x33,0xE8,0x98,0xFE,
0xFF,0xFF,0x4D,0x31,0x31,0x33,0x32,0x36,0x32,0x32,0x31,0x39,0x35,0x5B,0x31,0x38,0x30,0x35,0x3C,0x3C,0x34,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x33,
0x33,0x38,0xE8,0x28,0x01,0x00,0x00,0x31,0x32,0x34,0x38,0x49,0x31,0x40,0x31,0x41,0x31,0x3F,0x36,0x30,0x3E,0x3B,0x36,0x3A,0x45,0x32,0x50,0x3C,0x45,0x3D,0x31,0x31,
0x3C,0x3A,0x3A,0x46,0x4A,0x3F,0x36,0x33,0x43,0x3C,0x3D,0x32,0x37,0x36,0x3B,0x3E,0x36,0x40,0x32,0x39,0x51,0x31,0x33,0x32,0x36,0x44,0x31,0x35,0x34,0x3A,0x32,0x37,
0x3D,0x33,0x48,0x45,0x31,0x31,0x30,0x3A,0x31,0x31,0x31,0x37,0x32,0x35,0x35,0x3B,0x35,0x35,0x48,0x38,0x33,0x61,0x40,0x36,0x33,0x36,0x39,0x30,0x30,0x3C,0x36,0x56,
0x3D,0xE8,0x12,0xFF,0xFF,0xFF,0x3C,0x33,0x33,0x45,0xE8,0x32,0x3D,0x3F,0x37,0x35,0x37,0xE8,0x7E,0x00,0x00,0x00,0x34,0x31,0x30,0x34,0x31,0x30,0x32,0x30,0x41,0x35,
0x31,0x44,0x3C,0x31,0x3A,0x4F,0x42,0x34,0x34,0x47,0x41,0x36,0x41,0x32,0x32,0x35,0x3A,0x41,0x37,0x32,0x43,0x31,0x38,0x40,0x3D,0x34,0x33,0x35,0x30,0x35,0x35,0x32,
0x36,0x31,0x35,0x30,0x33,0x49,0x41,0x33,0x44,0x44,0x35,0x3B,0x3C,0x32,0x33,0x4D,0x33,0x32,0xE8,0xE9,0xFF,0xFF,0xFF,0x33,0x38,0x49,0x3F,0x3C,0x32,0x33,0x4D,0x33,
0x32,0x38,0x3D,0x31,0x55,0x33,0x37,0x3C,0x30,0x3B,0x35,0x3D,0x4F,0x42,0x4F,0x33,0x33,0x3A,0x4D,0x35,0x34,0xE8,0x62,0xFF,0xFF,0xFF,0x31,0x33,0x5E,0x33,0x52,0x51,
0x3E,0x31,0x41,0x34,0x40,0x44,0x3F,0x30,0x52,0x33,0x35,0x36,0x3D,0x3F,0x37,0x41,0x44,0x33,0x39,0x34,0x39,0x30,0x33,0x31,0x37,0x41,0x46,0x3C,0x3A,0xE8,0x30,0x3C,
0x3B,0x48,0x36,0x32,0x33,0x33,0x36,0x3A,0x42,0x43,0x43,0x30,0x37,0x35,0x30,0x4B,0x46,0x4B,0x3C,0x54,0x36,0x3F,0x32,0x31,0x3D,0x3B,0x34,0x30,0x3E,0x32,0x34,0x4C,
0x3F,0x30,0x41,0x32,0x43,0x30,0x36,0x33,0x41,0x36,0x35,0x31,0x30,0x47,0x38,0x31,0x35,0xE8,0x89,0xFF,0xFF,0xFF,0xFF,0xFF,0x32,0x52,0x32,0x32,0x50,0x39,0x3D,0x37,
0x4E,0x33,0x34,0x30,0x4E,0x3A,0x49,0x35,0x37,0x37,0x33,0x44,0x36,0x32,0x3A,0x50,0x3A,0x32,0x34,0x36,0x3D,0x36,0x34,0x3C,0x4C,0x45,0x45,0x38,0x39,0x33,0x33,0x35,
0x33,0x32,0x33,0x3D,0x38,0x38,0x32,0x37,0x32,0x42,0x32,0x36,0x40,0x57,0x34,0x33,0x33,0x4F,0x4D,0x42,0x39,0x34,0x30,0x3A,0x31,0x33,0x45,0x46,0x46,0x35,0x42,0x3D,
0x38,0x3B,0x33,0x34,0x33,0x3F,0x38,0x37,0x4B,0x36,0x33,0x30,0x43,0x42,0x38,0x31,0x4B,0x40,0x4D,0x3F,0x56,0x41,0x33,0x41,0x36,0x3A,0x31,0x4F,0x36,0x44,0x33,0x45,
0x34,0x4B,0x37,0x46,0x34,0x36,0x3F,0x30,0x3B,0x36,0x39,0x36,0x3B,0x34,0xE8,0x4D,0xFF,0xFF,0xFF,0x39,0x34,0x3D,0x38,0x3D,0x34,0x31,0x31,0x37,0x33,0x30,0x32,0x38,
0x34,0x38,0x39,0x35,0x33,0x30,0x34,0x4B,0xE8,0x37,0xFF,0xFF,0xFF,0x33,0x32,0x3A,0x31,0x3B,0x36,0x3A,0x44,0x31,0x57,0x33,0x3E,0x3E,0x33,0x3C,0x32,0x33,0x4D,0x33,
0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x38,0x49,0x3F,0x47,0x3C,0x32,0x33,0x4D,0x33,0x32,0x44,0x33,0x4E,0x40,0x5B,0x33,0x4E,0x3F,0x3D,0x35,0x4D,0x32,0x31,0x51,0x30,
0x35,0x37,0x52,0x33,0x38,0x3A,0x39,0x3A,0x30,0x35,0x37,0x32,0x36,0x34,0x31,0x3A,0x32,0x31,0x38,0x38,0x3C,0x3C,0x3B,0x4F,0x4E,0x30,0x41,0x35,0x33,0x33,0x31,0x30,
0x40,0x38,0x46,0x3F,0x32,0x31,0x3E,0x45,0x33,0x33,0x3B,0x31,0x31,0x35,0x38,0x57,0x38,0x37,0x39,0x33,0x30,0x35,0x33,0x48,0x36,0x37,0x32,0x48,0x3B,0x47,0x3E };
#define BLOCKTYPE2_NO_TIMESTAMP_SIZE 1024
static BYTE old_blocktype2_no_timestamp[] = {
0x0E,0x52,0xCE,0x03,0xD9,0xFC,0xA7,0x06,0xF4,0x1D,0xC5,0x05,0x14,0x54,0xFD,0x06,0xA1,0xC2,0xDE,0x07,0x14,0x54,0xFD,0x06,0xB0,0xAC,0x7A,0x00,0x0E,0x52,0xCE,0x03,
0x0E,0x52,0xCE,0x03,0x82,0x7E,0xBA,0x04,0xE5,0x00,0x7B,0x00,0x0E,0x52,0xCE,0x03,0x0E,0x52,0xCE,0x03,0x0E,0x52,0xCE,0x03,0x0E,0x52,0xCE,0x03,0xAF,0x95,0x59,0x00,
0x0A,0x28,0x93,0x06,0x0E,0x52,0xCE,0x03,0x46,0x94,0x38,0x03,0xAD,0xBD,0xCC,0x03,0x97,0xB3,0xAD,0x02,0x0E,0x52,0xCE,0x03,0x56,0xD1,0x32,0x00,0xD6,0xDC,0xA3,0x04,
0x05,0x9C,0xBE,0x05,0x88,0x25,0x30,0x01,0x63,0x74,0x09,0x01,0x75,0x27,0xD0,0x07,0x80,0x03,0x3F,0x01,0xF9,0xD4,0x98,0x06,0x14,0x1A,0x6E,0x06,0x0E,0x52,0xCE,0x03,
0x0E,0x52,0xCE,0x03,0xE3,0x9C,0x04,0x02,0xC6,0x36,0x2C,0x01,0x0E,0x52,0xCE,0x03,0xA5,0x44,0xC0,0x03,0x0F,0xD2,0x8F,0x01,0x21,0x39,0x89,0x02,0x4A,0xFB,0x56,0x01,
0xF7,0x34,0x60,0x03,0xB2,0x08,0x7A,0x03,0x16,0x0A,0x07,0x07,0xB5,0xD5,0xC5,0x02,0x01,0x5A,0x3F,0x06,0x0E,0x52,0xCE,0x03,0xF7,0x0A,0xEC,0x06,0x07,0x5A,0xC5,0x01,
0x14,0x54,0xFD,0x06,0x79,0x63,0x08,0x03,0x74,0x8A,0xE0,0x04,0x1C,0x0E,0x41,0x02,0x84,0xCE,0xA9,0x07,0x8B,0x5A,0x9E,0x02,0x87,0xB6,0xDB,0x07,0xD0,0xBF,0x77,0x04,
0xD3,0xB6,0x15,0x01,0xA5,0x44,0xC0,0x03,0xEE,0xBC,0x96,0x05,0x1A,0x99,0xA1,0x07,0x05,0x9C,0xBE,0x05,0x18,0x36,0xEF,0x03,0xD5,0x29,0x71,0x01,0x89,0xDC,0xD3,0x01,
0x26,0xFB,0x79,0x06,0x75,0xCB,0x98,0x03,0x84,0xC7,0x4F,0x03,0x06,0x02,0x65,0x03,0x94,0xCA,0x63,0x03,0x35,0x52,0x88,0x07,0xC6,0xCC,0xFC,0x02,0xA2,0x8E,0xB1,0x01,
0x9B,0xDB,0x34,0x06,0xB4,0x2D,0x3C,0x07,0x20,0xBF,0x0E,0x05,0x84,0xC7,0x4F,0x03,0xFA,0x91,0x5B,0x03,0xAD,0xBD,0xCC,0x03,0xC8,0xA3,0xAE,0x01,0x8F,0x99,0x0B,0x01,
0x48,0xA8,0xF2,0x03,0xDC,0x54,0xFC,0x07,0xDA,0xAB,0x04,0x02,0x46,0x80,0x24,0x06,0x8F,0x4E,0x16,0x05,0xB9,0xA9,0x30,0x01,0x74,0x72,0xA1,0x05,0x34,0x67,0x4C,0x01,
0xB1,0x56,0xA4,0x00,0x0A,0x28,0x93,0x06,0x31,0xCA,0x54,0x04,0x14,0x54,0xFD,0x06,0x5A,0xCA,0x57,0x03,0x85,0x6C,0x93,0x04,0x97,0xC3,0x42,0x06,0x0A,0x28,0x93,0x06,
0x21,0x39,0x89,0x02,0x89,0x5E,0xFB,0x06,0xFD,0x6D,0x46,0x00,0x54,0x23,0x25,0x05,0x0E,0x52,0xCE,0x03,0x5A,0xDB,0xFA,0x01,0x0E,0x52,0xCE,0x03,0x81,0xE4,0x1E,0x01,
0x9B,0x21,0x30,0x04,0x09,0x53,0xAC,0x05,0xF1,0xA9,0x2D,0x07,0xDD,0x4D,0x30,0x06,0xFF,0x38,0xBD,0x02,0xAD,0xAA,0xDB,0x03,0xEC,0xAE,0x4E,0x01,0x40,0x19,0x44,0x02,
0x35,0x52,0x88,0x07,0x4A,0x85,0xEF,0x02,0x80,0x03,0x3F,0x01,0xDB,0x5A,0x88,0x07,0x36,0x77,0x4F,0x07,0x9B,0x21,0x30,0x04,0x1D,0x52,0x4F,0x02,0xA5,0x97,0xFB,0x00,
0x2F,0xC8,0x67,0x01,0x32,0x96,0xB0,0x06,0x35,0x52,0x88,0x07,0x4E,0x46,0x30,0x06,0xE9,0x98,0x28,0x05,0xF8,0x0D,0xD9,0x01,0x0E,0x52,0xCE,0x03,0x6F,0x7C,0x24,0x07,
0x1A,0x99,0xA1,0x07,0x11,0x2D,0x22,0x04,0x15,0xA4,0xB7,0x05,0x77,0xD9,0xA0,0x06,0xB8,0x56,0x63,0x02,0xD8,0xB3,0xE2,0x05,0x9F,0xE5,0x87,0x02,0x2D,0x97,0x69,0x03,
0xE9,0x98,0x28,0x05,0xDC,0x08,0xA4,0x02,0x0A,0x28,0x93,0x06,0x5F,0xF4,0x6C,0x03,0xC4,0xC3,0xBC,0x01,0xA5,0x44,0xC0,0x03,0xA1,0x0C,0xFE,0x05,0x3C,0x05,0x75,0x07,
0x76,0x91,0xA1,0x06,0x42,0x63,0x1F,0x04,0x36,0xCE,0x65,0x04,0xB0,0x0A,0x67,0x02,0xB2,0x5D,0xE4,0x02,0x87,0x78,0x84,0x06,0xFD,0xF4,0x8D,0x05,0x6E,0x25,0xA3,0x06,
0xD8,0xE0,0x0C,0x01,0x12,0x7F,0xAD,0x04,0xD8,0x18,0x1C,0x02,0xFD,0xC6,0x99,0x01,0x41,0xCC,0x03,0x07,0xAF,0xBC,0xCB,0x03,0x8C,0x2E,0xF9,0x07,0x0A,0x28,0x93,0x06,
0xCB,0xA6,0xAC,0x01,0x87,0x78,0x84,0x06,0x88,0x6C,0x61,0x02,0xA8,0x31,0x66,0x03,0x05,0xFD,0xD0,0x07,0x14,0x54,0xFD,0x06,0x70,0x1D,0x18,0x06,0x87,0x78,0x84,0x06,
0x0E,0x52,0xCE,0x03,0x2A,0x24,0xF0,0x02,0x18,0xDB,0x54,0x04,0x8F,0xCF,0x4B,0x03,0xD1,0x44,0xCA,0x02,0x2E,0xEB,0x35,0x07,0xCF,0xBA,0xA5,0x01,0x70,0x6D,0x49,0x01,
0x4D,0x1B,0xA7,0x01,0x96,0x88,0x0C,0x06,0x20,0x75,0x29,0x00,0x98,0xB9,0x56,0x04,0x5C,0x45,0x03,0x00,0x07,0xE5,0xAC,0x00,0x09,0x12,0x6A,0x02,0x9E,0xFB,0xC2,0x02,
0x43,0x70,0x56,0x02,0xDA,0x0C,0x6E,0x04,0x1F,0xD4,0xBB,0x05,0x98,0xB6,0xC2,0x03,0x71,0x8B,0x0C,0x04,0x23,0x99,0x84,0x06,0x07,0xAE,0xC5,0x04,0x04,0xE5,0x61,0x00,
0xDE,0xE5,0xC1,0x02,0x6F,0x79,0x37,0x01,0xA8,0xA6,0x74,0x07,0xF9,0xCD,0xD7,0x03,0x6E,0x39,0xFE,0x02,0x87,0x78,0x80,0x03,0x14,0xA8,0x7C,0x05,0xEC,0x42,0xB0,0x03,
0x9F,0xE5,0x87,0x02,0xA5,0x44,0xC0,0x03,0xD8,0x41,0x5C,0x06,0xAB,0x8E,0xD2,0x05,0xA7,0x33,0x9A,0x01,0x62,0x03,0x5C,0x07,0xD5,0x27,0x82,0x07,0xEF,0x85,0xD2,0x03,
0xA5,0x84,0x92,0x05,0x8D,0x30,0xE3,0x03,0x8A,0xC2,0x51,0x04,0x57,0x8C,0x27,0x01,0xF9,0xD4,0x98,0x06,0x62,0xB1,0xAB,0x06,0x27,0x5F,0x4B,0x00,0xBB,0xD0,0x92,0x04,
0x5F,0x4B,0x14,0x06,0x8D,0x03,0x68,0x06,0x4C,0x5F,0x17,0x00,0x2D,0x57,0xF5,0x00,0x03,0xF9,0xE9,0x05,0x0E,0x52,0xCE,0x03,0xC2,0xC3,0x24,0x06,0x86,0x4A,0x94,0x01,
0x00,0xE2,0xE0,0x01,0x27,0x30,0xBE,0x00,0x3A,0xA8,0xC6,0x00,0xEF,0x85,0xD2,0x03,0x31,0x58,0x7E,0x01,0xB1,0x03,0x02,0x04,0x0E,0x52,0xCE,0x03,0xE5,0xA7,0x59,0x01,
0x56,0xB7,0x19,0x01,0x87,0x78,0x84,0x06,0x06,0x7A,0x52,0x02,0x85,0x6C,0x93,0x04,0x87,0xDB,0x40,0x04,0x1A,0xCF,0xBF,0x06,0xAB,0x8E,0xD2,0x05,0xD0,0x9F,0xD3,0x03,
0xC8,0xC7,0xF8,0x01,0x2F,0x13,0x04,0x06,0xE9,0x98,0x28,0x05,0x1E,0x06,0x61,0x07,0x9F,0xE5,0x87,0x02,0x17,0x0D,0xDB,0x03,0xFA,0x91,0x5B,0x03,0x36,0xA6,0xA5,0x03,
0x9B,0x1A,0xC2,0x03,0x8B,0xD9,0x3F,0x04,0x7F,0x5B,0x6C,0x01,0xAA,0x08,0x58,0x04,0xF3,0x03,0x33,0x02,0xD5,0x29,0x71,0x01,0x37,0x32,0x48,0x3B,0x47,0x3E,0x3E,0xCC };
static BYTE patch_blocktype2_no_timestamp[] = {
0x50,0x41,0x31,0x39,0x01,0x00,0x44,0x00,0x00,0x88,0xEA,0x93,0x4F,0x32,0x01,0x80,0x40,0xBF,0x4B,0x5E,0x00,0x00,0x80,0x00,0x84,0xFE,0x01,0x00,0x20,0x00,0x40,0x00,
0x08,0x00,0x81,0x00,0x00,0x24,0x03,0x00,0x66,0x50,0x00,0xEF,0x0B,0xFB,0xFE,0xFB,0xEE,0x11,0x71,0x65,0x4E,0xE6,0xD8,0x87,0x0A,0x24,0x25,0xCC,0xE6,0xED,0x36,0x37,
0x38,0x5A,0x78,0xAF,0x4B,0xF0,0x12,0x25,0xA1,0x4A,0xE1,0x45,0x9C,0x1A,0x5D,0xC0,0xAB,0x16,0xDE,0xB4,0x35,0x8E,0xCB,0xC8,0xDB,0x78,0xDB,0xCA,0x5B,0x5D,0x85,0xAA,
0xD4,0x28,0x45,0x90,0x8A,0xAA,0x50,0x21,0x57,0x00,0x00,0x03,0x00,0x46,0x43,0x00,0x60,0x02,0x45,0x4C,0x99,0x65,0xDC,0xD0,0xA7,0xCD,0xB7,0xC2,0x4B,0x4B,0xBC,0x8D,
0xC0,0x2B,0x9C,0xB3,0xC4,0xBC,0x85,0xC0,0x4D,0xC4,0x8B,0x20,0xDD,0x14,0xDE,0x85,0xB0,0x19,0xFF,0x34,0xF5,0x27,0x5A,0xEE,0xBF,0x00,0x04,0x00,0x00,0x00,0x00,0x0C,
0x01,0x08,0x10,0xFC,0x38,0xC7,0x60,0xBF,0x5F,0xFC,0x7E,0xF0,0x84,0xF4,0x09,0x4A,0xF2,0x26,0x9D,0x1F,0x1A,0x1D,0xC7,0x7A,0x53,0x32,0x6C,0x40,0xAF,0xB1,0x1A,0xED,
0x3F,0xD0,0x13,0xB7,0xF3,0xDB,0xB9,0x5C,0xA4,0xF3,0x44,0xE7,0x66,0x44,0x98,0x9E,0xF4,0xBC,0x13,0x7C,0xBD,0xE0,0x42,0x53,0x87,0x74,0x2D,0x00,0xDB,0xDF,0xEA,0xE9,
0x46,0xE8,0xC1,0x1D,0x78,0x92,0xCA,0xFB,0x2F,0x82,0xD8,0x66,0x48,0x39,0xF3,0x66,0xC7,0xBC,0xEA,0xD8,0x67,0xDB,0x77,0x4A,0xAE,0x0C,0x47,0x21,0x1B,0xE8,0x44,0x28,
0xEB,0x5E,0xA4,0x0E,0xC7,0x83,0x28,0xFB,0x8A,0x03,0x0D,0x27,0x53,0x15,0xEE,0xC6,0x94,0xB5,0x46,0xE3,0x58,0xFE,0x26,0x09,0xCF,0x75,0xD8,0x3A,0x1E,0x79,0x47,0xA3,
0x91,0xB2,0xD7,0x36,0xB6,0x97,0x07,0xC0,0xE0,0x03,0xB8,0x49,0x0E,0x4D,0xC3,0x33,0xBA,0xBE,0x5C,0xEB,0xC7,0xEC,0xCD,0x69,0x9F,0xB8,0x41,0x8A,0x78,0x26,0x85,0x8A,
0x90,0xBF,0xB8,0x46,0x2D,0x3C,0x72,0x34,0xDC,0x6D,0x33,0x68,0x55,0x13,0x67,0x32,0x1C,0xD2,0x90,0x7C,0xA4,0x54,0xD2,0x14,0x8A,0x58,0xB8,0xCF,0x1F,0xF8,0x5A,0x38,
0xC8,0xD6,0xD5,0x20,0x34,0xEE,0x43,0xEC,0x5F,0x24,0xD1,0x1F,0x71,0xB3,0x72,0x0F,0x2E,0x22,0xD3,0xEE,0x9C,0x95,0x7E,0x2C,0x81,0x60,0x05,0x9F,0x13,0xA0,0x84,0xF0,
0xE4,0x00,0x2B,0x84,0x96,0x3D,0xF8,0x60,0xF0,0xAE,0xE8,0x3A,0x81,0xEB,0xF9,0x7E,0xB7,0x8F,0x2A,0x88,0x7F,0xBA,0x43,0xE0,0xD2,0x6F,0x17,0xFD,0xE7,0x9E,0x6C,0x94,
0xF2,0x63,0x3F,0xA2,0xAD,0xE7,0x9E,0x12,0xB5,0xF3,0x2D,0x53,0x4A,0x09,0x65,0x2C,0x84,0x4F,0x0E,0xA6,0x0E,0xE8,0xC3,0x2B,0x01,0x4E,0x28,0xF9,0xDB,0x89,0x8E,0xE7,
0x17,0x58,0x81,0xDF,0x04,0x05,0xD4,0x8A,0xEB,0xC7,0xB2,0xE3,0xF1,0x8A,0xF0,0x16,0x06,0xA8,0x48,0x03,0x96,0x3F,0xD4,0xE4,0xCF,0x61,0xC8,0x81,0x43,0xE9,0x7F,0xA9,
0x7C,0xCA,0xCA,0xEE,0x67,0xAB,0x50,0x3C,0xAF,0xFF,0xE2,0x85,0x29,0xE4,0xA9,0x21,0x31,0xC7,0xCD,0xFE,0xCE,0xA9,0xB8,0xB7,0xBB,0xCD,0x6B,0xFF,0x16,0x64,0xDD,0xD4,
0xBA,0x56,0xEC,0x93,0xBE,0xDF,0x92,0xBF,0xE6,0xD4,0x83,0xF5,0xC7,0x7A,0x98,0x33,0x7E,0x77,0x1E,0x18,0x1C,0x47,0x03,0x40,0x4B,0x36,0x5E,0xC3,0x06 };
#define NULL_INPUT_UNCOMPRESSED_SIZE 65
static BYTE patch_null_input_uncompressed[] = {
0x50,0x41,0x31,0x39,0x01,0x00,0xC4,0x00,0xC5,0xA5,0xBA,0x5C,0xC1,0x48,0x7F,0x15,0x2D,0x01,0x41,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xD4,0x52,0x00,0x00,0x30,
0x10,0x04,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xF0,0x9B,0x50,0x8E,0xD9,0x89,0x50,0x0D,0x9C,0xD6,0x8A,0xF9,0x6E,0xB9,0xEF,0xEE,0x0F,0x9C,
0xA6,0xE1,0x16,0x54,0x80,0x55,0x8B,0x97,0x65,0x8D,0x02,0xA1,0x85,0xEA,0x51,0x08,0xD6,0xE6,0x0B,0x19,0x01,0xF5,0x7F,0x9D,0x63,0x71,0x58,0x28,0x33,0x70,0xA8,0x93,
0xF8,0x62,0x5E,0x56,0x11,0x47,0x60,0x22,0x9E,0x76,0x26,0x8C,0xFC,0x41,0x97,0x00,0x0E,0x73,0xBF,0xE4 };
#define UNNECESSARY_SIZE 65
static BYTE old_unnecessary[] = {
0xF0,0x9B,0x50,0x8E,0xD9,0x89,0x50,0x0D,0x9C,0xD6,0x8A,0xF9,0x6E,0xB9,0xEF,0xEE,0x0F,0x9C,0xA6,0xE1,0x16,0x54,0x80,0x55,0x8B,0x97,0x65,0x8D,0x02,0xA1,0x85,0xEA,
0x51,0x08,0xD6,0xE6,0x0B,0x19,0x01,0xF5,0x7F,0x9D,0x63,0x71,0x58,0x28,0x33,0x70,0xA8,0x93,0xF8,0x62,0x5E,0x56,0x11,0x47,0x60,0x22,0x9E,0x76,0x26,0x8C,0xFC,0x41,
0x97 };
static BYTE patch_unnecessary[] = {
0x50,0x41,0x31,0x39,0x01,0x00,0xC4,0x00,0xC5,0xA5,0xBA,0x5C,0xC1,0x48,0x7F,0x15,0x2D,0x01,0x80,0x48,0x7F,0x15,0x2D,0x00,0x00,0x80,0x80,0x90,0x68,0xE9,0x14 };
struct file_def
{
BYTE *buf;
size_t size;
char *name;
};
static char old_two_files_ranges_0_tmp[MAX_PATH];
static char patch_two_files_ranges_tmp[MAX_PATH];
static char patch_header_only_tmp[MAX_PATH];
static char old_blocktype2_no_timestamp_tmp[MAX_PATH];
static char patch_null_input_uncompressed_tmp[MAX_PATH];
static char output_file_temp[MAX_PATH];
static struct file_def test_files[] = {
{old_two_files_ranges_0, sizeof(old_two_files_ranges_0), old_two_files_ranges_0_tmp},
{patch_two_files_ranges, sizeof(patch_two_files_ranges), patch_two_files_ranges_tmp},
{patch_header_only, sizeof(patch_header_only), patch_header_only_tmp},
{old_blocktype2_no_timestamp, sizeof(old_blocktype2_no_timestamp), old_blocktype2_no_timestamp_tmp},
{patch_null_input_uncompressed, sizeof(patch_null_input_uncompressed), patch_null_input_uncompressed_tmp},
{NULL, 0, NULL}
};
static BOOL CALLBACK progress(void *context, ULONG current, ULONG max)
{
*(ULONG*)context = current * 100 / (max + !max);
return TRUE;
}
static BOOL CALLBACK progress_cancel(void *context, ULONG current, ULONG max)
{
*(ULONG*)context = current * 100 / (max + !max);
return FALSE;
}
static BOOL create_temp_file(const BYTE *buf, size_t size, const char *temppath, char *tempname)
{
HANDLE hndl;
DWORD written;
BOOL b;
GetTempFileNameA(temppath, "pat", 0, tempname);
hndl = CreateFileA(tempname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hndl == INVALID_HANDLE_VALUE)
return FALSE;
b = WriteFile(hndl, buf, size, &written, NULL);
CloseHandle(hndl);
return b && written == size;
}
static void delete_test_files(void)
{
size_t i;
for (i = 0; test_files[i].buf != NULL; ++i)
DeleteFileA(test_files[i].name);
}
static BOOL setup_test_files(void)
{
char temppath[MAX_PATH];
size_t i;
GetTempPathA(MAX_PATH, temppath);
for (i = 0; test_files[i].buf != NULL; ++i) {
if (!create_temp_file(test_files[i].buf, test_files[i].size, temppath, test_files[i].name))
{
skip("Failed to create/write temporary test files\n");
delete_test_files();
return FALSE;
}
}
GetTempFileNameA(temppath, "pat", 0, output_file_temp);
return TRUE;
}
static void compare_file(const char *name, const BYTE *buf, size_t size)
{
size_t i;
HANDLE hndl = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
ok(hndl != INVALID_HANDLE_VALUE, "Expected test result file opened, got INVALID_HANDLE_VALUE\n");
if (hndl != INVALID_HANDLE_VALUE)
{
DWORD fpos;
for (i = 0; i < size; ++i)
{
BYTE c;
DWORD nread;
BOOL b = ReadFile(hndl, &c, 1, &nread, NULL);
ok(b, "Unexpected end of file during comparison\n");
if (!b)
break;
ok(c == buf[i], "Character mismatch at offset %u: 0x%02X vs 0x%02X\n", (int)i, c, buf[i]);
if (c != buf[i])
break;
}
fpos = SetFilePointer(hndl, 0, NULL, FILE_END);
ok(fpos == size, "Output size larger than expected\n");
CloseHandle(hndl);
}
}
static BOOL file_closed(const char *name)
{
/* This will test for handle closure on Windows and any other system with sharing restrictions */
HANDLE hndl = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hndl != INVALID_HANDLE_VALUE)
{
CloseHandle(hndl);
return TRUE;
}
return FALSE;
}
static void test_ApplyPatchToFile(void)
{
ULONG current;
DWORD err;
/* XP fails with ERROR_PATH_NOT_FOUND */
if (win_version < 0x600)
{
skip("NULL parameter not supported in XP\n");
}
else
{
/* null old file */
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileA(patch_null_input_uncompressed_tmp, NULL, output_file_temp, APPLY_OPTION_FAIL_IF_EXACT),
"ApplyPatchToFileA: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
}
/* dual input patch - first file */
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileA(patch_two_files_ranges_tmp, old_two_files_ranges_0_tmp, output_file_temp, APPLY_OPTION_FAIL_IF_EXACT),
"ApplyPatchToFileA: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
/* ensure that ranges were applied properly by comparing with the result from Windows */
compare_file(output_file_temp, windows_output_0, sizeof(windows_output_0));
/* handles were closed */
ok(file_closed(patch_two_files_ranges_tmp), "File handle was not closed: %s\n", patch_two_files_ranges_tmp);
ok(file_closed(old_two_files_ranges_0_tmp), "File handle was not closed: %s\n", old_two_files_ranges_0_tmp);
ok(file_closed(output_file_temp), "File handle was not closed: %s\n", output_file_temp);
/* old file passed where none required */
DeleteFileA(output_file_temp);
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileA(patch_null_input_uncompressed_tmp, old_two_files_ranges_0_tmp, output_file_temp, 0),
"ApplyPatchToFileA: expected FALSE\n");
err = GetLastError();
/* error code is unstable across Windows versions and architectures (bug) */
ok(err == ERROR_PATCH_WRONG_FILE || err == ERROR_SUCCESS,
"Expected ERROR_SUCCESS or ERROR_PATCH_WRONG_FILE, got 0x%X\n", err);
/* output deleted on failure */
ok(GetFileAttributesA(output_file_temp) == INVALID_FILE_ATTRIBUTES, "Output file should not exist\n");
/* handles were closed */
ok(file_closed(patch_null_input_uncompressed_tmp), "File handle was not closed: %s\n", patch_null_input_uncompressed_tmp);
ok(file_closed(old_two_files_ranges_0_tmp), "File handle was not closed: %s\n", old_two_files_ranges_0_tmp);
/* wrong old file for patch */
DeleteFileA(output_file_temp);
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileA(patch_two_files_ranges_tmp, patch_null_input_uncompressed_tmp, output_file_temp, 0),
"ApplyPatchToFileA: expected FALSE\n");
err = GetLastError();
/* error code is unstable across Windows versions and architectures (bug) */
ok(err == ERROR_PATCH_WRONG_FILE || err == ERROR_SUCCESS,
"Expected ERROR_SUCCESS or ERROR_PATCH_WRONG_FILE, got 0x%X\n", err);
/* output deleted on failure */
ok(GetFileAttributesA(output_file_temp) == INVALID_FILE_ATTRIBUTES, "Output file should not exist\n");
/* missing patch file */
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileA("snarfalargle", old_two_files_ranges_0_tmp, output_file_temp, 0), "ApplyPatchToFileA: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got 0x%X\n", err);
ok(file_closed(old_two_files_ranges_0_tmp), "File handle was not closed: %s\n", old_two_files_ranges_0_tmp);
ok(GetFileAttributesA(output_file_temp) == INVALID_FILE_ATTRIBUTES, "Output file should not exist\n");
/* missing old file */
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileA(patch_two_files_ranges_tmp, "elbernoffle", output_file_temp, 0), "ApplyPatchToFileA: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got 0x%X\n", err);
ok(file_closed(patch_two_files_ranges_tmp), "File handle was not closed: %s\n", patch_two_files_ranges_tmp);
ok(GetFileAttributesA(output_file_temp) == INVALID_FILE_ATTRIBUTES, "Output file should not exist\n");
/* bad output file */
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileA(patch_two_files_ranges_tmp, old_two_files_ranges_0_tmp, "up\\down\\left\\right", 0),
"ApplyPatchToFileA: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got 0x%X\n", err);
ok(file_closed(patch_two_files_ranges_tmp), "File handle was not closed: %s\n", patch_two_files_ranges_tmp);
ok(file_closed(old_two_files_ranges_0_tmp), "File handle was not closed: %s\n", old_two_files_ranges_0_tmp);
if (!pApplyPatchToFileExA)
return;
/* progress function in ApplyPatchToFileExA */
SetLastError(0xdeadbeef);
current = 0xdeadbeef;
ok(pApplyPatchToFileExA(patch_two_files_ranges_tmp, old_two_files_ranges_0_tmp, output_file_temp, APPLY_OPTION_FAIL_IF_EXACT,
progress, &current), "ApplyPatchToFileExA: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
ok(current <= 100, "Expected 0-100, got 0xdeadbeef\n");
/* cancellation in ApplyPatchToFileExA */
SetLastError(0xdeadbeef);
current = 0xdeadbeef;
ok(!pApplyPatchToFileExA(patch_two_files_ranges_tmp, old_two_files_ranges_0_tmp, output_file_temp, APPLY_OPTION_FAIL_IF_EXACT,
progress_cancel, &current), "ApplyPatchToFileExA: expected FALSE\n");
err = GetLastError();
/* the file is so small that cancellation occurs on completion and sometimes Windows reports success */
ok(err == ERROR_CANCELLED || err == ERROR_SUCCESS, "Expected ERROR_SUCCESS or ERROR_CANCELLED, got 0x%X\n", err);
ok(current <= 100, "Expected 0-100, got 0xdeadbeef\n");
}
static void test_ApplyPatchToFileByHandles(void)
{
HANDLE patch_hndl = INVALID_HANDLE_VALUE;
HANDLE old_hndl = INVALID_HANDLE_VALUE;
HANDLE new_hndl = INVALID_HANDLE_VALUE;
ULONG current;
DWORD err;
DWORD size;
DWORD w;
if (!pApplyPatchToFileByHandles)
return;
patch_hndl = CreateFileA(patch_two_files_ranges_tmp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (patch_hndl == INVALID_HANDLE_VALUE)
{
skip("Failed to open patch file %s: %u\n", patch_two_files_ranges_tmp, GetLastError());
goto close_handles;
}
old_hndl = CreateFileA(old_two_files_ranges_0_tmp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (old_hndl == INVALID_HANDLE_VALUE)
{
skip("Failed to open old file %s: %u\n", old_two_files_ranges_0_tmp, GetLastError());
goto close_handles;
}
new_hndl = CreateFileA(output_file_temp, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (new_hndl == INVALID_HANDLE_VALUE)
{
skip("Failed to open new file %s: %u\n", output_file_temp, GetLastError());
goto close_handles;
}
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByHandles(patch_hndl, old_hndl, new_hndl, APPLY_OPTION_FAIL_IF_EXACT),
"ApplyPatchToFileByHandles: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
w = SetFilePointer(patch_hndl, 0, NULL, FILE_CURRENT);
ok(w == 0, "Expected file pointer 0, got %u\n", w);
w = SetFilePointer(old_hndl, 0, NULL, FILE_CURRENT);
ok(w == 0, "Expected file pointer 0, got %u\n", w);
w = SetFilePointer(new_hndl, 0, NULL, FILE_CURRENT);
ok(w == sizeof(windows_output_0), "Expected file pointer %u, got %u\n", (unsigned)sizeof(windows_output_0), w);
size = SetFilePointer(new_hndl, 0, NULL, FILE_END);
ok(size == sizeof(windows_output_0), "Expected file size %u, got %u\n",(unsigned)sizeof(windows_output_0), size);
/* lengthen and check for truncation */
WriteFile(new_hndl, "", 1, &w, 0);
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByHandles(patch_hndl, old_hndl, new_hndl, APPLY_OPTION_FAIL_IF_EXACT),
"ApplyPatchToFileByHandles: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
w = SetFilePointer(new_hndl, 0, NULL, FILE_END);
ok(w == size, "Expected file size %u, got %u\n", size, w);
if (!pTestApplyPatchToFileByHandles)
goto close_handles;
SetLastError(0xdeadbeef);
ok(pTestApplyPatchToFileByHandles(patch_hndl, old_hndl, APPLY_OPTION_FAIL_IF_EXACT),
"TestApplyPatchToFileByHandles: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
if (!pApplyPatchToFileByHandlesEx)
goto close_handles;
/* progress */
SetLastError(0xdeadbeef);
current = 0xdeadbeef;
ok(pApplyPatchToFileByHandlesEx(patch_hndl, old_hndl, new_hndl, APPLY_OPTION_FAIL_IF_EXACT, progress, &current),
"ApplyPatchToFileByHandlesEx: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
ok(current <= 100, "Expected 0-100, got 0xdeadbeef\n");
w = SetFilePointer(new_hndl, 0, NULL, FILE_END);
ok(w == size, "Expected file size %u, got %u\n", size, w);
/* progress cancelled */
SetLastError(0xdeadbeef);
current = 0xdeadbeef;
ok(!pApplyPatchToFileByHandlesEx(patch_hndl, old_hndl, new_hndl, APPLY_OPTION_FAIL_IF_EXACT,
progress_cancel, &current), "ApplyPatchToFileByHandlesEx: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_CANCELLED || err == ERROR_SUCCESS, "Expected ERROR_SUCCESS or ERROR_CANCELLED, got 0x%X\n", err);
ok(current <= 100, "Expected 0-100, got 0xdeadbeef\n");
close_handles:
if (new_hndl != INVALID_HANDLE_VALUE)
CloseHandle(new_hndl);
if (old_hndl != INVALID_HANDLE_VALUE)
CloseHandle(old_hndl);
if (patch_hndl != INVALID_HANDLE_VALUE)
CloseHandle(patch_hndl);
}
static void test_ApplyPatchToFileByBuffers(void)
{
BYTE *new_buf = NULL;
ULONG new_size = 0;
FILETIME new_time = { 0, 0 };
ULONG current = 0xdeadbeef;
BYTE target_buf[sizeof(old_two_files_ranges_1)];
BYTE corrupt_buf[sizeof(patch_blocktype2_no_timestamp)];
DWORD err;
if (!pApplyPatchToFileByBuffers)
return;
/* output buffer allocated by api */
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByBuffers(patch_two_files_ranges, sizeof(patch_two_files_ranges),
old_two_files_ranges_0, sizeof(old_two_files_ranges_0), &new_buf, 0, &new_size, &new_time, 0, progress, &current),
"ApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
ok(new_buf != NULL, "Expected buffer returned, got NULL\n");
ok(new_size == sizeof(windows_output_0), "Expected size %u, got %u\n", (unsigned)sizeof(windows_output_0), new_size);
if(new_buf != NULL)
ok(memcmp(new_buf, windows_output_0, new_size) == 0, "Expected data equal, got not equal\n");
ok(current <= 100, "Expected progress 0-100, got 0xdeadbeef\n");
if (new_buf != NULL)
ok(VirtualFree(new_buf, 0, MEM_RELEASE),
"ApplyPatchToFileByBuffers output buffer should be allocaed with VirtualAlloc\n");
/* buffer supplied by caller */
new_buf = target_buf;
new_size = 0;
new_time.dwHighDateTime = 0;
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByBuffers(patch_blocktype2_no_timestamp, sizeof(patch_blocktype2_no_timestamp),
old_blocktype2_no_timestamp, sizeof(old_blocktype2_no_timestamp), &new_buf, sizeof(target_buf), &new_size,
&new_time, 0, NULL, NULL), "ApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
ok(new_buf == target_buf, "Buffer pre-allocated; pointer should not be modified\n");
ok(new_size == BLOCKTYPE2_NO_TIMESTAMP_SIZE, "Expected size %u, got %u\n", BLOCKTYPE2_NO_TIMESTAMP_SIZE, new_size);
ok(new_time.dwHighDateTime == 0, "Expected datetime 0, got nonzero\n");
/* null old file */
new_buf = target_buf;
new_size = 0;
new_time.dwHighDateTime = 0;
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByBuffers(patch_null_input_uncompressed, sizeof(patch_null_input_uncompressed),
NULL, 0, &new_buf, sizeof(target_buf), &new_size, &new_time, 0, NULL, NULL),
"ApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
ok(new_size == NULL_INPUT_UNCOMPRESSED_SIZE, "Expected size %u, got %u\n", NULL_INPUT_UNCOMPRESSED_SIZE, new_size);
ok(new_time.dwHighDateTime != 0, "Expected nonzero, got 0\n");
/* null output */
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileByBuffers(patch_null_input_uncompressed, sizeof(patch_null_input_uncompressed),
NULL, 0, NULL, 0, &new_size, &new_time, 0, NULL, NULL), "ApplyPatchToFileByBuffers: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got 0x%X\n", err);
/* null output test only */
new_time.dwHighDateTime = 0;
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByBuffers(patch_null_input_uncompressed, sizeof(patch_null_input_uncompressed),
NULL, 0, NULL, 0, NULL, &new_time, APPLY_OPTION_TEST_ONLY, NULL, NULL),
"ApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
ok(new_time.dwHighDateTime != 0, "Expected nonzero, got 0\n");
/* null old file test only */
new_size = 0;
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByBuffers(patch_null_input_uncompressed, sizeof(patch_null_input_uncompressed),
NULL, 0, NULL, 0, &new_size, NULL, APPLY_OPTION_TEST_ONLY, NULL, NULL),
"ApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
ok(new_size == NULL_INPUT_UNCOMPRESSED_SIZE, "Expected size %u, got %u\n", NULL_INPUT_UNCOMPRESSED_SIZE, new_size);
/* alternate old file */
new_buf = target_buf;
new_size = 0;
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByBuffers(patch_two_files_ranges, sizeof(patch_two_files_ranges),
old_two_files_ranges_1, sizeof(old_two_files_ranges_1), &new_buf, sizeof(target_buf), &new_size,
NULL, 0, NULL, NULL), "ApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(new_size == TWO_FILES_RANGES_SIZE, "Expected size %u, got %u\n", TWO_FILES_RANGES_SIZE, new_size);
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
/* wrong old file */
new_buf = target_buf;
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileByBuffers(patch_two_files_ranges, sizeof(patch_two_files_ranges),
old_blocktype2_no_timestamp, sizeof(old_blocktype2_no_timestamp), &new_buf, sizeof(target_buf),
NULL, &new_time, 0, NULL, NULL), "ApplyPatchToFileByBuffers: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_PATCH_WRONG_FILE, "Expected ERROR_PATCH_WRONG_FILE, got 0x%X\n", err);
memcpy(corrupt_buf, patch_blocktype2_no_timestamp, sizeof(corrupt_buf));
/* patch truncated */
new_buf = target_buf;
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileByBuffers(corrupt_buf, sizeof(corrupt_buf) - 1,
old_blocktype2_no_timestamp, sizeof(old_blocktype2_no_timestamp), &new_buf, sizeof(target_buf),
NULL, &new_time, 0, NULL, NULL), "ApplyPatchToFileByBuffers: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_PATCH_CORRUPT, "Expected ERROR_PATCH_CORRUPT, got 0x%X\n", err);
corrupt_buf[sizeof(corrupt_buf) / 2] ^= 0xFF;
/* patch corrupt */
new_buf = target_buf;
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileByBuffers(corrupt_buf, sizeof(corrupt_buf),
old_blocktype2_no_timestamp, sizeof(old_blocktype2_no_timestamp), &new_buf, sizeof(target_buf),
NULL, &new_time, 0, NULL, NULL), "ApplyPatchToFileByBuffers: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_PATCH_CORRUPT, "Expected ERROR_PATCH_CORRUPT, got 0x%X\n", err);
/* patch created from identical files */
new_buf = target_buf;
SetLastError(0xdeadbeef);
ok(pApplyPatchToFileByBuffers(patch_unnecessary, sizeof(patch_unnecessary),
old_unnecessary, sizeof(old_unnecessary), &new_buf, sizeof(target_buf), NULL, &new_time, 0, NULL, NULL),
"ApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
/* patch created from identical files and APPLY_OPTION_FAIL_IF_EXACT */
new_buf = target_buf;
SetLastError(0xdeadbeef);
ok(!pApplyPatchToFileByBuffers(patch_unnecessary, sizeof(patch_unnecessary),
old_unnecessary, sizeof(old_unnecessary), &new_buf, sizeof(target_buf), NULL, &new_time,
APPLY_OPTION_FAIL_IF_EXACT, NULL, NULL), "ApplyPatchToFileByBuffers: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_PATCH_NOT_NECESSARY, "Expected ERROR_PATCH_NOT_NECESSARY, got 0x%X\n", err);
if (!pTestApplyPatchToFileByBuffers)
return;
/* header test */
new_size = 0;
SetLastError(0xdeadbeef);
ok(pTestApplyPatchToFileByBuffers(patch_blocktype2_no_timestamp, sizeof(patch_blocktype2_no_timestamp),
old_blocktype2_no_timestamp, sizeof(old_blocktype2_no_timestamp), &new_size, 0),
"TestApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
ok(new_size == BLOCKTYPE2_NO_TIMESTAMP_SIZE, "Expected size %u, got %u\n", BLOCKTYPE2_NO_TIMESTAMP_SIZE, new_size);
/* header test, no size returned */
SetLastError(0xdeadbeef);
ok(pTestApplyPatchToFileByBuffers(patch_blocktype2_no_timestamp, sizeof(patch_blocktype2_no_timestamp),
old_blocktype2_no_timestamp, sizeof(old_blocktype2_no_timestamp), NULL, 0),
"TestApplyPatchToFileByBuffers: expected TRUE\n");
err = GetLastError();
ok(err == 0xdeadbeef || err == ERROR_SUCCESS, "Expected 0xdeadbeef or ERROR_SUCCESS, got 0x%X\n", err);
}
static void test_TestApplyPatchToFile(void)
{
DWORD err;
if (!pTestApplyPatchToFileByBuffers)
return;
/* These test files created in Win10 crash native TestApplyPatchToFileA() in Vista or earlier every
* time on all of the test servers, even though ApplyPatchToFileA() succeeds on the same files. */
if (win_version < 0x601)
{
skip("Windows version is less than 6.1\n");
return;
}
/* correct old file */
SetLastError(0xdeadbeef);
ok(pTestApplyPatchToFileA(patch_header_only_tmp, old_two_files_ranges_0_tmp, 0), "TestApplyPatchToFileA: expected TRUE\n");
err = GetLastError();
ok(err == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got 0x%X\n", err);
/* wrong old file */
SetLastError(0xdeadbeef);
ok(!pTestApplyPatchToFileA(patch_header_only_tmp, old_blocktype2_no_timestamp_tmp, 0), "TestApplyPatchToFileA: expected FALSE\n");
err = GetLastError();
ok(err == ERROR_PATCH_WRONG_FILE, "Expected ERROR_PATCH_WRONG_FILE, got 0x%X\n", err);
}
START_TEST(apply_patch)
{
if (!init_function_pointers())
return;
if (!setup_test_files())
return;
test_ApplyPatchToFile();
test_ApplyPatchToFileByBuffers();
test_ApplyPatchToFileByHandles();
test_TestApplyPatchToFile();
delete_test_files();
}