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
, "EndUpdateResource 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
, "EndUpdateResource 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
, "EndUpdateResource 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 if (0) /* this causes subsequent tests to fail on Vista */
178 r
= UpdateResource( res
,
179 MAKEINTRESOURCE(0x1230),
180 MAKEINTRESOURCE(0x4567),
183 ok( r
== FALSE
, "UpdateResource failed\n");
186 r
= UpdateResource( res
,
187 MAKEINTRESOURCE(0x1230),
188 MAKEINTRESOURCE(0x4567),
191 ok( r
== TRUE
, "UpdateResource failed: %d\n", GetLastError());
193 r
= EndUpdateResource( res
, FALSE
);
194 ok( r
, "EndUpdateResource failed: %d\n", GetLastError());
198 typedef void (*res_check_func
)( IMAGE_RESOURCE_DIRECTORY
* );
200 static void check_empty( IMAGE_RESOURCE_DIRECTORY
*dir
)
204 ok( dir
->NumberOfNamedEntries
== 0, "NumberOfNamedEntries should be 0 instead of %d\n", dir
->NumberOfNamedEntries
);
205 ok( dir
->NumberOfIdEntries
== 0, "NumberOfIdEntries should be 0 instead of %d\n", dir
->NumberOfIdEntries
);
207 pad
= (char*) &dir
[1];
209 ok( !memcmp( pad
, "PADDINGXXPADDING", 16), "padding wrong\n");
212 static void check_not_empty( IMAGE_RESOURCE_DIRECTORY
*dir
)
214 ok( dir
->NumberOfNamedEntries
== 0, "NumberOfNamedEntries should be 0 instead of %d\n", dir
->NumberOfNamedEntries
);
215 ok( dir
->NumberOfIdEntries
== 1, "NumberOfIdEntries should be 1 instead of %d\n", dir
->NumberOfIdEntries
);
218 static void check_exe( res_check_func fn
)
220 IMAGE_DOS_HEADER
*dos
;
221 IMAGE_NT_HEADERS
*nt
;
222 IMAGE_SECTION_HEADER
*sec
;
223 IMAGE_RESOURCE_DIRECTORY
*dir
;
224 HANDLE file
, mapping
;
227 file
= CreateFile(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
228 ok (file
!= INVALID_HANDLE_VALUE
, "failed to create file (%d)\n", GetLastError());
230 length
= GetFileSize( file
, NULL
);
231 ok( length
== 0x3000, "file size wrong\n");
233 mapping
= CreateFileMapping( file
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
234 ok (mapping
!= NULL
, "failed to create file\n");
236 dos
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, length
);
237 ok( dos
!= NULL
, "failed to map file\n");
242 nt
= (void*) ((BYTE
*) dos
+ dos
->e_lfanew
);
243 ok( nt
->FileHeader
.NumberOfSections
== 2, "number of sections wrong\n" );
245 if (nt
->FileHeader
.NumberOfSections
< 2)
248 sec
= (void*) &nt
[1];
250 ok( !memcmp(sec
[1].Name
, ".rsrc", 6), "resource section name wrong\n");
252 dir
= (void*) ((BYTE
*) dos
+ sec
[1].VirtualAddress
);
254 ok( dir
->Characteristics
== 0, "Characteristics wrong\n");
255 ok( dir
->TimeDateStamp
== 0 || abs( dir
->TimeDateStamp
- GetTickCount() ) < 1000 /* nt4 */,
256 "TimeDateStamp wrong %u\n", dir
->TimeDateStamp
);
257 ok( dir
->MajorVersion
== 4, "MajorVersion wrong\n");
258 ok( dir
->MinorVersion
== 0, "MinorVersion wrong\n");
263 UnmapViewOfFile( dos
);
265 CloseHandle( mapping
);
270 static void test_find_resource(void)
274 rsrc
= FindResourceW( GetModuleHandle(0), (LPCWSTR
)MAKEINTRESOURCE(1), (LPCWSTR
)RT_MENU
);
275 ok( rsrc
!= 0, "resource not found\n" );
276 rsrc
= FindResourceExW( GetModuleHandle(0), (LPCWSTR
)RT_MENU
, (LPCWSTR
)MAKEINTRESOURCE(1),
277 MAKELANGID( LANG_NEUTRAL
, SUBLANG_NEUTRAL
));
278 ok( rsrc
!= 0, "resource not found\n" );
279 rsrc
= FindResourceExW( GetModuleHandle(0), (LPCWSTR
)RT_MENU
, (LPCWSTR
)MAKEINTRESOURCE(1),
280 MAKELANGID( LANG_GERMAN
, SUBLANG_DEFAULT
));
281 ok( rsrc
!= 0, "resource not found\n" );
283 SetLastError( 0xdeadbeef );
284 rsrc
= FindResourceW( GetModuleHandle(0), (LPCWSTR
)MAKEINTRESOURCE(1), (LPCWSTR
)RT_DIALOG
);
285 ok( !rsrc
, "resource found\n" );
286 ok( GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND
, "wrong error %u\n", GetLastError() );
288 SetLastError( 0xdeadbeef );
289 rsrc
= FindResourceW( GetModuleHandle(0), (LPCWSTR
)MAKEINTRESOURCE(2), (LPCWSTR
)RT_MENU
);
290 ok( !rsrc
, "resource found\n" );
291 ok( GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND
, "wrong error %u\n", GetLastError() );
293 SetLastError( 0xdeadbeef );
294 rsrc
= FindResourceExW( GetModuleHandle(0), (LPCWSTR
)RT_MENU
, (LPCWSTR
)MAKEINTRESOURCE(1),
295 MAKELANGID( LANG_ENGLISH
, SUBLANG_DEFAULT
) );
296 ok( !rsrc
, "resource found\n" );
297 ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND
, "wrong error %u\n", GetLastError() );
299 SetLastError( 0xdeadbeef );
300 rsrc
= FindResourceExW( GetModuleHandle(0), (LPCWSTR
)RT_MENU
, (LPCWSTR
)MAKEINTRESOURCE(1),
301 MAKELANGID( LANG_FRENCH
, SUBLANG_DEFAULT
) );
302 ok( !rsrc
, "resource found\n" );
303 ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND
, "wrong error %u\n", GetLastError() );
308 DeleteFile( filename
);
309 update_missing_exe();
311 if (GLE
== ERROR_CALL_NOT_IMPLEMENTED
)
313 skip("Resource calls are not implemented\n");
319 update_resources_none();
320 check_exe( check_empty
);
321 update_resources_delete();
322 check_exe( check_empty
);
323 update_resources_version();
324 check_exe( check_not_empty
);
325 DeleteFile( filename
);
326 test_find_resource();