ReactOS 0.4.15-dev-7924-g5949c20
mspatcha.c
Go to the documentation of this file.
1/*
2 * PROJECT: mspatcha_apitest
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests for mspatcha
5 * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8#define WIN32_NO_STATUS
9#include <windows.h>
10
11#include "wine/test.h"
12#include <patchapi.h>
13
14
15/* Headers created with ExtractPatchHeaderToFileA */
16unsigned char in1_bin[8] =
17{
18 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, /* testdata */
19};
20unsigned char out1_bin[26] =
21{
22 0x74, 0x65, 0x73, 0x74, 0x20, 0x44, 0x61, 0x74, 0x61, 0x0d, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x20, /* test Data..With */
23 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, /* some extra */
24};
25unsigned char patch1_bin[75] =
26{
27 0x50, 0x41, 0x31, 0x39, 0x01, 0x00, 0xc4, 0x00, 0x4e, 0x28, 0xb3, 0x5b, 0x9a, 0x08, 0xd1, 0x51, /* PA19....N(.[...Q */
28 0xf6, 0x01, 0xd2, 0x5e, 0x36, 0xe5, 0x99, 0x00, 0x00, 0x80, 0xac, 0x2a, 0x00, 0x00, 0x30, 0xa0, /* ...^6......*..0. */
29 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, /* .............tes */
30 0x74, 0x20, 0x44, 0x61, 0x74, 0x61, 0x0d, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x20, 0x73, 0x6f, 0x6d, /* t Data..With som */
31 0x65, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0xa7, 0x19, 0x4a, 0x68, /* e extra..Jh */
32};
33unsigned char patch1_header_bin[31] =
34{
35 0x50, 0x41, 0x31, 0x39, 0x01, 0x00, 0xc4, 0x00, 0x4e, 0x28, 0xb3, 0x5b, 0x9a, 0x08, 0xd1, 0x51, /* PA19....N(.[...Q */
36 0xf6, 0x01, 0xd2, 0x5e, 0x36, 0xe5, 0x99, 0x00, 0x00, 0x80, 0xac, 0xe9, 0xf0, 0x53, 0xf7, /* ...^6........S. */
37};
38
39unsigned char in2_bin[25] =
40{
41 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xaa, /* ........"3DUfw.. */
42 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, /* ......... */
43};
44unsigned char out2_bin[25] =
45{
46 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xbb, /* ........"3DUfw.. */
47 0x00, 0xbb, 0x00, 0xbb, 0x00, 0xbb, 0x00, 0xbb, 0x00, /* ......... */
48};
49unsigned char patch2_bin[75] =
50{
51 0x50, 0x41, 0x31, 0x39, 0x01, 0x00, 0xc4, 0x00, 0x62, 0x35, 0xb3, 0x5b, 0x99, 0xfa, 0xa0, 0x8a, /* PA19....b5.[.... */
52 0x02, 0x01, 0x80, 0x1d, 0xc2, 0x54, 0xfc, 0x00, 0x00, 0x80, 0xac, 0x2a, 0x00, 0x00, 0x30, 0x90, /* .....T.....*..0. */
53 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, /* ................ */
54 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xbb, 0x00, 0xbb, 0x00, /* ....."3DUfw..... */
55 0xbb, 0x00, 0xbb, 0x00, 0xbb, 0x00, 0x00, 0x14, 0x06, 0xeb, 0x61, /* ..........a */
56};
57unsigned char patch2_header_bin[31] =
58{
59 0x50, 0x41, 0x31, 0x39, 0x01, 0x00, 0xc4, 0x00, 0x62, 0x35, 0xb3, 0x5b, 0x99, 0xfa, 0xa0, 0x8a, /* PA19....b5.[.... */
60 0x02, 0x01, 0x80, 0x1d, 0xc2, 0x54, 0xfc, 0x00, 0x00, 0x80, 0xac, 0xce, 0x5d, 0x8c, 0xed, /* .....T......].. */
61};
62
63/* Minimum output size to trigger compression */
64unsigned char in3_bin[138] =
65{
66 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
67 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
68 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
69 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
70 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
71 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
72 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
73 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
74 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* .......... */
75};
76unsigned char out3_bin[152] =
77{
78 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
79 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* ................ */
80 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ................ */
81 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ................ */
82 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ................ */
83 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ................ */
84 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ................ */
85 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ................ */
86 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ................ */
87 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, /* ........ */
88};
89unsigned char patch3_bin[88] =
90{
91 0x50, 0x41, 0x31, 0x39, 0x01, 0x00, 0xc4, 0x00, 0xb1, 0x57, 0xb3, 0x5b, 0x18, 0x81, 0xf9, 0xd8, /* PA19.....W.[.... */
92 0x1d, 0x41, 0x01, 0xce, 0xd9, 0x52, 0x0a, 0xf1, 0x00, 0x00, 0x80, 0xb8, 0x36, 0x00, 0x00, 0x10, /* .A...R......6... */
93 0x82, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x22, 0xff, 0xff, 0x35, 0xd8, /* ........ .."..5. */
94 0xfb, 0x8f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x03, 0xb7, 0x08, 0xf7, 0x7d, /* ..........!....} */
95 0x7e, 0xdf, 0x40, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x0d, 0x20, 0x7d, 0xbe, /* ~.@L......@.. }. */
96 0xf9, 0xbe, 0x68, 0xf4, 0x1f, 0x45, 0x3e, 0x35, /* ..h..E>5 */
97};
98unsigned char patch3_header_bin[32] =
99{
100 0x50, 0x41, 0x31, 0x39, 0x01, 0x00, 0xc4, 0x00, 0xb1, 0x57, 0xb3, 0x5b, 0x18, 0x81, 0xf9, 0xd8, /* PA19.....W.[.... */
101 0x1d, 0x41, 0x01, 0xce, 0xd9, 0x52, 0x0a, 0xf1, 0x00, 0x00, 0x80, 0xb8, 0xbd, 0xeb, 0x70, 0xdd, /* .A...R........p. */
102};
103
104typedef struct _bin_file
105{
106 unsigned char* data;
107 size_t len;
109
110typedef struct _patch_data
111{
112 char* name;
120
121#define MAKE_BIN(data_) { data_, sizeof(data_) }
122
124
125BOOL extract2(char* filename, const unsigned char* data, size_t len)
126{
128 BOOL bRet;
129 DWORD dwWritten;
130
131 if (!GetTempFileNameA(temp_path, "mpa", 0, filename))
132 {
133 ok(0, "GetTempFileNameA failed %lu\n", GetLastError());
134 return FALSE;
135 }
136
139 {
140 ok(0, "CreateFileA failed %lu\n", GetLastError());
142 return FALSE;
143 }
144
145 bRet = WriteFile(hFile, data, (DWORD)len, &dwWritten, NULL);
147 bRet = bRet && (dwWritten == len);
148
149 if (!bRet)
150 {
151 ok(0, "WriteFile failed %lu\n", GetLastError());
153 }
154
155 return bRet;
156}
157
159{
160 return extract2(filename, bin->data, bin->len);
161}
162
164{
165 DWORD dwAccess = GENERIC_READ | (bWrite ? GENERIC_WRITE : 0);
168 dwAttr, NULL);
169}
170
171void compare_file_(char* filename, const unsigned char* data, size_t len, const char* test_name, int line)
172{
173 char* buf;
174 size_t size;
177
179 {
180 ok_(__FILE__, line)(0, "Unable to open file %s(%lu), %s\n", filename, GetLastError(), test_name);
181 return;
182 }
184 ok(size == len, "Filesize is %u instead of %u, %s\n", size, len, test_name);
185
186 buf = malloc(size);
187 if (buf)
188 {
189 DWORD dwRead;
190 if (ReadFile(hFile, buf, (DWORD)size, &dwRead, NULL) && dwRead == size)
191 {
192 ok(!memcmp(buf, data, min(size,len)), "Data mismatch, %s\n", test_name);
193 }
194 else
195 {
196 ok_(__FILE__, line)(0, "Unable to read %s(%lu), %s\n", filename, GetLastError(), test_name);
197 }
198
199 free(buf);
200 }
201 else
202 {
203 ok_(__FILE__, line)(0, "Unable to allocate %u, %s\n", size, test_name);
204 }
205
207}
208
209#define compare_file(filename, data, len, test_name) compare_file_(filename, data, len, test_name, __LINE__)
210
211static void validate_signature(const char* casename, const char* fieldname, const bin_file* bin, const char* expected)
212{
213 char filename[MAX_PATH];
216 unsigned char data[0x100];
217 char signature[0x20] = {0};
218 WCHAR signatureW[0x20] = {0};
219 BOOL bResult;
220
221 memset(signature, 0xaa, sizeof(signature));
222 memcpy(data, bin->data, bin->len);
223
224 if (!extract(filename, bin))
225 return;
226
227 memset(signature, 0xaa, sizeof(signature)-1);
228 bResult = GetFilePatchSignatureA(filename, 0, NULL, 0, NULL, 0, NULL, sizeof(signature), signature);
229 ok(bResult, "GetFilePatchSignatureA failed %lu, %s.%s\n", GetLastError(), casename, fieldname);
230 if (bResult)
231 {
232 // Signature is crc32 of data
233 ok(!_stricmp(expected, signature), "Got %s for %s.%s\n", signature, casename, fieldname);
234 }
235
236 memset(signature, 0xaa, sizeof(signature)-1);
237 memset(signatureW, 0xaa, sizeof(signatureW)-sizeof(WCHAR));
238 // Widechar version has a widechar signature
240 bResult = GetFilePatchSignatureW(filenameW, 0, NULL, 0, NULL, 0, NULL, sizeof(signatureW), signatureW);
241 ok(bResult, "GetFilePatchSignatureW failed %lu, %s.%s\n", GetLastError(), casename, fieldname);
242 if (bResult)
243 {
244 WideCharToMultiByte(CP_ACP, 0, signatureW, -1, signature, _countof(signature), NULL, NULL);
245 // Signature is crc32 of data
246 ok(!_stricmp(expected, signature), "Got %s for %s.%s\n", signature, casename, fieldname);
247 }
248
249 memset(signature, 0xaa, sizeof(signature)-1);
250 // 'Handle' version has ansi signature
252 ok(hFile != INVALID_HANDLE_VALUE, "Unable to open file %lu\n", GetLastError());
254 {
255 bResult = GetFilePatchSignatureByHandle(hFile, 0, NULL, 0, NULL, 0, NULL, sizeof(signature), signature);
256 ok(bResult, "GetFilePatchSignatureByHandle failed %lu, %s.%s\n", GetLastError(), casename, fieldname);
257 if (bResult)
258 {
259 // Signature is crc32 of data
260 ok(!_stricmp(expected, signature), "Got %s for %s.%s\n", signature, casename, fieldname);
261 }
262
264 }
265
267}
268
269/* Copyright (C) 1986 Gary S. Brown
270 * Modified by Robert Shearman. You may use the following calc_crc32 code or
271 * tables extracted from it, as desired without restriction. */
272static const unsigned int crc_32_tab[] =
273{ /* CRC polynomial 0xedb88320 */
274 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
275 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
276 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
277 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
278 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
279 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
280 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
281 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
282 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
283 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
284 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
285 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
286 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
287 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
288 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
289 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
290 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
291 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
292 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
293 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
294 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
295 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
296 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
297 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
298 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
299 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
300 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
301 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
302 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
303 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
304 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
305 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
306 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
307 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
308 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
309 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
310 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
311 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
312 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
313 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
314 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
315 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
316 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
317};
318
319unsigned int crc32(unsigned int seed, unsigned char* msg, unsigned int msglen)
320{
321 unsigned int rem = seed;
322 unsigned int i;
323
324 for (i = 0; i < msglen; i++)
325 {
326 rem = crc_32_tab[(rem ^ msg[i]) & 0xff] ^ (rem >> 8);
327 }
328
329 return rem;
330}
331
333{
334 UINT crc;
335
336 crc = crc32(~0, current->patch.data, (UINT)current->patch.len);
337 ok(crc == 0, "Invalid patch crc 0x%x for %s\n", crc, current->name);
338
339 crc = crc32(~0, current->patch_header.data, (UINT)current->patch_header.len);
340 ok(crc == 0, "Invalid patch_header crc 0x%x for %s\n", crc, current->name);
341}
342
344{
345 char patchname[MAX_PATH], targetname[MAX_PATH], outputname[MAX_PATH];
346 BOOL bResult;
347 DWORD dwErr;
348 HANDLE hPatch, hTarget, hFind;
349 WIN32_FIND_DATAA wfd = { sizeof(wfd) };
350
351 if (!GetTempFileNameA(temp_path, "MPO", 0, outputname))
352 {
353 ok(0, "GetTempFileNameA failed %lu, %s\n", GetLastError(), current->name);
354 return;
355 }
356 DeleteFileA(outputname);
357
358 if (!extract(patchname, &current->patch))
359 return;
360 if (!extract(targetname, &current->input))
361 {
362 DeleteFileA(patchname);
363 return;
364 }
365 // There is a bug in 2k3, where calling 'TestApplyPatchToFileA' gives an AV...
366#if 0
367 bResult = TestApplyPatchToFileA(patchname, targetname, 0);
368#else
369 hPatch = open_file(patchname, FALSE);
370 hTarget = open_file(targetname, FALSE);
371 bResult = TestApplyPatchToFileByHandles(hPatch, hTarget, 0);
372 CloseHandle(hPatch);
373 CloseHandle(hTarget);
374#endif
375 ok(bResult, "TestApplyPatchToFileA failed %lu, %s\n", GetLastError(), current->name);
376 // Files are not touched
377 compare_file(patchname, current->patch.data, current->patch.len, current->name);
378 compare_file(targetname, current->input.data, current->input.len, current->name);
379 DeleteFileA(patchname);
380 DeleteFileA(targetname);
381
382
383 if (!extract2(patchname, current->patch.data, current->patch.len -1))
384 return;
385 if (!extract(targetname, &current->input))
386 {
387 DeleteFileA(patchname);
388 return;
389 }
390 hPatch = open_file(patchname, FALSE);
391 hTarget = open_file(targetname, FALSE);
392 bResult = TestApplyPatchToFileByHandles(hPatch, hTarget, 0);
394 CloseHandle(hPatch);
395 CloseHandle(hTarget);
396 ok(!bResult, "TestApplyPatchToFileA succeeded, %s\n", current->name);
397 ok(dwErr == ERROR_PATCH_CORRUPT, "TestApplyPatchToFileA GetLastError %lx, %s\n", dwErr, current->name);
398 // Files are not touched
399 compare_file(patchname, current->patch.data, current->patch.len - 1, current->name);
400 compare_file(targetname, current->input.data, current->input.len, current->name);
401 DeleteFileA(patchname);
402 DeleteFileA(targetname);
403
404 if (!extract(patchname, &current->patch))
405 return;
406 if (!extract2(targetname, current->input.data, current->input.len -1))
407 {
408 DeleteFileA(patchname);
409 return;
410 }
411 hPatch = open_file(patchname, FALSE);
412 hTarget = open_file(targetname, FALSE);
413 bResult = TestApplyPatchToFileByHandles(hPatch, hTarget, 0);
415 CloseHandle(hPatch);
416 CloseHandle(hTarget);
417 ok(!bResult, "TestApplyPatchToFileA succeeded, %s\n", current->name);
418 ok(dwErr == ERROR_PATCH_WRONG_FILE, "TestApplyPatchToFileA GetLastError %lx, %s\n", dwErr, current->name);
419 // Files are not touched
420 compare_file(patchname, current->patch.data, current->patch.len, current->name);
421 compare_file(targetname, current->input.data, current->input.len -1, current->name);
422 DeleteFileA(patchname);
423 DeleteFileA(targetname);
424
425 if (!extract(patchname, &current->patch))
426 return;
427 if (!extract(targetname, &current->input))
428 {
429 DeleteFileA(patchname);
430 return;
431 }
432 bResult = ApplyPatchToFileA(patchname, targetname, outputname, APPLY_OPTION_TEST_ONLY);
433
434 ok(bResult, "ApplyPatchToFileA failed %lu, %s\n", GetLastError(), current->name);
435 // Files are not touched
436 compare_file(patchname, current->patch.data, current->patch.len, current->name);
437 compare_file(targetname, current->input.data, current->input.len, current->name);
438 // W2k3 creates an empty file, W10 does not create a file
439 hFind = FindFirstFileA(outputname, &wfd);
440 ok(hFind == INVALID_HANDLE_VALUE || wfd.nFileSizeLow == 0, "Got a (non-empty) file, %s\n", current->name);
441 if (hFind != INVALID_HANDLE_VALUE)
442 FindClose(hFind);
443 DeleteFileA(patchname);
444 DeleteFileA(targetname);
445 DeleteFileA(outputname);
446
447 if (!extract(patchname, &current->patch))
448 return;
449 if (!extract(targetname, &current->input))
450 {
451 DeleteFileA(patchname);
452 return;
453 }
454 bResult = ApplyPatchToFileA(patchname, targetname, outputname, 0);
455 ok(bResult, "ApplyPatchToFileA failed %lu, %s\n", GetLastError(), current->name);
456 // Files are not touched
457 compare_file(patchname, current->patch.data, current->patch.len, current->name);
458 compare_file(targetname, current->input.data, current->input.len, current->name);
459 // One output file
460 compare_file(outputname, current->output.data, current->output.len, current->name);
461 DeleteFileA(patchname);
462 DeleteFileA(targetname);
463 DeleteFileA(outputname);
464}
465
466
468{
469 validate_signature(current->name, "input", &current->input, current->input_signature);
470 validate_signature(current->name, "output", &current->output, current->output_signature);
473}
474
475
476
477static patch_data data[] =
478{
479 {
480 "in1_text",
482 "99e5365e",
484 "f651d108",
487 },
488 {
489 "in2_binary",
491 "fc54c21d",
493 "028aa0fa",
496 },
497 {
498 "in3_compression",
500 "f10a52d9",
502 "411dd8f9",
505 },
506};
507
508
509START_TEST(mspatcha)
510{
511 size_t n;
512
514
515 for (n = 0; n < _countof(data); ++n)
516 {
517 test_one(data + n);
518 }
519}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
DWORD dwErr
Definition: service.c:36
#define _stricmp
Definition: cat.c:22
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
#define crc32(crc, buf, len)
Definition: inflate.c:1081
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
HANDLE WINAPI FindFirstFileA(IN LPCSTR lpFileName, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:263
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char * filename
Definition: ioapi.h:137
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct task_struct * current
Definition: linux.c:32
#define CREATE_ALWAYS
Definition: disk.h:72
static const WCHAR filenameW[]
Definition: amstream.c:41
BOOL expected
Definition: store.c:2063
static struct _PeImage bin
static const char * test_name
Definition: run.c:177
#define min(a, b)
Definition: monoChain.cc:55
struct _bin_file bin_file
void compare_file_(char *filename, const unsigned char *data, size_t len, const char *test_name, int line)
Definition: mspatcha.c:171
#define MAKE_BIN(data_)
Definition: mspatcha.c:121
unsigned char out2_bin[25]
Definition: mspatcha.c:44
unsigned char in1_bin[8]
Definition: mspatcha.c:16
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
static void apply_patch(patch_data *current)
Definition: mspatcha.c:343
#define compare_file(filename, data, len, test_name)
Definition: mspatcha.c:209
unsigned char patch1_bin[75]
Definition: mspatcha.c:25
unsigned char out3_bin[152]
Definition: mspatcha.c:76
BOOL extract2(char *filename, const unsigned char *data, size_t len)
Definition: mspatcha.c:125
struct _patch_data patch_data
unsigned char patch2_bin[75]
Definition: mspatcha.c:49
unsigned char patch3_bin[88]
Definition: mspatcha.c:89
static void validate_patch(patch_data *current)
Definition: mspatcha.c:332
BOOL extract(char *filename, const bin_file *bin)
Definition: mspatcha.c:158
unsigned char patch2_header_bin[31]
Definition: mspatcha.c:57
unsigned char in2_bin[25]
Definition: mspatcha.c:39
unsigned char patch3_header_bin[32]
Definition: mspatcha.c:98
HANDLE open_file(char *filename, BOOL bWrite)
Definition: mspatcha.c:163
static void validate_signature(const char *casename, const char *fieldname, const bin_file *bin, const char *expected)
Definition: mspatcha.c:211
unsigned char out1_bin[26]
Definition: mspatcha.c:20
unsigned char patch1_header_bin[31]
Definition: mspatcha.c:33
static const unsigned int crc_32_tab[]
Definition: mspatcha.c:272
void test_one(patch_data *current)
Definition: mspatcha.c:467
unsigned char in3_bin[138]
Definition: mspatcha.c:64
BOOL WINAPI ApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, LPCSTR new_file, ULONG apply_flags)
BOOL WINAPI GetFilePatchSignatureW(LPCWSTR filename, ULONG flags, PVOID data, ULONG ignore_range_count, PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count, PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
BOOL WINAPI TestApplyPatchToFileByHandles(HANDLE patch_file, HANDLE old_file, ULONG apply_flags)
BOOL WINAPI GetFilePatchSignatureByHandle(HANDLE hFile, ULONG flags, PVOID data, ULONG ignore_range_count, PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count, PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
BOOL WINAPI GetFilePatchSignatureA(LPCSTR filename, ULONG flags, PVOID data, ULONG ignore_range_count, PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count, PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
BOOL WINAPI TestApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, ULONG apply_flags)
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define GENERIC_WRITE
Definition: nt_native.h:90
#define ERROR_PATCH_WRONG_FILE
Definition: patchapi.h:38
#define ERROR_PATCH_CORRUPT
Definition: patchapi.h:36
#define APPLY_OPTION_TEST_ONLY
Definition: patchapi.h:28
#define memset(x, y, z)
Definition: compat.h:39
#define _countof(array)
Definition: sndvol32.h:68
size_t len
Definition: mspatcha.c:107
unsigned char * data
Definition: mspatcha.c:106
char * output_signature
Definition: mspatcha.c:116
bin_file output
Definition: mspatcha.c:115
bin_file input
Definition: mspatcha.c:113
bin_file patch
Definition: mspatcha.c:117
char * input_signature
Definition: mspatcha.c:114
char * name
Definition: mspatcha.c:112
bin_file patch_header
Definition: mspatcha.c:118
Definition: parser.c:49
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
__wchar_t WCHAR
Definition: xmlstorage.h:180