Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
cb1806db
Commit
cb1806db
authored
Oct 31, 2013
by
André Hentschel
Committed by
Alexandre Julliard
Nov 04, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32/tests: Test ResolveDelayLoadedAPI with generated dll.
parent
58e83ebd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
211 additions
and
54 deletions
+211
-54
loader.c
dlls/kernel32/tests/loader.c
+211
-54
No files found.
dlls/kernel32/tests/loader.c
View file @
cb1806db
...
...
@@ -2197,12 +2197,37 @@ static PVOID WINAPI failuredllhook(ULONG ul, DELAYLOAD_INFO* pd)
static
void
test_ResolveDelayLoadedAPI
(
void
)
{
static
const
char
test_dll
[]
=
"secur32.dll"
;
static
const
char
test_func
[]
=
"SealMessage"
;
static
const
char
filler
[
0x1000
];
char
temp_path
[
MAX_PATH
];
char
dll_name
[
MAX_PATH
];
IMAGE_DELAYLOAD_DESCRIPTOR
idd
,
*
delaydir
;
IMAGE_THUNK_DATA
itd32
;
HANDLE
hfile
;
HMODULE
hlib
;
int
i
;
static
const
char
*
td
[]
=
DWORD
dummy
,
file_size
,
i
;
WORD
hint
=
0
;
BOOL
ret
;
static
const
struct
test_data
{
"advapi32.dll"
,
"comdlg32.dll"
,
BOOL
func
;
UINT_PTR
ordinal
;
BOOL
succeeds
;
}
td
[]
=
{
{
TRUE
,
0
,
TRUE
},
{
FALSE
,
IMAGE_ORDINAL_FLAG
|
2
,
TRUE
},
{
FALSE
,
IMAGE_ORDINAL_FLAG
|
5
,
TRUE
},
{
FALSE
,
IMAGE_ORDINAL_FLAG
|
0
,
FALSE
},
};
if
(
!
pResolveDelayLoadedAPI
)
...
...
@@ -2226,66 +2251,198 @@ static void test_ResolveDelayLoadedAPI(void)
ok
(
cb_count
==
1
,
"Wrong callback count: %d
\n
"
,
cb_count
);
}
for
(
i
=
0
;
i
<
sizeof
(
td
)
/
sizeof
(
td
[
0
]);
i
++
)
GetTempPathA
(
MAX_PATH
,
temp_path
);
GetTempFileNameA
(
temp_path
,
"ldr"
,
0
,
dll_name
);
trace
(
"creating %s
\n
"
,
dll_name
);
hfile
=
CreateFileA
(
dll_name
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
0
,
0
);
if
(
hfile
==
INVALID_HANDLE_VALUE
)
{
IMAGE_DELAYLOAD_DESCRIPTOR
*
delaydir
;
ULONG
size
;
ok
(
0
,
"could not create %s
\n
"
,
dll_name
);
return
;
}
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
dos_header
,
sizeof
(
dos_header
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
nt_header
.
FileHeader
.
NumberOfSections
=
2
;
nt_header
.
FileHeader
.
SizeOfOptionalHeader
=
sizeof
(
IMAGE_OPTIONAL_HEADER
);
nt_header
.
OptionalHeader
.
SectionAlignment
=
0x1000
;
nt_header
.
OptionalHeader
.
FileAlignment
=
0x1000
;
nt_header
.
OptionalHeader
.
SizeOfImage
=
sizeof
(
dos_header
)
+
sizeof
(
nt_header
)
+
sizeof
(
IMAGE_SECTION_HEADER
)
+
0x2200
;
nt_header
.
OptionalHeader
.
SizeOfHeaders
=
sizeof
(
dos_header
)
+
sizeof
(
nt_header
)
+
2
*
sizeof
(
IMAGE_SECTION_HEADER
);
nt_header
.
OptionalHeader
.
NumberOfRvaAndSizes
=
15
;
nt_header
.
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
].
VirtualAddress
=
0x1000
;
nt_header
.
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
].
Size
=
0x100
;
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
nt_header
,
sizeof
(
DWORD
)
+
sizeof
(
IMAGE_FILE_HEADER
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
nt_header
.
OptionalHeader
,
sizeof
(
IMAGE_OPTIONAL_HEADER
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
/* sections */
section
.
PointerToRawData
=
nt_header
.
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
].
VirtualAddress
;
section
.
VirtualAddress
=
nt_header
.
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
].
VirtualAddress
;
section
.
Misc
.
VirtualSize
=
nt_header
.
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
].
Size
;
section
.
Characteristics
=
IMAGE_SCN_CNT_INITIALIZED_DATA
|
IMAGE_SCN_MEM_READ
;
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
section
,
sizeof
(
section
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
section
.
PointerToRawData
=
0x2000
;
section
.
VirtualAddress
=
0x2000
;
i
=
sizeof
(
td
)
/
sizeof
(
td
[
0
]);
section
.
Misc
.
VirtualSize
=
sizeof
(
test_dll
)
+
sizeof
(
hint
)
+
sizeof
(
test_func
)
+
sizeof
(
HMODULE
)
+
2
*
(
i
+
1
)
*
sizeof
(
IMAGE_THUNK_DATA
);
ok
(
section
.
Misc
.
VirtualSize
<=
0x1000
,
"Too much tests, add a new section!
\n
"
);
section
.
Characteristics
=
IMAGE_SCN_CNT_INITIALIZED_DATA
|
IMAGE_SCN_MEM_READ
|
IMAGE_SCN_MEM_WRITE
;
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
section
,
sizeof
(
section
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
/* fill up to delay data */
file_size
=
GetFileSize
(
hfile
,
NULL
);
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
filler
,
nt_header
.
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
].
VirtualAddress
-
file_size
,
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
/* delay data */
idd
.
Attributes
.
AllAttributes
=
1
;
idd
.
DllNameRVA
=
0x2000
;
idd
.
ModuleHandleRVA
=
idd
.
DllNameRVA
+
sizeof
(
test_dll
)
+
sizeof
(
hint
)
+
sizeof
(
test_func
);
idd
.
ImportAddressTableRVA
=
idd
.
ModuleHandleRVA
+
sizeof
(
HMODULE
);
idd
.
ImportNameTableRVA
=
idd
.
ImportAddressTableRVA
+
(
i
+
1
)
*
sizeof
(
IMAGE_THUNK_DATA
);
idd
.
BoundImportAddressTableRVA
=
0
;
idd
.
UnloadInformationTableRVA
=
0
;
idd
.
TimeDateStamp
=
0
;
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
idd
,
sizeof
(
idd
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
filler
,
sizeof
(
idd
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
/* fill up to extended delay data */
file_size
=
GetFileSize
(
hfile
,
NULL
);
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
filler
,
idd
.
DllNameRVA
-
file_size
,
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
/* extended delay data */
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
test_dll
,
sizeof
(
test_dll
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
hint
,
sizeof
(
hint
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
test_func
,
sizeof
(
test_func
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
file_size
=
GetFileSize
(
hfile
,
NULL
);
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
filler
,
idd
.
ImportNameTableRVA
-
file_size
,
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
for
(
i
=
0
;
i
<
sizeof
(
td
)
/
sizeof
(
td
[
0
]);
i
++
)
{
if
(
td
[
i
].
func
)
itd32
.
u1
.
AddressOfData
=
idd
.
DllNameRVA
+
sizeof
(
test_dll
);
else
itd32
.
u1
.
Ordinal
=
td
[
i
].
ordinal
;
SetLastError
(
0xdeadbeef
);
hlib
=
LoadLibraryA
(
td
[
i
]);
ok
(
hlib
!=
NULL
,
"LoadLibrary error %u
\n
"
,
GetLastError
());
if
(
!
hlib
)
{
skip
(
"couldn't load %s.
\n
"
,
td
[
i
]);
continue
;
}
ret
=
WriteFile
(
hfile
,
&
itd32
,
sizeof
(
itd32
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
}
delaydir
=
RtlImageDirectoryEntryToData
(
hlib
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
,
&
size
);
if
(
!
delaydir
)
{
skip
(
"haven't found section for delay import directory in %s.
\n
"
,
td
[
i
]);
FreeLibrary
(
hlib
);
continue
;
}
itd32
.
u1
.
Ordinal
=
0
;
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
&
itd32
,
sizeof
(
itd32
),
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
for
(;;)
/* fill up to eof */
file_size
=
GetFileSize
(
hfile
,
NULL
);
SetLastError
(
0xdeadbeef
);
ret
=
WriteFile
(
hfile
,
filler
,
section
.
VirtualAddress
+
section
.
Misc
.
VirtualSize
-
file_size
,
&
dummy
,
NULL
);
ok
(
ret
,
"WriteFile error %d
\n
"
,
GetLastError
());
CloseHandle
(
hfile
);
SetLastError
(
0xdeadbeef
);
hlib
=
LoadLibraryA
(
dll_name
);
ok
(
hlib
!=
NULL
,
"LoadLibrary error %u
\n
"
,
GetLastError
());
if
(
!
hlib
)
{
skip
(
"couldn't load %s.
\n
"
,
dll_name
);
DeleteFileA
(
dll_name
);
return
;
}
delaydir
=
RtlImageDirectoryEntryToData
(
hlib
,
TRUE
,
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
,
&
file_size
);
if
(
!
delaydir
)
{
skip
(
"haven't found section for delay import directory.
\n
"
);
FreeLibrary
(
hlib
);
DeleteFileA
(
dll_name
);
return
;
}
for
(;;)
{
IMAGE_THUNK_DATA
*
itdn
,
*
itda
;
HMODULE
htarget
;
if
(
!
delaydir
->
DllNameRVA
||
!
delaydir
->
ImportAddressTableRVA
||
!
delaydir
->
ImportNameTableRVA
)
break
;
itdn
=
RVAToAddr
(
delaydir
->
ImportNameTableRVA
,
hlib
);
itda
=
RVAToAddr
(
delaydir
->
ImportAddressTableRVA
,
hlib
);
htarget
=
LoadLibraryA
(
RVAToAddr
(
delaydir
->
DllNameRVA
,
hlib
));
for
(
i
=
0
;
i
<
sizeof
(
td
)
/
sizeof
(
td
[
0
]);
i
++
)
{
const
IMAGE_THUNK_DATA
*
itdn
;
IMAGE_THUNK_DATA
*
itda
;
HMODULE
htarget
;
int
j
;
if
(
!
delaydir
->
DllNameRVA
||
!
delaydir
->
ImportAddressTableRVA
||
!
delaydir
->
ImportNameTableRVA
)
break
;
itdn
=
RVAToAddr
(
delaydir
->
ImportNameTableRVA
,
hlib
);
itda
=
RVAToAddr
(
delaydir
->
ImportAddressTableRVA
,
hlib
);
htarget
=
LoadLibraryA
(
RVAToAddr
(
delaydir
->
DllNameRVA
,
hlib
));
for
(
j
=
0
;
itdn
[
j
].
u1
.
Ordinal
;
j
++
)
{
void
*
ret
,
*
load
;
void
*
ret
,
*
load
;
if
(
IMAGE_SNAP_BY_ORDINAL
(
itdn
[
j
].
u1
.
Ordinal
))
load
=
(
void
*
)
GetProcAddress
(
htarget
,
(
LPSTR
)
IMAGE_ORDINAL
(
itdn
[
j
].
u1
.
Ordinal
));
else
{
const
IMAGE_IMPORT_BY_NAME
*
iibn
=
RVAToAddr
(
itdn
[
j
].
u1
.
AddressOfData
,
hlib
);
load
=
(
void
*
)
GetProcAddress
(
htarget
,
(
char
*
)
iibn
->
Name
);
}
if
(
IMAGE_SNAP_BY_ORDINAL
(
itdn
[
i
].
u1
.
Ordinal
))
load
=
(
void
*
)
GetProcAddress
(
htarget
,
(
LPSTR
)
IMAGE_ORDINAL
(
itdn
[
i
].
u1
.
Ordinal
));
else
{
const
IMAGE_IMPORT_BY_NAME
*
iibn
=
RVAToAddr
(
itdn
[
i
].
u1
.
AddressOfData
,
hlib
);
load
=
(
void
*
)
GetProcAddress
(
htarget
,
(
char
*
)
iibn
->
Name
);
}
cb_count
=
0
;
ret
=
pResolveDelayLoadedAPI
(
hlib
,
delaydir
,
failuredllhook
,
NULL
,
&
itda
[
j
],
0
);
ok
(
ret
!=
NULL
,
"ResolveDelayLoadedAPI failed
\n
"
);
ok
(
ret
==
load
,
"expected %p, got %p
\n
"
,
ret
,
load
);
ok
(
ret
==
(
void
*
)
itda
[
j
].
u1
.
AddressOfData
,
"expected %p, got %p
\n
"
,
ret
,
(
void
*
)
itda
[
j
].
u1
.
AddressOfData
);
ok
(
!
cb_count
,
"Wrong callback count: %d
\n
"
,
cb_count
);
cb_count
=
0
;
ret
=
pResolveDelayLoadedAPI
(
hlib
,
delaydir
,
failuredllhook
,
NULL
,
&
itda
[
i
],
0
);
if
(
td
[
i
].
succeeds
)
{
ok
(
ret
!=
NULL
,
"Test %u: ResolveDelayLoadedAPI failed
\n
"
,
i
);
ok
(
ret
==
load
,
"Test %u: expected %p, got %p
\n
"
,
i
,
load
,
ret
);
ok
(
ret
==
(
void
*
)
itda
[
i
].
u1
.
AddressOfData
,
"Test %u: expected %p, got %p
\n
"
,
i
,
ret
,
(
void
*
)
itda
[
i
].
u1
.
AddressOfData
);
ok
(
!
cb_count
,
"Test %u: Wrong callback count: %d
\n
"
,
i
,
cb_count
);
}
else
{
ok
(
ret
==
NULL
,
"Test %u: ResolveDelayLoadedAPI succeeded
\n
"
,
i
);
ok
(
cb_count
,
"Test %u: Wrong callback count: %d
\n
"
,
i
,
cb_count
);
}
delaydir
++
;
}
FreeLibrary
(
hlib
)
;
delaydir
++
;
}
FreeLibrary
(
hlib
);
trace
(
"deleting %s
\n
"
,
dll_name
);
DeleteFileA
(
dll_name
);
}
START_TEST
(
loader
)
...
...
@@ -2330,8 +2487,8 @@ START_TEST(loader)
}
test_Loader
();
test_ResolveDelayLoadedAPI
();
test_ImportDescriptors
();
test_section_access
();
test_ExitProcess
();
test_ResolveDelayLoadedAPI
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment