diff --git a/dlls/kernel32/resource.c b/dlls/kernel32/resource.c index 0050cb9ad5f..50918048ece 100644 --- a/dlls/kernel32/resource.c +++ b/dlls/kernel32/resource.c @@ -1372,10 +1372,7 @@ static IMAGE_SECTION_HEADER *get_resource_section( void *base, DWORD mapping_siz break; if (i == num_sections) - { - FIXME(".rsrc doesn't exist\n"); return NULL; - } return &sec[i]; } @@ -1400,7 +1397,7 @@ static BOOL write_raw_resources( QUEUEDUPDATES *updates ) { static const WCHAR prefix[] = { 'r','e','s','u',0 }; WCHAR tempdir[MAX_PATH], tempfile[MAX_PATH]; - DWORD mapping_size, section_size, old_size; + DWORD section_size; BOOL ret = FALSE; IMAGE_SECTION_HEADER *sec; IMAGE_NT_HEADERS *nt; @@ -1449,21 +1446,35 @@ static BOOL write_raw_resources( QUEUEDUPDATES *updates ) goto done; } - sec = get_resource_section( write_map->base, write_map->size ); - if (!sec) + if (nt->OptionalHeader.FileAlignment <= 0) + { + ERR("invalid file alignment %04x\n", nt->OptionalHeader.FileAlignment); goto done; + } + + sec = get_resource_section( write_map->base, write_map->size ); + if (!sec) /* no section, add one */ + { + DWORD num_sections; + + sec = get_section_header( write_map->base, write_map->size, &num_sections ); + if (!sec) + goto done; + + sec += num_sections; + nt->FileHeader.NumberOfSections++; + + memset( sec, 0, sizeof *sec ); + memcpy( sec->Name, ".rsrc", 5 ); + sec->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; + sec->VirtualAddress = nt->OptionalHeader.SizeOfImage; + } if (!sec->PointerToRawData) /* empty section */ { - sec->PointerToRawData = write_map->size; + sec->PointerToRawData = write_map->size + (-write_map->size) % nt->OptionalHeader.FileAlignment; sec->SizeOfRawData = 0; } - else if ((sec->SizeOfRawData + sec->PointerToRawData) != write_map->size) - { - FIXME(".rsrc isn't at the end of the image %08x + %08x != %08x for %s\n", - sec->SizeOfRawData, sec->PointerToRawData, write_map->size, debugstr_w(updates->pFileName)); - goto done; - } TRACE("before .rsrc at %08x, size %08x\n", sec->PointerToRawData, sec->SizeOfRawData); @@ -1471,38 +1482,85 @@ static BOOL write_raw_resources( QUEUEDUPDATES *updates ) /* round up the section size */ section_size = res_size.total_size; - section_size += (-section_size) % nt->OptionalHeader.SectionAlignment; - - mapping_size = sec->PointerToRawData + section_size; + section_size += (-section_size) % nt->OptionalHeader.FileAlignment; TRACE("requires %08x (%08x) bytes\n", res_size.total_size, section_size ); /* check if the file size needs to be changed */ if (section_size != sec->SizeOfRawData) { - old_size = write_map->size; + DWORD old_size = write_map->size; + DWORD virtual_section_size = res_size.total_size + (-res_size.total_size) % nt->OptionalHeader.SectionAlignment; + int delta = section_size - (sec->SizeOfRawData + (-sec->SizeOfRawData) % nt->OptionalHeader.FileAlignment); + int rva_delta = virtual_section_size - + (sec->Misc.VirtualSize + (-sec->Misc.VirtualSize) % nt->OptionalHeader.SectionAlignment); + BOOL rsrc_is_last = sec->PointerToRawData + sec->SizeOfRawData == old_size; + /* align .rsrc size when possible */ + DWORD mapping_size = rsrc_is_last ? sec->PointerToRawData + section_size : old_size + delta; + + /* postpone file truncation if there are some data to be moved down from file end */ + BOOL resize_after = mapping_size < old_size && !rsrc_is_last; TRACE("file size %08x -> %08x\n", old_size, mapping_size); - /* unmap the file before changing the file size */ - ret = resize_mapping( write_map, mapping_size ); - - /* get the pointers again - they might be different after remapping */ - nt = get_nt_header( write_map->base, mapping_size ); - if (!nt) + if (!resize_after) { - ERR("couldn't get NT header\n"); - goto done; + /* unmap the file before changing the file size */ + ret = resize_mapping( write_map, mapping_size ); + + /* get the pointers again - they might be different after remapping */ + nt = get_nt_header( write_map->base, mapping_size ); + if (!nt) + { + ERR("couldn't get NT header\n"); + goto done; + } + + sec = get_resource_section( write_map->base, mapping_size ); + if (!sec) + goto done; } - sec = get_resource_section( write_map->base, mapping_size ); - if (!sec) - goto done; + if (!rsrc_is_last) /* not last section, relocate trailing sections */ + { + IMAGE_SECTION_HEADER *s; + DWORD tail_start = sec->PointerToRawData + sec->SizeOfRawData; + DWORD i, num_sections = 0; + + memmove( (char*)write_map->base + tail_start + delta, (char*)write_map->base + tail_start, old_size - tail_start ); + + s = get_section_header( write_map->base, mapping_size, &num_sections ); + + for (i=0; i sec->PointerToRawData) + { + s[i].PointerToRawData += delta; + s[i].VirtualAddress += rva_delta; + } + } + } + + if (resize_after) + { + ret = resize_mapping( write_map, mapping_size ); + + nt = get_nt_header( write_map->base, mapping_size ); + if (!nt) + { + ERR("couldn't get NT header\n"); + goto done; + } + + sec = get_resource_section( write_map->base, mapping_size ); + if (!sec) + goto done; + } /* adjust the PE header information */ - nt->OptionalHeader.SizeOfImage += (mapping_size - old_size); sec->SizeOfRawData = section_size; - sec->Misc.VirtualSize = section_size; + sec->Misc.VirtualSize = virtual_section_size; + nt->OptionalHeader.SizeOfImage += rva_delta; nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = res_size.total_size; nt->OptionalHeader.SizeOfInitializedData = get_init_data_size( write_map->base, mapping_size ); } diff --git a/dlls/kernel32/tests/resource.c b/dlls/kernel32/tests/resource.c index a2c02c81aeb..092787796af 100644 --- a/dlls/kernel32/tests/resource.c +++ b/dlls/kernel32/tests/resource.c @@ -26,16 +26,180 @@ static const char filename[] = "test_.exe"; static DWORD GLE; -static int build_exe( void ) +enum { + page_size = 0x1000, + rva_rsrc_start = page_size * 3, + max_sections = 3 +} constants; + +/* rodata @ [0x1000-0x3000) */ +static const IMAGE_SECTION_HEADER sh_rodata_1 = +{ + ".rodata", {2*page_size}, page_size, 2*page_size, page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rodata @ [0x1000-0x4000) */ +static const IMAGE_SECTION_HEADER sh_rodata_2 = +{ + ".rodata", {3*page_size}, page_size, 3*page_size, page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rodata @ [0x1000-0x2000) */ +static const IMAGE_SECTION_HEADER sh_rodata_3 = +{ + ".rodata", {page_size}, page_size, page_size, page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x3000-0x4000) */ +static const IMAGE_SECTION_HEADER sh_rsrc_1 = +{ + ".rsrc\0\0", {page_size}, rva_rsrc_start, page_size, rva_rsrc_start, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x4000-0x5000) */ +static const IMAGE_SECTION_HEADER sh_rsrc_2 = +{ + ".rsrc\0\0", {page_size}, 4*page_size, page_size, 4*page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x2000-0x4000) */ +static const IMAGE_SECTION_HEADER sh_rsrc_3 = +{ + ".rsrc\0\0", {2*page_size}, rva_rsrc_start-page_size, 2*page_size, rva_rsrc_start-page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x2000-0x3000) */ +static const IMAGE_SECTION_HEADER sh_rsrc_4 = +{ + ".rsrc\0\0", {page_size}, rva_rsrc_start-page_size, page_size, rva_rsrc_start-page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x3000-0x6000) */ +static const IMAGE_SECTION_HEADER sh_rsrc_5 = +{ + ".rsrc\0\0", {3*page_size}, rva_rsrc_start, 3*page_size, rva_rsrc_start, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x4000-0x7000) */ +static const IMAGE_SECTION_HEADER sh_rsrc_6 = +{ + ".rsrc\0\0", {3*page_size}, 4*page_size, 3*page_size, 4*page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x2000-0x5000) */ +static const IMAGE_SECTION_HEADER sh_rsrc_7 = +{ + ".rsrc\0\0", {3*page_size}, 2*page_size, 3*page_size, 2*page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* rsrc @ [0x3000-0x4000), small SizeOfRawData */ +static const IMAGE_SECTION_HEADER sh_rsrc_8 = +{ + ".rsrc\0\0", {page_size}, rva_rsrc_start, 8, rva_rsrc_start, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* reloc @ [0x4000-0x5000) */ +static const IMAGE_SECTION_HEADER sh_junk = +{ + ".reloc\0", {page_size}, 4*page_size, page_size, 4*page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +/* reloc @ [0x6000-0x7000) */ +static const IMAGE_SECTION_HEADER sh_junk_2 = +{ + ".reloc\0", {page_size}, 6*page_size, page_size, 6*page_size, 0, 0, 0, 0, + IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +}; + +typedef struct _sec_build +{ + const IMAGE_SECTION_HEADER *sect_in[max_sections]; +} sec_build; + +typedef struct _sec_verify +{ + const IMAGE_SECTION_HEADER *sect_out[max_sections]; + DWORD length; + int rsrc_section; + DWORD NumberOfNamedEntries, NumberOfIdEntries; +} sec_verify; + +static const struct _sec_variants +{ + sec_build build; + sec_verify chk_none, chk_delete, chk_version, chk_bigdata; +} sec_variants[] = +{ + /* .rsrc is the last section, data directory entry points to whole section */ + { + {{&sh_rodata_1, &sh_rsrc_1, NULL}}, + {{&sh_rodata_1, &sh_rsrc_1, NULL}, 4*page_size, 1, 0, 0}, + {{&sh_rodata_1, &sh_rsrc_1, NULL}, 4*page_size, 1, 0, 0}, + {{&sh_rodata_1, &sh_rsrc_1, NULL}, 4*page_size, 1, 0, 1}, + {{&sh_rodata_1, &sh_rsrc_5, NULL}, 6*page_size, 1, 0, 1} + }, + /* single .rodata section with compatible characteristics, data directory entry points to section end */ + /* Vista+ - existing section isn't used, new section is created at the end of file */ + /* NT4/2000/2003 - image is broken */ +#if 0 + { + {{&sh_rodata_2, NULL, NULL}}, + {{&sh_rodata_2, &sh_rsrc_2, NULL}, 5*page_size, 1, 0, 0}, + {{&sh_rodata_2, &sh_rsrc_2, NULL}, 5*page_size, 1, 0, 0}, + {{&sh_rodata_2, &sh_rsrc_2, NULL}, 5*page_size, 1, 0, 1}, + {{&sh_rodata_2, &sh_rsrc_6, NULL}, 7*page_size, 1, 0, 1} + }, +#endif + /* .rsrc is the last section, data directory entry points to section end */ + /* Vista+ - resources are moved to section start (trashing data that could be there), and section is trimmed */ + /* NT4/2000/2003 - resources are moved to section start (trashing data that could be there); section isn't trimmed */ + { + {{&sh_rodata_3, &sh_rsrc_3, NULL}}, + {{&sh_rodata_3, &sh_rsrc_4, NULL}, 3*page_size, 1, 0, 0}, + {{&sh_rodata_3, &sh_rsrc_4, NULL}, 3*page_size, 1, 0, 0}, + {{&sh_rodata_3, &sh_rsrc_4, NULL}, 3*page_size, 1, 0, 1}, + {{&sh_rodata_3, &sh_rsrc_7, NULL}, 5*page_size, 1, 0, 1} + }, + /* .rsrc is not the last section */ + /* section is reused; sections after .rsrc are shifted to give space to rsrc (in-image offset and RVA!) */ + { + {{&sh_rodata_1, &sh_rsrc_1, &sh_junk}}, + {{&sh_rodata_1, &sh_rsrc_1, &sh_junk}, 5*page_size, 1, 0, 0}, + {{&sh_rodata_1, &sh_rsrc_1, &sh_junk}, 5*page_size, 1, 0, 0}, + {{&sh_rodata_1, &sh_rsrc_1, &sh_junk}, 5*page_size, 1, 0, 1}, + {{&sh_rodata_1, &sh_rsrc_5, &sh_junk_2}, 7*page_size, 1, 0, 1} + }, + /* .rsrc is the last section, data directory entry points to whole section, file size is not aligned on FileAlign */ + { + {{&sh_rodata_1, &sh_rsrc_8, NULL}}, + {{&sh_rodata_1, &sh_rsrc_1, NULL}, 4*page_size, 1, 0, 0}, + {{&sh_rodata_1, &sh_rsrc_1, NULL}, 4*page_size, 1, 0, 0}, + {{&sh_rodata_1, &sh_rsrc_1, NULL}, 4*page_size, 1, 0, 1}, + {{&sh_rodata_1, &sh_rsrc_5, NULL}, 6*page_size, 1, 0, 1} + } +}; + +static int build_exe( const sec_build* sec_descr ) { IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS *nt; IMAGE_SECTION_HEADER *sec; IMAGE_OPTIONAL_HEADER *opt; HANDLE file; - DWORD written; - BYTE page[0x1000]; - const int page_size = 0x1000; + DWORD written, i, file_size; + BYTE page[page_size]; memset( page, 0, sizeof page ); @@ -47,7 +211,7 @@ static int build_exe( void ) nt->Signature = IMAGE_NT_SIGNATURE; nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386; - nt->FileHeader.NumberOfSections = 2; + nt->FileHeader.NumberOfSections = 0; nt->FileHeader.SizeOfOptionalHeader = sizeof nt->OptionalHeader; nt->FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL; @@ -61,7 +225,7 @@ static int build_exe( void ) opt->MajorImageVersion = 1; opt->MajorSubsystemVersion = 4; opt->SizeOfHeaders = sizeof *dos + sizeof *nt + sizeof *sec * 2; - opt->SizeOfImage = page_size*3; + opt->SizeOfImage = page_size; opt->Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI; /* if SectionAlignment and File alignment are not specified */ @@ -69,21 +233,27 @@ static int build_exe( void ) opt->SectionAlignment = page_size; opt->FileAlignment = page_size; + opt->DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY].VirtualAddress = rva_rsrc_start; + opt->DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY].Size = page_size; + sec = (void*) &nt[1]; - memcpy( sec[0].Name, ".rodata", 8 ); - sec[0].Misc.VirtualSize = page_size; - sec[0].PointerToRawData = page_size; - sec[0].SizeOfRawData = page_size; - sec[0].VirtualAddress = page_size; - sec[0].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; - - memcpy( sec[1].Name, ".rsrc", 6 ); - sec[1].Misc.VirtualSize = page_size; - sec[1].SizeOfRawData = page_size; - sec[1].PointerToRawData = page_size*2; - sec[1].VirtualAddress = page_size*2; - sec[1].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ; + file_size = 0; + for ( i = 0; i < max_sections; i++ ) + if ( sec_descr->sect_in[i] ) + { + DWORD virt_end_of_section = sec_descr->sect_in[i]->Misc.VirtualSize + + sec_descr->sect_in[i]->VirtualAddress; + DWORD phys_end_of_section = sec_descr->sect_in[i]->SizeOfRawData + + sec_descr->sect_in[i]->PointerToRawData; + memcpy( sec + nt->FileHeader.NumberOfSections, sec_descr->sect_in[i], + sizeof(sec[0]) ); + nt->FileHeader.NumberOfSections++; + if ( opt->SizeOfImage < virt_end_of_section ) + opt->SizeOfImage = virt_end_of_section; + if ( file_size < phys_end_of_section ) + file_size = phys_end_of_section; + } file = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); ok (file != INVALID_HANDLE_VALUE, "failed to create file\n"); @@ -91,13 +261,13 @@ static int build_exe( void ) /* write out the header */ WriteFile( file, page, sizeof page, &written, NULL ); - /* write out an empty page for rodata */ + /* write out zeroed pages for sections */ memset( page, 0, sizeof page ); - WriteFile( file, page, sizeof page, &written, NULL ); - - /* write out an empty page for the resources */ - memset( page, 0, sizeof page ); - WriteFile( file, page, sizeof page, &written, NULL ); + for ( i = page_size; i < file_size; i += page_size ) + { + DWORD size = min(page_size, file_size - i); + WriteFile( file, page, size, &written, NULL ); + } CloseHandle( file ); @@ -169,7 +339,7 @@ static void update_resources_delete( void ) ok( r, "EndUpdateResource failed\n"); } -static void update_resources_version(void) +static void update_resources_version( void ) { HANDLE res = NULL; BOOL r; @@ -199,41 +369,41 @@ static void update_resources_version(void) ok( r, "EndUpdateResource failed: %d\n", GetLastError()); } - -typedef void (*res_check_func)( IMAGE_RESOURCE_DIRECTORY* ); - -static void check_empty( IMAGE_RESOURCE_DIRECTORY *dir ) +static void update_resources_bigdata( void ) { - char *pad; + HANDLE res = NULL; + BOOL r; + char foo[2*page_size] = "foobar"; - ok( dir->NumberOfNamedEntries == 0, "NumberOfNamedEntries should be 0 instead of %d\n", dir->NumberOfNamedEntries); - ok( dir->NumberOfIdEntries == 0, "NumberOfIdEntries should be 0 instead of %d\n", dir->NumberOfIdEntries); + res = BeginUpdateResource( filename, TRUE ); + ok( res != NULL, "BeginUpdateResource succeeded\n"); - pad = (char*) &dir[1]; + r = UpdateResource( res, + MAKEINTRESOURCE(0x3012), + MAKEINTRESOURCE(0x5647), + 0xcdba, + foo, sizeof foo ); + ok( r == TRUE, "UpdateResource failed: %d\n", GetLastError()); - ok( !memcmp( pad, "PADDINGXXPADDING", 16), "padding wrong\n"); + r = EndUpdateResource( res, FALSE ); + ok( r, "EndUpdateResource failed\n"); } -static void check_not_empty( IMAGE_RESOURCE_DIRECTORY *dir ) -{ - ok( dir->NumberOfNamedEntries == 0, "NumberOfNamedEntries should be 0 instead of %d\n", dir->NumberOfNamedEntries); - ok( dir->NumberOfIdEntries == 1, "NumberOfIdEntries should be 1 instead of %d\n", dir->NumberOfIdEntries); -} - -static void check_exe( res_check_func fn ) +static void check_exe( const sec_verify *verify ) { + int i; IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS *nt; IMAGE_SECTION_HEADER *sec; IMAGE_RESOURCE_DIRECTORY *dir; HANDLE file, mapping; - DWORD length; + DWORD length, sec_count = 0; file = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); ok (file != INVALID_HANDLE_VALUE, "failed to create file (%d)\n", GetLastError()); length = GetFileSize( file, NULL ); - ok( length == 0x3000, "file size wrong\n"); + ok( length >= verify->length, "file size wrong\n"); mapping = CreateFileMapping( file, NULL, PAGE_READONLY, 0, 0, NULL ); ok (mapping != NULL, "failed to create file\n"); @@ -245,24 +415,36 @@ static void check_exe( res_check_func fn ) goto end; nt = (void*) ((BYTE*) dos + dos->e_lfanew); - ok( nt->FileHeader.NumberOfSections == 2, "number of sections wrong\n" ); - - if (nt->FileHeader.NumberOfSections < 2) - goto end; - sec = (void*) &nt[1]; - ok( !memcmp(sec[1].Name, ".rsrc", 6), "resource section name wrong\n"); + for(i = 0; i < max_sections; i++) + if (verify->sect_out[i]) + { + ok( !memcmp(&verify->sect_out[i]->Name, &sec[sec_count].Name, 8), "section %d name wrong\n", sec_count); + ok( verify->sect_out[i]->VirtualAddress == sec[sec_count].VirtualAddress, "section %d vaddr wrong\n", sec_count); + ok( verify->sect_out[i]->SizeOfRawData <= sec[sec_count].SizeOfRawData, "section %d SizeOfRawData wrong (%d vs %d)\n", sec_count, verify->sect_out[i]->SizeOfRawData ,sec[sec_count].SizeOfRawData); + ok( verify->sect_out[i]->PointerToRawData == sec[sec_count].PointerToRawData, "section %d PointerToRawData wrong\n", sec_count); + ok( verify->sect_out[i]->Characteristics == sec[sec_count].Characteristics , "section %d characteristics wrong\n", sec_count); + sec_count++; + } - dir = (void*) ((BYTE*) dos + sec[1].VirtualAddress); + ok( nt->FileHeader.NumberOfSections == sec_count, "number of sections wrong\n" ); - ok( dir->Characteristics == 0, "Characteristics wrong\n"); - ok( dir->TimeDateStamp == 0 || abs( dir->TimeDateStamp - GetTickCount() ) < 1000 /* nt4 */, - "TimeDateStamp wrong %u\n", dir->TimeDateStamp); - ok( dir->MajorVersion == 4, "MajorVersion wrong\n"); - ok( dir->MinorVersion == 0, "MinorVersion wrong\n"); + if (verify->rsrc_section >= 0 && verify->rsrc_section < nt->FileHeader.NumberOfSections) + { + dir = (void*) ((BYTE*) dos + sec[verify->rsrc_section].VirtualAddress); - fn( dir ); + ok( dir->Characteristics == 0, "Characteristics wrong\n"); + ok( dir->TimeDateStamp == 0 || abs( dir->TimeDateStamp - GetTickCount() ) < 1000 /* nt4 */, + "TimeDateStamp wrong %u\n", dir->TimeDateStamp); + ok( dir->MajorVersion == 4, "MajorVersion wrong\n"); + ok( dir->MinorVersion == 0, "MinorVersion wrong\n"); + + ok( dir->NumberOfNamedEntries == verify->NumberOfNamedEntries, "NumberOfNamedEntries should be %d instead of %d\n", + verify->NumberOfNamedEntries, dir->NumberOfNamedEntries); + ok( dir->NumberOfIdEntries == verify->NumberOfIdEntries, "NumberOfIdEntries should be %d instead of %d\n", + verify->NumberOfIdEntries, dir->NumberOfIdEntries); + } end: UnmapViewOfFile( dos ); @@ -310,6 +492,8 @@ static void test_find_resource(void) START_TEST(resource) { + DWORD i; + DeleteFile( filename ); update_missing_exe(); @@ -320,13 +504,20 @@ START_TEST(resource) } update_empty_exe(); - build_exe(); - update_resources_none(); - check_exe( check_empty ); - update_resources_delete(); - check_exe( check_empty ); - update_resources_version(); - check_exe( check_not_empty ); - DeleteFile( filename ); + + for(i=0; i < sizeof( sec_variants ) / sizeof( sec_variants[0] ); i++) + { + const struct _sec_variants *sec = &sec_variants[i]; + build_exe( &sec->build ); + update_resources_none(); + check_exe( &sec->chk_none ); + update_resources_delete(); + check_exe( &sec->chk_delete ); + update_resources_version(); + check_exe( &sec->chk_version ); + update_resources_bigdata(); + check_exe( &sec->chk_bigdata ); + DeleteFile( filename ); + } test_find_resource(); }