[APPHELP][APPHELP_APITEST] Add SdbGetFileAttributes + tests, based on the work of...
[reactos.git] / rostests / apitests / apphelp / data.c
1 /*
2 * Copyright 2015 Mark Jansen
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include <exdisp.h>
20 #include <winbase.h>
21 #include "wine/test.h"
22
23
24 static IMAGE_DOS_HEADER dos_header =
25 {
26 IMAGE_DOS_SIGNATURE, /* e_magic */
27 144, /* e_cblp */
28 3, /* e_cp */
29 0, /* e_crlc */
30 4, /* e_cparhdr */
31 0, /* e_minalloc */
32 65535, /* e_maxalloc */
33 0, /* e_ss */
34 184, /* e_sp */
35 0, /* e_csum */
36 0, /* e_ip */
37 0, /* e_cs */
38 64, /* e_lfarlc */
39 0, /* e_ovno */
40 { 0 }, /* e_res[4] */
41 0, /* e_oemid */
42 0, /* e_oeminfo */
43 { 0 }, /* e_res2[10] */
44 0x80 /* e_lfanew */
45 };
46
47 static IMAGE_NT_HEADERS32 nt_header =
48 {
49 IMAGE_NT_SIGNATURE, /* Signature */
50 {
51 IMAGE_FILE_MACHINE_I386, /* Machine */
52 2, /* NumberOfSections */
53 0x12345, /* TimeDateStamp */
54 0, /* PointerToSymbolTable */
55 0, /* NumberOfSymbols */
56 sizeof(IMAGE_OPTIONAL_HEADER), /* SizeOfOptionalHeader */
57 IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_32BIT_MACHINE /* Characteristics */
58 },
59 {
60 IMAGE_NT_OPTIONAL_HDR_MAGIC, /* Magic */
61 6, /* MajorLinkerVersion */
62 3, /* MinorLinkerVersion */
63 0, /* SizeOfCode */
64 0, /* SizeOfInitializedData */
65 0, /* SizeOfUninitializedData */
66 0x1000, /* AddressOfEntryPoint */
67 0x1000, /* BaseOfCode */
68 #ifndef _WIN64
69 0, /* BaseOfData */
70 #endif
71 0x400000, /* ImageBase */
72 0x1000, /* SectionAlignment */
73 0x200, /* FileAlignment */
74 4, /* MajorOperatingSystemVersion */
75 1, /* MinorOperatingSystemVersion */
76 4, /* MajorImageVersion */
77 2, /* MinorImageVersion */
78 4, /* MajorSubsystemVersion */
79 3, /* MinorSubsystemVersion */
80 0, /* Win32VersionValue */
81 0x3000, /* SizeOfImage */
82 0x200, /* SizeOfHeaders */
83 0xBAAD, /* CheckSum: This checksum is not the correct checksum, intentionally! */
84 IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */
85 0, /* DllCharacteristics */
86 0x100000, /* SizeOfStackReserve */
87 0x1000, /* SizeOfStackCommit */
88 0x100000, /* SizeOfHeapReserve */
89 0x1000, /* SizeOfHeapCommit */
90 0, /* LoaderFlags */
91 0x10, /* NumberOfRvaAndSizes */
92 {
93 /* IMAGE_DIRECTORY_ENTRY_EXPORT */
94 {
95 0x2370, /* VirtualAddress */
96 76, /* Size */
97 },
98 { 0 },
99 /* IMAGE_DIRECTORY_ENTRY_RESOURCE */
100 {
101 0x2000, /* VirtualAddress */
102 868, /* Size */
103 },
104 } /* DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] */
105 }
106 };
107
108 static IMAGE_SECTION_HEADER section_headers[] =
109 {
110 {
111 { '.','t','e','x','t',0 }, /* Name */
112 { 24 }, /* VirtualSize */
113 0x1000, /* VirtualAddress */
114 0x200, /* SizeOfRawData */
115 0x200, /* PointerToRawData */
116 0, /* PointerToRelocations */
117 0, /* PointerToLinenumbers */
118 0, /* NumberOfRelocations */
119 0, /* NumberOfLinenumbers */
120 IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ /* Characteristics */
121 },
122 {
123 { '.','r','s','r','c',0 }, /* Name */
124 { 880 }, /* VirtualSize */
125 0x2000, /* VirtualAddress */
126 0x400, /* SizeOfRawData */
127 0x400, /* PointerToRawData */
128 0, /* PointerToRelocations */
129 0, /* PointerToLinenumbers */
130 0, /* NumberOfRelocations */
131 0, /* NumberOfLinenumbers */
132 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ /* Characteristics */
133 }
134 };
135
136 static const unsigned char text_section[] =
137 {
138 0x33, 0xc0, /* xor eax, eax */
139 0xc3 /* ret */
140 };
141
142
143 /* taken from fusionpriv.h */
144 typedef struct
145 {
146 WORD wLength;
147 WORD wValueLength;
148 WORD wType;
149 WCHAR szKey[17];
150 VS_FIXEDFILEINFO Value;
151 } VS_VERSIONINFO;
152
153 typedef struct
154 {
155 WORD wLength;
156 WORD wValueLength;
157 WORD wType;
158 WCHAR szKey[15];
159 } STRINGFILEINFO;
160
161 typedef struct
162 {
163 WORD wLength;
164 WORD wValueLength;
165 WORD wType;
166 WCHAR szKey[9];
167 } STRINGTABLE;
168
169 typedef struct
170 {
171 WORD wLength;
172 WORD wValueLength;
173 WORD wType;
174 } STRINGHDR;
175
176 typedef struct
177 {
178 WORD wLength;
179 WORD wValueLength;
180 WORD wType;
181 WCHAR szKey[13];
182 } VARFILEINFO;
183
184 typedef struct
185 {
186 WORD wLength;
187 WORD wValueLength;
188 WORD wType;
189 WCHAR szKey[13];
190 DWORD Value;
191 } VAR;
192
193 typedef struct rsrc_section_t
194 {
195 IMAGE_RESOURCE_DIRECTORY header;
196 IMAGE_RESOURCE_DIRECTORY_ENTRY file_info_id;
197 IMAGE_RESOURCE_DIRECTORY file_info_header;
198 IMAGE_RESOURCE_DIRECTORY_ENTRY version_info_id;
199 IMAGE_RESOURCE_DIRECTORY version_info_header;
200 IMAGE_RESOURCE_DIRECTORY_ENTRY version_lang_id;
201 IMAGE_RESOURCE_DATA_ENTRY version_data_entry;
202
203 VS_VERSIONINFO version_info;
204 STRINGFILEINFO string_file_info;
205 STRINGTABLE string_table;
206
207 STRINGHDR FileVersion_hdr;
208 WCHAR FileVersion_key[13];
209 WCHAR FileVersion_val[8];
210
211 STRINGHDR ProductVersion_hdr;
212 WCHAR ProductVersion_key[15];
213 WCHAR ProductVersion_val[8];
214
215 STRINGHDR CompanyName_hdr;
216 WCHAR CompanyName_key[13];
217 WCHAR CompanyName_val[12];
218
219 STRINGHDR FileDescription_hdr;
220 WCHAR FileDescription_key[17];
221 WCHAR FileDescription_val[16];
222
223 STRINGHDR InternalName_hdr;
224 WCHAR InternalName_key[13];
225 WCHAR InternalName_val[14];
226
227 STRINGHDR LegalCopyright_hdr;
228 WCHAR LegalCopyright_key[15];
229 WCHAR LegalCopyright_val[16];
230
231 STRINGHDR LegalTrademarks_hdr;
232 WCHAR LegalTrademarks_key[17];
233 WCHAR LegalTrademarks_val[16];
234
235 STRINGHDR OriginalFilename_hdr;
236 WCHAR OriginalFilename_key[17];
237 WCHAR OriginalFilename_val[18];
238
239 STRINGHDR Productname_hdr;
240 WCHAR Productname_key[13];
241 WCHAR Productname_val[12];
242
243 VARFILEINFO file_info;
244 VAR translation;
245 } rsrc_section_t;
246
247 static const rsrc_section_t rsrc_section =
248 {
249 /* header */
250 {
251 0, /* Characteristics */
252 0x55FE8E21, /* TimeDateStamp, 20/09/2015 10:44:49 */
253 0, /* MajorVersion */
254 0, /* MinorVersion */
255 0, /* NumberOfNamedEntries */
256 1, /* NumberOfIdEntries */
257 },
258 /* file_info_id */
259 {
260 {{
261 (DWORD)VS_FILE_INFO, /* NameOffset:31 */
262 0 /* NameIsString:1 */
263 }},
264 {
265 0x80000018 /* OffsetToData */
266 }
267 },
268 /* file_info_header */
269 {
270 0, /* Characteristics */
271 0x55FE8E21, /* TimeDateStamp, 20/09/2015 10:44:49 */
272 0, /* MajorVersion */
273 0, /* MinorVersion */
274 0, /* NumberOfNamedEntries */
275 1, /* NumberOfIdEntries */
276 },
277 /* version_info_id */
278 {
279 {{
280 VS_VERSION_INFO, /* NameOffset:31 */
281 0 /* NameIsString:1 */
282 }},
283 {
284 0x80000030 /* OffsetToData */
285 },
286 },
287 /* version_info_header */
288 {
289 0, /* Characteristics */
290 0x55FE8E21, /* TimeDateStamp, 20/09/2015 10:44:49 */
291 0, /* MajorVersion */
292 0, /* MinorVersion */
293 0, /* NumberOfNamedEntries */
294 1, /* NumberOfIdEntries */
295 },
296 /* version_lang_id */
297 {
298 {{
299 1033, /* NameOffset:31 */
300 0 /* NameIsString:1 */
301 }},
302 {
303 0x48 /* OffsetToDirectory */
304 }
305 },
306 /* version_data_entry */
307 {
308 0x2058, /* OffsetToData */
309 0x30C, /* Size */
310 0, /* CodePage */
311 0, /* Reserved */
312 },
313
314 /* version_info */
315 {
316 0x30C, /* wLength */
317 0x34, /* wValueLength */
318 0, /* wType: Binary */
319 { 'V','S','_','V','E','R','S','I','O','N','_','I','N','F','O','\0','\0' }, /* szKey[17] */
320 /* Value */
321 {
322 0xFEEF04BD, /* dwSignature */
323 0x10000, /* dwStrucVersion */
324 0x10000, /* dwFileVersionMS */
325 0, /* dwFileVersionLS */
326 0x10000, /* dwProductVersionMS */
327 1, /* dwProductVersionLS */
328 0, /* dwFileFlagsMask */
329 0, /* dwFileFlags */
330 VOS__WINDOWS32, /* dwFileOS */
331 VFT_APP, /* dwFileType */
332 0, /* dwFileSubtype */
333 0x01d1a019, /* dwFileDateMS */
334 0xac754c50 /* dwFileDateLS */
335 },
336 },
337
338 /* string_file_info */
339 {
340 0x26C, /* wLength */
341 0, /* wValueLength */
342 1, /* wType: Text */
343 { 'S','t','r','i','n','g','F','i','l','e','I','n','f','o','\0' } /* szKey[15] */
344 },
345 /* string_table */
346 {
347 0x248, /* wLength */
348 0, /* wValueLength */
349 1, /* wType: Text */
350 { 'F','F','F','F','0','0','0','0','\0' } /* szKey[9] */
351 },
352
353 /* FileVersion */
354 {
355 48, /* wLength */
356 8, /* wValueLength */
357 1, /* wType: Text */
358 },
359 { 'F','i','l','e','V','e','r','s','i','o','n','\0' },
360 { '1','.','0','.','0','.','0','\0' },
361
362 /* ProductVersion */
363 {
364 52, /* wLength */
365 8, /* wValueLength */
366 1, /* wType: Text */
367 },
368 { 'P','r','o','d','u','c','t','V','e','r','s','i','o','n','\0' },
369 { '1','.','0','.','0','.','1','\0' },
370
371 /* CompanyName */
372 {
373 56, /* wLength */
374 12, /* wValueLength */
375 1, /* wType: Text */
376 },
377 { 'C','o','m','p','a','n','y','N','a','m','e','\0' },
378 { 'C','o','m','p','a','n','y','N','a','m','e','\0' },
379
380 /* FileDescription */
381 {
382 72, /* wLength */
383 16, /* wValueLength */
384 1, /* wType: Text */
385 },
386 { 'F','i','l','e','D','e','s','c','r','i','p','t','i','o','n','\0' },
387 { 'F','i','l','e','D','e','s','c','r','i','p','t','i','o','n','\0' },
388
389 /* InternalName */
390 {
391 58, /* wLength */
392 13, /* wValueLength */
393 1, /* wType: Text */
394 },
395 { 'I','n','t','e','r','n','a','l','N','a','m','e','\0' },
396 { 'I','n','t','e','r','n','a','l','N','a','m','e','\0' },
397
398 /* LegalCopyright */
399 {
400 66, /* wLength */
401 15, /* wValueLength */
402 1, /* wType: Text */
403 },
404 { 'L','e','g','a','l','C','o','p','y','r','i','g','h','t','\0' },
405 { 'L','e','g','a','l','C','o','p','y','r','i','g','h','t','\0' },
406
407 /* LegalTrademarks */
408 {
409 72, /* wLength */
410 16, /* wValueLength */
411 1, /* wType: Text */
412 },
413 { 'L','e','g','a','l','T','r','a','d','e','m','a','r','k','s','\0' },
414 { 'L','e','g','a','l','T','r','a','d','e','m','a','r','k','s','\0' },
415
416 /* OriginalFilename */
417 {
418 74, /* wLength */
419 17, /* wValueLength */
420 1, /* wType: Text */
421 },
422 { 'O','r','i','g','i','n','a','l','F','i','l','e','n','a','m','e','\0' },
423 { 'O','r','i','g','i','n','a','l','F','i','l','e','n','a','m','e','\0' },
424
425 /* ProductName */
426 {
427 56, /* wLength */
428 12, /* wValueLength */
429 1, /* wType: Text */
430 },
431 { 'P','r','o','d','u','c','t','N','a','m','e','\0' },
432 { 'P','r','o','d','u','c','t','N','a','m','e','\0' },
433
434
435 /* file_info */
436 {
437 0x44, /* wLength */
438 0, /* wValueLength */
439 1, /* wType: Text */
440 { 'V','a','r','F','i','l','e','I','n','f','o','\0' } /* szKey[13] */
441 },
442
443 /* translation */
444 {
445 0x24, /* wLength */
446 4, /* wValueLength */
447 0, /* wType: Binary */
448 { 'T','r','a','n','s','l','a','t','i','o','n','\0' }, /* szKey[13] */
449 0xffff /* Value */
450 }
451 };
452
453 typedef struct export_section_t
454 {
455 IMAGE_EXPORT_DIRECTORY desc;
456 char binary_name[10];
457 } export_section_t;
458
459 /* This export section is not complete, but the Name RVA is only taken into account */
460 static export_section_t export_dir =
461 {
462 {
463 0, /* Characteristics */
464 0, /* TimeDateStamp */
465 0, /* MajorVersion */
466 0, /* MinorVersion */
467 0x2398, /* Name (RVA) */
468 1, /* Base */
469 0, /* NumberOfFunctions */
470 0, /* NumberOfNames */
471 0, /* AddressOfFunctions (RVA) */
472 0, /* AddressOfNames (RVA) */
473 0, /* AddressOfNameOrdinals (RVA) */
474 },
475 { 'T','e','S','t','2','.','e','x','e',0 }, /* binary_name */
476 };
477
478
479 void test_create_exe_imp(const char* name, int skip_rsrc_exports)
480 {
481 HANDLE file;
482 char *buf, *cur;
483 DWORD size = 0x800;
484 buf = malloc(size);
485
486 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
487 winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file\n");
488 if(file == INVALID_HANDLE_VALUE)
489 return;
490
491 memset(buf, 0, size);
492 cur = buf;
493 cur = memcpy(buf, &dos_header, sizeof(dos_header));
494 cur += dos_header.e_lfanew;
495
496 memcpy(cur, &nt_header, sizeof(nt_header));
497 if (skip_rsrc_exports)
498 {
499 ((IMAGE_NT_HEADERS32*)cur)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = 0;
500 ((IMAGE_NT_HEADERS32*)cur)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = 0;
501 }
502 cur += sizeof(nt_header);
503 memcpy(cur, section_headers, sizeof(section_headers));
504
505 /* write code section: */
506 cur = buf + section_headers[0].PointerToRawData;
507 memcpy(cur, text_section, sizeof(text_section));
508
509 if (!skip_rsrc_exports)
510 {
511 /* write resource section: */
512 cur = buf + section_headers[1].PointerToRawData;
513 memcpy(cur, &rsrc_section, sizeof(rsrc_section));
514
515 /* write minimal export directory: */
516 cur += 0x370;
517 memcpy(cur, &export_dir, sizeof(export_dir));
518 }
519
520 WriteFile(file, buf, size, &size, NULL);
521 free(buf);
522 CloseHandle(file);
523 }
524
525
526 /* Almost everything in this filetype is ignored, only e_lfanew, ne_restab and ne_nrestab are relevant */
527 void test_create_ne_imp(const char* name, int skip_names)
528 {
529 HANDLE file;
530 DWORD size;
531 IMAGE_DOS_HEADER MZ_hdr = { IMAGE_DOS_SIGNATURE, 0 };
532 IMAGE_OS2_HEADER NE_hdr = { IMAGE_OS2_SIGNATURE, 0 };
533 static const BYTE NE_names[] =
534 {
535 /* Show that the length is used, not the nullterm*/
536 11,'T','E','S','T','M','O','D','.','h','X','x','x',0,0,0,
537 20,'M','O','D',' ','D','E','S','C','R','I','P','T','I','O','N',' ','H','E','R','E',0,0,0
538 };
539
540 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
541 winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file\n");
542 if(file == INVALID_HANDLE_VALUE)
543 return;
544
545 MZ_hdr.e_lfanew = sizeof(MZ_hdr);
546 if (!skip_names)
547 {
548 NE_hdr.ne_restab = sizeof(NE_hdr); /* First entry (pascal string + ordinal) = module name */
549 NE_hdr.ne_nrestab = sizeof(MZ_hdr) + sizeof(NE_hdr) + 16; /* First entry (pascal string + ordinal) = module description */
550 }
551
552 WriteFile(file, &MZ_hdr, sizeof(MZ_hdr), &size, NULL);
553 WriteFile(file, &NE_hdr, sizeof(NE_hdr), &size, NULL);
554 WriteFile(file, NE_names, sizeof(NE_names), &size, NULL);
555
556 CloseHandle(file);
557 }
558
559 void test_create_file_imp(const char* name, const char* contents, size_t len)
560 {
561 HANDLE file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
562 winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file\n");
563 if (file != INVALID_HANDLE_VALUE)
564 {
565 if (contents && len)
566 {
567 DWORD size;
568 WriteFile(file, contents, len, &size, NULL);
569 }
570 CloseHandle(file);
571 }
572 }
573