2 * Unit test suite for environment functions.
4 * Copyright 2006 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
26 static const char filename
[] = "test_.exe";
29 static int build_exe( void )
31 IMAGE_DOS_HEADER
*dos
;
33 IMAGE_SECTION_HEADER
*sec
;
34 IMAGE_OPTIONAL_HEADER
*opt
;
38 const int page_size
= 0x1000;
40 memset( page
, 0, sizeof page
);
43 dos
->e_magic
= IMAGE_DOS_SIGNATURE
;
44 dos
->e_lfanew
= sizeof *dos
;
48 nt
->Signature
= IMAGE_NT_SIGNATURE
;
49 nt
->FileHeader
.Machine
= IMAGE_FILE_MACHINE_I386
;
50 nt
->FileHeader
.NumberOfSections
= 2;
51 nt
->FileHeader
.SizeOfOptionalHeader
= sizeof nt
->OptionalHeader
;
52 nt
->FileHeader
.Characteristics
= IMAGE_FILE_EXECUTABLE_IMAGE
| IMAGE_FILE_DLL
;
54 opt
= &nt
->OptionalHeader
;
56 opt
->Magic
= IMAGE_NT_OPTIONAL_HDR_MAGIC
;
57 opt
->MajorLinkerVersion
= 1;
58 opt
->BaseOfCode
= 0x10;
59 opt
->ImageBase
= 0x10000000;
60 opt
->MajorOperatingSystemVersion
= 4;
61 opt
->MajorImageVersion
= 1;
62 opt
->MajorSubsystemVersion
= 4;
63 opt
->SizeOfHeaders
= sizeof *dos
+ sizeof *nt
+ sizeof *sec
* 2;
64 opt
->SizeOfImage
= page_size
*3;
65 opt
->Subsystem
= IMAGE_SUBSYSTEM_WINDOWS_CUI
;
67 /* if SectionAlignment and File alignment are not specified */
68 /* UpdateResource fails trying to create a huge temporary file */
69 opt
->SectionAlignment
= page_size
;
70 opt
->FileAlignment
= page_size
;
74 memcpy( sec
[0].Name
, ".rodata", 8 );
75 sec
[0].Misc
.VirtualSize
= page_size
;
76 sec
[0].PointerToRawData
= page_size
;
77 sec
[0].SizeOfRawData
= page_size
;
78 sec
[0].VirtualAddress
= page_size
;
79 sec
[0].Characteristics
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_MEM_READ
;
81 memcpy( sec
[1].Name
, ".rsrc", 6 );
82 sec
[1].Misc
.VirtualSize
= page_size
;
83 sec
[1].SizeOfRawData
= page_size
;
84 sec
[1].PointerToRawData
= page_size
*2;
85 sec
[1].VirtualAddress
= page_size
*2;
86 sec
[1].Characteristics
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_MEM_READ
;
88 file
= CreateFile(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
89 ok (file
!= INVALID_HANDLE_VALUE
, "failed to create file\n");
91 /* write out the header */
92 WriteFile( file
, page
, sizeof page
, &written
, NULL
);
94 /* write out an empty page for rodata */
95 memset( page
, 0, sizeof page
);
96 WriteFile( file
, page
, sizeof page
, &written
, NULL
);
98 /* write out an empty page for the resources */
99 memset( page
, 0, sizeof page
);
100 WriteFile( file
, page
, sizeof page
, &written
, NULL
);
107 static void update_missing_exe( void )
111 SetLastError(0xdeadbeef);
112 res
= BeginUpdateResource( filename
, TRUE
);
113 GLE
= GetLastError();
114 ok( res
== NULL
, "BeginUpdateResource should fail\n");
117 static void update_empty_exe( void )
119 HANDLE file
, res
, test
;
122 file
= CreateFile(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
123 ok (file
!= INVALID_HANDLE_VALUE
, "failed to create file\n");
127 res
= BeginUpdateResource( filename
, TRUE
);
128 ok( res
!= NULL
, "BeginUpdateResource failed\n");
130 /* check if it's possible to open the file now */
131 test
= CreateFile(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
132 ok (test
!= INVALID_HANDLE_VALUE
, "failed to create file\n");
136 r
= EndUpdateResource( res
, FALSE
);
137 ok( r
== FALSE
, "EndUpdateResouce failed\n");
139 res
= BeginUpdateResource( filename
, FALSE
);
140 ok( res
== NULL
, "BeginUpdateResource failed\n");
143 static void update_resources_none( void )
148 res
= BeginUpdateResource( filename
, FALSE
);
149 ok( res
!= NULL
, "BeginUpdateResource failed\n");
151 r
= EndUpdateResource( res
, FALSE
);
152 ok( r
, "EndUpdateResouce failed\n");
155 static void update_resources_delete( void )
160 res
= BeginUpdateResource( filename
, TRUE
);
161 ok( res
!= NULL
, "BeginUpdateResource failed\n");
163 r
= EndUpdateResource( res
, FALSE
);
164 ok( r
, "EndUpdateResouce failed\n");
167 static void update_resources_version(void)
171 char foo
[] = "red and white";
173 res
= BeginUpdateResource( filename
, TRUE
);
174 ok( res
!= NULL
, "BeginUpdateResource failed\n");
176 r
= UpdateResource( res
,
177 MAKEINTRESOURCE(0x1230),
178 MAKEINTRESOURCE(0x4567),
181 ok( r
== FALSE
, "UpdateResouce failed\n");
183 r
= UpdateResource( res
,
184 MAKEINTRESOURCE(0x1230),
185 MAKEINTRESOURCE(0x4567),
188 ok( r
== TRUE
, "UpdateResouce failed\n");
190 r
= EndUpdateResource( res
, FALSE
);
191 ok( r
, "EndUpdateResouce failed\n");
195 typedef void (*res_check_func
)( IMAGE_RESOURCE_DIRECTORY
* );
197 static void check_empty( IMAGE_RESOURCE_DIRECTORY
*dir
)
201 ok( dir
->NumberOfNamedEntries
== 0, "NumberOfNamedEntries should be 0 instead of %d\n", dir
->NumberOfNamedEntries
);
202 ok( dir
->NumberOfIdEntries
== 0, "NumberOfIdEntries should be 0 instead of %d\n", dir
->NumberOfIdEntries
);
204 pad
= (char*) &dir
[1];
206 ok( !memcmp( pad
, "PADDINGXXPADDING", 16), "padding wrong\n");
209 static void check_not_empty( IMAGE_RESOURCE_DIRECTORY
*dir
)
211 ok( dir
->NumberOfNamedEntries
== 0, "NumberOfNamedEntries should be 0 instead of %d\n", dir
->NumberOfNamedEntries
);
212 ok( dir
->NumberOfIdEntries
== 1, "NumberOfIdEntries should be 1 instead of %d\n", dir
->NumberOfIdEntries
);
215 static void check_exe( res_check_func fn
)
217 IMAGE_DOS_HEADER
*dos
;
218 IMAGE_NT_HEADERS
*nt
;
219 IMAGE_SECTION_HEADER
*sec
;
220 IMAGE_RESOURCE_DIRECTORY
*dir
;
221 HANDLE file
, mapping
;
224 file
= CreateFile(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
225 ok (file
!= INVALID_HANDLE_VALUE
, "failed to create file (%d)\n", GetLastError());
227 length
= GetFileSize( file
, NULL
);
228 ok( length
== 0x3000, "file size wrong\n");
230 mapping
= CreateFileMapping( file
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
231 ok (mapping
!= NULL
, "failed to create file\n");
233 dos
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, length
);
234 ok( dos
!= NULL
, "failed to map file\n");
239 nt
= (void*) ((BYTE
*) dos
+ dos
->e_lfanew
);
240 ok( nt
->FileHeader
.NumberOfSections
== 2, "number of sections wrong\n" );
242 if (nt
->FileHeader
.NumberOfSections
< 2)
245 sec
= (void*) &nt
[1];
247 ok( !memcmp(sec
[1].Name
, ".rsrc", 6), "resource section name wrong\n");
249 dir
= (void*) ((BYTE
*) dos
+ sec
[1].VirtualAddress
);
251 ok( dir
->Characteristics
== 0, "Characteristics wrong\n");
252 ok( dir
->TimeDateStamp
== 0, "TimeDateStamp wrong\n");
253 ok( dir
->MajorVersion
== 4, "MajorVersion wrong\n");
254 ok( dir
->MinorVersion
== 0, "MinorVersion wrong\n");
259 UnmapViewOfFile( dos
);
261 CloseHandle( mapping
);
268 DeleteFile( filename
);
269 update_missing_exe();
271 if (GLE
== ERROR_CALL_NOT_IMPLEMENTED
)
273 skip("Resource calls are not implemented\n");
279 update_resources_none();
280 check_exe( check_empty
);
281 update_resources_delete();
282 check_exe( check_empty
);
283 update_resources_version();
284 check_exe( check_not_empty
);
285 DeleteFile( filename
);