ReactOS  0.4.14-dev-114-gc8cbd56
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 */
16 unsigned char in1_bin[8] =
17 {
18  0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, /* testdata */
19 };
20 unsigned 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 };
25 unsigned 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 };
33 unsigned 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 
39 unsigned 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 };
44 unsigned 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 };
49 unsigned 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 };
57 unsigned 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 */
64 unsigned 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 };
76 unsigned 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 };
89 unsigned 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 };
98 unsigned 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 
104 typedef struct _bin_file
105 {
106  unsigned char* data;
107  size_t len;
108 } bin_file;
109 
110 typedef struct _patch_data
111 {
112  char* name;
119 } patch_data;
120 
121 #define MAKE_BIN(data_) { data_, sizeof(data_) }
122 
124 
125 BOOL extract2(char* filename, const unsigned char* data, size_t len)
126 {
127  HANDLE hFile;
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, 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 
171 void 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, 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 
211 static void validate_signature(const char* casename, const char* fieldname, const bin_file* bin, const char* expected)
212 {
213  char filename[MAX_PATH];
215  HANDLE hFile;
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. */
272 static 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 
319 unsigned 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, 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, 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);
393  dwErr = GetLastError();
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);
414  dwErr = GetLastError();
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 
477 static patch_data data[] =
478 {
479  {
480  "in1_text",
481  MAKE_BIN(in1_bin),
482  "99e5365e",
484  "f651d108",
487  },
488  {
489  "in2_binary",
490  MAKE_BIN(in2_bin),
491  "fc54c21d",
493  "028aa0fa",
496  },
497  {
498  "in3_compression",
499  MAKE_BIN(in3_bin),
500  "f10a52d9",
502  "411dd8f9",
505  },
506 };
507 
508 
509 START_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 }
unsigned char patch3_header_bin[32]
Definition: mspatcha.c:98
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
unsigned char * data
Definition: mspatcha.c:106
#define CloseHandle
Definition: compat.h:398
void test_one(patch_data *current)
Definition: mspatcha.c:467
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BOOL extract2(char *filename, const unsigned char *data, size_t len)
Definition: mspatcha.c:125
#define WideCharToMultiByte
Definition: compat.h:101
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)
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
START_TEST(mspatcha)
Definition: mspatcha.c:509
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
unsigned char out2_bin[25]
Definition: mspatcha.c:44
#define CP_ACP
Definition: compat.h:99
#define _countof(array)
Definition: fontsub.cpp:30
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)
#define free
Definition: debug_ros.c:5
GLdouble n
Definition: glext.h:7729
#define APPLY_OPTION_TEST_ONLY
Definition: patchapi.h:28
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
char * input_signature
Definition: mspatcha.c:114
unsigned char patch1_bin[75]
Definition: mspatcha.c:25
bin_file patch
Definition: mspatcha.c:117
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
const char * filename
Definition: ioapi.h:135
unsigned char patch2_bin[75]
Definition: mspatcha.c:49
#define _stricmp
Definition: cat.c:22
#define FILE_SHARE_READ
Definition: compat.h:125
BOOL extract(char *filename, const bin_file *bin)
Definition: mspatcha.c:158
unsigned char patch3_bin[88]
Definition: mspatcha.c:89
static const WCHAR filenameW[]
Definition: amstream.c:41
unsigned char in2_bin[25]
Definition: mspatcha.c:39
struct _patch_data patch_data
void compare_file_(char *filename, const unsigned char *data, size_t len, const char *test_name, int line)
Definition: mspatcha.c:171
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
struct _bin_file bin_file
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI TestApplyPatchToFileByHandles(HANDLE patch_file, HANDLE old_file, ULONG apply_flags)
#define GENERIC_WRITE
Definition: nt_native.h:90
bin_file output
Definition: mspatcha.c:115
static void apply_patch(patch_data *current)
Definition: mspatcha.c:343
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
Definition: parser.c:48
#define compare_file(filename, data, len, test_name)
Definition: mspatcha.c:209
#define OPEN_EXISTING
Definition: compat.h:426
static void validate_patch(patch_data *current)
Definition: mspatcha.c:332
DWORD dwErr
Definition: service.c:36
BOOL WINAPI ApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, LPCSTR new_file, ULONG apply_flags)
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
char * output_signature
Definition: mspatcha.c:116
bin_file input
Definition: mspatcha.c:113
#define MAX_PATH
Definition: compat.h:26
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned int crc32(unsigned int seed, unsigned char *msg, unsigned int msglen)
Definition: mspatcha.c:319
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
BOOL WINAPI TestApplyPatchToFileA(LPCSTR patch_file, LPCSTR old_file, ULONG apply_flags)
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned char in1_bin[8]
Definition: mspatcha.c:16
#define ERROR_PATCH_CORRUPT
Definition: patchapi.h:36
static const char * test_name
Definition: run.c:166
static const unsigned int crc_32_tab[]
Definition: mspatcha.c:272
#define CREATE_ALWAYS
Definition: disk.h:72
unsigned char out3_bin[152]
Definition: mspatcha.c:76
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
#define MAKE_BIN(data_)
Definition: mspatcha.c:121
#define ok(value,...)
Definition: atltest.h:57
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)
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define MultiByteToWideChar
Definition: compat.h:100
static struct _PeImage bin
#define msg(x)
Definition: auth_time.c:54
unsigned char patch2_header_bin[31]
Definition: mspatcha.c:57
unsigned char in3_bin[138]
Definition: mspatcha.c:64
bin_file patch_header
Definition: mspatcha.c:118
size_t len
Definition: mspatcha.c:107
#define malloc
Definition: debug_ros.c:4
char * name
Definition: mspatcha.c:112
unsigned char patch1_header_bin[31]
Definition: mspatcha.c:33
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399
#define ERROR_PATCH_WRONG_FILE
Definition: patchapi.h:38
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define memset(x, y, z)
Definition: compat.h:39
HANDLE WINAPI FindFirstFileA(IN LPCSTR lpFileName, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:263
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
HANDLE open_file(char *filename, BOOL bWrite)
Definition: mspatcha.c:163
BOOL expected
Definition: store.c:2063
struct task_struct * current
Definition: linux.c:32
#define ok_(x1, x2)
Definition: atltest.h:61
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502