[PATCH 1/3] kernel32: Add a short test for Begin/EndUpdateResource
Mike McCormack
mike at codeweavers.com
Tue Dec 26 23:13:35 CST 2006
---
dlls/kernel32/tests/Makefile.in | 1 +
dlls/kernel32/tests/resource.c | 296
+++++++++++++++++++++++++++++++++++++++
2 files changed, 297 insertions(+), 0 deletions(-)
diff --git a/dlls/kernel32/tests/Makefile.in
b/dlls/kernel32/tests/Makefile.in
index 948ac28..c71bf4f 100644
--- a/dlls/kernel32/tests/Makefile.in
+++ b/dlls/kernel32/tests/Makefile.in
@@ -27,6 +27,7 @@ CTESTS = \
pipe.c \
process.c \
profile.c \
+ resource.c \
sync.c \
thread.c \
time.c \
diff --git a/dlls/kernel32/tests/resource.c b/dlls/kernel32/tests/resource.c
new file mode 100644
index 0000000..d5f3707
--- /dev/null
+++ b/dlls/kernel32/tests/resource.c
@@ -0,0 +1,296 @@
+/*
+ * Unit test suite for environment functions.
+ *
+ * Copyright 2006 Mike McCormack
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301, USA
+ */
+
+#include <windows.h>
+#include <stdio.h>
+
+#include "wine/test.h"
+
+static const char filename[] = "test_.exe";
+
+static int build_exe( void )
+{
+ 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;
+
+ memset( page, 0, sizeof page );
+
+ dos = (void*) page;
+ dos->e_magic = IMAGE_DOS_SIGNATURE;
+ dos->e_lfanew = sizeof *dos;
+
+ nt = (void*) &dos[1];
+
+ nt->Signature = IMAGE_NT_SIGNATURE;
+ nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
+ nt->FileHeader.NumberOfSections = 2;
+ nt->FileHeader.SizeOfOptionalHeader = sizeof nt->OptionalHeader;
+ nt->FileHeader.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE |
IMAGE_FILE_DLL;
+
+ opt = &nt->OptionalHeader;
+
+ opt->Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
+ opt->MajorLinkerVersion = 1;
+ opt->BaseOfCode = 0x10;
+ opt->ImageBase = 0x10000000;
+ opt->MajorOperatingSystemVersion = 4;
+ opt->MajorImageVersion = 1;
+ opt->MajorSubsystemVersion = 4;
+ opt->SizeOfHeaders = sizeof *dos + sizeof *nt + sizeof *sec * 2;
+ opt->SizeOfImage = page_size*3;
+ opt->Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
+
+ /* if SectionAlignment and File alignment are not specified */
+ /* UpdateResource fails trying to create a huge temporary file */
+ opt->SectionAlignment = page_size;
+ opt->FileAlignment = 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 = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
0, 0);
+ ok (file != INVALID_HANDLE_VALUE, "failed to create file\n");
+
+ /* write out the header */
+ WriteFile( file, page, sizeof page, &written, NULL );
+
+ /* write out an empty page for rodata */
+ 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 );
+
+ CloseHandle( file );
+
+ return 0;
+}
+
+static void update_missing_exe( void )
+{
+ HANDLE res;
+
+ res = BeginUpdateResource( filename, TRUE );
+ ok( res == NULL, "BeginUpdateResource should fail\n");
+}
+
+static void update_empty_exe( void )
+{
+ HANDLE file, res, test;
+ BOOL r;
+
+ file = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
0, 0);
+ ok (file != INVALID_HANDLE_VALUE, "failed to create file\n");
+
+ CloseHandle( file );
+
+ res = BeginUpdateResource( filename, TRUE );
+ todo_wine ok( res != NULL, "BeginUpdateResource failed\n");
+
+ /* check if it's possible to open the file now */
+ test = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
0, 0);
+ ok (test != INVALID_HANDLE_VALUE, "failed to create file\n");
+
+ CloseHandle( test );
+
+ r = EndUpdateResource( res, FALSE );
+ ok( r == FALSE, "EndUpdateResouce failed\n");
+
+ res = BeginUpdateResource( filename, FALSE );
+ ok( res == NULL, "BeginUpdateResource failed\n");
+}
+
+static void update_resources_none( void )
+{
+ HMODULE res;
+ BOOL r;
+
+ res = BeginUpdateResource( filename, FALSE );
+ todo_wine ok( res != NULL, "BeginUpdateResource failed\n");
+
+ r = EndUpdateResource( res, FALSE );
+ todo_wine ok( r, "EndUpdateResouce failed\n");
+}
+
+static void update_resources_delete( void )
+{
+ HMODULE res;
+ BOOL r;
+
+ res = BeginUpdateResource( filename, TRUE );
+ todo_wine ok( res != NULL, "BeginUpdateResource failed\n");
+
+ r = EndUpdateResource( res, FALSE );
+ todo_wine ok( r, "EndUpdateResouce failed\n");
+}
+
+struct verhdr {
+ WORD wLength;
+ WORD wValueLength;
+ WORD wType;
+ WCHAR key[1];
+};
+
+void update_resources_version(void)
+{
+ HANDLE res = NULL;
+ BOOL r;
+ struct verhdr hdr;
+ char foo[] = "red and white";
+
+ todo_wine {
+ res = BeginUpdateResource( filename, TRUE );
+ ok( res != NULL, "BeginUpdateResource failed\n");
+
+ memset( &hdr, 0, sizeof hdr );
+ r = UpdateResource( res,
+ RT_VERSION,
+ MAKEINTRESOURCE(VS_VERSION_INFO),
+ MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL),
+ &hdr, sizeof hdr );
+ ok( r, "UpdateResouce failed\n");
+ }
+
+ r = UpdateResource( res,
+ MAKEINTRESOURCE(0x1230),
+ MAKEINTRESOURCE(0x4567),
+ 0xabcd,
+ NULL, 0 );
+ ok( r == FALSE, "UpdateResouce failed\n");
+
+ todo_wine {
+ r = UpdateResource( res,
+ MAKEINTRESOURCE(0x1230),
+ MAKEINTRESOURCE(0x4567),
+ 0xabcd,
+ foo, sizeof foo );
+ ok( r == TRUE, "UpdateResouce failed\n");
+
+ r = EndUpdateResource( res, FALSE );
+ ok( r, "EndUpdateResouce failed\n");
+ }
+}
+
+
+typedef void (*res_check_func)( IMAGE_RESOURCE_DIRECTORY* );
+
+void check_empty( IMAGE_RESOURCE_DIRECTORY *dir )
+{
+ char *pad;
+
+ ok( dir->NumberOfNamedEntries == 0, "NumberOfNamedEntries wrong\n");
+ ok( dir->NumberOfIdEntries == 0, "NumberOfIdEntries wrong\n");
+
+ pad = (char*) &dir[1];
+
+ todo_wine ok( !memcmp( pad, "PADDINGXXPADDING", 16), "padding
wrong\n");
+}
+
+void check_version( IMAGE_RESOURCE_DIRECTORY *dir )
+{
+ ok( dir->NumberOfNamedEntries == 0, "NumberOfNamedEntries wrong\n");
+ todo_wine ok( dir->NumberOfIdEntries == 2, "NumberOfIdEntries
wrong\n");
+}
+
+void check_exe( res_check_func fn )
+{
+ IMAGE_DOS_HEADER *dos;
+ IMAGE_NT_HEADERS *nt;
+ IMAGE_SECTION_HEADER *sec;
+ IMAGE_RESOURCE_DIRECTORY *dir;
+ HANDLE file, mapping;
+ DWORD length;
+
+ 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");
+
+ mapping = CreateFileMapping( file, NULL, PAGE_READONLY, 0, 0, NULL );
+ ok (mapping != NULL, "failed to create file\n");
+
+ dos = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
+ ok( dos != NULL, "failed to map file\n");
+
+ if (!dos)
+ 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");
+
+ dir = (void*) ((BYTE*) dos + sec[1].VirtualAddress);
+
+ ok( dir->Characteristics == 0, "Characteristics wrong\n");
+ ok( dir->TimeDateStamp == 0, "TimeDateStamp wrong\n");
+ todo_wine ok( dir->MajorVersion == 4, "MajorVersion wrong\n");
+ ok( dir->MinorVersion == 0, "MinorVersion wrong\n");
+
+ fn( dir );
+
+end:
+ UnmapViewOfFile( dos );
+
+ CloseHandle( mapping );
+
+ CloseHandle( file );
+}
+
+START_TEST(resource)
+{
+ DeleteFile( filename );
+ update_missing_exe();
+ 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_version );
+ DeleteFile( filename );
+}
--
1.4.4.1.g431f
More information about the wine-patches
mailing list