ReactOS 0.4.16-dev-2207-geb15453
loader.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winnls.h"
#include "wine/test.h"
#include "delayloadhandler.h"
Include dependency graph for loader.c:

Go to the source code of this file.

Classes

struct  PROCESS_BASIC_INFORMATION_PRIVATE
 

Macros

#define WIN32_NO_STATUS
 
#define PROCESS_ALL_ACCESS_NT4   (PROCESS_ALL_ACCESS & ~0xf000)
 
#define ALIGN_SIZE(size, alignment)   (((size) + ((ULONG_PTR)(alignment) - 1)) & ~(((ULONG_PTR)(alignment) - 1)))
 
#define DATA_RVA(ptr)   (page_size + ((char *)(ptr) - (char *)&data))
 
#define ADD_RELOC(field)   data.rel.type_off[nb_rel++] = (IMAGE_REL_BASED_HIGHLOW << 12) + offsetof( struct imports, field )
 
#define MAX_COUNT   10
 
#define OK_FIELD(x, f)   ok( nt->x == nt_file->x, "%s:%u: wrong " #x " " f " / " f "\n", name, i, nt->x, nt_file->x )
 

Functions

static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *
 
static void (WINAPI *pLdrShutdownProcess)(void)
 
static BOOLEAN (WINAPI *pRtlDllShutdownInProgress)(void)
 
static PVOID (WINAPI *pResolveDelayLoadedAPI)(PVOID
 
static ULONG *static PIMAGE_NT_HEADERS (WINAPI *pRtlImageNtHeader)(HMODULE)
 
static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION)
 
static BOOL (WINAPI *pFlsSetValue)(DWORD
 
static HMODULE (WINAPI *pLoadPackagedLibrary)(LPCWSTR lpwLibFileName
 
static void void **static PVOID RVAToAddr (DWORD_PTR rva, HMODULE module)
 
static WORD get_alt_machine (WORD orig_machine)
 
static WORD get_alt_bitness_machine (WORD orig_machine)
 
static DWORD create_test_dll (const IMAGE_DOS_HEADER *dos_header, UINT dos_size, const IMAGE_NT_HEADERS *nt_header, char dll_name[MAX_PATH])
 
static DWORD create_test_dll_sections (const IMAGE_DOS_HEADER *dos_header, const IMAGE_NT_HEADERS *nt_header, const IMAGE_SECTION_HEADER *sections, const void *section_data, char dll_name[MAX_PATH])
 
static BOOL query_image_section (int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header, const void *section_data)
 
static void init_load_path (const char *fallback_dll)
 
static void delete_load_path (void)
 
static UINT get_com_dir_size (const IMAGE_NT_HEADERS *nt)
 
static NTSTATUS map_image_section (const IMAGE_NT_HEADERS *nt_header, const IMAGE_SECTION_HEADER *sections, const void *section_data, int line)
 
static void test_Loader (void)
 
static void test_filenames (void)
 
static void test_ImportDescriptors (void)
 
static void test_image_mapping (const char *dll_name, DWORD scn_page_access, BOOL is_dll)
 
static BOOL is_mem_writable (DWORD prot)
 
static void test_VirtualProtect (void *base, void *section)
 
static void test_section_access (void)
 
static void check_tls_index (HANDLE dll, BOOL tls_initialized)
 
static DWORD WINAPI tls_thread_fn (void *tlsidx_v)
 
static void test_import_resolution (void)
 
static HANDLE gen_forward_chain_testdll (char testdll_path[MAX_PATH], const char source_dll[MAX_PATH], BOOL is_export, BOOL is_import, DWORD *exp_func_base_rva, DWORD *imp_thunk_base_rva)
 
static void subtest_export_forwarder_dep_chain (size_t num_chained_export_modules, size_t exporter_index, BOOL test_static_import)
 
static void test_export_forwarder_dep_chain (void)
 
static DWORD WINAPI mutex_thread_proc (void *param)
 
static DWORD WINAPI semaphore_thread_proc (void *param)
 
static DWORD WINAPI noop_thread_proc (void *param)
 
static VOID WINAPI fls_callback (PVOID lpFlsData)
 
static unsigned int check_linked_list (const LIST_ENTRY *le, const LIST_ENTRY *search_entry, unsigned int *index_found)
 
static BOOL WINAPI dll_entry_point (HINSTANCE hinst, DWORD reason, LPVOID param)
 
static void CALLBACK ldr_notify_callback (ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
 
static void child_process (const char *dll_name, DWORD target_offset)
 
static void test_ExitProcess (void)
 
static PVOID WINAPI failuredllhook (ULONG ul, DELAYLOAD_INFO *pd)
 
static PVOID WINAPI failuresyshook (const char *dll, const char *function)
 
static void test_ResolveDelayLoadedAPI (void)
 
static void test_InMemoryOrderModuleList (void)
 
static BOOL is_path_made_of (const char *filename, const char *pfx, const char *sfx)
 
static void test_wow64_redirection_for_dll (const char *libname, BOOL will_fail)
 
static void test_wow64_redirection (void)
 
static void test_dll_file (const char *name)
 
static void test_LoadPackagedLibrary (void)
 
static void test_Wow64Transition (void)
 
 START_TEST (loader)
 

Variables

static LONGchild_failures
 
static WORD cb_count
 
static WORD cb_count_sys
 
static DWORD page_size
 
static BOOL is_win64 = sizeof(void *) > sizeof(int)
 
static BOOL is_wow64
 
static char system_dir [MAX_PATH]
 
static char syswow_dir [MAX_PATH]
 
static ACCESS_MASK
 
static const OBJECT_ATTRIBUTES const LARGE_INTEGER ULONG
 
static const OBJECT_ATTRIBUTES const LARGE_INTEGER HANDLE
 
static SECTION_INFORMATION_CLASS
 
static void SIZE_T
 
static void SIZE_T *static PVOID ULONG_PTR
 
static PVOID
 
static PROCESSINFOCLASS
 
static PULONG
 
static DWORD
 
static LPCWSTR
 
static PCIMAGE_DELAYLOAD_DESCRIPTOR
 
static PDELAYLOAD_FAILURE_DLL_CALLBACK
 
static PDELAYLOAD_FAILURE_SYSTEM_ROUTINE
 
static PIMAGE_THUNK_DATA ThunkAddress
 
static BOOL
 
static WORD
 
static PBOOL
 
static DWORD Reserved
 
static PLDR_DLL_NOTIFICATION_FUNCTION
 
static IMAGE_DOS_HEADER dos_header
 
static const IMAGE_NT_HEADERS nt_header_template
 
static IMAGE_SECTION_HEADER section
 
static const char filler [0x1000]
 
static const char section_data [0x10] = "section data"
 
static const WCHAR wldr_nameW [] = {'w','l','d','r','t','e','s','t','.','d','l','l',0}
 
static WCHAR load_test_name [MAX_PATH]
 
static WCHAR load_fallback_name [MAX_PATH]
 
static WCHAR load_path [MAX_PATH]
 
static int tls_init_fn_output
 
static HANDLE attached_thread [MAX_COUNT]
 
static DWORD attached_thread_count
 
static HANDLE event
 
static HANDLE mutex
 
static HANDLE semaphore
 
static HANDLE stop_event
 
static HANDLE loader_lock_event
 
static HANDLE peb_lock_event
 
static HANDLE heap_lock_event
 
static HANDLE cs_lock_event
 
static HANDLE ack_event
 
static CRITICAL_SECTION cs_lock
 
static int test_dll_phase
 
static int inside_loader_lock
 
static int inside_peb_lock
 
static int inside_heap_lock
 
static int inside_cs_lock
 
static LONG fls_callback_count
 
static LIST_ENTRYfls_list_head
 

Macro Definition Documentation

◆ ADD_RELOC

#define ADD_RELOC (   field)    data.rel.type_off[nb_rel++] = (IMAGE_REL_BASED_HIGHLOW << 12) + offsetof( struct imports, field )

◆ ALIGN_SIZE

#define ALIGN_SIZE (   size,
  alignment 
)    (((size) + ((ULONG_PTR)(alignment) - 1)) & ~(((ULONG_PTR)(alignment) - 1)))

Definition at line 40 of file loader.c.

◆ DATA_RVA

#define DATA_RVA (   ptr)    (page_size + ((char *)(ptr) - (char *)&data))

◆ MAX_COUNT

#define MAX_COUNT   10

Definition at line 2944 of file loader.c.

◆ OK_FIELD

#define OK_FIELD (   x,
  f 
)    ok( nt->x == nt_file->x, "%s:%u: wrong " #x " " f " / " f "\n", name, i, nt->x, nt_file->x )

◆ PROCESS_ALL_ACCESS_NT4

#define PROCESS_ALL_ACCESS_NT4   (PROCESS_ALL_ACCESS & ~0xf000)

Definition at line 38 of file loader.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 26 of file loader.c.

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pFlsSetValue)
static

◆ BOOLEAN()

static BOOLEAN ( WINAPI pRtlDllShutdownInProgress)
static

◆ check_linked_list()

static unsigned int check_linked_list ( const LIST_ENTRY le,
const LIST_ENTRY search_entry,
unsigned int index_found 
)
static

Definition at line 3050 of file loader.c.

3051{
3052 unsigned int count = 0;
3054
3055 *index_found = ~0;
3056
3057 for (entry = le->Flink; entry != le; entry = entry->Flink)
3058 {
3059 if (entry == search_entry)
3060 {
3061 ok(*index_found == ~0, "Duplicate list entry.\n");
3062 *index_found = count;
3063 }
3064 ++count;
3065 }
3066 return count;
3067}
#define ok(value,...)
Definition: atltest.h:57
GLuint GLuint GLsizei count
Definition: gl.h:1545
uint32_t entry
Definition: isohybrid.c:63
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by dll_entry_point().

◆ check_tls_index()

static void check_tls_index ( HANDLE  dll,
BOOL  tls_initialized 
)
static

Definition at line 2142 of file loader.c.

2143{
2144 BOOL found_dll = FALSE;
2145 LIST_ENTRY *root = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
2146 for (LIST_ENTRY *entry = root->Flink; entry != root; entry = entry->Flink)
2147 {
2149 if (wcsicmp(L"ntdll.dll", mod->BaseDllName.Buffer) == 0)
2150 {
2151 /* Pick ntdll as a dll that definitely won't have TLS */
2152 ok(mod->TlsIndex == 0, "ntdll.dll TlsIndex: %d instead of 0\n", mod->TlsIndex);
2153 }
2154 else if (mod->DllBase == dll)
2155 {
2156 SHORT expected = tls_initialized ? -1 : 0;
2157 ok(mod->TlsIndex == expected, "Test exe TlsIndex: %d instead of %d\n", mod->TlsIndex, expected);
2158 found_dll = TRUE;
2159 }
2160 else
2161 {
2162 ok(mod->TlsIndex == 0 || mod->TlsIndex == -1, "%s TlsIndex: %d\n",
2163 debugstr_w(mod->BaseDllName.Buffer), mod->TlsIndex);
2164 }
2165 }
2166 ok(found_dll, "Couldn't find dll %p in module list\n", dll);
2167}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:66
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define wcsicmp
Definition: compat.h:15
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
#define NtCurrentTeb
#define debugstr_w
Definition: kernel32.h:32
BOOL expected
Definition: store.c:2000
short SHORT
Definition: pedump.c:59
Definition: btrfs_drv.h:1876
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by test_import_resolution().

◆ child_process()

static void child_process ( const char dll_name,
DWORD  target_offset 
)
static

Definition at line 3472 of file loader.c.

3473{
3474 void *target;
3475 DWORD ret, dummy, i, code, expected_code;
3477 HMODULE hmod;
3480 void *cookie;
3481
3482 trace("phase %d: writing %p at %#lx\n", test_dll_phase, dll_entry_point, target_offset);
3483
3484 if (pFlsAlloc)
3485 {
3486 fls_list_head = NtCurrentTeb()->Peb->FlsListHead.Flink ? &NtCurrentTeb()->Peb->FlsListHead
3487 : NtCurrentTeb()->FlsSlots->fls_list_entry.Flink;
3488 }
3489
3490 SetLastError(0xdeadbeef);
3492 ok(mutex != 0, "CreateMutex error %ld\n", GetLastError());
3493
3494 SetLastError(0xdeadbeef);
3496 ok(semaphore != 0, "CreateSemaphore error %ld\n", GetLastError());
3497
3498 SetLastError(0xdeadbeef);
3499 event = CreateEventW(NULL, TRUE, FALSE, NULL);
3500 ok(event != 0, "CreateEvent error %ld\n", GetLastError());
3501
3502 SetLastError(0xdeadbeef);
3504 ok(loader_lock_event != 0, "CreateEvent error %ld\n", GetLastError());
3505
3506 SetLastError(0xdeadbeef);
3508 ok(peb_lock_event != 0, "CreateEvent error %ld\n", GetLastError());
3509
3510 SetLastError(0xdeadbeef);
3512 ok(heap_lock_event != 0, "CreateEvent error %ld\n", GetLastError());
3513
3515 SetLastError(0xdeadbeef);
3517 ok(cs_lock_event != 0, "CreateEvent error %ld\n", GetLastError());
3518
3519 SetLastError(0xdeadbeef);
3521 ok(ack_event != 0, "CreateEvent error %ld\n", GetLastError());
3522
3525 {
3526 ok(0, "could not open %s\n", dll_name);
3527 return;
3528 }
3529 SetFilePointer(file, target_offset, NULL, FILE_BEGIN);
3530 SetLastError(0xdeadbeef);
3532 ret = WriteFile(file, &target, sizeof(target), &dummy, NULL);
3533 ok(ret, "WriteFile error %ld\n", GetLastError());
3535
3536 SetLastError(0xdeadbeef);
3537 hmod = LoadLibraryA(dll_name);
3538 ok(hmod != 0, "LoadLibrary error %ld\n", GetLastError());
3539
3540 SetLastError(0xdeadbeef);
3542 ok(stop_event != 0, "CreateEvent error %ld\n", GetLastError());
3543
3544 SetLastError(0xdeadbeef);
3546 ok(thread != 0, "CreateThread error %ld\n", GetLastError());
3549
3551
3552 SetLastError(0xdeadbeef);
3554 ok(thread != 0, "CreateThread error %ld\n", GetLastError());
3557
3559 Sleep(100);
3560
3561 ok(attached_thread_count == 2, "attached thread count should be 2\n");
3562 for (i = 0; i < attached_thread_count; i++)
3563 {
3565 trace("child: GetExitCodeThread(%lu) => %ld,%lu\n", i, ret, code);
3566 ok(ret == 1, "GetExitCodeThread returned %ld, expected 1\n", ret);
3567 ok(code == STILL_ACTIVE, "expected thread exit code STILL_ACTIVE, got %lu\n", code);
3568 }
3569
3571 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3573 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3574
3576 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3578 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3580 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3581
3582 ret = pRtlDllShutdownInProgress();
3583 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3584
3585 SetLastError(0xdeadbeef);
3587 ok(process != NULL, "OpenProcess error %ld\n", GetLastError());
3588
3589 SetLastError(0xdeadbeef);
3590 ret = TerminateProcess(0, 195);
3591 ok(!ret, "TerminateProcess(0) should fail\n");
3592 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
3593
3594 Sleep(100);
3595
3596 affinity = 1;
3597 ret = pNtSetInformationProcess(process, ProcessAffinityMask, &affinity, sizeof(affinity));
3598 ok(!ret, "NtSetInformationProcess error %#lx\n", ret);
3599
3600 switch (test_dll_phase)
3601 {
3602 case 0:
3603 ret = pRtlDllShutdownInProgress();
3604 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3605
3606 trace("call NtTerminateProcess(0, 195)\n");
3607 ret = pNtTerminateProcess(0, 195);
3608 ok(!ret, "NtTerminateProcess error %#lx\n", ret);
3609
3610 memset(&pbi, 0, sizeof(pbi));
3611 ret = pNtQueryInformationProcess(process, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
3612 ok(!ret, "NtQueryInformationProcess error %#lx\n", ret);
3613 ok(pbi.ExitStatus == STILL_ACTIVE || pbi.ExitStatus == 195,
3614 "expected STILL_ACTIVE, got %lu\n", pbi.ExitStatus);
3615 affinity = 1;
3616 ret = pNtSetInformationProcess(process, ProcessAffinityMask, &affinity, sizeof(affinity));
3617 ok(!ret, "NtSetInformationProcess error %#lx\n", ret);
3618
3619 ret = pRtlDllShutdownInProgress();
3620 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3621
3622 hmod = GetModuleHandleA(dll_name);
3623 ok(hmod != 0, "DLL should not be unloaded\n");
3624
3625#ifdef __REACTOS__
3627#endif
3628 SetLastError(0xdeadbeef);
3630 ok(!thread, "CreateThread should fail\n");
3631 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
3632#ifdef __REACTOS__
3633 }
3634#endif
3635
3636 trace("call LdrShutdownProcess()\n");
3637 pLdrRegisterDllNotification(0, ldr_notify_callback, NULL, &cookie);
3638 pLdrShutdownProcess();
3639
3640 ret = pRtlDllShutdownInProgress();
3641 ok(ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3642
3643 hmod = GetModuleHandleA(dll_name);
3644 ok(hmod != 0, "DLL should not be unloaded\n");
3645
3646 memset(&pbi, 0, sizeof(pbi));
3647 ret = pNtQueryInformationProcess(process, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
3648 ok(!ret, "NtQueryInformationProcess error %#lx\n", ret);
3649 ok(pbi.ExitStatus == STILL_ACTIVE || pbi.ExitStatus == 195,
3650 "expected STILL_ACTIVE, got %lu\n", pbi.ExitStatus);
3651 affinity = 1;
3652 ret = pNtSetInformationProcess(process, ProcessAffinityMask, &affinity, sizeof(affinity));
3653 ok(!ret, "NtSetInformationProcess error %#lx\n", ret);
3654 break;
3655
3656 case 1: /* normal ExitProcess */
3657 ret = pRtlDllShutdownInProgress();
3658 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3659 break;
3660
3661 case 2: /* ExitProcess will be called by the PROCESS_DETACH handler */
3662 ret = pRtlDllShutdownInProgress();
3663 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3664
3665 trace("call FreeLibrary(%p)\n", hmod);
3666 SetLastError(0xdeadbeef);
3667 ret = FreeLibrary(hmod);
3668 ok(ret, "FreeLibrary error %ld\n", GetLastError());
3669 hmod = GetModuleHandleA(dll_name);
3670 ok(!hmod, "DLL should be unloaded\n");
3671
3672 if (test_dll_phase == 2)
3673 ok(0, "FreeLibrary+ExitProcess should never return\n");
3674
3675 ret = pRtlDllShutdownInProgress();
3676 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3677
3678 break;
3679
3680 case 3:
3681 trace("signalling thread exit\n");
3683 break;
3684
3685 case 4:
3686 trace("setting loader_lock_event\n");
3689 ok(inside_loader_lock != 0, "inside_loader_lock is not set\n");
3690
3691 /* calling NtTerminateProcess should not cause a deadlock */
3692 trace("call NtTerminateProcess(0, 198)\n");
3693 ret = pNtTerminateProcess(0, 198);
3694 ok(!ret, "NtTerminateProcess error %#lx\n", ret);
3695
3697
3698 /* Windows fails to release loader lock acquired from another thread,
3699 * so the LdrUnlockLoaderLock call fails here and ExitProcess deadlocks
3700 * later on, so NtTerminateProcess is used instead.
3701 */
3702 trace("call NtTerminateProcess(GetCurrentProcess(), 198)\n");
3703 pNtTerminateProcess(GetCurrentProcess(), 198);
3704 ok(0, "NtTerminateProcess should not return\n");
3705 break;
3706
3707 case 5:
3708 trace("setting peb_lock_event\n");
3711 ok(inside_peb_lock != 0, "inside_peb_lock is not set\n");
3712
3714
3715 /* calling ExitProcess should cause a deadlock */
3716 trace("call ExitProcess(198)\n");
3717 ExitProcess(198);
3718 ok(0, "ExitProcess should not return\n");
3719 break;
3720
3721 case 6:
3722 trace("setting heap_lock_event\n");
3725 ok(inside_heap_lock != 0, "inside_heap_lock is not set\n");
3726
3728
3729 /* calling ExitProcess should cause a deadlock */
3730 trace("call ExitProcess(1)\n");
3731 ExitProcess(1);
3732 ok(0, "ExitProcess should not return\n");
3733 break;
3734
3735 case 7:
3736 trace("setting cs_lock_event\n");
3739 ok(inside_cs_lock != 0, "inside_cs_lock is not set\n");
3740
3742
3743 /* calling ExitProcess should not cause a deadlock */
3744 trace("call ExitProcess(199)\n");
3745 ExitProcess(199);
3746 ok(0, "ExitProcess should not return\n");
3747 break;
3748
3749 default:
3750 assert(0);
3751 break;
3752 }
3753
3754 if (test_dll_phase == 0) expected_code = 195;
3755 else if (test_dll_phase == 3) expected_code = 196;
3756 else if (test_dll_phase == 4) expected_code = 198;
3757 else expected_code = STILL_ACTIVE;
3758
3759 if (expected_code == STILL_ACTIVE)
3760 {
3762 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3764 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3765 }
3766 else
3767 {
3769 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#lx\n", ret);
3771 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#lx\n", ret);
3772 }
3773
3774 for (i = 0; i < attached_thread_count; i++)
3775 {
3777 trace("child: GetExitCodeThread(%lu) => %ld,%lu\n", i, ret, code);
3778 ok(ret == 1, "GetExitCodeThread returned %ld, expected 1\n", ret);
3779 ok(code == expected_code, "expected thread exit code %lu, got %lu\n", expected_code, code);
3780 }
3781
3783
3784 trace("call ExitProcess(195)\n");
3785 ExitProcess(195);
3786}
#define GetNTVersion()
Definition: apitest.h:17
#define trace
Definition: atltest.h:70
static HANDLE thread
Definition: service.c:33
@ ProcessBasicInformation
Definition: cicbase.cpp:63
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
#define FILE_BEGIN
Definition: compat.h:761
#define OPEN_EXISTING
Definition: compat.h:775
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define FreeLibrary(x)
Definition: compat.h:748
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1489
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1534
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1227
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
#define assert(_expr)
Definition: assert.h:32
return ret
Definition: mutex.c:146
KAFFINITY affinity
Definition: wave.h:2
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _cl_event * event
Definition: glext.h:7739
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ ProcessAffinityMask
Definition: winternl.h:1903
LONG winetest_get_failures(void)
#define STILL_ACTIVE
Definition: minwinbase.h:43
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static int inside_loader_lock
Definition: loader.c:2950
static int test_dll_phase
Definition: loader.c:2950
static HANDLE peb_lock_event
Definition: loader.c:2948
static HANDLE semaphore
Definition: loader.c:2947
static DWORD WINAPI noop_thread_proc(void *param)
Definition: loader.c:3030
static LONG * child_failures
Definition: loader.c:52
#define PROCESS_ALL_ACCESS_NT4
Definition: loader.c:38
static int inside_cs_lock
Definition: loader.c:2950
static HANDLE heap_lock_event
Definition: loader.c:2948
static HANDLE attached_thread[MAX_COUNT]
Definition: loader.c:2945
static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
Definition: loader.c:3069
static HANDLE loader_lock_event
Definition: loader.c:2948
static HANDLE ack_event
Definition: loader.c:2948
static LIST_ENTRY * fls_list_head
Definition: loader.c:3048
static HANDLE stop_event
Definition: loader.c:2948
static int inside_heap_lock
Definition: loader.c:2950
static int inside_peb_lock
Definition: loader.c:2950
static CRITICAL_SECTION cs_lock
Definition: loader.c:2949
static HANDLE cs_lock_event
Definition: loader.c:2948
static DWORD WINAPI semaphore_thread_proc(void *param)
Definition: loader.c:3010
static DWORD attached_thread_count
Definition: loader.c:2946
static DWORD WINAPI mutex_thread_proc(void *param)
Definition: loader.c:2953
static void CALLBACK ldr_notify_callback(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
Definition: loader.c:3465
#define GENERIC_WRITE
Definition: nt_native.h:90
#define memset(x, y, z)
Definition: compat.h:39
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
Definition: inflate.c:139
Definition: cookie.c:34
Definition: fci.c:127
Definition: module.h:456
Definition: tools.h:99
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreW(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, IN LONG lInitialCount, IN LONG lMaximumCount, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:444
uint32_t DWORD_PTR
Definition: typedefs.h:65
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define WAIT_OBJECT_0
Definition: winbase.h:383
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917

◆ create_test_dll()

static DWORD create_test_dll ( const IMAGE_DOS_HEADER dos_header,
UINT  dos_size,
const IMAGE_NT_HEADERS nt_header,
char  dll_name[MAX_PATH] 
)
static

Definition at line 208 of file loader.c.

210{
211 char temp_path[MAX_PATH];
212 DWORD dummy, size, file_align;
213 HANDLE hfile;
214 BOOL ret;
215
217 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
218
219 hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
220 ok( hfile != INVALID_HANDLE_VALUE, "failed to create %s err %lu\n", dll_name, GetLastError() );
221 if (hfile == INVALID_HANDLE_VALUE) return 0;
222
223 SetLastError(0xdeadbeef);
224 ret = WriteFile(hfile, dos_header, dos_size, &dummy, NULL);
225 ok(ret, "WriteFile error %ld\n", GetLastError());
226
227 SetLastError(0xdeadbeef);
228 ret = WriteFile(hfile, nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
229 ok(ret, "WriteFile error %ld\n", GetLastError());
230
232 {
233 SetLastError(0xdeadbeef);
235 sizeof(IMAGE_OPTIONAL_HEADER),
236 &dummy, NULL);
237 ok(ret, "WriteFile error %ld\n", GetLastError());
239 {
241 assert(file_align < sizeof(filler));
242 SetLastError(0xdeadbeef);
243 ret = WriteFile(hfile, filler, file_align, &dummy, NULL);
244 ok(ret, "WriteFile error %ld\n", GetLastError());
245 }
246 }
247
250 {
252
253 section.SizeOfRawData = 10;
254
256 {
257 section.PointerToRawData = dos_size;
259 section.Misc.VirtualSize = section.SizeOfRawData * 10;
260 }
261 else
262 {
263 section.PointerToRawData = nt_header->OptionalHeader.SizeOfHeaders;
265 section.Misc.VirtualSize = 5;
266 }
267
268 SetLastError(0xdeadbeef);
269 ret = WriteFile(hfile, &section, sizeof(section), &dummy, NULL);
270 ok(ret, "WriteFile error %ld\n", GetLastError());
271
272 /* section data */
273 SetLastError(0xdeadbeef);
274 ret = WriteFile(hfile, section_data, sizeof(section_data), &dummy, NULL);
275 ok(ret, "WriteFile error %ld\n", GetLastError());
276 }
277
278 /* Minimal PE image that Windows7+ is able to load: 268 bytes */
279 size = GetFileSize(hfile, NULL);
280 if (size < 268)
281 {
282 file_align = 268 - size;
283 SetLastError(0xdeadbeef);
284 ret = WriteFile(hfile, filler, file_align, &dummy, NULL);
285 ok(ret, "WriteFile error %ld\n", GetLastError());
286 }
287
288 size = GetFileSize(hfile, NULL);
289 CloseHandle(hfile);
290 return size;
291}
#define MAX_PATH
Definition: compat.h:34
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
GLsizeiptr size
Definition: glext.h:5919
#define CREATE_ALWAYS
Definition: disk.h:72
static IMAGE_NT_HEADERS32 nt_header
Definition: data.c:36
static const char filler[0x1000]
Definition: loader.c:179
static IMAGE_DOS_HEADER dos_header
Definition: loader.c:102
static const char section_data[0x10]
Definition: loader.c:180
static DWORD page_size
Definition: loader.c:54
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
struct _IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER
WORD SizeOfOptionalHeader
Definition: ntddk_ex.h:127
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
Definition: parser.c:56

Referenced by test_filenames(), and test_Loader().

◆ create_test_dll_sections()

static DWORD create_test_dll_sections ( const IMAGE_DOS_HEADER dos_header,
const IMAGE_NT_HEADERS nt_header,
const IMAGE_SECTION_HEADER sections,
const void section_data,
char  dll_name[MAX_PATH] 
)
static

Definition at line 293 of file loader.c.

296{
297 char temp_path[MAX_PATH];
298 DWORD dummy, i, size;
299 HANDLE hfile;
300 BOOL ret;
301
303 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
304
305 hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
306 ok( hfile != INVALID_HANDLE_VALUE, "failed to create %s err %lu\n", dll_name, GetLastError() );
307 if (hfile == INVALID_HANDLE_VALUE) return 0;
308
309 SetLastError(0xdeadbeef);
310 ret = WriteFile(hfile, dos_header, sizeof(*dos_header), &dummy, NULL);
311 ok(ret, "WriteFile error %ld\n", GetLastError());
312
313 SetLastError(0xdeadbeef);
315 ok(ret, "WriteFile error %ld\n", GetLastError());
316
317 SetLastError(0xdeadbeef);
319 &dummy, NULL);
320 ok(ret, "WriteFile error %ld\n", GetLastError());
321
322 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
323 {
324 SetFilePointer(hfile, sections[i].PointerToRawData, NULL, FILE_BEGIN);
325 SetLastError(0xdeadbeef);
326 ret = WriteFile(hfile, section_data, sections[i].SizeOfRawData, &dummy, NULL);
327 ok(ret, "WriteFile error %ld\n", GetLastError());
328 }
329 size = GetFileSize(hfile, NULL);
330 CloseHandle(hfile);
331 return size;
332}
struct section sections[2]
Definition: diskspace.c:792
#define offsetof(TYPE, MEMBER)

Referenced by map_image_section(), and test_Loader().

◆ delete_load_path()

static void delete_load_path ( void  )
static

Definition at line 588 of file loader.c.

589{
590 WCHAR *p;
591
593 for (p = load_test_name + lstrlenW(load_test_name) - 1; *p != '\\'; p--) ;
594 *p = 0;
597 for (p = load_fallback_name + lstrlenW(load_fallback_name) - 1; *p != '\\'; p--) ;
598 *p = 0;
600}
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
GLfloat GLfloat p
Definition: glext.h:8902
static WCHAR load_fallback_name[MAX_PATH]
Definition: loader.c:556
static WCHAR load_test_name[MAX_PATH]
Definition: loader.c:556
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by test_Loader().

◆ dll_entry_point()

static BOOL WINAPI dll_entry_point ( HINSTANCE  hinst,
DWORD  reason,
LPVOID  param 
)
static

Definition at line 3069 of file loader.c.

3070{
3071 static LONG noop_thread_started;
3072 static DWORD fls_index = FLS_OUT_OF_INDEXES, fls_index2 = FLS_OUT_OF_INDEXES;
3073 static int fls_count = 0;
3074 static int thread_detach_count = 0;
3075 static int thread_count;
3076 DWORD ret;
3077
3078 ok(!inside_loader_lock, "inside_loader_lock should not be set\n");
3079 ok(!inside_peb_lock, "inside_peb_lock should not be set\n");
3080
3081 switch (reason)
3082 {
3083 case DLL_PROCESS_ATTACH:
3084 trace("dll: %p, DLL_PROCESS_ATTACH, %p\n", hinst, param);
3085
3086 ret = pRtlDllShutdownInProgress();
3087 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3088
3089 /* Set up the FLS slot, if FLS is available */
3090 if (pFlsGetValue)
3091 {
3092 void* value;
3093 BOOL bret;
3094 ret = pFlsAlloc(&fls_callback);
3095 ok(ret != FLS_OUT_OF_INDEXES, "FlsAlloc returned %ld\n", ret);
3096 fls_index = ret;
3097 SetLastError(0xdeadbeef);
3098 value = pFlsGetValue(fls_index);
3099 ok(!value, "FlsGetValue returned %p, expected NULL\n", value);
3100 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %lu\n", GetLastError());
3101 bret = pFlsSetValue(fls_index, (void*) 0x31415);
3102 ok(bret, "FlsSetValue failed\n");
3103 fls_count++;
3104
3105 fls_index2 = pFlsAlloc(&fls_callback);
3106 ok(fls_index2 != FLS_OUT_OF_INDEXES, "FlsAlloc returned %ld\n", ret);
3107 }
3108 ++thread_count;
3109 break;
3110 case DLL_PROCESS_DETACH:
3111 {
3112 DWORD code, expected_code, i;
3114 void *addr;
3115 SIZE_T size;
3117 DEBUG_EVENT de;
3118
3119 trace("dll: %p, DLL_PROCESS_DETACH, %p\n", hinst, param);
3120
3121 if (test_dll_phase == 4 || test_dll_phase == 5)
3122 {
3123 ok(0, "dll_entry_point(DLL_PROCESS_DETACH) should not be called\n");
3124 break;
3125 }
3126
3127 /* The process should already deadlock at this point */
3128 if (test_dll_phase == 6)
3129 {
3130 /* In reality, code below never gets executed, probably some other
3131 * code tries to access process heap and deadlocks earlier, even XP
3132 * doesn't call the DLL entry point on process detach either.
3133 */
3135 todo_wine
3136 ok(0, "dll_entry_point: process should already deadlock\n");
3137 break;
3138 }
3139 else if (test_dll_phase == 7)
3140 {
3142 }
3143
3144 if (test_dll_phase == 0 || test_dll_phase == 1 || test_dll_phase == 3 || test_dll_phase == 7)
3145 ok(param != NULL, "dll: param %p\n", param);
3146 else
3147 ok(!param, "dll: param %p\n", param);
3148
3149 if (test_dll_phase == 0 || test_dll_phase == 1) expected_code = 195;
3150 else if (test_dll_phase == 3) expected_code = 196;
3151 else if (test_dll_phase == 7) expected_code = 199;
3152 else expected_code = STILL_ACTIVE;
3153
3154 ret = pRtlDllShutdownInProgress();
3155 if (test_dll_phase == 0 || test_dll_phase == 1 || test_dll_phase == 3)
3156 {
3157 ok(ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3158 }
3159 else
3160 {
3161 /* FIXME: remove once Wine is fixed */
3162 todo_wine_if (!(expected_code == STILL_ACTIVE || expected_code == 196))
3163#ifdef __REACTOS__
3164 ok(!ret || broken(GetNTVersion() < _WIN32_WINNT_VISTA), "RtlDllShutdownInProgress returned %ld\n", ret);
3165#else
3166 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3167#endif
3168 }
3169
3170 /* In the case that the process is terminating, FLS slots should still be accessible, but
3171 * the callback should be already run for this thread and the contents already NULL.
3172 */
3173 if (param && pFlsGetValue)
3174 {
3175 void* value;
3176 SetLastError(0xdeadbeef);
3177 value = pFlsGetValue(fls_index);
3178#ifdef __REACTOS__
3179 ok(value == NULL || broken(value == (void*)0x31415) /* WS03 */, "FlsGetValue returned %p, expected NULL\n", value);
3180#else
3181 ok(value == NULL, "FlsGetValue returned %p, expected NULL\n", value);
3182#endif
3183 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %lu\n", GetLastError());
3184#ifdef __REACTOS__
3185 ok(fls_callback_count == thread_detach_count + 1 || broken(GetNTVersion() < _WIN32_WINNT_VISTA),
3186 "wrong FLS callback count %ld, expected %d\n", fls_callback_count, thread_detach_count + 1);
3187#else
3188 ok(fls_callback_count == thread_detach_count + 1,
3189 "wrong FLS callback count %ld, expected %d\n", fls_callback_count, thread_detach_count + 1);
3190#endif
3191 }
3192 if (pFlsFree)
3193 {
3194 BOOL ret;
3195 /* Call FlsFree now and run the remaining callbacks from uncleanly terminated threads */
3196 ret = pFlsFree(fls_index);
3197 ok(ret, "FlsFree failed with error %lu\n", GetLastError());
3198 fls_index = FLS_OUT_OF_INDEXES;
3199#ifdef __REACTOS__
3201#endif
3202 ok(fls_callback_count == fls_count,
3203 "wrong FLS callback count %ld, expected %d\n", fls_callback_count, fls_count);
3204 }
3205
3206 ok(attached_thread_count >= 2, "attached thread count should be >= 2\n");
3207
3208 for (i = 0; i < attached_thread_count; i++)
3209 {
3210 /* Calling GetExitCodeThread() without waiting for thread termination
3211 * leads to different results due to a race condition.
3212 */
3213 if (expected_code != STILL_ACTIVE)
3214 {
3216 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#lx\n", ret);
3217 }
3219 trace("dll: GetExitCodeThread(%lu) => %ld,%lu\n", i, ret, code);
3220 ok(ret == 1, "GetExitCodeThread returned %ld, expected 1\n", ret);
3221 ok(code == expected_code, "expected thread exit code %lu, got %lu\n", expected_code, code);
3222 }
3223
3225 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3226
3228 if (expected_code == STILL_ACTIVE)
3229 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3230 else
3231 ok(ret == WAIT_ABANDONED, "expected WAIT_ABANDONED, got %#lx\n", ret);
3232
3233 /* semaphore is not abandoned on thread termination */
3235 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3236
3237 if (expected_code == STILL_ACTIVE)
3238 {
3240 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3242 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3243 }
3244 else
3245 {
3247 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#lx\n", ret);
3249 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#lx\n", ret);
3250 }
3251
3252 /* win7 doesn't allow creating a thread during process shutdown but
3253 * earlier Windows versions allow it.
3254 */
3255 noop_thread_started = 0;
3256 SetLastError(0xdeadbeef);
3257 handle = CreateThread(NULL, 0, noop_thread_proc, &noop_thread_started, 0, &ret);
3258 if (param)
3259 {
3260#ifdef __REACTOS__
3261 ok(!handle || broken(handle != 0) /* Pre-Win7 */, "CreateThread should fail\n");
3262
3263 if (!handle)
3264 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
3265 else
3266 {
3268 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
3270 }
3271#else
3272 ok(!handle, "CreateThread should fail\n");
3273 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
3274#endif
3275 }
3276 else
3277 {
3278 ok(handle != 0, "CreateThread error %ld\n", GetLastError());
3280 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3281 ok(!noop_thread_started, "thread shouldn't start yet\n");
3283 }
3284
3285 SetLastError(0xdeadbeef);
3287 ok(process != NULL, "OpenProcess error %ld\n", GetLastError());
3288
3289 noop_thread_started = 0;
3290 SetLastError(0xdeadbeef);
3291 handle = CreateRemoteThread(process, NULL, 0, noop_thread_proc, &noop_thread_started, 0, &ret);
3292 if (param)
3293 {
3294#ifdef __REACTOS__
3295 ok(!handle || broken(handle != 0) /* Pre-Win7 */, "CreateRemoteThread should fail\n");
3296
3297 if (!handle)
3298 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
3299 else
3300 {
3302 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
3304 }
3305#else
3306 ok(!handle, "CreateRemoteThread should fail\n");
3307 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
3308#endif
3309 }
3310 else
3311 {
3312 ok(handle != 0, "CreateRemoteThread error %ld\n", GetLastError());
3314 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#lx\n", ret);
3315 ok(!noop_thread_started, "thread shouldn't start yet\n");
3317 }
3318
3319 SetLastError(0xdeadbeef);
3321 ok(handle != 0, "CreateFileMapping error %ld\n", GetLastError());
3322
3323 offset.u.LowPart = 0;
3324 offset.u.HighPart = 0;
3325 addr = NULL;
3326 size = 0;
3327 ret = pNtMapViewOfSection(handle, process, &addr, 0, 0, &offset,
3328 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
3329 ok(ret == STATUS_SUCCESS, "NtMapViewOfSection error %#lx\n", ret);
3330 ret = pNtUnmapViewOfSection(process, addr);
3331 ok(ret == STATUS_SUCCESS, "NtUnmapViewOfSection error %#lx\n", ret);
3332
3335
3336 handle = GetModuleHandleA("winver.exe");
3337 ok(!handle, "winver.exe shouldn't be loaded yet\n");
3338 SetLastError(0xdeadbeef);
3339 handle = LoadLibraryA("winver.exe");
3340 ok(handle != 0, "LoadLibrary error %ld\n", GetLastError());
3341 SetLastError(0xdeadbeef);
3343 ok(ret, "FreeLibrary error %ld\n", GetLastError());
3344 handle = GetModuleHandleA("winver.exe");
3345 if (param)
3346 ok(handle != 0, "winver.exe should not be unloaded\n");
3347 else
3348 todo_wine
3349 ok(!handle, "winver.exe should be unloaded\n");
3350
3351 SetLastError(0xdeadbeef);
3352 ret = WaitForDebugEvent(&de, 0);
3353 ok(!ret, "WaitForDebugEvent should fail\n");
3354 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
3355
3356 SetLastError(0xdeadbeef);
3358 ok(!ret, "DebugActiveProcess should fail\n");
3359 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
3360
3361 SetLastError(0xdeadbeef);
3362 ret = WaitForDebugEvent(&de, 0);
3363 ok(!ret, "WaitForDebugEvent should fail\n");
3364 ok(GetLastError() == ERROR_SEM_TIMEOUT, "expected ERROR_SEM_TIMEOUT, got %ld\n", GetLastError());
3365
3366 if (test_dll_phase == 2)
3367 {
3368 trace("dll: call ExitProcess()\n");
3370 ExitProcess(197);
3371 }
3372 trace("dll: %p, DLL_PROCESS_DETACH, %p => DONE\n", hinst, param);
3373 break;
3374 }
3375 case DLL_THREAD_ATTACH:
3376 trace("dll: %p, DLL_THREAD_ATTACH, %p\n", hinst, param);
3377
3378 ++thread_count;
3379
3380 ret = pRtlDllShutdownInProgress();
3381 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3382
3384 {
3388 }
3389
3390 /* Make sure the FLS slot is empty, if FLS is available */
3391 if (pFlsGetValue)
3392 {
3393 void* value;
3394 BOOL ret;
3395 SetLastError(0xdeadbeef);
3396 value = pFlsGetValue(fls_index);
3397 ok(!value, "FlsGetValue returned %p, expected NULL\n", value);
3398 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %lu\n", GetLastError());
3399 ret = pFlsSetValue(fls_index, (void*) 0x31415);
3400 ok(ret, "FlsSetValue failed\n");
3401 fls_count++;
3402 }
3403
3404 break;
3405 case DLL_THREAD_DETACH:
3406 trace("dll: %p, DLL_THREAD_DETACH, %p\n", hinst, param);
3407 --thread_count;
3408 thread_detach_count++;
3409
3410 ret = pRtlDllShutdownInProgress();
3411 /* win7 doesn't allow creating a thread during process shutdown but
3412 * earlier Windows versions allow it. In that case DLL_THREAD_DETACH is
3413 * sent on thread exit, but DLL_THREAD_ATTACH is never received.
3414 */
3415 if (noop_thread_started)
3416 ok(ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3417 else
3418 ok(!ret, "RtlDllShutdownInProgress returned %ld\n", ret);
3419
3420 /* FLS data should already be destroyed, if FLS is available.
3421 */
3422 if (pFlsGetValue && fls_index != FLS_OUT_OF_INDEXES)
3423 {
3424 unsigned int index, count;
3425 void* value;
3426 BOOL bret;
3427
3428 SetLastError(0xdeadbeef);
3429 value = pFlsGetValue(fls_index);
3430#ifdef __REACTOS__
3431 ok(!value || broken(value == (void*)0x31415) /* WS03 */, "FlsGetValue returned %p, expected NULL\n", value);
3432#else
3433 ok(!value, "FlsGetValue returned %p, expected NULL\n", value);
3434#endif
3435 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %lu\n", GetLastError());
3436
3437 bret = pFlsSetValue(fls_index2, (void*) 0x31415);
3438 ok(bret, "FlsSetValue failed\n");
3439
3440 if (fls_list_head)
3441 {
3442 count = check_linked_list(fls_list_head, &NtCurrentTeb()->FlsSlots->fls_list_entry, &index);
3443#ifdef __REACTOS__
3445#endif
3446 ok(count <= thread_count, "Got unexpected count %u, thread_count %u.\n", count, thread_count);
3447 ok(index == ~0, "Got unexpected index %u.\n", index);
3448#ifdef __REACTOS__
3449 }
3450#endif
3451 }
3452 }
3453
3454 break;
3455 default:
3456 trace("dll: %p, %ld, %p\n", hinst, reason, param);
3457 break;
3458 }
3459
3461
3462 return TRUE;
3463}
#define broken(x)
Definition: atltest.h:178
#define index(s, c)
Definition: various.h:29
#define ERROR_SUCCESS
Definition: deptool.c:10
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
#define GetProcessHeap()
Definition: compat.h:736
#define PAGE_READONLY
Definition: compat.h:138
#define DLL_THREAD_DETACH
Definition: compat.h:133
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define DLL_THREAD_ATTACH
Definition: compat.h:132
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:445
BOOL WINAPI WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent, IN DWORD dwMilliseconds)
Definition: debugger.c:590
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
HANDLE WINAPI CreateRemoteThread(IN HANDLE hProcess, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:159
GLintptr offset
Definition: glext.h:5920
GLuint index
Definition: glext.h:6031
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat param
Definition: glext.h:5796
BOOL WINAPI HeapLock(HANDLE hHeap)
Definition: heapmem.c:123
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
static HINSTANCE hinst
Definition: edit.c:551
static VOID WINAPI fls_callback(PVOID lpFlsData)
Definition: loader.c:3042
static LONG fls_callback_count
Definition: loader.c:2951
#define MAX_COUNT
Definition: loader.c:2944
static unsigned int check_linked_list(const LIST_ENTRY *le, const LIST_ENTRY *search_entry, unsigned int *index_found)
Definition: loader.c:3050
#define PAGE_READWRITE
Definition: nt_native.h:1307
long LONG
Definition: pedump.c:60
static uint32_t thread_count(IN pnfs_layout_state *state, IN enum pnfs_iomode iomode, IN uint64_t offset, IN uint64_t length)
Definition: pnfs_io.c:137
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG_PTR SIZE_T
Definition: typedefs.h:80
Definition: pdh_main.c:96
#define WAIT_ABANDONED
Definition: winbase.h:389
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:556
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define ERROR_SEM_TIMEOUT
Definition: winerror.h:315
#define DUPLICATE_SAME_ACCESS

Referenced by child_process(), and test_ExitProcess().

◆ DWORD()

static DWORD ( WINAPI pFlsAlloc)
static

◆ failuredllhook()

static PVOID WINAPI failuredllhook ( ULONG  ul,
DELAYLOAD_INFO pd 
)
static

Definition at line 4290 of file loader.c.

4291{
4292 ok(ul == 4, "expected 4, got %lu\n", ul);
4293 ok(!!pd, "no delayload info supplied\n");
4294 if (pd)
4295 {
4296 ok(pd->Size == sizeof(*pd), "got %lu\n", pd->Size);
4297 ok(!!pd->DelayloadDescriptor, "no DelayloadDescriptor supplied\n");
4298 if (pd->DelayloadDescriptor)
4299 {
4301 "expected 1, got %lu\n", pd->DelayloadDescriptor->Attributes.AllAttributes);
4302 ok(pd->DelayloadDescriptor->DllNameRVA == 0x2000,
4303 "expected 0x2000, got %lx\n", pd->DelayloadDescriptor->DllNameRVA);
4304 ok(pd->DelayloadDescriptor->ModuleHandleRVA == 0x201a,
4305 "expected 0x201a, got %lx\n", pd->DelayloadDescriptor->ModuleHandleRVA);
4307 "expected %lx > %lx\n", pd->DelayloadDescriptor->ImportAddressTableRVA,
4310 "expected %lx > %lx\n", pd->DelayloadDescriptor->ImportNameTableRVA,
4313 "expected 0, got %lx\n", pd->DelayloadDescriptor->BoundImportAddressTableRVA);
4315 "expected 0, got %lx\n", pd->DelayloadDescriptor->UnloadInformationTableRVA);
4317 "expected 0, got %lx\n", pd->DelayloadDescriptor->TimeDateStamp);
4318 }
4319
4320 ok(!!pd->ThunkAddress, "no ThunkAddress supplied\n");
4321 if (pd->ThunkAddress)
4322 ok(pd->ThunkAddress->u1.Ordinal, "no ThunkAddress value supplied\n");
4323
4324 ok(!!pd->TargetDllName, "no TargetDllName supplied\n");
4325 if (pd->TargetDllName)
4326 ok(!strcmp(pd->TargetDllName, "secur32.dll"),
4327 "expected \"secur32.dll\", got \"%s\"\n", pd->TargetDllName);
4328
4330 "expected 0, got %lx\n", pd->TargetApiDescriptor.ImportDescribedByName);
4333 "expected 0, got %lx\n", pd->TargetApiDescriptor.Description.Ordinal);
4334
4335 ok(!!pd->TargetModuleBase, "no TargetModuleBase supplied\n");
4336 ok(pd->Unused == NULL, "expected NULL, got %p\n", pd->Unused);
4337 ok(pd->LastError, "no LastError supplied\n");
4338 }
4339 cb_count++;
4340 return (void*)0xdeadbeef;
4341}
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
static WORD cb_count
Definition: loader.c:53
PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor
DELAYLOAD_PROC_DESCRIPTOR TargetApiDescriptor
PIMAGE_THUNK_DATA ThunkAddress
union _DELAYLOAD_PROC_DESCRIPTOR::@3113 Description
union _IMAGE_DELAYLOAD_DESCRIPTOR::@4531 Attributes
union _IMAGE_THUNK_DATA32::@2337 u1

Referenced by test_ResolveDelayLoadedAPI().

◆ failuresyshook()

static PVOID WINAPI failuresyshook ( const char dll,
const char function 
)
static

Definition at line 4343 of file loader.c.

4344{
4345 ok(!strcmp(dll, "secur32.dll"), "wrong dll: %s\n", dll);
4346 ok(!((ULONG_PTR)function >> 16), "expected ordinal, got %p\n", function);
4347 cb_count_sys++;
4348 return (void*)0x12345678;
4349}
static WORD cb_count_sys
Definition: loader.c:53
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by test_ResolveDelayLoadedAPI().

◆ fls_callback()

static VOID WINAPI fls_callback ( PVOID  lpFlsData)
static

Definition at line 3042 of file loader.c.

3043{
3044 ok(lpFlsData == (void*) 0x31415, "lpFlsData is %p, expected %p\n", lpFlsData, (void*) 0x31415);
3046}
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by dll_entry_point().

◆ gen_forward_chain_testdll()

static HANDLE gen_forward_chain_testdll ( char  testdll_path[MAX_PATH],
const char  source_dll[MAX_PATH],
BOOL  is_export,
BOOL  is_import,
DWORD exp_func_base_rva,
DWORD imp_thunk_base_rva 
)
static

Definition at line 2502 of file loader.c.

2507{
2508 DWORD text_rva = page_size; /* assumes that the PE/COFF headers fit in a page */
2509 DWORD text_size = page_size;
2510 DWORD edata_rva = text_rva + text_size;
2511 DWORD edata_size = page_size;
2512 DWORD idata_rva = edata_rva + text_size;
2513 DWORD idata_size = page_size;
2514 DWORD eof_rva = idata_rva + edata_size;
2515 const IMAGE_SECTION_HEADER sections[3] = {
2516 {
2517 .Name = ".text",
2518 .Misc = { .VirtualSize = text_size },
2519 .VirtualAddress = text_rva,
2520 .SizeOfRawData = text_size,
2521 .PointerToRawData = text_rva,
2523 },
2524 {
2525 .Name = ".edata",
2526 .Misc = { .VirtualSize = edata_size },
2527 .VirtualAddress = edata_rva,
2528 .SizeOfRawData = edata_size,
2529 .PointerToRawData = edata_rva,
2531 },
2532 {
2533 .Name = ".idata",
2534 .Misc = { .VirtualSize = edata_size },
2535 .VirtualAddress = idata_rva,
2536 .SizeOfRawData = idata_size,
2537 .PointerToRawData = idata_rva,
2539 },
2540 };
2541 struct expdesc
2542 {
2544
2545 DWORD functions[2];
2546
2547 const DWORD names[2];
2548 const WORD name_ords[2];
2549 const char str_forward_test_func[32];
2550 const char str_forward_test_func2[32];
2551
2552 char dll_name[MAX_PATH]; /* dynamically populated */
2553 char strpool[2][MAX_PATH + 16]; /* for names of export forwarders */
2554 } expdesc = {
2555 .dir = {
2556 .Characteristics = 0,
2557 .TimeDateStamp = 0x12345678,
2558 .Name = edata_rva + offsetof(struct expdesc, dll_name),
2559 .Base = 1,
2560 .NumberOfFunctions = ARRAY_SIZE(expdesc.functions),
2561 .NumberOfNames = ARRAY_SIZE(expdesc.names),
2562 .AddressOfFunctions = edata_rva + offsetof(struct expdesc, functions),
2563 .AddressOfNames = edata_rva + offsetof(struct expdesc, names),
2564 .AddressOfNameOrdinals = edata_rva + offsetof(struct expdesc, name_ords),
2565 },
2566 .functions = {
2567 text_rva + 0x4, /* may be overwritten */
2568 text_rva + 0x8, /* may be overwritten */
2569 },
2570 .names = {
2571 edata_rva + offsetof(struct expdesc, str_forward_test_func),
2572 edata_rva + offsetof(struct expdesc, str_forward_test_func2),
2573 },
2574 .name_ords = {
2575 0,
2576 1,
2577 },
2578 .str_forward_test_func = "forward_test_func",
2579 .str_forward_test_func2 = "forward_test_func2",
2580 };
2581 struct impdesc
2582 {
2584 const IMAGE_THUNK_DATA original_thunks[3];
2585 const IMAGE_THUNK_DATA thunks[3];
2586 const struct { WORD hint; char name[32]; } impname_forward_test_func;
2587
2588 char module[MAX_PATH]; /* dynamically populated */
2589 } impdesc = {
2590 .descr = {
2591 {
2592 .OriginalFirstThunk = idata_rva + offsetof(struct impdesc, original_thunks),
2593 .TimeDateStamp = 0,
2594 .ForwarderChain = -1,
2595 .Name = idata_rva + offsetof(struct impdesc, module),
2596 .FirstThunk = idata_rva + offsetof(struct impdesc, thunks),
2597 },
2598 {{ 0 }},
2599 },
2600 .original_thunks = {
2601 {{ idata_rva + offsetof(struct impdesc, impname_forward_test_func) }},
2602 {{ IMAGE_ORDINAL_FLAG | 2 }},
2603 {{ 0 }},
2604 },
2605 .thunks = {
2606 {{ idata_rva + offsetof(struct impdesc, impname_forward_test_func) }},
2607 {{ IMAGE_ORDINAL_FLAG | 2 }},
2608 {{ 0 }},
2609 },
2610 .impname_forward_test_func = { 0, "forward_test_func" },
2611 };
2613 char temp_path[MAX_PATH];
2614 HANDLE file, file_w;
2615 LARGE_INTEGER qpc;
2616 DWORD outlen;
2617 BOOL ret;
2618 int res;
2619
2621 res = snprintf( expdesc.dll_name, ARRAY_SIZE(expdesc.dll_name),
2622 "ldr%05lx.dll", qpc.LowPart & 0xfffffUL );
2623 ok( res > 0 && res < ARRAY_SIZE(expdesc.dll_name), "snprintf failed\n" );
2624
2625 if (source_dll)
2626 {
2627 const char *export_names[2] = {
2628 "forward_test_func",
2629 "#2",
2630 };
2631 const char *backslash = strrchr( source_dll, '\\' );
2632 const char *dllname = backslash ? backslash + 1 : source_dll;
2633 const char *dot = strrchr( dllname, '.' );
2634 size_t ext_start = dot ? dot - dllname : strlen(dllname);
2635 size_t i;
2636
2637 res = snprintf( impdesc.module, ARRAY_SIZE(impdesc.module), "%s", dllname );
2638 ok( res > 0 && res < ARRAY_SIZE(impdesc.module), "snprintf() failed\n" );
2639
2640 for (i = 0; i < ARRAY_SIZE(export_names); i++)
2641 {
2642 char *buf;
2643 size_t buf_size;
2644
2645 assert( i < ARRAY_SIZE(expdesc.strpool) );
2646 buf = expdesc.strpool[i];
2647 buf_size = ARRAY_SIZE(expdesc.strpool[i]);
2648
2649 assert( ext_start < buf_size );
2650 memcpy( buf, dllname, ext_start );
2651 buf += ext_start;
2652 buf_size -= ext_start;
2653
2654 res = snprintf( buf, buf_size, ".%s", export_names[i] );
2655 ok( res > 0 && res < buf_size, "snprintf() failed\n" );
2656
2657 assert( i < ARRAY_SIZE(expdesc.functions) );
2658 expdesc.functions[i] = edata_rva + (expdesc.strpool[i] - (char *)&expdesc);
2659 }
2660 }
2661
2663 nt_header.FileHeader.TimeDateStamp = 0x12345678;
2666
2670 nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(sections);
2672 if (is_export)
2673 {
2676 }
2677 /* Always have an import descriptor (even if empty) just like a real DLL */
2680
2682 "headers (size %#lx) should not overlap with text area (RVA %#lx)\n",
2684
2686 ok( outlen > 0 && outlen < ARRAY_SIZE(temp_path), "GetTempPathA() err=%lu\n", GetLastError() );
2687
2688 res = snprintf( testdll_path, MAX_PATH, "%s\\%s", temp_path, expdesc.dll_name );
2689 ok( res > 0 && res < MAX_PATH, "snprintf failed\n" );
2690
2691 /* Open file handle that will be deleted on close or process termination */
2692 file = CreateFileA( testdll_path,
2693 DELETE,
2695 NULL,
2696 CREATE_NEW,
2698 NULL );
2699 ok( file != INVALID_HANDLE_VALUE, "CreateFile(%s) for delete returned error %lu\n",
2700 wine_dbgstr_a( testdll_path ), GetLastError() );
2701
2702 /* Open file again with write access */
2703 file_w = CreateFileA( testdll_path,
2706 NULL,
2709 NULL );
2710 ok( file_w != INVALID_HANDLE_VALUE, "CreateFile(%s) for write returned error %lu\n",
2711 wine_dbgstr_a( testdll_path ), GetLastError() );
2712
2713 ret = WriteFile( file_w, &dos_header, sizeof(dos_header), &outlen, NULL );
2714 ok( ret && outlen == sizeof(dos_header), "write dos_header: err=%lu outlen=%lu\n", GetLastError(), outlen );
2715
2716 ret = WriteFile( file_w, &nt_header, sizeof(nt_header), &outlen, NULL );
2717 ok( ret && outlen == sizeof(nt_header), "write nt_header: err=%lu outlen=%lu\n", GetLastError(), outlen );
2718
2719 ret = WriteFile( file_w, sections, sizeof(sections), &outlen, NULL );
2720 ok( ret && outlen == sizeof(sections), "write sections: err=%lu outlen=%lu\n", GetLastError(), outlen );
2721
2722 if (is_export)
2723 {
2724 SetFilePointer( file_w, edata_rva, NULL, FILE_BEGIN );
2725 ret = WriteFile( file_w, &expdesc, sizeof(expdesc), &outlen, NULL );
2726 ok( ret && outlen == sizeof(expdesc), "write expdesc: err=%lu outlen=%lu\n", GetLastError(), outlen );
2727 }
2728
2729 if (is_import)
2730 {
2731 SetFilePointer( file_w, idata_rva, NULL, FILE_BEGIN );
2732 ret = WriteFile( file_w, &impdesc, sizeof(impdesc), &outlen, NULL );
2733 ok( ret && outlen == sizeof(impdesc), "write impdesc: err=%lu outlen=%lu\n", GetLastError(), outlen );
2734 }
2735
2736 ret = SetFilePointer( file_w, eof_rva, NULL, FILE_BEGIN );
2737 ok( ret, "%lu\n", GetLastError() );
2738 ret = SetEndOfFile( file_w );
2739 ok( ret, "%lu\n", GetLastError() );
2740
2741 ret = CloseHandle( file_w );
2742 ok( ret, "%lu\n", GetLastError() );
2743
2744 if (exp_func_base_rva)
2745 {
2746 *exp_func_base_rva = is_export ? edata_rva + ((char *)&expdesc.functions - (char *)&expdesc) : 0;
2747 }
2748
2749 if (imp_thunk_base_rva)
2750 {
2751 *imp_thunk_base_rva = is_import ? idata_rva + ((char *)&impdesc.thunks - (char *)&impdesc) : 0;
2752 }
2753
2754 return file;
2755}
unsigned int dir
Definition: maze.c:112
#define ARRAY_SIZE(A)
Definition: main.h:20
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
BOOL WINAPI QueryPerformanceCounter(OUT PLARGE_INTEGER lpPerformanceCount)
Definition: perfcnt.c:23
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint res
Definition: glext.h:9613
GLuint GLuint * names
Definition: glext.h:11545
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define FILE_FLAG_DELETE_ON_CLOSE
Definition: disk.h:42
#define CREATE_NEW
Definition: disk.h:69
static const IMAGE_NT_HEADERS nt_header_template
Definition: loader.c:104
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define DELETE
Definition: nt_native.h:57
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: ntimage.h:231
#define IMAGE_SCN_CNT_CODE
Definition: ntimage.h:230
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define IMAGE_ORDINAL_FLAG
Definition: pedump.c:336
const char int int int static __inline const char * wine_dbgstr_a(const char *s)
Definition: debug.h:187
const char * descr
Definition: boot.c:45
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
Definition: name.c:39
ULONG LowPart
Definition: typedefs.h:106
DWORD hint
Definition: vfdcmd.c:88
#define snprintf
Definition: wintirpc.h:48

Referenced by subtest_export_forwarder_dep_chain().

◆ get_alt_bitness_machine()

static WORD get_alt_bitness_machine ( WORD  orig_machine)
static

Definition at line 196 of file loader.c.

197{
198 switch (orig_machine)
199 {
204 }
205 return 0;
206}
#define IMAGE_FILE_MACHINE_ARMNT
Definition: compat.h:127
#define IMAGE_FILE_MACHINE_ARM64
Definition: compat.h:129
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174

Referenced by test_Loader().

◆ get_alt_machine()

static WORD get_alt_machine ( WORD  orig_machine)
static

Definition at line 183 of file loader.c.

184{
185 switch (orig_machine)
186 {
191 }
192 return 0;
193}

Referenced by map_image_section().

◆ get_com_dir_size()

static UINT get_com_dir_size ( const IMAGE_NT_HEADERS nt)
static

Definition at line 602 of file loader.c.

603{
605 return ((const IMAGE_NT_HEADERS32 *)nt)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
607 return ((const IMAGE_NT_HEADERS64 *)nt)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size;
608 else
609 return 0;
610}
IMAGE_NT_HEADERS nt
Definition: module.c:68
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: ntimage.h:376
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489

Referenced by map_image_section().

◆ HMODULE()

static HMODULE ( WINAPI pLoadPackagedLibrary)
static

◆ init_load_path()

static void init_load_path ( const char fallback_dll)
static

Definition at line 559 of file loader.c.

560{
561 static const WCHAR pathW[] = {'P','A','T','H',0};
562 static const WCHAR ldrW[] = {'l','d','r',0};
563 static const WCHAR sepW[] = {';',0};
564 static const WCHAR bsW[] = {'\\',0};
566
571 ok( CreateDirectoryW( load_test_name, NULL ), "failed to create dir\n" );
573 ok( CreateDirectoryW( load_fallback_name, NULL ), "failed to create dir\n" );
575 lstrcatW( load_path, sepW );
577 lstrcatW( load_path, sepW );
584 MultiByteToWideChar( CP_ACP, 0, fallback_dll, -1, path, MAX_PATH );
586}
#define CP_ACP
Definition: compat.h:109
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1104
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
static const WCHAR bsW[]
Definition: filesystem.c:45
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static const WCHAR wldr_nameW[]
Definition: loader.c:555
static WCHAR load_path[MAX_PATH]
Definition: loader.c:557
static const WCHAR pathW[]
Definition: path.c:2368

Referenced by test_Loader().

◆ is_mem_writable()

static BOOL is_mem_writable ( DWORD  prot)
static

Definition at line 1777 of file loader.c.

1778{
1779 switch (prot & 0xff)
1780 {
1781 case PAGE_READWRITE:
1782 case PAGE_WRITECOPY:
1785 return TRUE;
1786
1787 default:
1788 return FALSE;
1789 }
1790}
#define PAGE_WRITECOPY
Definition: nt_native.h:1308
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1312
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311

Referenced by test_section_access().

◆ is_path_made_of()

static BOOL is_path_made_of ( const char filename,
const char pfx,
const char sfx 
)
static

Definition at line 4665 of file loader.c.

4666{
4667 const size_t len = strlen(pfx);
4668 return !strncasecmp(filename, pfx, len) && filename[len] == '\\' &&
4669 !strcasecmp(filename + len + 1, sfx);
4670}
#define strncasecmp
Definition: fake.h:10
#define strcasecmp
Definition: fake.h:9
GLenum GLsizei len
Definition: glext.h:6722
const char * filename
Definition: ioapi.h:137

Referenced by test_wow64_redirection_for_dll().

◆ ldr_notify_callback()

static void CALLBACK ldr_notify_callback ( ULONG  reason,
LDR_DLL_NOTIFICATION_DATA data,
void context 
)
static

Definition at line 3465 of file loader.c.

3466{
3467 /* If some DLL happens to be loaded during process shutdown load notification is called but never unload
3468 * notification. */
3469 ok(reason == LDR_DLL_NOTIFICATION_REASON_LOADED, "got reason %lu.\n", reason);
3470}
#define LDR_DLL_NOTIFICATION_REASON_LOADED
Definition: ldrtypes.h:203

Referenced by child_process().

◆ map_image_section()

static NTSTATUS map_image_section ( const IMAGE_NT_HEADERS nt_header,
const IMAGE_SECTION_HEADER sections,
const void section_data,
int  line 
)
static

Definition at line 613 of file loader.c.

615{
616 char dll_name[MAX_PATH];
620 HANDLE file, map;
621 NTSTATUS status, expect_status, ldr_status;
623 BOOL has_code = FALSE, il_only = FALSE, want_32bit = FALSE, expect_fallback = FALSE, wrong_machine = FALSE;
624 HMODULE mod = 0, ldr_mod;
625
627
629 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
630
631 size.QuadPart = file_size;
634 expect_status = status;
635
637 {
638 /* invalid COR20 header seems to corrupt internal loader state on Windows */
639 if (get_com_dir_size( nt_header ) < sizeof(IMAGE_COR20_HEADER)) goto done;
640 if (!((const IMAGE_COR20_HEADER *)section_data)->Flags) goto done;
641 }
642
643 if (!status)
644 {
646 SIZE_T info_size = 0xdeadbeef;
647 NTSTATUS ret = pNtQuerySection( map, SectionBasicInformation, &info, sizeof(info), &info_size );
648 ok( !ret, "NtQuerySection failed err %lx\n", ret );
649 ok( info_size == sizeof(info), "NtQuerySection wrong size %Iu\n", info_size );
650 ok( info.Attributes == (SEC_IMAGE | SEC_FILE), "NtQuerySection wrong attr %lx\n", info.Attributes );
651 ok( info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", info.BaseAddress );
652 ok( info.Size.QuadPart == file_size, "NtQuerySection wrong size %lx%08lx / %08lx\n",
653 info.Size.u.HighPart, info.Size.u.LowPart, file_size );
654 has_code = query_image_section( line, dll_name, nt_header, section_data );
655
657 {
658 const IMAGE_COR20_HEADER *cor_header = section_data;
659 il_only = (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) != 0;
660 if (il_only) want_32bit = (cor_header->Flags & COMIMAGE_FLAGS_32BITREQUIRED) != 0;
661 }
662
663 SetLastError( 0xdeadbeef );
665 /* test loading dll of wrong 32/64 bitness */
668 {
669 if (!has_code && is_win64)
670 {
671 ok_(__FILE__,line)( mod != NULL || want_32bit || broken(il_only), /* <= win7 */
672 "loading failed err %lu\n", GetLastError() );
673 }
674 else
675 {
676 ok_(__FILE__, line)( !mod, "loading succeeded\n" );
677 ok_(__FILE__, line)( GetLastError() == ERROR_BAD_EXE_FORMAT, "wrong error %lu\n", GetLastError() );
679 {
680 wrong_machine = TRUE;
681 expect_status = STATUS_INVALID_IMAGE_FORMAT;
682 }
683 }
684 }
685 else
686 {
688
689 ok( mod != NULL || broken(il_only) || /* <= win7 */
690 broken( wrong_machine ), /* win8 */
691 "%u: loading failed err %lu\n", line, GetLastError() );
692 }
693 if (mod) FreeLibrary( mod );
694 expect_fallback = !mod;
695 }
696
697 /* test fallback to another dll further in the load path */
698
699 MultiByteToWideChar( CP_ACP, 0, dll_name, -1, path, MAX_PATH );
701 pRtlInitUnicodeString( &name, wldr_nameW );
702 ldr_status = pLdrLoadDll( load_path, 0, &name, &ldr_mod );
703 if (!ldr_status)
704 {
705 GetModuleFileNameW( ldr_mod, path, MAX_PATH );
707 {
708 if (!expect_status)
709 ok( !expect_fallback, "%u: got test dll but expected fallback\n", line );
710 else
711 ok( !expect_fallback, "%u: got test dll but expected failure %lx\n", line, expect_status );
712 }
713 else if (!lstrcmpiW( path, load_fallback_name ))
714 {
715 trace( "%u: loaded fallback\n", line );
716#ifdef __REACTOS__
717 ok( !expect_status || broken(is_win64) /* Broken on Vista, 8.1 x64 */, "%u: got fallback but expected failure %lx\n", line, expect_status );
718 ok( expect_fallback || broken(is_win64) /* Broken on Vista, 8.1 x64 */ ||
719#else
720 ok( !expect_status, "%u: got fallback but expected failure %lx\n", line, expect_status );
721 ok( expect_fallback ||
722#endif
723 /* win10 also falls back for 32-bit dll without code, even though it could be loaded */
724 (is_win64 && !has_code &&
726 "%u: got fallback but expected test dll\n", line );
727 }
728 else ok( 0, "%u: got unexpected path %s instead of %s\n", line, wine_dbgstr_w(path), wine_dbgstr_w(load_test_name));
729 pLdrUnloadDll( ldr_mod );
730 }
731 else if (ldr_status == STATUS_DLL_INIT_FAILED ||
732 ldr_status == STATUS_ACCESS_VIOLATION ||
733 ldr_status == STATUS_ILLEGAL_INSTRUCTION)
734 {
735 /* some dlls with invalid entry point will crash, but this means we loaded the test dll */
736#ifdef __REACTOS__
737 ok( !expect_fallback || broken(is_win64 && GetNTVersion() == _WIN32_WINNT_WIN8) /* Broken on 8.1 x64 */, "%u: got test dll but expected fallback\n", line );
738#else
739 ok( !expect_fallback, "%u: got test dll but expected fallback\n", line );
740#endif
741 }
742 else
743 {
744 ok( ldr_status == expect_status ||
745 (wrong_machine && !expect_status && ldr_status == STATUS_INVALID_IMAGE_FORMAT) ||
746 broken(il_only && !expect_status && ldr_status == STATUS_INVALID_IMAGE_FORMAT) ||
748 "%u: wrong status %lx/%lx\n", line, ldr_status, expect_status );
749 ok( !expect_fallback || wrong_machine || broken(il_only),
750 "%u: failed with %lx expected fallback\n", line, ldr_status );
751 }
752
753done:
754 if (map) CloseHandle( map );
755 CloseHandle( file );
756 DeleteFileA( dll_name );
757 return status;
758}
#define ok_(x1, x2)
Definition: atltest.h:61
LONG NTSTATUS
Definition: precomp.h:26
Definition: _map.h:48
#define STATUS_ILLEGAL_INSTRUCTION
Definition: d3dkmdt.h:41
#define SECTION_MAP_READ
Definition: compat.h:139
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:159
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4265
#define STATUS_ACCESS_VIOLATION
#define wine_dbgstr_w
Definition: kernel32.h:34
static UINT get_com_dir_size(const IMAGE_NT_HEADERS *nt)
Definition: loader.c:602
static BOOL query_image_section(int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header, const void *section_data)
Definition: loader.c:334
static DWORD create_test_dll_sections(const IMAGE_DOS_HEADER *dos_header, const IMAGE_NT_HEADERS *nt_header, const IMAGE_SECTION_HEADER *sections, const void *section_data, char dll_name[MAX_PATH])
Definition: loader.c:293
static BOOL is_win64
Definition: loader.c:55
static WORD get_alt_machine(WORD orig_machine)
Definition: loader.c:183
#define SEC_IMAGE
Definition: mmtypes.h:97
#define SEC_FILE
Definition: mmtypes.h:96
@ SectionBasicInformation
Definition: mmtypes.h:195
#define SECTION_QUERY
Definition: nt_native.h:1290
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
#define STATUS_INVALID_IMAGE_NE_FORMAT
Definition: ntstatus.h:613
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:453
#define STATUS_DLL_INIT_FAILED
Definition: ntstatus.h:652
#define IMAGE_OS2_SIGNATURE
Definition: pedump.c:90
static unsigned int file_size
Definition: regtests2xml.c:47
#define _WIN32_WINNT_WIN8
Definition: sdkddkver.h:29
Definition: parser.c:49
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define DONT_RESOLVE_DLL_REFERENCES
Definition: winbase.h:337
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:373
@ COMIMAGE_FLAGS_ILONLY
Definition: winnt_old.h:3493
@ COMIMAGE_FLAGS_32BITREQUIRED
Definition: winnt_old.h:3494
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by test_Loader().

◆ mutex_thread_proc()

static DWORD WINAPI mutex_thread_proc ( void param)
static

Definition at line 2953 of file loader.c.

2954{
2955 HANDLE wait_list[5];
2956 DWORD ret;
2957
2959 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#lx\n", ret);
2960
2961 SetEvent(param);
2962
2963 wait_list[0] = stop_event;
2964 wait_list[1] = loader_lock_event;
2965 wait_list[2] = peb_lock_event;
2966 wait_list[3] = heap_lock_event;
2967 wait_list[4] = cs_lock_event;
2968
2969 trace("%04lx: mutex_thread_proc: starting\n", GetCurrentThreadId());
2970 while (1)
2971 {
2972 ret = WaitForMultipleObjects(ARRAY_SIZE(wait_list), wait_list, FALSE, 50);
2973 if (ret == WAIT_OBJECT_0) break;
2974 else if (ret == WAIT_OBJECT_0 + 1)
2975 {
2976 ULONG_PTR loader_lock_magic;
2977 trace("%04lx: mutex_thread_proc: Entering loader lock\n", GetCurrentThreadId());
2978 ret = pLdrLockLoaderLock(0, NULL, &loader_lock_magic);
2979 ok(!ret, "LdrLockLoaderLock error %#lx\n", ret);
2982 }
2983 else if (ret == WAIT_OBJECT_0 + 2)
2984 {
2985 trace("%04lx: mutex_thread_proc: Entering PEB lock\n", GetCurrentThreadId());
2986 pRtlAcquirePebLock();
2989 }
2990 else if (ret == WAIT_OBJECT_0 + 3)
2991 {
2992 trace("%04lx: mutex_thread_proc: Entering heap lock\n", GetCurrentThreadId());
2996 }
2997 else if (ret == WAIT_OBJECT_0 + 4)
2998 {
2999 trace("%04lx: mutex_thread_proc: Entering CS lock\n", GetCurrentThreadId());
3003 }
3004 }
3005
3006 trace("%04lx: mutex_thread_proc: exiting\n", GetCurrentThreadId());
3007 return 196;
3008}
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459

Referenced by child_process().

◆ noop_thread_proc()

static DWORD WINAPI noop_thread_proc ( void param)
static

Definition at line 3030 of file loader.c.

3031{
3032 if (param)
3033 {
3034 LONG *noop_thread_started = param;
3035 InterlockedIncrement(noop_thread_started);
3036 }
3037
3038 trace("%04lx: noop_thread_proc: exiting\n", GetCurrentThreadId());
3039 return 195;
3040}

Referenced by child_process(), and dll_entry_point().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pNtCreateSection)
static

◆ PIMAGE_NT_HEADERS()

static ULONG *static PIMAGE_NT_HEADERS ( WINAPI pRtlImageNtHeader)
static

◆ PVOID()

static PVOID ( WINAPI pResolveDelayLoadedAPI)
static

◆ query_image_section()

static BOOL query_image_section ( int  id,
const char dll_name,
const IMAGE_NT_HEADERS nt_header,
const void section_data 
)
static

Definition at line 334 of file loader.c.

336{
339 const IMAGE_COR20_HEADER *cor_header = NULL;
340 SIZE_T info_size = (SIZE_T)0xdeadbeef << 16;
344 LARGE_INTEGER map_size;
345 SIZE_T max_stack, commit_stack;
346 void *entry_point;
347 BOOL truncated;
348
350 NULL, OPEN_EXISTING, 0, 0 );
351 ok( file != INVALID_HANDLE_VALUE, "%u: CreateFile error %ld\n", id, GetLastError() );
353
356 ok( !status, "%u: NtCreateSection failed err %lx\n", id, status );
357 if (status)
358 {
359 CloseHandle( file );
360 return FALSE;
361 }
362 status = pNtQuerySection( mapping, SectionImageInformation, &image, sizeof(image), &info_size );
363 ok( !status, "%u: NtQuerySection failed err %lx\n", id, status );
364 ok( info_size == sizeof(image), "%u: NtQuerySection wrong size %Iu\n", id, info_size );
367 {
372 if (!truncated &&
375 cor_header = section_data;
376 }
378 {
379 const IMAGE_NT_HEADERS64 *nt64 = (const IMAGE_NT_HEADERS64 *)nt_header;
380 max_stack = 0x100000;
381 commit_stack = 0x10000;
382 entry_point = (void *)0x81231234;
384 if (!truncated &&
387 cor_header = section_data;
388 }
389 else
390 {
391 const IMAGE_NT_HEADERS32 *nt32 = (const IMAGE_NT_HEADERS32 *)nt_header;
392 max_stack = nt32->OptionalHeader.SizeOfStackReserve;
393 commit_stack = nt32->OptionalHeader.SizeOfStackCommit;
394 entry_point = (char *)(ULONG_PTR)nt32->OptionalHeader.ImageBase + nt32->OptionalHeader.AddressOfEntryPoint;
396 if (!truncated &&
399 cor_header = section_data;
400 }
401 ok( (char *)image.TransferAddress == (char *)entry_point ||
402 (image.ImageDynamicallyRelocated && LOWORD(image.TransferAddress) == LOWORD(entry_point)),
403 "%u: TransferAddress wrong %p / %p (%08lx)\n", id,
404 image.TransferAddress, entry_point, nt_header->OptionalHeader.AddressOfEntryPoint );
405 ok( image.ZeroBits == 0, "%u: ZeroBits wrong %08lx\n", id, image.ZeroBits );
406 ok( image.MaximumStackSize == max_stack,
407 "%u: MaximumStackSize wrong %Ix / %Ix\n", id, image.MaximumStackSize, max_stack );
408 ok( image.CommittedStackSize == commit_stack,
409 "%u: CommittedStackSize wrong %Ix / %Ix\n", id, image.CommittedStackSize, commit_stack );
410 ok( image.SubSystemType == nt_header->OptionalHeader.Subsystem,
411 "%u: SubSystemType wrong %08lx / %08x\n", id,
412 image.SubSystemType, nt_header->OptionalHeader.Subsystem );
413 ok( image.MinorSubsystemVersion == nt_header->OptionalHeader.MinorSubsystemVersion,
414 "%u: MinorSubsystemVersion wrong %04x / %04x\n", id,
415 image.MinorSubsystemVersion, nt_header->OptionalHeader.MinorSubsystemVersion );
416 ok( image.MajorSubsystemVersion == nt_header->OptionalHeader.MajorSubsystemVersion,
417 "%u: MajorSubsystemVersion wrong %04x / %04x\n", id,
418 image.MajorSubsystemVersion, nt_header->OptionalHeader.MajorSubsystemVersion );
419 ok( image.MajorOperatingSystemVersion == nt_header->OptionalHeader.MajorOperatingSystemVersion ||
420 broken( !image.MajorOperatingSystemVersion), /* before win10 */
421 "%u: MajorOperatingSystemVersion wrong %04x / %04x\n", id,
422 image.MajorOperatingSystemVersion, nt_header->OptionalHeader.MajorOperatingSystemVersion );
423 ok( image.MinorOperatingSystemVersion == nt_header->OptionalHeader.MinorOperatingSystemVersion,
424 "%u: MinorOperatingSystemVersion wrong %04x / %04x\n", id,
425 image.MinorOperatingSystemVersion, nt_header->OptionalHeader.MinorOperatingSystemVersion );
426 ok( image.ImageCharacteristics == nt_header->FileHeader.Characteristics,
427 "%u: ImageCharacteristics wrong %04x / %04x\n", id,
428 image.ImageCharacteristics, nt_header->FileHeader.Characteristics );
429 ok( image.DllCharacteristics == nt_header->OptionalHeader.DllCharacteristics,
430 "%u: DllCharacteristics wrong %04x / %04x\n", id,
431 image.DllCharacteristics, nt_header->OptionalHeader.DllCharacteristics );
432 ok( image.Machine == nt_header->FileHeader.Machine, "%u: Machine wrong %04x / %04x\n", id,
433 image.Machine, nt_header->FileHeader.Machine );
434 ok( image.LoaderFlags == (cor_header != NULL), "%u: LoaderFlags wrong %08lx\n", id, image.LoaderFlags );
435 ok( image.ImageFileSize == file_size,
436 "%u: ImageFileSize wrong %08lx / %08lx\n", id, image.ImageFileSize, file_size );
438 "%u: CheckSum wrong %08lx / %08lx\n", id,
440
442 ok( image.ImageContainsCode == TRUE, "%u: ImageContainsCode wrong %u\n", id,
443 image.ImageContainsCode );
446 (section.Characteristics & IMAGE_SCN_MEM_EXECUTE)))
447 ok( image.ImageContainsCode == TRUE || broken(!image.ImageContainsCode), /* <= win8 */
448 "%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode );
449 else
450 ok( !image.ImageContainsCode, "%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode );
451
452 if (cor_header &&
453 (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) &&
454 (cor_header->MajorRuntimeVersion > 2 ||
455 (cor_header->MajorRuntimeVersion == 2 && cor_header->MinorRuntimeVersion >= 5)))
456 {
457#ifdef __REACTOS__
458 ok( image.ComPlusILOnly || broken(GetNTVersion() < _WIN32_WINNT_VISTA),
459#else
460 ok( image.ComPlusILOnly,
461#endif
462 "%u: wrong ComPlusILOnly flags %02x\n", id, image.ImageFlags );
464 !(cor_header->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
465#ifdef __REACTOS__
466 ok( image.ComPlusNativeReady || broken(GetNTVersion() < _WIN32_WINNT_VISTA),
467#else
468 ok( image.ComPlusNativeReady,
469#endif
470 "%u: wrong ComPlusNativeReady flags %02x\n", id, image.ImageFlags );
471 else
472 ok( !image.ComPlusNativeReady,
473 "%u: wrong ComPlusNativeReady flags %02x\n", id, image.ImageFlags );
475 (cor_header->Flags & COMIMAGE_FLAGS_32BITPREFERRED))
476 ok( image.ComPlusPrefer32bit ||
477 broken( !image.MajorOperatingSystemVersion ), /* before win10 */
478 "%u: wrong ComPlusPrefer32bit flags %02x\n", id, image.ImageFlags );
479 else
480 ok( !image.ComPlusPrefer32bit, "%u: wrong ComPlusPrefer32bit flags %02x\n", id, image.ImageFlags );
481 }
482 else
483 {
484 ok( !image.ComPlusILOnly, "%u: wrong ComPlusILOnly flags %02x\n", id, image.ImageFlags );
485 ok( !image.ComPlusNativeReady, "%u: wrong ComPlusNativeReady flags %02x\n", id, image.ImageFlags );
486 ok( !image.ComPlusPrefer32bit, "%u: wrong ComPlusPrefer32bit flags %02x\n", id, image.ImageFlags );
487 }
489 ok( !image.ImageMappedFlat, "%u: wrong ImageMappedFlat flags %02x\n", id, image.ImageFlags );
490 else
491#ifdef __REACTOS__
492 ok( image.ImageMappedFlat || broken(GetNTVersion() < _WIN32_WINNT_VISTA),
493#else
494 ok( image.ImageMappedFlat,
495#endif
496 "%u: wrong ImageMappedFlat flags %02x\n", id, image.ImageFlags );
497
499 ok( !image.ImageDynamicallyRelocated || broken( image.ComPlusILOnly ), /* <= win7 */
500 "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, image.ImageFlags );
501 else if (image.ImageContainsCode && !image.ImageMappedFlat && !cor_header)
502#ifdef __REACTOS__
503 ok( image.ImageDynamicallyRelocated || broken(GetNTVersion() < _WIN32_WINNT_VISTA),
504#else
505 ok( image.ImageDynamicallyRelocated,
506#endif
507 "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, image.ImageFlags );
508 else
509 ok( !image.ImageDynamicallyRelocated || broken(TRUE), /* <= win8 */
510 "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, image.ImageFlags );
511 ok( !image.BaseBelow4gb, "%u: wrong BaseBelow4gb flags %02x\n", id, image.ImageFlags );
512
513 map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1);
514 status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
515 ok( !status, "NtQuerySection failed err %lx\n", status );
516 ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %lx%08lx / %lx%08lx\n",
517 info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
519
520 map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1);
522 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
523 ok( !status, "%u: NtCreateSection failed err %lx\n", id, status );
524 status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
525 ok( !status, "NtQuerySection failed err %lx\n", status );
526 ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %lx%08lx / %lx%08lx\n",
527 info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
529
530 map_size.QuadPart++;
532 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
533 ok( status == STATUS_SECTION_TOO_BIG, "%u: NtCreateSection failed err %lx\n", id, status );
534
535 SetFilePointerEx( file, map_size, NULL, FILE_BEGIN );
538 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
539 ok( status == STATUS_SECTION_TOO_BIG, "%u: NtCreateSection failed err %lx\n", id, status );
540
541 map_size.QuadPart = 1;
543 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
544 ok( !status, "%u: NtCreateSection failed err %lx\n", id, status );
545 status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
546 ok( !status, "NtQuerySection failed err %lx\n", status );
547 ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %lx%08lx / %lx%08lx\n",
548 info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
550
551 CloseHandle( file );
552 return image.ImageContainsCode && (!cor_header || !(cor_header->Flags & COMIMAGE_FLAGS_ILONLY));
553}
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
struct _IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER32
GLeglImageOES image
Definition: gl.h:2204
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
if(dx< 0)
Definition: linetemp.h:194
static void SIZE_T
Definition: loader.c:62
@ SectionImageInformation
Definition: mmtypes.h:196
struct _IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER64
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
Definition: ntimage.h:455
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:394
#define LOWORD(l)
Definition: pedump.c:82
IMAGE_OPTIONAL_HEADER64 OptionalHeader
Definition: ntimage.h:396
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
WORD MinorOperatingSystemVersion
Definition: ntddk_ex.h:161
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2502 u
@ COMIMAGE_FLAGS_32BITPREFERRED
Definition: winnt_old.h:3499

Referenced by map_image_section(), and test_Loader().

◆ RVAToAddr()

static void void **static PVOID RVAToAddr ( DWORD_PTR  rva,
HMODULE  module 
)
static

Definition at line 95 of file loader.c.

96{
97 if (rva == 0)
98 return NULL;
99 return ((char*) module) + rva;
100}

Referenced by test_ImportDescriptors(), and test_ResolveDelayLoadedAPI().

◆ semaphore_thread_proc()

static DWORD WINAPI semaphore_thread_proc ( void param)
static

Definition at line 3010 of file loader.c.

3011{
3012 DWORD ret;
3013
3015 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#lx\n", ret);
3016
3017 SetEvent(param);
3018
3019 while (1)
3020 {
3021 if (winetest_debug > 1)
3022 trace("%04lx: semaphore_thread_proc: still alive\n", GetCurrentThreadId());
3023 if (WaitForSingleObject(stop_event, 50) != WAIT_TIMEOUT) break;
3024 }
3025
3026 trace("%04lx: semaphore_thread_proc: exiting\n", GetCurrentThreadId());
3027 return 196;
3028}
int winetest_debug

Referenced by child_process().

◆ START_TEST()

START_TEST ( loader  )

Definition at line 4819 of file loader.c.

4820{
4821 int argc;
4822 char **argv;
4823 HANDLE ntdll, mapping, kernel32;
4825 DWORD len;
4826
4827 ntdll = GetModuleHandleA("ntdll.dll");
4828 kernel32 = GetModuleHandleA("kernel32.dll");
4829 pNtCreateSection = (void *)GetProcAddress(ntdll, "NtCreateSection");
4830 pNtQuerySection = (void *)GetProcAddress(ntdll, "NtQuerySection");
4831 pNtMapViewOfSection = (void *)GetProcAddress(ntdll, "NtMapViewOfSection");
4832 pNtUnmapViewOfSection = (void *)GetProcAddress(ntdll, "NtUnmapViewOfSection");
4833 pNtTerminateProcess = (void *)GetProcAddress(ntdll, "NtTerminateProcess");
4834 pNtQueryInformationProcess = (void *)GetProcAddress(ntdll, "NtQueryInformationProcess");
4835 pNtSetInformationProcess = (void *)GetProcAddress(ntdll, "NtSetInformationProcess");
4836 pLdrShutdownProcess = (void *)GetProcAddress(ntdll, "LdrShutdownProcess");
4837 pRtlDllShutdownInProgress = (void *)GetProcAddress(ntdll, "RtlDllShutdownInProgress");
4838 pNtAllocateVirtualMemory = (void *)GetProcAddress(ntdll, "NtAllocateVirtualMemory");
4839 pNtFreeVirtualMemory = (void *)GetProcAddress(ntdll, "NtFreeVirtualMemory");
4840 pLdrLockLoaderLock = (void *)GetProcAddress(ntdll, "LdrLockLoaderLock");
4841 pLdrUnlockLoaderLock = (void *)GetProcAddress(ntdll, "LdrUnlockLoaderLock");
4842 pLdrLoadDll = (void *)GetProcAddress(ntdll, "LdrLoadDll");
4843 pLdrUnloadDll = (void *)GetProcAddress(ntdll, "LdrUnloadDll");
4844 pRtlInitUnicodeString = (void *)GetProcAddress(ntdll, "RtlInitUnicodeString");
4845 pRtlAcquirePebLock = (void *)GetProcAddress(ntdll, "RtlAcquirePebLock");
4846 pRtlReleasePebLock = (void *)GetProcAddress(ntdll, "RtlReleasePebLock");
4847 pRtlImageDirectoryEntryToData = (void *)GetProcAddress(ntdll, "RtlImageDirectoryEntryToData");
4848 pRtlImageNtHeader = (void *)GetProcAddress(ntdll, "RtlImageNtHeader");
4849 pLdrRegisterDllNotification = (void *)GetProcAddress(ntdll, "LdrRegisterDllNotification");
4850 pFlsAlloc = (void *)GetProcAddress(kernel32, "FlsAlloc");
4851 pFlsSetValue = (void *)GetProcAddress(kernel32, "FlsSetValue");
4852 pFlsGetValue = (void *)GetProcAddress(kernel32, "FlsGetValue");
4853 pFlsFree = (void *)GetProcAddress(kernel32, "FlsFree");
4854 pIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process");
4855 pWow64DisableWow64FsRedirection = (void *)GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection");
4856 pWow64RevertWow64FsRedirection = (void *)GetProcAddress(kernel32, "Wow64RevertWow64FsRedirection");
4857 pResolveDelayLoadedAPI = (void *)GetProcAddress(kernel32, "ResolveDelayLoadedAPI");
4858 pLoadPackagedLibrary = (void *)GetProcAddress(kernel32, "LoadPackagedLibrary");
4859
4860 if (pIsWow64Process) pIsWow64Process( GetCurrentProcess(), &is_wow64 );
4861 GetSystemInfo( &si );
4864 dos_header.e_lfanew = sizeof(dos_header);
4865
4866 mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_loader");
4867 ok(mapping != 0, "CreateFileMapping failed\n");
4869 if (*child_failures == -1)
4870 {
4871 *child_failures = 0;
4872 }
4873 else
4874 *child_failures = -1;
4875
4877 if (argc > 4)
4878 {
4879 test_dll_phase = atoi(argv[4]);
4880 child_process(argv[2], atol(argv[3]));
4881 return;
4882 }
4883
4885 ok(len && len < ARRAY_SIZE(system_dir), "Couldn't get system directory: %lu\n", GetLastError());
4886 if (is_wow64)
4887 {
4889 ok(len && len < ARRAY_SIZE(syswow_dir), "Couldn't get wow directory: %lu\n", GetLastError());
4890 }
4891
4902 test_dll_file( "ntdll.dll" );
4903 test_dll_file( "kernel32.dll" );
4904 test_dll_file( "advapi32.dll" );
4905 test_dll_file( "user32.dll" );
4907 /* loader test must be last, it can corrupt the internal loader state on Windows */
4908 test_Loader();
4909}
static int argc
Definition: ServiceArgs.c:12
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FILE_MAP_READ
Definition: compat.h:776
#define MapViewOfFile
Definition: compat.h:745
UINT WINAPI GetSystemWow64DirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2438
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
_ACRTIMP __msvcrt_long __cdecl atol(const char *)
Definition: string.c:1782
_ACRTIMP int __cdecl atoi(const char *)
Definition: string.c:1715
HANDLE NTAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCSTR lpName)
Definition: filemap.c:23
static HMODULE ntdll
Definition: debugger.c:59
static void test_LoadPackagedLibrary(void)
Definition: loader.c:4775
static void test_ImportDescriptors(void)
Definition: loader.c:1619
static void test_export_forwarder_dep_chain(void)
Definition: loader.c:2920
static char system_dir[MAX_PATH]
Definition: loader.c:57
static char syswow_dir[MAX_PATH]
Definition: loader.c:58
static BOOL is_wow64
Definition: loader.c:56
static void test_dll_file(const char *name)
Definition: loader.c:4734
static void test_ExitProcess(void)
Definition: loader.c:3788
static void test_ResolveDelayLoadedAPI(void)
Definition: loader.c:4351
static void test_Loader(void)
Definition: loader.c:761
static void test_section_access(void)
Definition: loader.c:1920
static void test_InMemoryOrderModuleList(void)
Definition: loader.c:4644
static void test_filenames(void)
Definition: loader.c:1539
static void test_import_resolution(void)
Definition: loader.c:2182
static void test_wow64_redirection(void)
Definition: loader.c:4702
static void test_Wow64Transition(void)
Definition: loader.c:4791
static SYSTEM_INFO si
Definition: virtual.c:39
static HANDLE child_process
Definition: cursoricon.c:300
#define argv
Definition: mplay32.c:18
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
int winetest_get_mainargs(char ***pargv)
DWORD dwPageSize
Definition: winbase.h:898
#define FILE_MAP_WRITE
Definition: winbase.h:156

◆ subtest_export_forwarder_dep_chain()

static void subtest_export_forwarder_dep_chain ( size_t  num_chained_export_modules,
size_t  exporter_index,
BOOL  test_static_import 
)
static

Definition at line 2757 of file loader.c.

2760{
2761 size_t num_modules = num_chained_export_modules + !!test_static_import;
2762 size_t importer_index = test_static_import ? num_modules - 1 : 0;
2763 DWORD imp_thunk_base_rva, exp_func_base_rva;
2764 size_t ultimate_depender_index = 0; /* latest module depending on modules earlier in chain */
2765 char temp_paths[4][MAX_PATH];
2766 HANDLE temp_files[4];
2767 UINT_PTR exports[2];
2768 HMODULE modules[4];
2769 BOOL res;
2770 size_t i;
2771
2772 assert(exporter_index < num_chained_export_modules);
2773 assert(num_modules > 1);
2774 assert(num_modules <= ARRAY_SIZE(temp_paths));
2775 assert(num_modules <= ARRAY_SIZE(temp_files));
2776 assert(num_modules <= ARRAY_SIZE(modules));
2777
2778 if (winetest_debug > 1)
2779 trace( "Generate a chain of test DLL fixtures\n" );
2780
2781 for (i = 0; i < num_modules; i++)
2782 {
2783 temp_files[i] = gen_forward_chain_testdll( temp_paths[i],
2784 i >= 1 ? temp_paths[i - 1] : NULL,
2785 i < num_chained_export_modules,
2786 importer_index && i == importer_index,
2787 i == 0 ? &exp_func_base_rva : NULL,
2788 i == importer_index ? &imp_thunk_base_rva : NULL );
2789 }
2790
2791 if (winetest_debug > 1)
2792 trace( "Load the entire test DLL chain\n" );
2793
2794 for (i = 0; i < num_modules; i++)
2795 {
2797
2798 ok( !GetModuleHandleA( temp_paths[i] ), "%s already loaded\n",
2799 wine_dbgstr_a( temp_paths[i] ) );
2800
2801 modules[i] = LoadLibraryA( temp_paths[i] );
2802 ok( !!modules[i], "LoadLibraryA(temp_paths[%Iu] = %s) err=%lu\n",
2803 i, wine_dbgstr_a( temp_paths[i] ), GetLastError() );
2804
2805 if (i == importer_index)
2806 {
2807 /* Statically importing export forwarder introduces a load-time dependency */
2808 ultimate_depender_index = max( ultimate_depender_index, importer_index );
2809 }
2810
2811 module = GetModuleHandleA( temp_paths[i] );
2812 ok( module == modules[i], "modules[%Iu] expected %p, got %p err=%lu\n",
2813 i, modules[i], module, GetLastError() );
2814 }
2815
2816 if (winetest_debug > 1)
2817 trace( "Get address of exported functions from the source module\n" );
2818
2819 for (i = 0; i < ARRAY_SIZE(exports); i++)
2820 {
2821 char *mod_base = (char *)modules[0]; /* source (non-forward) DLL */
2822 exports[i] = (UINT_PTR)(mod_base + ((DWORD *)(mod_base + exp_func_base_rva))[i]);
2823 }
2824
2825 if (winetest_debug > 1)
2826 trace( "Check import address table of the importer DLL, if any\n" );
2827
2828 if (importer_index)
2829 {
2830 UINT_PTR *imp_thunk_base = (UINT_PTR *)((char *)modules[importer_index] + imp_thunk_base_rva);
2831 for (i = 0; i < ARRAY_SIZE(exports); i++)
2832 {
2833 ok( imp_thunk_base[i] == exports[i], "import thunk mismatch [%Iu]: (%#Ix, %#Ix)\n",
2834 i, imp_thunk_base[i], exports[i] );
2835 }
2836 }
2837
2838 if (winetest_debug > 1)
2839 trace( "Call GetProcAddress() on the exporter DLL, if any\n" );
2840
2841 if (exporter_index)
2842 {
2843 UINT_PTR proc;
2844
2845 proc = (UINT_PTR)GetProcAddress( modules[exporter_index], "forward_test_func" );
2846 ok( proc == exports[0], "GetProcAddress mismatch [0]: (%#Ix, %#Ix)\n", proc, exports[0] );
2847
2848 proc = (UINT_PTR)GetProcAddress( modules[exporter_index], (LPSTR)2 );
2849 ok( proc == exports[1], "GetProcAddress mismatch [1]: (%#Ix, %#Ix)\n", proc, exports[1] );
2850
2851 /* Dynamically importing export forwarder introduces a runtime dependency */
2852 ultimate_depender_index = max( ultimate_depender_index, exporter_index );
2853 }
2854
2855 if (winetest_debug > 1)
2856 trace( "Unreference modules except the ultimate dependant DLL\n" );
2857
2858 for (i = 0; i < ultimate_depender_index; i++)
2859 {
2861
2862 res = FreeLibrary( modules[i] );
2863 ok( res, "FreeLibrary(modules[%Iu]) err=%lu\n", i, GetLastError() );
2864
2865 /* FreeLibrary() should *not* unload the DLL immediately */
2866 module = GetModuleHandleA( temp_paths[i] );
2867 todo_wine_if(i < ultimate_depender_index && i + 1 != importer_index)
2868 ok( module == modules[i], "modules[%Iu] expected %p, got %p (unloaded?) err=%lu\n",
2869 i, modules[i], module, GetLastError() );
2870 }
2871
2872 if (winetest_debug > 1)
2873 trace( "The ultimate dependant DLL should keep other DLLs from being unloaded\n" );
2874
2875 for (i = 0; i < num_modules; i++)
2876 {
2877 HMODULE module = GetModuleHandleA( temp_paths[i] );
2878
2879 todo_wine_if(i < ultimate_depender_index && i + 1 != importer_index)
2880 ok( module == modules[i], "modules[%Iu] expected %p, got %p (unloaded?) err=%lu\n",
2881 i, modules[i], module, GetLastError() );
2882 }
2883
2884 if (winetest_debug > 1)
2885 trace( "Unreference the remaining modules (including the dependant DLL)\n" );
2886
2887 for (i = ultimate_depender_index; i < num_modules; i++)
2888 {
2889 res = FreeLibrary( modules[i] );
2890 ok( res, "FreeLibrary(modules[%Iu]) err=%lu\n", i, GetLastError() );
2891
2892 /* FreeLibrary() should unload the DLL immediately */
2893 ok( !GetModuleHandleA( temp_paths[i] ), "modules[%Iu] should not be kept loaded (2)\n", i );
2894 }
2895
2896 if (winetest_debug > 1)
2897 trace( "All modules should be unloaded; the unloading process should not reload any DLL\n" );
2898
2899#ifdef __REACTOS__
2901#endif
2902 for (i = 0; i < num_modules; i++)
2903 {
2904 ok( !GetModuleHandleA( temp_paths[i] ), "modules[%Iu] should not be kept loaded (3)\n", i );
2905 }
2906#ifdef __REACTOS__
2907 }
2908#endif
2909
2910 if (winetest_debug > 1)
2911 trace( "Close and delete temp files\n" );
2912
2913 for (i = 0; i < num_modules; i++)
2914 {
2915 /* handles should be delete-on-close */
2917 }
2918}
static HANDLE gen_forward_chain_testdll(char testdll_path[MAX_PATH], const char source_dll[MAX_PATH], BOOL is_export, BOOL is_import, DWORD *exp_func_base_rva, DWORD *imp_thunk_base_rva)
Definition: loader.c:2502
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
static HANDLE proc()
Definition: pdb.c:34
struct strarray temp_files
Definition: widl.c:133
#define max(a, b)
Definition: svc.c:63
char * LPSTR
Definition: xmlstorage.h:182

Referenced by test_export_forwarder_dep_chain().

◆ test_dll_file()

static void test_dll_file ( const char name)
static

Definition at line 4734 of file loader.c.

4735{
4737 IMAGE_NT_HEADERS *nt, *nt_file;
4738 IMAGE_SECTION_HEADER *sec, *sec_file;
4739 char path[MAX_PATH];
4741 int i = 0;
4742 void *ptr;
4743
4746 ok( file != INVALID_HANDLE_VALUE, "can't open '%s': %lu\n", path, GetLastError() );
4747
4749 ok( mapping != NULL, "%s: CreateFileMappingW failed err %lu\n", name, GetLastError() );
4750 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
4751 ok( ptr != NULL, "%s: MapViewOfFile failed err %lu\n", name, GetLastError() );
4753 CloseHandle( file );
4754
4755 nt = pRtlImageNtHeader( module );
4756 nt_file = pRtlImageNtHeader( ptr );
4757 ok( nt_file != NULL, "%s: invalid header\n", path );
4758#define OK_FIELD(x, f) ok( nt->x == nt_file->x, "%s:%u: wrong " #x " " f " / " f "\n", name, i, nt->x, nt_file->x )
4759 OK_FIELD( FileHeader.NumberOfSections, "%x" );
4760 OK_FIELD( OptionalHeader.AddressOfEntryPoint, "%lx" );
4761 OK_FIELD( OptionalHeader.NumberOfRvaAndSizes, "%lx" );
4762 for (i = 0; i < nt->OptionalHeader.NumberOfRvaAndSizes; i++)
4763 {
4764 OK_FIELD( OptionalHeader.DataDirectory[i].VirtualAddress, "%lx" );
4765 OK_FIELD( OptionalHeader.DataDirectory[i].Size, "%lx" );
4766 }
4767 sec = IMAGE_FIRST_SECTION( nt );
4768 sec_file = IMAGE_FIRST_SECTION( nt_file );
4769 for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
4770 ok( !memcmp( sec + i, sec_file + i, sizeof(*sec) ), "%s: wrong section %d\n", name, i );
4772#undef OK_FIELD
4773}
#define UnmapViewOfFile
Definition: compat.h:746
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
static PVOID ptr
Definition: dispmode.c:27
#define OK_FIELD(x, f)
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427

Referenced by START_TEST().

◆ test_ExitProcess()

static void test_ExitProcess ( void  )
static

Definition at line 3788 of file loader.c.

3789{
3790#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
3791#include "pshpack1.h"
3792#ifdef __x86_64__
3793 static struct section_data
3794 {
3795 BYTE mov_rax[2];
3796 void *target;
3797 BYTE jmp_rax[2];
3798 } section_data = { { 0x48,0xb8 }, dll_entry_point, { 0xff,0xe0 } };
3799#elif defined(__i386__)
3800 static struct section_data
3801 {
3802 BYTE mov_eax;
3803 void *target;
3804 BYTE jmp_eax[2];
3805 } section_data = { 0xb8, dll_entry_point, { 0xff,0xe0 } };
3806#elif defined(__aarch64__)
3807 static struct section_data
3808 {
3809 DWORD ldr; /* ldr x0,target */
3810 DWORD br; /* br x0 */
3811 void *target;
3812 } section_data = { 0x58000040, 0xd61f0000, dll_entry_point };
3813#endif
3814#include "poppack.h"
3815 DWORD dummy, file_align;
3816 HANDLE file, thread, process, hmap, hmap_dup;
3817 char temp_path[MAX_PATH], dll_name[MAX_PATH], cmdline[MAX_PATH * 2];
3818 DWORD ret, target_offset, old_prot;
3819 char **argv, buf[256];
3821 STARTUPINFOA si = { sizeof(si) };
3822 CONTEXT ctx;
3826 void *addr;
3828 SIZE_T size;
3830
3831 if (!pRtlDllShutdownInProgress)
3832 {
3833 win_skip("RtlDllShutdownInProgress is not available on this platform (XP+)\n");
3834 return;
3835 }
3836 if (!pNtQueryInformationProcess || !pNtSetInformationProcess)
3837 {
3838 win_skip("NtQueryInformationProcess/NtSetInformationProcess are not available on this platform\n");
3839 return;
3840 }
3841 if (!pNtAllocateVirtualMemory || !pNtFreeVirtualMemory)
3842 {
3843 win_skip("NtAllocateVirtualMemory/NtFreeVirtualMemory are not available on this platform\n");
3844 return;
3845 }
3846
3847 /* prevent displaying of the "Unable to load this DLL" message box */
3849
3851 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
3852
3853 /*trace("creating %s\n", dll_name);*/
3854 file = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
3856 {
3857 ok(0, "could not create %s\n", dll_name);
3858 return;
3859 }
3860
3861 SetLastError(0xdeadbeef);
3862 ret = WriteFile(file, &dos_header, sizeof(dos_header), &dummy, NULL);
3863 ok(ret, "WriteFile error %ld\n", GetLastError());
3864
3869 nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x1000;
3871 SetLastError(0xdeadbeef);
3872 ret = WriteFile(file, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
3873 ok(ret, "WriteFile error %ld\n", GetLastError());
3874 SetLastError(0xdeadbeef);
3876 ok(ret, "WriteFile error %ld\n", GetLastError());
3877
3878 section.SizeOfRawData = sizeof(section_data);
3879 section.PointerToRawData = nt_header.OptionalHeader.FileAlignment;
3881 section.Misc.VirtualSize = sizeof(section_data);
3883 SetLastError(0xdeadbeef);
3884 ret = WriteFile(file, &section, sizeof(section), &dummy, NULL);
3885 ok(ret, "WriteFile error %ld\n", GetLastError());
3886
3888 assert(file_align < sizeof(filler));
3889 SetLastError(0xdeadbeef);
3890 ret = WriteFile(file, filler, file_align, &dummy, NULL);
3891 ok(ret, "WriteFile error %ld\n", GetLastError());
3892
3893 target_offset = SetFilePointer(file, 0, NULL, FILE_CURRENT) + FIELD_OFFSET(struct section_data, target);
3894
3895 /* section data */
3896 SetLastError(0xdeadbeef);
3898 ok(ret, "WriteFile error %ld\n", GetLastError());
3899
3901
3903
3904 /* phase 0 */
3905 *child_failures = -1;
3906 sprintf(cmdline, "\"%s\" loader %s %lu 0", argv[0], dll_name, target_offset);
3907 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3908 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
3910 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3913#ifdef __REACTOS__
3914 ok(ret == 195 || broken(ret == 0xc0000005) /* WS03 */, "expected exit code 195, got %lu\n", ret);
3915#else
3916 ok(ret == 195, "expected exit code 195, got %lu\n", ret);
3917#endif
3918 if (*child_failures)
3919 {
3920 trace("%ld failures in child process\n", *child_failures);
3922 }
3925
3926 /* phase 1 */
3927 *child_failures = -1;
3928 sprintf(cmdline, "\"%s\" loader %s %lu 1", argv[0], dll_name, target_offset);
3929 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3930 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
3932 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3935 ok(ret == 195, "expected exit code 195, got %lu\n", ret);
3936 if (*child_failures)
3937 {
3938 trace("%ld failures in child process\n", *child_failures);
3940 }
3943
3944 /* phase 2 */
3945 *child_failures = -1;
3946 sprintf(cmdline, "\"%s\" loader %s %lu 2", argv[0], dll_name, target_offset);
3947 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3948 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
3950 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3953 ok(ret == 197, "expected exit code 197, got %lu\n", ret);
3954 if (*child_failures)
3955 {
3956 trace("%ld failures in child process\n", *child_failures);
3958 }
3961
3962 /* phase 3 */
3963 *child_failures = -1;
3964 sprintf(cmdline, "\"%s\" loader %s %lu 3", argv[0], dll_name, target_offset);
3965 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3966 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
3968 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3971 ok(ret == 195, "expected exit code 195, got %lu\n", ret);
3972 if (*child_failures)
3973 {
3974 trace("%ld failures in child process\n", *child_failures);
3976 }
3979
3980 /* phase 4 */
3981 if (pLdrLockLoaderLock && pLdrUnlockLoaderLock)
3982 {
3983 *child_failures = -1;
3984 sprintf(cmdline, "\"%s\" loader %s %lu 4", argv[0], dll_name, target_offset);
3985 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3986 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
3988 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3991 ok(ret == 198, "expected exit code 198, got %lu\n", ret);
3992 if (*child_failures)
3993 {
3994 trace("%ld failures in child process\n", *child_failures);
3996 }
3999 }
4000 else
4001 win_skip("LdrLockLoaderLock/LdrUnlockLoaderLock are not available on this platform\n");
4002
4003 /* phase 5 */
4004 if (pRtlAcquirePebLock && pRtlReleasePebLock)
4005 {
4006 *child_failures = -1;
4007 sprintf(cmdline, "\"%s\" loader %s %lu 5", argv[0], dll_name, target_offset);
4008 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
4009 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
4011 ok(ret == WAIT_TIMEOUT, "child process should fail to terminate\n");
4012 if (ret != WAIT_OBJECT_0)
4013 {
4014 trace("terminating child process\n");
4016 }
4018 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
4020 ok(ret == 199, "expected exit code 199, got %lu\n", ret);
4021 if (*child_failures)
4022 {
4023 trace("%ld failures in child process\n", *child_failures);
4025 }
4028 }
4029 else
4030 win_skip("RtlAcquirePebLock/RtlReleasePebLock are not available on this platform\n");
4031
4032 /* phase 6 */
4033 *child_failures = -1;
4034 sprintf(cmdline, "\"%s\" loader %s %lu 6", argv[0], dll_name, target_offset);
4035 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
4036 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
4038 todo_wine
4039#ifdef __REACTOS__
4040 ok(ret == WAIT_TIMEOUT || broken(ret == WAIT_OBJECT_0) /* WS03 */, "child process should fail to terminate\n");
4041#else
4042 ok(ret == WAIT_TIMEOUT, "child process should fail to terminate\n");
4043#endif
4044 if (ret != WAIT_OBJECT_0)
4045 {
4046 trace("terminating child process\n");
4048 }
4050 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
4052 todo_wine
4053#ifdef __REACTOS__
4054 ok(ret == 201 || broken(ret == 1) /* WS03 */, "expected exit code 201, got %lu\n", ret);
4055#else
4056 ok(ret == 201, "expected exit code 201, got %lu\n", ret);
4057#endif
4058 if (*child_failures)
4059 {
4060 trace("%ld failures in child process\n", *child_failures);
4062 }
4065
4066 /* phase 7 */
4067 *child_failures = -1;
4068 sprintf(cmdline, "\"%s\" loader %s %lu 7", argv[0], dll_name, target_offset);
4069 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
4070 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
4072 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
4073 if (ret != WAIT_OBJECT_0)
4074 {
4075 trace("terminating child process\n");
4077 }
4079 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
4081 ok(ret == 199, "expected exit code 199, got %lu\n", ret);
4082 if (*child_failures)
4083 {
4084 trace("%ld failures in child process\n", *child_failures);
4086 }
4089
4090 /* test remote process termination */
4091 SetLastError(0xdeadbeef);
4093 ok(ret, "CreateProcess(%s) error %ld\n", argv[0], GetLastError());
4094
4095 SetLastError(0xdeadbeef);
4097 ok(addr != NULL, "VirtualAllocEx error %ld\n", GetLastError());
4098 SetLastError(0xdeadbeef);
4099 ret = VirtualProtectEx(pi.hProcess, addr, 4096, PAGE_READONLY, &old_prot);
4100 ok(ret, "VirtualProtectEx error %ld\n", GetLastError());
4101 ok(old_prot == PAGE_READWRITE, "expected PAGE_READWRITE, got %#lx\n", old_prot);
4102 SetLastError(0xdeadbeef);
4103 size = VirtualQueryEx(pi.hProcess, NULL, &mbi, sizeof(mbi));
4104 ok(size == sizeof(mbi), "VirtualQueryEx error %ld\n", GetLastError());
4105
4106 SetLastError(0xdeadbeef);
4108 ok(ret, "ReadProcessMemory error %ld\n", GetLastError());
4109 ok(size == 4, "expected 4, got %Iu\n", size);
4110
4111 SetLastError(0xdeadbeef);
4113 ok(hmap != 0, "CreateFileMapping error %ld\n", GetLastError());
4114
4115 SetLastError(0xdeadbeef);
4116 ret = DuplicateHandle(GetCurrentProcess(), hmap, pi.hProcess, &hmap_dup,
4118 ok(ret, "DuplicateHandle error %ld\n", GetLastError());
4119
4120 offset.u.LowPart = 0;
4121 offset.u.HighPart = 0;
4122 addr = NULL;
4123 size = 0;
4124 ret = pNtMapViewOfSection(hmap, pi.hProcess, &addr, 0, 0, &offset,
4125 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
4126 ok(!ret, "NtMapViewOfSection error %#lx\n", ret);
4127 ret = pNtUnmapViewOfSection(pi.hProcess, addr);
4128 ok(!ret, "NtUnmapViewOfSection error %#lx\n", ret);
4129
4130 SetLastError(0xdeadbeef);
4131 thread = CreateRemoteThread(pi.hProcess, NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret);
4132 ok(thread != 0, "CreateRemoteThread error %ld\n", GetLastError());
4133 SetLastError(0xdeadbeef);
4134 ctx.ContextFlags = CONTEXT_INTEGER;
4136 ok(ret, "GetThreadContext error %ld\n", GetLastError());
4137 SetLastError(0xdeadbeef);
4138 ctx.ContextFlags = CONTEXT_INTEGER;
4140 ok(ret, "SetThreadContext error %ld\n", GetLastError());
4141 SetLastError(0xdeadbeef);
4143 ok(ret, "SetThreadPriority error %ld\n", GetLastError());
4144
4145 SetLastError(0xdeadbeef);
4146 ret = TerminateThread(thread, 199);
4147 ok(ret, "TerminateThread error %ld\n", GetLastError());
4148 /* Calling GetExitCodeThread() without waiting for thread termination
4149 * leads to different results due to a race condition.
4150 */
4152 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed: %lx\n", ret);
4154 ok(ret == 199, "expected exit code 199, got %lu\n", ret);
4155
4156 SetLastError(0xdeadbeef);
4158 ok(ret, "TerminateProcess error %ld\n", GetLastError());
4159 /* Checking process state without waiting for process termination
4160 * leads to different results due to a race condition.
4161 */
4163 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed: %lx\n", ret);
4164
4165 SetLastError(0xdeadbeef);
4167 ok(process != NULL, "OpenProcess error %ld\n", GetLastError());
4169
4170 memset(&pbi, 0, sizeof(pbi));
4171 ret = pNtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
4172 ok(!ret, "NtQueryInformationProcess error %#lx\n", ret);
4173 ok(pbi.ExitStatus == 198, "expected 198, got %lu\n", pbi.ExitStatus);
4174 affinity = 1;
4175 ret = pNtSetInformationProcess(pi.hProcess, ProcessAffinityMask, &affinity, sizeof(affinity));
4176 ok(ret == STATUS_PROCESS_IS_TERMINATING, "expected STATUS_PROCESS_IS_TERMINATING, got %#lx\n", ret);
4177
4178 SetLastError(0xdeadbeef);
4179 ctx.ContextFlags = CONTEXT_INTEGER;
4181 ok(!ret, "GetThreadContext should fail\n");
4183 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
4184 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */ ||
4185 GetLastError() == ERROR_ACCESS_DENIED /* Win10 32-bit */,
4186 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4187 SetLastError(0xdeadbeef);
4188 ctx.ContextFlags = CONTEXT_INTEGER;
4190 ok(!ret, "SetThreadContext should fail\n");
4192 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
4193 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */,
4194 "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4195 SetLastError(0xdeadbeef);
4197 ok(ret, "SetThreadPriority error %ld\n", GetLastError());
4199
4201 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed: %lx\n", ret);
4202 SetLastError(0xdeadbeef);
4203 ctx.ContextFlags = CONTEXT_INTEGER;
4205 ok(!ret, "GetThreadContext should fail\n");
4207 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
4208 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */ ||
4209 GetLastError() == ERROR_ACCESS_DENIED /* Win10 32-bit */,
4210 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4211 SetLastError(0xdeadbeef);
4212 ctx.ContextFlags = CONTEXT_INTEGER;
4214 ok(!ret, "SetThreadContext should fail\n");
4216 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
4217 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */,
4218 "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4219 SetLastError(0xdeadbeef);
4220 ret = VirtualProtectEx(pi.hProcess, addr, 4096, PAGE_READWRITE, &old_prot);
4221 ok(!ret, "VirtualProtectEx should fail\n");
4222 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4223 SetLastError(0xdeadbeef);
4224 size = 0;
4226 ok(!ret, "ReadProcessMemory should fail\n");
4228 "expected ERROR_PARTIAL_COPY, got %ld\n", GetLastError());
4229 ok(!size, "expected 0, got %Iu\n", size);
4230 SetLastError(0xdeadbeef);
4232 ok(!ret, "VirtualFreeEx should fail\n");
4233 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4234 SetLastError(0xdeadbeef);
4236 ok(!addr, "VirtualAllocEx should fail\n");
4237 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4238 SetLastError(0xdeadbeef);
4239 size = VirtualQueryEx(pi.hProcess, NULL, &mbi, sizeof(mbi));
4240 ok(!size, "VirtualQueryEx should fail\n");
4241 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4242
4243 /* CloseHandle() call below leads to premature process termination
4244 * under some Windows versions.
4245 */
4246if (0)
4247{
4248 SetLastError(0xdeadbeef);
4249 ret = CloseHandle(hmap_dup);
4250 ok(ret, "CloseHandle should not fail\n");
4251}
4252
4253 SetLastError(0xdeadbeef);
4254 ret = DuplicateHandle(GetCurrentProcess(), hmap, pi.hProcess, &hmap_dup,
4256 ok(!ret, "DuplicateHandle should fail\n");
4257 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4258
4259 offset.u.LowPart = 0;
4260 offset.u.HighPart = 0;
4261 addr = NULL;
4262 size = 0;
4263 ret = pNtMapViewOfSection(hmap, pi.hProcess, &addr, 0, 0, &offset,
4264 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
4265 ok(ret == STATUS_PROCESS_IS_TERMINATING, "expected STATUS_PROCESS_IS_TERMINATING, got %#lx\n", ret);
4266
4267 SetLastError(0xdeadbeef);
4268 thread = CreateRemoteThread(pi.hProcess, NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret);
4269 ok(!thread, "CreateRemoteThread should fail\n");
4270 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4271
4272 SetLastError(0xdeadbeef);
4274 ok(!ret, "DebugActiveProcess should fail\n");
4275 ok(GetLastError() == ERROR_ACCESS_DENIED /* 64-bit */ || GetLastError() == ERROR_NOT_SUPPORTED /* 32-bit */,
4276 "ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4277
4279 ok(ret == 198, "expected exit code 198, got %lu\n", ret);
4282
4283 ret = DeleteFileA(dll_name);
4284 ok(ret, "DeleteFile error %ld\n", GetLastError());
4285#else
4286 skip("x86 specific ExitProcess test\n");
4287#endif
4288}
#define skip(...)
Definition: atltest.h:64
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
UINT WINAPI SetErrorMode(IN UINT uMode)
Definition: except.c:751
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4749
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
BOOL WINAPI SetThreadContext(IN HANDLE hThread, IN CONST CONTEXT *lpContext)
Definition: thread.c:521
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:587
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
#define win_skip
Definition: minitest.h:67
void winetest_add_failures(LONG new_failures)
#define sprintf
Definition: sprintf.c:45
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define CONTEXT_INTEGER
Definition: nt_native.h:1373
#define MEM_RELEASE
Definition: nt_native.h:1319
#define MEM_COMMIT
Definition: nt_native.h:1316
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:596
struct _IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER
TCHAR * cmdline
Definition: stretchblt.cpp:32
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
LPVOID NTAPI VirtualAllocEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:23
BOOL NTAPI VirtualProtectEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:153
SIZE_T NTAPI VirtualQueryEx(IN HANDLE hProcess, IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:227
BOOL NTAPI VirtualFreeEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:83
#define FILE_CURRENT
Definition: winbase.h:115
#define CREATE_SUSPENDED
Definition: winbase.h:182
#define ERROR_PARTIAL_COPY
Definition: winerror.h:424
#define ERROR_GEN_FAILURE
Definition: winerror.h:256
unsigned char BYTE
Definition: xxhash.c:193

Referenced by START_TEST().

◆ test_export_forwarder_dep_chain()

static void test_export_forwarder_dep_chain ( void  )
static

Definition at line 2920 of file loader.c.

2921{
2922 winetest_push_context( "no import" );
2923 /* export forwarder does not introduce a dependency on its own */
2926
2927 winetest_push_context( "static import of export forwarder" );
2930
2931 winetest_push_context( "static import of chained export forwarder" );
2934
2935 winetest_push_context( "dynamic import of export forwarder" );
2938
2939 winetest_push_context( "dynamic import of chained export forwarder" );
2942}
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
static void subtest_export_forwarder_dep_chain(size_t num_chained_export_modules, size_t exporter_index, BOOL test_static_import)
Definition: loader.c:2757

Referenced by START_TEST().

◆ test_filenames()

static void test_filenames ( void  )
static

Definition at line 1539 of file loader.c.

1540{
1542 char dll_name[MAX_PATH], long_path[MAX_PATH], short_path[MAX_PATH], buffer[MAX_PATH];
1543 HMODULE mod, mod2;
1544 BOOL ret;
1545
1548
1554
1555 create_test_dll( &dos_header, sizeof(dos_header), &nt_header, dll_name );
1556 strcpy( long_path, dll_name );
1557 strcpy( strrchr( long_path, '\\' ), "\\this-is-a-long-name.dll" );
1558 ret = MoveFileA( dll_name, long_path );
1559 ok( ret, "MoveFileA failed err %lu\n", GetLastError() );
1560 GetShortPathNameA( long_path, short_path, MAX_PATH );
1561
1562 mod = LoadLibraryA( short_path );
1563 ok( mod != NULL, "loading failed err %lu\n", GetLastError() );
1565 ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path );
1566 mod2 = GetModuleHandleA( short_path );
1567 ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path );
1568 mod2 = GetModuleHandleA( long_path );
1569 ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
1570 mod2 = LoadLibraryA( long_path );
1571 ok( mod2 != NULL, "loading failed err %lu\n", GetLastError() );
1572 ok( mod == mod2, "library loaded twice\n" );
1574 ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path );
1575 FreeLibrary( mod2 );
1576 FreeLibrary( mod );
1577
1578 mod = LoadLibraryA( long_path );
1579 ok( mod != NULL, "loading failed err %lu\n", GetLastError() );
1581 ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path );
1582 mod2 = GetModuleHandleA( short_path );
1583 ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path );
1584 mod2 = GetModuleHandleA( long_path );
1585 ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
1586 mod2 = LoadLibraryA( short_path );
1587 ok( mod2 != NULL, "loading failed err %lu\n", GetLastError() );
1588 ok( mod == mod2, "library loaded twice\n" );
1590 ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path );
1591 FreeLibrary( mod2 );
1592 FreeLibrary( mod );
1593
1594 strcpy( dll_name, long_path );
1595 strcpy( strrchr( dll_name, '\\' ), "\\this-is-another-name.dll" );
1596 ret = CreateHardLinkA( dll_name, long_path, NULL );
1597 ok( ret, "CreateHardLinkA failed err %lu\n", GetLastError() );
1598 if (ret)
1599 {
1600 mod = LoadLibraryA( dll_name );
1601 ok( mod != NULL, "loading failed err %lu\n", GetLastError() );
1603 ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, dll_name );
1604 mod2 = GetModuleHandleA( long_path );
1605 ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
1606 mod2 = LoadLibraryA( long_path );
1607 ok( mod2 != NULL, "loading failed err %lu\n", GetLastError() );
1608 ok( mod == mod2, "library loaded twice\n" );
1610 ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, short_path );
1611 FreeLibrary( mod2 );
1612 FreeLibrary( mod );
1613 DeleteFileA( dll_name );
1614 }
1615 DeleteFileA( long_path );
1616}
#define mod2(n)
Definition: vgavideo.h:71
BOOL WINAPI MoveFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName)
Definition: move.c:1137
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1752
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4227
GLuint buffer
Definition: glext.h:5915
static DWORD create_test_dll(const IMAGE_DOS_HEADER *dos_header, UINT dos_size, const IMAGE_NT_HEADERS *nt_header, char dll_name[MAX_PATH])
Definition: loader.c:208
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT
Definition: ntimage.h:457
strcpy
Definition: string.h:131

Referenced by START_TEST().

◆ test_image_mapping()

static void test_image_mapping ( const char dll_name,
DWORD  scn_page_access,
BOOL  is_dll 
)
static

Definition at line 1673 of file loader.c.

1674{
1675 HANDLE hfile, hmap;
1678 SIZE_T size;
1679 void *addr1, *addr2;
1681
1682 if (!pNtMapViewOfSection) return;
1683
1684 SetLastError(0xdeadbeef);
1685 hfile = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1686 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
1687
1688 SetLastError(0xdeadbeef);
1689 hmap = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, 0);
1690 ok(hmap != 0, "CreateFileMapping error %ld\n", GetLastError());
1691
1692 offset.u.LowPart = 0;
1693 offset.u.HighPart = 0;
1694
1695 addr1 = NULL;
1696 size = 0;
1697 status = pNtMapViewOfSection(hmap, GetCurrentProcess(), &addr1, 0, 0, &offset,
1698 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
1699 ok(NT_SUCCESS(status), "NtMapViewOfSection error %lx\n", status);
1700 ok(addr1 != 0, "mapped address should be valid\n");
1701
1702 SetLastError(0xdeadbeef);
1703 size = VirtualQuery((char *)addr1 + section.VirtualAddress, &info, sizeof(info));
1704 ok(size == sizeof(info), "VirtualQuery error %ld\n", GetLastError());
1705 ok(info.BaseAddress == (char *)addr1 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr1 + section.VirtualAddress);
1706 ok(info.RegionSize == page_size, "got %#Ix != expected %#lx\n", info.RegionSize, page_size);
1707 ok(info.Protect == scn_page_access, "got %#lx != expected %#lx\n", info.Protect, scn_page_access);
1708 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
1709 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#lx != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
1710 ok(info.State == MEM_COMMIT, "%#lx != MEM_COMMIT\n", info.State);
1711 ok(info.Type == SEC_IMAGE, "%#lx != SEC_IMAGE\n", info.Type);
1712
1713 addr2 = NULL;
1714 size = 0;
1715 status = pNtMapViewOfSection(hmap, GetCurrentProcess(), &addr2, 0, 0, &offset,
1716 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
1717 ok(status == STATUS_IMAGE_NOT_AT_BASE, "expected STATUS_IMAGE_NOT_AT_BASE, got %lx\n", status);
1718 ok(addr2 != 0, "mapped address should be valid\n");
1719 ok(addr2 != addr1, "mapped addresses should be different\n");
1720
1721 SetLastError(0xdeadbeef);
1722 size = VirtualQuery((char *)addr2 + section.VirtualAddress, &info, sizeof(info));
1723 ok(size == sizeof(info), "VirtualQuery error %ld\n", GetLastError());
1724 ok(info.BaseAddress == (char *)addr2 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr2 + section.VirtualAddress);
1725 ok(info.RegionSize == page_size, "got %#Ix != expected %#lx\n", info.RegionSize, page_size);
1726 ok(info.Protect == scn_page_access, "got %#lx != expected %#lx\n", info.Protect, scn_page_access);
1727 ok(info.AllocationBase == addr2, "%p != %p\n", info.AllocationBase, addr2);
1728 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#lx != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
1729 ok(info.State == MEM_COMMIT, "%#lx != MEM_COMMIT\n", info.State);
1730 ok(info.Type == SEC_IMAGE, "%#lx != SEC_IMAGE\n", info.Type);
1731
1732 status = pNtUnmapViewOfSection(GetCurrentProcess(), addr2);
1733 ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection error %lx\n", status);
1734
1735 addr2 = MapViewOfFile(hmap, 0, 0, 0, 0);
1736 ok(addr2 != 0, "mapped address should be valid\n");
1737 ok(addr2 != addr1, "mapped addresses should be different\n");
1738
1739 SetLastError(0xdeadbeef);
1740 size = VirtualQuery((char *)addr2 + section.VirtualAddress, &info, sizeof(info));
1741 ok(size == sizeof(info), "VirtualQuery error %ld\n", GetLastError());
1742 ok(info.BaseAddress == (char *)addr2 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr2 + section.VirtualAddress);
1743 ok(info.RegionSize == page_size, "got %#Ix != expected %#lx\n", info.RegionSize, page_size);
1744 ok(info.Protect == scn_page_access, "got %#lx != expected %#lx\n", info.Protect, scn_page_access);
1745 ok(info.AllocationBase == addr2, "%p != %p\n", info.AllocationBase, addr2);
1746 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#lx != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
1747 ok(info.State == MEM_COMMIT, "%#lx != MEM_COMMIT\n", info.State);
1748 ok(info.Type == SEC_IMAGE, "%#lx != SEC_IMAGE\n", info.Type);
1749
1750 UnmapViewOfFile(addr2);
1751
1752 SetLastError(0xdeadbeef);
1753 addr2 = LoadLibraryA(dll_name);
1754 if (!addr2)
1755 {
1756 ok(is_dll, "LoadLibrary should fail, is_dll %d\n", is_dll);
1757 ok(GetLastError() == ERROR_INVALID_ADDRESS, "expected ERROR_INVALID_ADDRESS, got %ld\n", GetLastError());
1758 }
1759 else
1760 {
1761 BOOL ret;
1762 ok(addr2 != 0, "LoadLibrary error %ld, is_dll %d\n", GetLastError(), is_dll);
1763 ok(addr2 != addr1, "mapped addresses should be different\n");
1764
1765 SetLastError(0xdeadbeef);
1766 ret = FreeLibrary(addr2);
1767 ok(ret, "FreeLibrary error %ld\n", GetLastError());
1768 }
1769
1770 status = pNtUnmapViewOfSection(GetCurrentProcess(), addr1);
1771 ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection error %lx\n", status);
1772
1773 CloseHandle(hmap);
1774 CloseHandle(hfile);
1775}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:192
SIZE_T NTAPI VirtualQuery(IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:211

Referenced by test_section_access().

◆ test_import_resolution()

static void test_import_resolution ( void  )
static

Definition at line 2182 of file loader.c.

2183{
2184 char temp_path[MAX_PATH];
2185 char dll_name[MAX_PATH];
2186 DWORD dummy;
2187 void *expect, *tmp;
2188 char *str;
2189 SIZE_T size;
2190 HANDLE hfile, mapping;
2191 HMODULE mod, mod2;
2194 struct imports
2195 {
2197 IMAGE_THUNK_DATA original_thunks[2];
2198 IMAGE_THUNK_DATA thunks[2];
2199 char module[16];
2200 struct { WORD hint; char name[32]; } function;
2202 UINT_PTR tls_init_fn_list[2];
2203 char tls_data[16];
2205 SHORT tls_index_hi;
2206 int* tls_init_fn_output;
2207 UCHAR tls_init_fn[64]; /* Note: Uses rip-relative address of tls_init_fn_output, don't separate */
2208 UCHAR entry_point_fn[16];
2209 struct
2210 {
2212 USHORT type_off[32];
2213 } rel;
2214 } data, *ptr;
2215 IMAGE_NT_HEADERS nt, *pnt;
2218 int test, tls_index_save, nb_rel;
2219#if defined(__i386__)
2220 static const UCHAR tls_init_code[] = {
2221 0xE8, 0x00, 0x00, 0x00, 0x00, /* call 1f */
2222 0x59, /* 1: pop ecx */
2223 0x8B, 0x49, 0xF7, /* mov ecx, [ecx - 9] ; mov ecx, [tls_init_fn_output] */
2224 0x8B, 0x54, 0x24, 0x08, /* mov edx, [esp + 8] */
2225 0x89, 0x11, /* mov [ecx], edx */
2226 0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
2227 0xC2, 0x0C, 0x00, /* ret 12 */
2228 };
2229 static const UCHAR entry_point_code[] = {
2230 0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
2231 0xC2, 0x0C, 0x00, /* ret 12 */
2232 };
2233#elif defined(__x86_64__)
2234 static const UCHAR tls_init_code[] = {
2235 0x48, 0x8B, 0x0D, 0xF1, 0xFF, 0xFF, 0xFF, /* mov rcx, [rip + tls_init_fn_output] */
2236 0x89, 0x11, /* mov [rcx], edx */
2237 0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
2238 0xC3, /* ret */
2239 };
2240 static const UCHAR entry_point_code[] = {
2241 0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
2242 0xC3, /* ret */
2243 };
2244#else
2245 static const UCHAR tls_init_code[] = { 0x00 };
2246 static const UCHAR entry_point_code[] = { 0x00 };
2247#endif
2248
2249 for (test = 0; test < 7; test++)
2250 {
2251#define DATA_RVA(ptr) (page_size + ((char *)(ptr) - (char *)&data))
2252#ifdef _WIN64
2253#define ADD_RELOC(field) data.rel.type_off[nb_rel++] = (IMAGE_REL_BASED_DIR64 << 12) + offsetof( struct imports, field )
2254#else
2255#define ADD_RELOC(field) data.rel.type_off[nb_rel++] = (IMAGE_REL_BASED_HIGHLOW << 12) + offsetof( struct imports, field )
2256#endif
2257 winetest_push_context( "%u", test );
2262 if (test != 2 && test != 5) nt.FileHeader.Characteristics |= IMAGE_FILE_DLL;
2275
2276 memset( &data, 0, sizeof(data) );
2277 data.descr[0].OriginalFirstThunk = DATA_RVA( data.original_thunks );
2278 data.descr[0].FirstThunk = DATA_RVA( data.thunks );
2279 data.descr[0].Name = DATA_RVA( data.module );
2280 strcpy( data.module, "kernel32.dll" );
2281 strcpy( data.function.name, "CreateEventA" );
2282 data.original_thunks[0].u1.AddressOfData = DATA_RVA( &data.function );
2283 data.thunks[0].u1.AddressOfData = 0xdeadbeef;
2284 nb_rel = 0;
2285
2286 data.tls.StartAddressOfRawData = nt.OptionalHeader.ImageBase + DATA_RVA( data.tls_data );
2287 ADD_RELOC( tls.StartAddressOfRawData );
2288 data.tls.EndAddressOfRawData = data.tls.StartAddressOfRawData + sizeof(data.tls_data);
2289 ADD_RELOC( tls.EndAddressOfRawData );
2290 data.tls.AddressOfIndex = nt.OptionalHeader.ImageBase + DATA_RVA( &data.tls_index );
2291 ADD_RELOC( tls.AddressOfIndex );
2292 strcpy( data.tls_data, "hello world" );
2293 data.tls_index = 9999;
2294 data.tls_index_hi = 9999;
2295
2296 if (test == 3 && sizeof(tls_init_code) > 1)
2297 {
2298 /* Windows doesn't consistently call tls init functions on dlls without entry points */
2299 assert(sizeof(tls_init_code) <= sizeof(data.tls_init_fn));
2300 assert(sizeof(entry_point_code) <= sizeof(data.entry_point_fn));
2301 memcpy(data.tls_init_fn, tls_init_code, sizeof(tls_init_code));
2302 memcpy(data.entry_point_fn, entry_point_code, sizeof(entry_point_code));
2303 tls_init_fn_output = 9999;
2304 data.tls_init_fn_output = &tls_init_fn_output;
2305 data.tls_init_fn_list[0] = nt.OptionalHeader.ImageBase + DATA_RVA(&data.tls_init_fn);
2306 ADD_RELOC( tls_init_fn_list[0] );
2307 data.tls.AddressOfCallBacks = nt.OptionalHeader.ImageBase + DATA_RVA(&data.tls_init_fn_list);
2308 ADD_RELOC( tls.AddressOfCallBacks );
2310 }
2311
2312 if (nb_rel % 2) nb_rel++;
2313 data.rel.reloc.VirtualAddress = nt.OptionalHeader.SectionAlignment;
2314 data.rel.reloc.SizeOfBlock = (char *)&data.rel.type_off[nb_rel] - (char *)&data.rel.reloc;
2317
2319 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
2320
2321 hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
2322 ok( hfile != INVALID_HANDLE_VALUE, "creation failed\n" );
2323
2324 memset( &section, 0, sizeof(section) );
2325 memcpy( section.Name, ".text", sizeof(".text") );
2326 section.PointerToRawData = nt.OptionalHeader.FileAlignment;
2327 section.VirtualAddress = nt.OptionalHeader.SectionAlignment;
2328 section.Misc.VirtualSize = sizeof(data);
2329 section.SizeOfRawData = sizeof(data);
2331 if (test == 3) section.Characteristics |= IMAGE_SCN_MEM_EXECUTE;
2332
2333 WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL);
2334 WriteFile(hfile, &nt, sizeof(nt), &dummy, NULL);
2335 WriteFile(hfile, &section, sizeof(section), &dummy, NULL);
2336
2337 SetFilePointer( hfile, section.PointerToRawData, NULL, SEEK_SET );
2338 WriteFile(hfile, &data, sizeof(data), &dummy, NULL);
2339
2340 CloseHandle( hfile );
2341
2342 switch (test)
2343 {
2344 case 0: /* normal load */
2345 mod = LoadLibraryA( dll_name );
2346 ok( mod != NULL, "failed to load err %lu\n", GetLastError() );
2347 if (!mod) break;
2348 ptr = (struct imports *)((char *)mod + page_size);
2349 expect = GetProcAddress( GetModuleHandleA( data.module ), data.function.name );
2350 ok( (void *)ptr->thunks[0].u1.Function == expect, "thunk %p instead of %p for %s.%s\n",
2351 (void *)ptr->thunks[0].u1.Function, expect, data.module, data.function.name );
2352#ifdef __REACTOS__
2353 ok( ptr->tls_index < 32 || broken(ptr->tls_index == 9999) /* WS03 */, "wrong tls index %d\n", ptr->tls_index );
2354 if (ptr->tls_index != 9999) {
2355#else
2356 ok( ptr->tls_index < 32, "wrong tls index %d\n", ptr->tls_index );
2357#endif
2358 str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[ptr->tls_index];
2359 ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str );
2360 ok(ptr->tls_index_hi == 0, "TLS Index written as a short, high half: %d\n", ptr->tls_index_hi);
2361#ifdef __REACTOS__
2362 }
2363#endif
2364 check_tls_index(mod, ptr->tls_index != 9999);
2365 FreeLibrary( mod );
2366 break;
2367 case 1: /* load with DONT_RESOLVE_DLL_REFERENCES doesn't resolve imports */
2369 ok( mod != NULL, "failed to load err %lu\n", GetLastError() );
2370 if (!mod) break;
2371 ptr = (struct imports *)((char *)mod + page_size);
2372 ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
2373 (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
2374 ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
2375
2376 mod2 = LoadLibraryA( dll_name );
2377 ok( mod2 == mod, "loaded twice %p / %p\n", mod, mod2 );
2378 ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
2379 (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
2380 ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
2381 check_tls_index(mod, ptr->tls_index != 9999);
2382 FreeLibrary( mod2 );
2383 FreeLibrary( mod );
2384 break;
2385 case 2: /* load without IMAGE_FILE_DLL doesn't resolve imports */
2386 mod = LoadLibraryA( dll_name );
2387 ok( mod != NULL, "failed to load err %lu\n", GetLastError() );
2388 if (!mod) break;
2389 ptr = (struct imports *)((char *)mod + page_size);
2390 ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
2391 (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
2392 ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
2393 check_tls_index(mod, ptr->tls_index != 9999);
2394 FreeLibrary( mod );
2395 break;
2396 case 3: /* load with tls init function */
2397 mod = LoadLibraryA( dll_name );
2398 ok( mod != NULL, "failed to load err %lu\n", GetLastError() );
2399 if (!mod) break;
2400 ptr = (struct imports *)((char *)mod + page_size);
2401 tls_index_save = ptr->tls_index;
2402#ifdef __REACTOS__
2403 ok( ptr->tls_index < 32 || broken(ptr->tls_index == 9999) /* WS03 */, "wrong tls index %d\n", ptr->tls_index );
2404 if (sizeof(tls_init_code) > 1 && ptr->tls_index != 9999)
2405#else
2406 ok( ptr->tls_index < 32, "wrong tls index %d\n", ptr->tls_index );
2407 if (sizeof(tls_init_code) > 1)
2408#endif
2409 {
2410 str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[ptr->tls_index];
2411 ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str );
2412 /* tls init function will write the reason to *tls_init_fn_output */
2414 "tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_PROCESS_ATTACH );
2415 tls_init_fn_output = 9999;
2418 "tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_THREAD_DETACH );
2419 }
2420 check_tls_index(mod, ptr->tls_index != 9999);
2421 tls_init_fn_output = 9999;
2422 FreeLibrary( mod );
2423 if (tls_index_save != 9999 && sizeof(tls_init_code) > 1)
2425 "tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_PROCESS_DETACH );
2426 break;
2427 case 4: /* map with ntdll */
2428 case 5: /* map with ntdll, without IMAGE_FILE_DLL */
2429 case 6: /* map with ntdll, without IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE */
2430 hfile = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2431 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %lu\n", GetLastError() );
2433 CloseHandle( hfile );
2434 if (test == 6 &&
2437 {
2438 ok( !mapping, "CreateFileMappingA succeeded\n" );
2439 ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "wrong error %lu\n", GetLastError() );
2440 break;
2441 }
2442 status = pNtQuerySection( mapping, SectionImageInformation, &image, sizeof(image), &size );
2443 ok( !status, "NtQuerySection failed %lx\n", status );
2444#ifdef __REACTOS__
2445 ok( test == 6 ? !image.ImageDynamicallyRelocated : image.ImageDynamicallyRelocated || broken(GetNTVersion() < _WIN32_WINNT_VISTA),
2446#else
2447 ok( test == 6 ? !image.ImageDynamicallyRelocated : image.ImageDynamicallyRelocated,
2448#endif
2449 "image flags %x\n", image.ImageFlags);
2450 ok( !image.ImageContainsCode, "contains code %x\n", image.ImageContainsCode);
2451 ok( mapping != 0, "CreateFileMappingA failed err %lu\n", GetLastError() );
2452 /* make sure that the address is not available */
2453 tmp = VirtualAlloc( (void *)nt.OptionalHeader.ImageBase, 0x10000,
2455 mod = NULL;
2456 size = 0;
2457 offset.QuadPart = 0;
2458 status = pNtMapViewOfSection( mapping, GetCurrentProcess(), (void **)&mod, 0, 0, &offset,
2459 &size, 1 /* ViewShare */, 0, PAGE_READONLY );
2460 todo_wine_if (test == 5)
2461#ifdef __REACTOS__
2463#else
2465#endif
2466 "NtMapViewOfSection failed %lx\n", status );
2467 ok( mod != (void *)nt.OptionalHeader.ImageBase, "loaded at image base %p\n", mod );
2468 pnt = pRtlImageNtHeader( mod );
2469 ptr = (void *)((char *)mod + page_size);
2470 if (test == 6)
2471 {
2472 ok( (void *)pnt->OptionalHeader.ImageBase != mod, "not relocated from %p\n", mod );
2473 ok( (char *)ptr->tls.StartAddressOfRawData == (char *)nt.OptionalHeader.ImageBase + DATA_RVA( data.tls_data ),
2474 "tls relocated %p / %p\n", (void *)ptr->tls.StartAddressOfRawData,
2475 (char *)nt.OptionalHeader.ImageBase + DATA_RVA( data.tls_data ));
2476 }
2477 else todo_wine_if (test == 5)
2478 {
2479#ifdef __REACTOS__
2481#endif
2482 ok( (void *)pnt->OptionalHeader.ImageBase == mod, "not at base %p / %p\n",
2483 (void *)pnt->OptionalHeader.ImageBase, mod );
2484 ok( (char *)ptr->tls.StartAddressOfRawData == (char *)mod + DATA_RVA( data.tls_data ),
2485 "tls not relocated %p / %p\n", (void *)ptr->tls.StartAddressOfRawData,
2486 (char *)mod + DATA_RVA( data.tls_data ));
2487#ifdef __REACTOS__
2488 }
2489#endif
2490 }
2493 if (tmp) VirtualFree( tmp, 0, MEM_RELEASE );
2494 break;
2495 }
2496 DeleteFileA( dll_name );
2498#undef DATA_RVA
2499 }
2500}
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#define INFINITE
Definition: serial.h:102
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES
Definition: ntddk_ex.h:135
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define SEEK_SET
Definition: jmemansi.c:26
static IMAGE_SECTION_HEADER section
Definition: loader.c:164
#define ADD_RELOC(field)
#define DATA_RVA(ptr)
static int tls_init_fn_output
Definition: loader.c:2169
static void check_tls_index(HANDLE dll, BOOL tls_initialized)
Definition: loader.c:2142
static DWORD WINAPI tls_thread_fn(void *tlsidx_v)
Definition: loader.c:2171
#define MEM_RESERVE
Definition: nt_native.h:1317
#define IMAGE_FILE_EXECUTABLE_IMAGE
Definition: pedump.c:160
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_DLL
Definition: pedump.c:169
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
unsigned short USHORT
Definition: pedump.c:61
#define test
Definition: rosglue.h:37
const WCHAR * str
DWORD tls_index
static DWORD tls
Definition: sock.c:229
char * name
Definition: compiler.c:66
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by START_TEST().

◆ test_ImportDescriptors()

static void test_ImportDescriptors ( void  )
static

Definition at line 1619 of file loader.c.

1620{
1621 HMODULE kernel32_module = NULL;
1622 PIMAGE_DOS_HEADER d_header;
1623 PIMAGE_NT_HEADERS nt_headers;
1624 DWORD import_dir_size;
1625 DWORD_PTR dir_offset;
1626 PIMAGE_IMPORT_DESCRIPTOR import_chunk;
1627
1628 /* Load kernel32 module */
1629 kernel32_module = GetModuleHandleA("kernel32.dll");
1630 assert( kernel32_module != NULL );
1631
1632 /* Get PE header info from module image */
1633 d_header = (PIMAGE_DOS_HEADER) kernel32_module;
1634 nt_headers = (PIMAGE_NT_HEADERS) (((char*) d_header) +
1635 d_header->e_lfanew);
1636
1637 /* Get size of import entry directory */
1638 import_dir_size = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
1639 if (!import_dir_size)
1640 {
1641 skip("Unable to continue testing due to missing import directory.\n");
1642 return;
1643 }
1644
1645 /* Get address of first import chunk */
1647 import_chunk = RVAToAddr(dir_offset, kernel32_module);
1648 ok(import_chunk != 0, "Invalid import_chunk: %p\n", import_chunk);
1649 if (!import_chunk) return;
1650
1651 /* Iterate through import descriptors and verify set name,
1652 * OriginalFirstThunk, and FirstThunk. Core Windows DLLs, such as
1653 * kernel32.dll, don't use Borland-style linking, where the table of
1654 * imported names is stored directly in FirstThunk and overwritten
1655 * by the relocation, instead of being stored in OriginalFirstThunk.
1656 * */
1657 for (; import_chunk->FirstThunk; import_chunk++)
1658 {
1659 LPCSTR module_name = RVAToAddr(import_chunk->Name, kernel32_module);
1660 PIMAGE_THUNK_DATA name_table = RVAToAddr(
1661 import_chunk->OriginalFirstThunk, kernel32_module);
1663 import_chunk->FirstThunk, kernel32_module);
1664 ok(module_name != NULL, "Imported module name should not be NULL\n");
1665 ok(name_table != NULL,
1666 "Name table for imported module %s should not be NULL\n",
1667 module_name);
1668 ok(iat != NULL, "IAT for imported module %s should not be NULL\n",
1669 module_name);
1670 }
1671}
static LPCWSTR LPCWSTR module_name
Definition: db.cpp:171
PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS
Definition: ntddk_ex.h:187
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
static void void **static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module)
Definition: loader.c:95
const char * LPCSTR
Definition: xmlstorage.h:183

Referenced by START_TEST().

◆ test_InMemoryOrderModuleList()

static void test_InMemoryOrderModuleList ( void  )
static

Definition at line 4644 of file loader.c.

4645{
4646 PEB_LDR_DATA *ldr = NtCurrentTeb()->Peb->LdrData;
4647 LIST_ENTRY *entry1, *mark1 = &ldr->InLoadOrderModuleList;
4648 LIST_ENTRY *entry2, *mark2 = &ldr->InMemoryOrderModuleList;
4649 LDR_DATA_TABLE_ENTRY *module1, *module2;
4650
4651 ok(ldr->Initialized == TRUE, "expected TRUE, got %u\n", ldr->Initialized);
4652
4653 for (entry1 = mark1->Flink, entry2 = mark2->Flink;
4654 entry1 != mark1 && entry2 != mark2;
4655 entry1 = entry1->Flink, entry2 = entry2->Flink)
4656 {
4657 module1 = CONTAINING_RECORD(entry1, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
4658 module2 = CONTAINING_RECORD(entry2, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
4659 ok(module1 == module2, "expected module1 == module2, got %p and %p\n", module1, module2);
4660 }
4661 ok(entry1 == mark1, "expected entry1 == mark1, got %p and %p\n", entry1, mark1);
4662 ok(entry2 == mark2, "expected entry2 == mark2, got %p and %p\n", entry2, mark2);
4663}
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:124
BOOLEAN Initialized
Definition: ntddk_ex.h:222

Referenced by START_TEST().

◆ test_Loader()

static void test_Loader ( void  )
static

Definition at line 761 of file loader.c.

762{
763 static const struct test_data
764 {
765 DWORD size_of_dos_header;
766 WORD number_of_sections, size_of_optional_header;
767 DWORD section_alignment, file_alignment;
768 DWORD size_of_image, size_of_headers;
769 DWORD errors[4]; /* 0 means LoadLibrary should succeed */
770 } td[] =
771 {
772 { sizeof(dos_header),
773 1, 0, 0, 0, 0, 0,
775 },
776 { sizeof(dos_header),
777 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000,
778 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0xe00,
779 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
780 { ERROR_BAD_EXE_FORMAT } /* XP doesn't like too small image size */
781 },
782 { sizeof(dos_header),
783 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000,
784 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
785 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
786 { ERROR_SUCCESS }
787 },
788 { sizeof(dos_header),
789 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000,
790 0x1f00,
791 0x1000,
792 { ERROR_SUCCESS }
793 },
794 { sizeof(dos_header),
795 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x200, 0x200,
796 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x200,
797 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
798 { ERROR_SUCCESS, ERROR_INVALID_ADDRESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
799 },
800 { sizeof(dos_header),
801 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x200, 0x1000,
802 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
803 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
804 { ERROR_BAD_EXE_FORMAT } /* XP doesn't like alignments */
805 },
806 { sizeof(dos_header),
807 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x200,
808 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
809 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
810 { ERROR_SUCCESS }
811 },
812 { sizeof(dos_header),
813 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x200,
814 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
815 0x200,
816 { ERROR_SUCCESS }
817 },
818 /* Mandatory are all fields up to SizeOfHeaders, everything else
819 * is really optional (at least that's true for XP).
820 */
821#if 0 /* 32-bit Windows 8 crashes inside of LoadLibrary */
822 { sizeof(dos_header),
823 1, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
824 sizeof(dos_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum) + sizeof(IMAGE_SECTION_HEADER) + 0x10,
825 sizeof(dos_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum) + sizeof(IMAGE_SECTION_HEADER),
828 },
829#endif
830 { sizeof(dos_header),
831 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
832 0xd0, /* beyond of the end of file */
833 0xc0, /* beyond of the end of file */
834 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
835 },
836 { sizeof(dos_header),
837 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
838 0x1000,
839 0,
840 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
841 },
842 { sizeof(dos_header),
843 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
844 1,
845 0,
846 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
847 },
848#if 0 /* not power of 2 alignments need more test cases */
849 { sizeof(dos_header),
850 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x300, 0x300,
851 1,
852 0,
853 { ERROR_BAD_EXE_FORMAT } /* alignment is not power of 2 */
854 },
855#endif
856 { sizeof(dos_header),
857 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 4, 4,
858 1,
859 0,
860 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
861 },
862 { sizeof(dos_header),
863 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 1, 1,
864 1,
865 0,
866 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
867 },
868 { sizeof(dos_header),
869 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
870 0,
871 0,
872 { ERROR_BAD_EXE_FORMAT } /* image size == 0 -> failure */
873 },
874 /* the following data mimics the PE image which upack creates */
875 { 0x10,
876 1, 0x148, 0x1000, 0x200,
877 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
878 0x200,
879 { ERROR_SUCCESS }
880 },
881 /* Minimal PE image that XP is able to load: 92 bytes */
882 { 0x04,
884 0x04 /* also serves as e_lfanew in the truncated MZ header */, 0x04,
885 1,
886 0,
887 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
888 },
889 /* Minimal PE image initially created for Windows 7 and accepted from
890 * Vista up to Windows 10 1709 with some unexplained exceptions:
891 * 268 bytes
892 */
893 { 0x04,
894 0, 0xf0, /* optional header size just forces 0xf0 bytes to be written,
895 0 or another number don't change the behaviour, what really
896 matters is file size regardless of values in the headers */
897 0x04 /* also serves as e_lfanew in the truncated MZ header */, 0x04,
898 0x40, /* minimal image size that Windows7 accepts */
899 0,
900 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* rejected by win10 1809+ */
901 },
902 /* the following data mimics the PE image which 8k demos have */
903 { 0x04,
904 0, 0x08,
905 0x04 /* also serves as e_lfanew in the truncated MZ header */, 0x04,
906 0x2000,
907 0x40,
909 }
910 };
911 int i;
913 HANDLE h;
914 HMODULE hlib, hlib_as_data_file;
915 char dll_name[MAX_PATH];
916 SIZE_T size;
917 BOOL ret;
921 IMAGE_COR20_HEADER cor_header;
922
923 /* prevent displaying of the "Unable to load this DLL" message box */
925
926 for (i = 0; i < ARRAY_SIZE(td); i++)
927 {
930 nt_header.FileHeader.NumberOfSections = td[i].number_of_sections;
931 nt_header.FileHeader.SizeOfOptionalHeader = td[i].size_of_optional_header;
932
933 nt_header.OptionalHeader.SectionAlignment = td[i].section_alignment;
934 nt_header.OptionalHeader.FileAlignment = td[i].file_alignment;
935 nt_header.OptionalHeader.SizeOfImage = td[i].size_of_image;
936 nt_header.OptionalHeader.SizeOfHeaders = td[i].size_of_headers;
937
939 file_size = create_test_dll( &dos_header, td[i].size_of_dos_header, &nt_header, dll_name );
940
941 SetLastError(0xdeadbeef);
942 hlib = LoadLibraryA(dll_name);
943 if (hlib)
944 {
946 void *ptr;
947
948 ok( td[i].errors[0] == ERROR_SUCCESS, "should have failed\n" );
949
950 SetLastError(0xdeadbeef);
951 size = VirtualQuery(hlib, &info, sizeof(info));
952 ok(size == sizeof(info),
953 "%d: VirtualQuery error %ld\n", i, GetLastError());
954 ok(info.BaseAddress == hlib, "%p != %p\n", info.BaseAddress, hlib);
955 ok(info.AllocationBase == hlib, "%p != %p\n", info.AllocationBase, hlib);
956 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%lx != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
957 ok(info.RegionSize == ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size), "got %Ix != expected %x\n",
959 ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
961 ok(info.Protect == PAGE_EXECUTE_WRITECOPY, "%lx != PAGE_EXECUTE_WRITECOPY\n", info.Protect);
962 else
963 ok(info.Protect == PAGE_READONLY, "%lx != PAGE_READONLY\n", info.Protect);
964 ok(info.Type == SEC_IMAGE, "%lx != SEC_IMAGE\n", info.Type);
965
966 SetLastError(0xdeadbeef);
967 ptr = VirtualAlloc(hlib, page_size, MEM_COMMIT, info.Protect);
968 ok(!ptr, "VirtualAlloc should fail\n");
969 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
970
971 SetLastError(0xdeadbeef);
972 size = VirtualQuery((char *)hlib + info.RegionSize, &info, sizeof(info));
973 ok(size == sizeof(info), "VirtualQuery error %ld\n", GetLastError());
976 {
977 ok(info.BaseAddress == (char *)hlib + ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size), "got %p != expected %p\n",
978 info.BaseAddress, (char *)hlib + ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size));
979 ok(info.AllocationBase == 0, "%p != 0\n", info.AllocationBase);
980 ok(info.AllocationProtect == 0, "%lx != 0\n", info.AllocationProtect);
981 /*ok(info.RegionSize == not_practical_value, "%d: %lx != not_practical_value\n", i, info.RegionSize);*/
982 ok(info.State == MEM_FREE, "%lx != MEM_FREE\n", info.State);
983 ok(info.Type == 0, "%lx != 0\n", info.Type);
984 ok(info.Protect == PAGE_NOACCESS, "%lx != PAGE_NOACCESS\n", info.Protect);
985 }
986 else
987 {
988 ok(info.Protect == PAGE_EXECUTE_WRITECOPY, "%lx != PAGE_EXECUTE_WRITECOPY\n", info.Protect);
989 ok(info.BaseAddress == hlib, "got %p != expected %p\n", info.BaseAddress, hlib);
990 ok(info.AllocationBase == hlib, "%p != %p\n", info.AllocationBase, hlib);
991 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%lx != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
992 ok(info.RegionSize == ALIGN_SIZE(file_size, page_size), "got %Ix != expected %x\n",
993 info.RegionSize, (UINT)ALIGN_SIZE(file_size, page_size));
994 ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
995 ok(info.Protect == PAGE_READONLY, "%lx != PAGE_READONLY\n", info.Protect);
996 ok(info.Type == SEC_IMAGE, "%lx != SEC_IMAGE\n", info.Type);
997 }
998
999 /* header: check the zeroing of alignment */
1001 {
1002 const char *start;
1003
1004 start = (const char *)hlib + nt_header.OptionalHeader.SizeOfHeaders;
1006 ok(!memcmp(start, filler, size), "header alignment is not cleared\n");
1007 }
1008
1010 {
1011 SetLastError(0xdeadbeef);
1012 size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info));
1013 ok(size == sizeof(info),
1014 "VirtualQuery error %ld\n", GetLastError());
1016 {
1017 ok(info.BaseAddress == hlib, "got %p != expected %p\n", info.BaseAddress, hlib);
1018 ok(info.RegionSize == ALIGN_SIZE(nt_header.OptionalHeader.SizeOfImage, page_size), "got %Ix != expected %x\n",
1020 ok(info.Protect == PAGE_EXECUTE_WRITECOPY, "%lx != PAGE_EXECUTE_WRITECOPY\n", info.Protect);
1021 }
1022 else
1023 {
1024 ok(info.BaseAddress == (char *)hlib + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)hlib + section.VirtualAddress);
1025 ok(info.RegionSize == ALIGN_SIZE(section.Misc.VirtualSize, page_size), "got %Ix != expected %x\n",
1026 info.RegionSize, (UINT)ALIGN_SIZE(section.Misc.VirtualSize, page_size));
1027 ok(info.Protect == PAGE_READONLY, "%lx != PAGE_READONLY\n", info.Protect);
1028 }
1029 ok(info.AllocationBase == hlib, "%p != %p\n", info.AllocationBase, hlib);
1030 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%lx != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
1031 ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
1032 ok(info.Type == SEC_IMAGE, "%lx != SEC_IMAGE\n", info.Type);
1033
1035 ok(!memcmp((const char *)hlib + section.VirtualAddress + section.PointerToRawData, &nt_header, section.SizeOfRawData), "wrong section data\n");
1036 else
1037 ok(!memcmp((const char *)hlib + section.PointerToRawData, section_data, section.SizeOfRawData), "wrong section data\n");
1038
1039 /* check the zeroing of alignment */
1041 {
1042 const char *start;
1043
1044 start = (const char *)hlib + section.VirtualAddress + section.PointerToRawData + section.SizeOfRawData;
1046 ok(memcmp(start, filler, size), "alignment should not be cleared\n");
1047 }
1048
1049 SetLastError(0xdeadbeef);
1050 ptr = VirtualAlloc((char *)hlib + section.VirtualAddress, page_size, MEM_COMMIT, info.Protect);
1051 ok(!ptr, "VirtualAlloc should fail\n");
1053 "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
1054 }
1055
1056 SetLastError(0xdeadbeef);
1057 hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE);
1058 ok(hlib_as_data_file != 0, "LoadLibraryEx error %lu\n", GetLastError());
1059 ok(hlib_as_data_file == hlib, "hlib_as_file and hlib are different\n");
1060
1061 SetLastError(0xdeadbeef);
1062 ret = FreeLibrary(hlib);
1063 ok(ret, "FreeLibrary error %ld\n", GetLastError());
1064
1065 SetLastError(0xdeadbeef);
1066 hlib = GetModuleHandleA(dll_name);
1067 ok(hlib != 0, "GetModuleHandle error %lu\n", GetLastError());
1068
1069 SetLastError(0xdeadbeef);
1070 ret = FreeLibrary(hlib_as_data_file);
1071 ok(ret, "FreeLibrary error %ld\n", GetLastError());
1072
1073 hlib = GetModuleHandleA(dll_name);
1074 ok(!hlib, "GetModuleHandle should fail\n");
1075
1076 SetLastError(0xdeadbeef);
1077 hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE);
1078 ok(hlib_as_data_file != 0, "LoadLibraryEx error %lu\n", GetLastError());
1079 ok(((ULONG_PTR)hlib_as_data_file & 3) == 1, "hlib_as_data_file got %p\n", hlib_as_data_file);
1080
1081 hlib = GetModuleHandleA(dll_name);
1082 ok(!hlib, "GetModuleHandle should fail\n");
1083
1084 SetLastError(0xdeadbeef);
1086 ok( h != INVALID_HANDLE_VALUE, "open failed err %lu\n", GetLastError() );
1087 CloseHandle( h );
1088
1089 SetLastError(0xdeadbeef);
1090 ret = FreeLibrary(hlib_as_data_file);
1091 ok(ret, "FreeLibrary error %ld\n", GetLastError());
1092
1093 SetLastError(0xdeadbeef);
1094 hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);
1095#ifdef __REACTOS__
1096 if (!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER) {
1097 skip("LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE not supported\n");
1098 FreeLibrary(hlib_as_data_file);
1099 } else {
1100#endif
1101 ok(hlib_as_data_file != 0, "LoadLibraryEx error %lu\n", GetLastError());
1102
1103 SetLastError(0xdeadbeef);
1105 ok( h == INVALID_HANDLE_VALUE, "open succeeded\n" );
1106 ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error %lu\n", GetLastError() );
1107 CloseHandle( h );
1108
1109 SetLastError(0xdeadbeef);
1111 ok( h != INVALID_HANDLE_VALUE, "open failed err %lu\n", GetLastError() );
1112 CloseHandle( h );
1113
1114 SetLastError(0xdeadbeef);
1115 ret = FreeLibrary(hlib_as_data_file);
1116 ok(ret, "FreeLibrary error %ld\n", GetLastError());
1117#ifdef __REACTOS__
1118 }
1119#endif
1120
1121 SetLastError(0xdeadbeef);
1122 hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE);
1123#ifdef __REACTOS__
1124 if (!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER) {
1125 skip("LOAD_LIBRARY_AS_IMAGE_RESOURCE not supported\n");
1126 FreeLibrary(hlib_as_data_file);
1127 } else {
1128#endif
1129 ok(hlib_as_data_file != 0, "LoadLibraryEx error %lu\n", GetLastError());
1130 ok(((ULONG_PTR)hlib_as_data_file & 3) == 2, "hlib_as_data_file got %p\n",
1131 hlib_as_data_file);
1132
1133 hlib = GetModuleHandleA(dll_name);
1134 ok(!hlib, "GetModuleHandle should fail\n");
1135
1136 SetLastError(0xdeadbeef);
1137 ret = FreeLibrary(hlib_as_data_file);
1138 ok(ret, "FreeLibrary error %ld\n", GetLastError());
1139#ifdef __REACTOS__
1140 }
1141#endif
1142
1143 SetLastError(0xdeadbeef);
1144 ret = DeleteFileA(dll_name);
1145 ok(ret, "DeleteFile error %ld\n", GetLastError());
1146
1148 file_size = create_test_dll( &dos_header, td[i].size_of_dos_header, &nt_header, dll_name );
1149 if (!file_size)
1150 {
1151 ok(0, "could not create %s\n", dll_name);
1153 break;
1154 }
1155
1156 query_image_section( i, dll_name, &nt_header, NULL );
1157 }
1158 else
1159 {
1160 BOOL error_match;
1161 int error_index;
1162
1163 error_match = FALSE;
1164 for (error_index = 0;
1165 ! error_match && error_index < ARRAY_SIZE(td[i].errors);
1166 error_index++)
1167 {
1168 error_match = td[i].errors[error_index] == GetLastError();
1169 }
1170 ok(error_match, "unexpected error %ld\n", GetLastError());
1171 }
1172
1173 SetLastError(0xdeadbeef);
1174 ret = DeleteFileA(dll_name);
1175 ok(ret, "DeleteFile error %ld\n", GetLastError());
1177 }
1178
1182
1188
1189 section.SizeOfRawData = sizeof(section_data);
1190 section.PointerToRawData = page_size;
1191 section.VirtualAddress = page_size;
1192 section.Misc.VirtualSize = page_size;
1193
1195 init_load_path( dll_name );
1196
1200 "NtCreateSection error %08lx\n", status );
1201
1205 "NtCreateSection error %08lx\n", status );
1206
1210 "NtCreateSection error %08lx\n", status );
1211
1214
1215 dos_header.e_magic = 0;
1217 ok( status == STATUS_INVALID_IMAGE_NOT_MZ, "NtCreateSection error %08lx\n", status );
1218
1222 ok( status == STATUS_INVALID_IMAGE_NE_FORMAT, "NtCreateSection error %08lx\n", status );
1223 for (i = 0; i < 16; i++)
1224 {
1225 ((IMAGE_OS2_HEADER *)&nt_header)->ne_exetyp = i;
1227 switch (i)
1228 {
1229 case 2:
1230 ok( status == STATUS_INVALID_IMAGE_WIN_16, "NtCreateSection %u error %08lx\n", i, status );
1231 break;
1232 case 5:
1233 ok( status == STATUS_INVALID_IMAGE_PROTECT, "NtCreateSection %u error %08lx\n", i, status );
1234 break;
1235 default:
1236 ok( status == STATUS_INVALID_IMAGE_NE_FORMAT, "NtCreateSection %u error %08lx\n", i, status );
1237 break;
1238 }
1239 }
1240 ((IMAGE_OS2_HEADER *)&nt_header)->ne_exetyp = ((IMAGE_OS2_HEADER *)&nt_header_template)->ne_exetyp;
1241
1242 dos_header.e_lfanew = 0x98760000;
1244 ok( status == STATUS_INVALID_IMAGE_PROTECT, "NtCreateSection error %08lx\n", status );
1245
1246 dos_header.e_lfanew = sizeof(dos_header);
1247 nt_header.Signature = 0xdeadbeef;
1249 ok( status == STATUS_INVALID_IMAGE_PROTECT, "NtCreateSection error %08lx\n", status );
1250
1254 ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08lx\n", status );
1255
1257 nt_header.FileHeader.Machine = 0xdead;
1259 ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08lx\n", status );
1260
1263 ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08lx\n", status );
1264
1267 ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08lx\n", status );
1268
1269 nt_header.FileHeader.Machine = orig_machine;
1273 section.SizeOfRawData = sizeof(cor_header);
1274
1275 memset( &cor_header, 0, sizeof(cor_header) );
1276 cor_header.cb = sizeof(cor_header);
1277 cor_header.MajorRuntimeVersion = 2;
1278 cor_header.MinorRuntimeVersion = 4;
1279 cor_header.Flags = COMIMAGE_FLAGS_ILONLY;
1280 cor_header.EntryPointToken = 0xbeef;
1281 status = map_image_section( &nt_header, &section, &cor_header, __LINE__ );
1282 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1283
1284 cor_header.MinorRuntimeVersion = 5;
1285 status = map_image_section( &nt_header, &section, &cor_header, __LINE__ );
1286 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1287
1288 cor_header.MajorRuntimeVersion = 3;
1289 cor_header.MinorRuntimeVersion = 0;
1290 status = map_image_section( &nt_header, &section, &cor_header, __LINE__ );
1291 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1292
1294 status = map_image_section( &nt_header, &section, &cor_header, __LINE__ );
1295 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1296
1298 status = map_image_section( &nt_header, &section, &cor_header, __LINE__ );
1299 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1300
1301 cor_header.Flags = 0;
1302 status = map_image_section( &nt_header, &section, &cor_header, __LINE__ );
1303 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1304
1307 status = map_image_section( &nt_header, &section, &cor_header, __LINE__ );
1308 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1309
1311 {
1312 IMAGE_NT_HEADERS64 nt64;
1313
1314 memset( &nt64, 0, sizeof(nt64) );
1316 nt64.FileHeader.Machine = orig_machine;
1322 nt64.OptionalHeader.SizeOfCode = 0x1000;
1323 nt64.OptionalHeader.AddressOfEntryPoint = 0x1000;
1324 nt64.OptionalHeader.ImageBase = 0x10000000;
1325 nt64.OptionalHeader.SectionAlignment = 0x1000;
1326 nt64.OptionalHeader.FileAlignment = 0x1000;
1330 nt64.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt64) + sizeof(IMAGE_SECTION_HEADER);
1333 nt64.OptionalHeader.SizeOfStackReserve = 0x321000;
1334 nt64.OptionalHeader.SizeOfStackCommit = 0x123000;
1336
1339 "NtCreateSection error %08lx\n", status );
1340
1341 switch (orig_machine)
1342 {
1345 }
1348 "NtCreateSection error %08lx\n", status );
1349
1350 nt64.FileHeader.Machine = get_alt_bitness_machine( orig_machine );
1353 "NtCreateSection error %08lx\n", status );
1354
1355 nt64.OptionalHeader.SizeOfCode = 0;
1356 nt64.OptionalHeader.AddressOfEntryPoint = 0x1000;
1357 section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
1360 "NtCreateSection error %08lx\n", status );
1361
1362 nt64.OptionalHeader.SizeOfCode = 0;
1367 "NtCreateSection error %08lx\n", status );
1368
1369 nt64.OptionalHeader.SizeOfCode = 0x1000;
1372 section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
1375 "NtCreateSection error %08lx\n", status );
1376
1377 nt64.OptionalHeader.SizeOfCode = 0;
1379 section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
1382 "NtCreateSection error %08lx\n", status );
1383
1387 cor_header.MajorRuntimeVersion = 2;
1388 cor_header.MinorRuntimeVersion = 4;
1389 cor_header.Flags = COMIMAGE_FLAGS_ILONLY;
1390 status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, &section, &cor_header, __LINE__ );
1392 "NtCreateSection error %08lx\n", status );
1393
1394 nt64.OptionalHeader.SizeOfCode = 0x1000;
1395 status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, &section, &cor_header, __LINE__ );
1397 "NtCreateSection error %08lx\n", status );
1398
1399 cor_header.MinorRuntimeVersion = 5;
1400 status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, &section, &cor_header, __LINE__ );
1402 "NtCreateSection error %08lx\n", status );
1403
1405 status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, &section, &cor_header, __LINE__ );
1407 "NtCreateSection error %08lx\n", status );
1408
1410 status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, &section, &cor_header, __LINE__ );
1412 "NtCreateSection error %08lx\n", status );
1413
1414 cor_header.Flags = 0;
1415 status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, &section, &cor_header, __LINE__ );
1417 "NtCreateSection error %08lx\n", status );
1418
1421 status = map_image_section( (IMAGE_NT_HEADERS *)&nt64, &section, &cor_header, __LINE__ );
1423 "NtCreateSection error %08lx\n", status );
1424 }
1425#ifdef __REACTOS__
1426 else if (is_reactos() && orig_machine == IMAGE_FILE_MACHINE_AMD64)
1427 {
1428 ok(FALSE, "FIXME: These tests crash on ReactOS x64!\n");
1429 }
1430 else
1431#else
1432 else
1433#endif
1434 {
1435 IMAGE_NT_HEADERS32 nt32;
1436
1437 memset( &nt32, 0, sizeof(nt32) );
1439 nt32.FileHeader.Machine = orig_machine;
1445 nt32.OptionalHeader.SizeOfCode = 0x1000;
1446 nt32.OptionalHeader.AddressOfEntryPoint = 0x1000;
1447 nt32.OptionalHeader.ImageBase = 0x10000000;
1448 nt32.OptionalHeader.SectionAlignment = 0x1000;
1449 nt32.OptionalHeader.FileAlignment = 0x1000;
1453 nt32.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt32) + sizeof(IMAGE_SECTION_HEADER);
1456 nt32.OptionalHeader.SizeOfStackReserve = 0x321000;
1457 nt32.OptionalHeader.SizeOfStackCommit = 0x123000;
1459
1461 ok( status == STATUS_INVALID_IMAGE_FORMAT, "NtCreateSection error %08lx\n", status );
1462
1463 if (orig_machine == IMAGE_FILE_MACHINE_AMD64)
1464 {
1468 "NtCreateSection error %08lx\n", status );
1469 }
1470
1473 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1474
1475 nt32.OptionalHeader.SizeOfCode = 0;
1476 nt32.OptionalHeader.AddressOfEntryPoint = 0x1000;
1477 section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
1479 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1480
1481 nt32.OptionalHeader.SizeOfCode = 0;
1485 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1486
1487 nt32.OptionalHeader.SizeOfCode = 0x1000;
1490 section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
1492 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1493
1494 nt32.OptionalHeader.SizeOfCode = 0;
1496 section.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE;
1498 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1499
1503 cor_header.MajorRuntimeVersion = 2;
1504 cor_header.MinorRuntimeVersion = 4;
1505 cor_header.Flags = COMIMAGE_FLAGS_ILONLY;
1506 status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, &section, &cor_header, __LINE__ );
1507 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1508
1509 nt32.OptionalHeader.SizeOfCode = 0x1000;
1510 status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, &section, &cor_header, __LINE__ );
1511 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1512
1513 cor_header.MinorRuntimeVersion = 5;
1514 status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, &section, &cor_header, __LINE__ );
1515 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1516
1518 status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, &section, &cor_header, __LINE__ );
1519 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1520
1522 status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, &section, &cor_header, __LINE__ );
1523 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1524
1525 cor_header.Flags = 0;
1526 status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, &section, &cor_header, __LINE__ );
1527 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1528
1531 status = map_image_section( (IMAGE_NT_HEADERS *)&nt32, &section, &cor_header, __LINE__ );
1532 ok( status == STATUS_SUCCESS, "NtCreateSection error %08lx\n", status );
1533 }
1534
1537}
struct _IMAGE_FILE_HEADER IMAGE_FILE_HEADER
GLuint start
Definition: gl.h:1545
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
static DWORD
Definition: loader.c:67
static WORD get_alt_bitness_machine(WORD orig_machine)
Definition: loader.c:196
static void delete_load_path(void)
Definition: loader.c:588
static NTSTATUS map_image_section(const IMAGE_NT_HEADERS *nt_header, const IMAGE_SECTION_HEADER *sections, const void *section_data, int line)
Definition: loader.c:613
static void init_load_path(const char *fallback_dll)
Definition: loader.c:559
#define ALIGN_SIZE(size, alignment)
Definition: loader.c:40
unsigned int UINT
Definition: ndis.h:50
#define MEM_FREE
Definition: nt_native.h:1320
#define PAGE_NOACCESS
Definition: nt_native.h:1305
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:1029
#define STATUS_INVALID_IMAGE_WIN_16
Definition: ntstatus.h:635
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:633
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:634
#define IMAGE_FILE_MACHINE_UNKNOWN
Definition: pedump.c:173
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define is_reactos()
Definition: test.h:1041
IMAGE_FILE_HEADER FileHeader
Definition: ntimage.h:395
USHORT MajorSubsystemVersion
Definition: ntimage.h:356
ULONGLONG SizeOfStackReserve
Definition: ntimage.h:364
ULONGLONG SizeOfStackCommit
Definition: ntimage.h:365
USHORT MajorOperatingSystemVersion
Definition: ntimage.h:352
#define LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
Definition: winbase.h:344
#define LOAD_LIBRARY_AS_IMAGE_RESOURCE
Definition: winbase.h:343
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:338
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:257
#define ERROR_NOACCESS
Definition: winerror.h:902

Referenced by START_TEST().

◆ test_LoadPackagedLibrary()

static void test_LoadPackagedLibrary ( void  )
static

Definition at line 4775 of file loader.c.

4776{
4777 HMODULE h;
4778
4779 if (!pLoadPackagedLibrary)
4780 {
4781 win_skip("LoadPackagedLibrary is not available.\n");
4782 return;
4783 }
4784
4785 SetLastError( 0xdeadbeef );
4786 h = pLoadPackagedLibrary(L"kernel32.dll", 0);
4787 ok(!h && GetLastError() == APPMODEL_ERROR_NO_PACKAGE, "Got unexpected handle %p, GetLastError() %lu.\n",
4788 h, GetLastError());
4789}
#define APPMODEL_ERROR_NO_PACKAGE
Definition: winerror.h:3400

Referenced by START_TEST().

◆ test_ResolveDelayLoadedAPI()

static void test_ResolveDelayLoadedAPI ( void  )
static

Definition at line 4351 of file loader.c.

4352{
4353 static const char test_dll[] = "secur32.dll";
4354 static const char test_func[] = "SealMessage";
4355 char temp_path[MAX_PATH];
4356 char dll_name[MAX_PATH];
4357 IMAGE_DELAYLOAD_DESCRIPTOR idd, *delaydir;
4358 IMAGE_THUNK_DATA itd32;
4359 HANDLE hfile;
4360 HMODULE hlib;
4362 WORD hint = 0;
4363 BOOL ret;
4365
4366 static const struct test_data
4367 {
4368 BOOL func;
4369 UINT_PTR ordinal;
4370 BOOL succeeds;
4371 } td[] =
4372 {
4373 {
4374 TRUE, 0, TRUE
4375 },
4376 {
4378 },
4379 {
4381 },
4382 {
4384 },
4385 {
4387 },
4388 };
4389
4390 if (!pResolveDelayLoadedAPI)
4391 {
4392 win_skip("ResolveDelayLoadedAPI is not available\n");
4393 return;
4394 }
4395
4396 if (0) /* crashes on native */
4397 {
4398 SetLastError(0xdeadbeef);
4399 ok(!pResolveDelayLoadedAPI(NULL, NULL, NULL, NULL, NULL, 0),
4400 "ResolveDelayLoadedAPI succeeded\n");
4401 ok(GetLastError() == 0xdeadbeef, "GetLastError changed to %lx\n", GetLastError());
4402
4403 cb_count = 0;
4404 SetLastError(0xdeadbeef);
4405 ok(!pResolveDelayLoadedAPI(NULL, NULL, failuredllhook, NULL, NULL, 0),
4406 "ResolveDelayLoadedAPI succeeded\n");
4407 ok(GetLastError() == 0xdeadbeef, "GetLastError changed to %lx\n", GetLastError());
4408 ok(cb_count == 1, "Wrong callback count: %d\n", cb_count);
4409 }
4410
4412 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
4413 trace("creating %s\n", dll_name);
4414 hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
4415 if (hfile == INVALID_HANDLE_VALUE)
4416 {
4417 ok(0, "could not create %s\n", dll_name);
4418 return;
4419 }
4420
4421 SetLastError(0xdeadbeef);
4422 ret = WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL);
4423 ok(ret, "WriteFile error %ld\n", GetLastError());
4424
4428
4431 nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x2200;
4436
4437 SetLastError(0xdeadbeef);
4438 ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
4439 ok(ret, "WriteFile error %ld\n", GetLastError());
4440
4441 SetLastError(0xdeadbeef);
4443 ok(ret, "WriteFile error %ld\n", GetLastError());
4444
4445 /* sections */
4448 section.Misc.VirtualSize = 0x1000;
4449 section.SizeOfRawData = 2 * sizeof(idd);
4451 SetLastError(0xdeadbeef);
4452 ret = WriteFile(hfile, &section, sizeof(section), &dummy, NULL);
4453 ok(ret, "WriteFile error %ld\n", GetLastError());
4454
4455 section.PointerToRawData = 0x2000;
4456 section.VirtualAddress = 0x2000;
4457 i = ARRAY_SIZE(td);
4458 section.SizeOfRawData = sizeof(test_dll) + sizeof(hint) + sizeof(test_func) + sizeof(HMODULE) +
4459 2 * (i + 1) * sizeof(IMAGE_THUNK_DATA);
4460 ok(section.SizeOfRawData <= 0x1000, "Too much tests, add a new section!\n");
4461 section.Misc.VirtualSize = 0x1000;
4463 SetLastError(0xdeadbeef);
4464 ret = WriteFile(hfile, &section, sizeof(section), &dummy, NULL);
4465 ok(ret, "WriteFile error %ld\n", GetLastError());
4466
4467 /* fill up to delay data */
4469
4470 /* delay data */
4471 idd.Attributes.AllAttributes = 1;
4472 idd.DllNameRVA = 0x2000;
4473 idd.ModuleHandleRVA = idd.DllNameRVA + sizeof(test_dll) + sizeof(hint) + sizeof(test_func);
4474 idd.ImportAddressTableRVA = idd.ModuleHandleRVA + sizeof(HMODULE);
4475 idd.ImportNameTableRVA = idd.ImportAddressTableRVA + (i + 1) * sizeof(IMAGE_THUNK_DATA);
4478 idd.TimeDateStamp = 0;
4479
4480 SetLastError(0xdeadbeef);
4481 ret = WriteFile(hfile, &idd, sizeof(idd), &dummy, NULL);
4482 ok(ret, "WriteFile error %ld\n", GetLastError());
4483
4484 SetLastError(0xdeadbeef);
4485 ret = WriteFile(hfile, filler, sizeof(idd), &dummy, NULL);
4486 ok(ret, "WriteFile error %ld\n", GetLastError());
4487
4488 /* fill up to extended delay data */
4489 SetFilePointer( hfile, idd.DllNameRVA, NULL, SEEK_SET );
4490
4491 /* extended delay data */
4492 SetLastError(0xdeadbeef);
4493 ret = WriteFile(hfile, test_dll, sizeof(test_dll), &dummy, NULL);
4494 ok(ret, "WriteFile error %ld\n", GetLastError());
4495
4496 SetLastError(0xdeadbeef);
4497 ret = WriteFile(hfile, &hint, sizeof(hint), &dummy, NULL);
4498 ok(ret, "WriteFile error %ld\n", GetLastError());
4499
4500 SetLastError(0xdeadbeef);
4501 ret = WriteFile(hfile, test_func, sizeof(test_func), &dummy, NULL);
4502 ok(ret, "WriteFile error %ld\n", GetLastError());
4503
4505
4506 for (i = 0; i < ARRAY_SIZE(td); i++)
4507 {
4508 /* 0x1a00 is an empty space between delay data and extended delay data, real thunks are not necessary */
4509 itd32.u1.Function = nt_header.OptionalHeader.ImageBase + 0x1a00 + i * 0x20;
4510 SetLastError(0xdeadbeef);
4511 ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
4512 ok(ret, "WriteFile error %ld\n", GetLastError());
4513 }
4514
4515 itd32.u1.Function = 0;
4516 SetLastError(0xdeadbeef);
4517 ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
4518 ok(ret, "WriteFile error %ld\n", GetLastError());
4519
4520 for (i = 0; i < ARRAY_SIZE(td); i++)
4521 {
4522 if (td[i].func)
4523 itd32.u1.AddressOfData = idd.DllNameRVA + sizeof(test_dll);
4524 else
4525 itd32.u1.Ordinal = td[i].ordinal;
4526 SetLastError(0xdeadbeef);
4527 ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
4528 ok(ret, "WriteFile error %ld\n", GetLastError());
4529 }
4530
4531 itd32.u1.Ordinal = 0;
4532 SetLastError(0xdeadbeef);
4533 ret = WriteFile(hfile, &itd32, sizeof(itd32), &dummy, NULL);
4534 ok(ret, "WriteFile error %ld\n", GetLastError());
4535
4536 /* fill up to eof */
4537 SetFilePointer( hfile, section.VirtualAddress + section.Misc.VirtualSize, NULL, SEEK_SET );
4538 SetEndOfFile( hfile );
4539 CloseHandle(hfile);
4540
4541 SetLastError(0xdeadbeef);
4542 hlib = LoadLibraryA(dll_name);
4543 ok(hlib != NULL, "LoadLibrary error %lu\n", GetLastError());
4544 if (!hlib)
4545 {
4546 skip("couldn't load %s.\n", dll_name);
4547 DeleteFileA(dll_name);
4548 return;
4549 }
4550
4551 delaydir = pRtlImageDirectoryEntryToData(hlib, TRUE, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, &file_size);
4552 if (!delaydir)
4553 {
4554 skip("haven't found section for delay import directory.\n");
4555 FreeLibrary(hlib);
4556 DeleteFileA(dll_name);
4557 return;
4558 }
4559
4560 for (;;)
4561 {
4562 IMAGE_THUNK_DATA *itdn, *itda;
4563 HMODULE htarget;
4564
4565 if (!delaydir->DllNameRVA ||
4566 !delaydir->ImportAddressTableRVA ||
4567 !delaydir->ImportNameTableRVA) break;
4568
4569 itdn = RVAToAddr(delaydir->ImportNameTableRVA, hlib);
4570 itda = RVAToAddr(delaydir->ImportAddressTableRVA, hlib);
4571 htarget = LoadLibraryA(RVAToAddr(delaydir->DllNameRVA, hlib));
4572
4573 for (i = 0; i < ARRAY_SIZE(td); i++)
4574 {
4575 void *ret, *load;
4576
4577 /* relocate thunk address by hand since we don't generate reloc records */
4578 itda[i].u1.AddressOfData += (char *)hlib - (char *)nt_header.OptionalHeader.ImageBase;
4579
4580 if (IMAGE_SNAP_BY_ORDINAL(itdn[i].u1.Ordinal))
4581 load = (void *)GetProcAddress(htarget, (LPSTR)IMAGE_ORDINAL(itdn[i].u1.Ordinal));
4582 else
4583 {
4584 const IMAGE_IMPORT_BY_NAME* iibn = RVAToAddr(itdn[i].u1.AddressOfData, hlib);
4585 load = (void *)GetProcAddress(htarget, (char*)iibn->Name);
4586 }
4587
4588 /* test without failure dll callback */
4589 cb_count = cb_count_sys = 0;
4590 ret = pResolveDelayLoadedAPI(hlib, delaydir, NULL, failuresyshook, &itda[i], 0);
4591 if (td[i].succeeds)
4592 {
4593 ok(ret != NULL, "Test %lu: ResolveDelayLoadedAPI failed\n", i);
4594 ok(ret == load, "Test %lu: expected %p, got %p\n", i, load, ret);
4595 ok(ret == (void*)itda[i].u1.AddressOfData, "Test %lu: expected %p, got %p\n",
4596 i, ret, (void*)itda[i].u1.AddressOfData);
4597 ok(!cb_count, "Test %lu: Wrong callback count: %d\n", i, cb_count);
4598 ok(!cb_count_sys, "Test %lu: Wrong sys callback count: %d\n", i, cb_count_sys);
4599 }
4600 else
4601 {
4602 ok(ret == (void*)0x12345678, "Test %lu: ResolveDelayLoadedAPI succeeded with %p\n", i, ret);
4603 ok(!cb_count, "Test %lu: Wrong callback count: %d\n", i, cb_count);
4604 ok(cb_count_sys == 1, "Test %lu: Wrong sys callback count: %d\n", i, cb_count_sys);
4605 }
4606
4607 /* test with failure dll callback */
4608 cb_count = cb_count_sys = 0;
4609 ret = pResolveDelayLoadedAPI(hlib, delaydir, failuredllhook, failuresyshook, &itda[i], 0);
4610 if (td[i].succeeds)
4611 {
4612 ok(ret != NULL, "Test %lu: ResolveDelayLoadedAPI failed\n", i);
4613 ok(ret == load, "Test %lu: expected %p, got %p\n", i, load, ret);
4614 ok(ret == (void*)itda[i].u1.AddressOfData, "Test %lu: expected %p, got %p\n",
4615 i, ret, (void*)itda[i].u1.AddressOfData);
4616 ok(!cb_count, "Test %lu: Wrong callback count: %d\n", i, cb_count);
4617 ok(!cb_count_sys, "Test %lu: Wrong sys callback count: %d\n", i, cb_count_sys);
4618 }
4619 else
4620 {
4621 if (ret == (void*)0x12345678)
4622 {
4623 /* Win10+ sometimes buffers the address of the stub function */
4624 ok(!cb_count, "Test %lu: Wrong callback count: %d\n", i, cb_count);
4625 ok(!cb_count_sys, "Test %lu: Wrong sys callback count: %d\n", i, cb_count_sys);
4626 }
4627 else if (ret == (void*)0xdeadbeef)
4628 {
4629 ok(cb_count == 1, "Test %lu: Wrong callback count: %d\n", i, cb_count);
4630 ok(!cb_count_sys, "Test %lu: Wrong sys callback count: %d\n", i, cb_count_sys);
4631 }
4632 else
4633 ok(0, "Test %lu: ResolveDelayLoadedAPI succeeded with %p\n", i, ret);
4634 }
4635 }
4636 delaydir++;
4637 }
4638
4639 FreeLibrary(hlib);
4640 trace("deleting %s\n", dll_name);
4641 DeleteFileA(dll_name);
4642}
GLenum func
Definition: glext.h:6028
GLdouble u1
Definition: glext.h:8308
static PVOID WINAPI failuresyshook(const char *dll, const char *function)
Definition: loader.c:4343
static PVOID WINAPI failuredllhook(ULONG ul, DELAYLOAD_INFO *pd)
Definition: loader.c:4290
static void test_func(IDispatchEx *obj)
Definition: script.c:1872
int load
Definition: msacm.c:1365
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
Definition: ntimage.h:488
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
HANDLE HMODULE
Definition: typedefs.h:77

Referenced by START_TEST().

◆ test_section_access()

static void test_section_access ( void  )
static

Definition at line 1920 of file loader.c.

1921{
1922 static const struct test_data
1923 {
1924 DWORD scn_file_access, scn_page_access, scn_page_access_after_write;
1925 } td[] =
1926 {
1927 { 0, PAGE_NOACCESS, 0 },
1935
1944
1953 };
1954 char buf[256];
1955 int i;
1956 DWORD dummy;
1957 HANDLE hfile;
1958 HMODULE hlib;
1959 char temp_path[MAX_PATH];
1960 char dll_name[MAX_PATH];
1961 SIZE_T size;
1962 PEB child_peb;
1964 SECTION_IMAGE_INFORMATION image_info;
1966 STARTUPINFOA sti;
1969 DWORD ret;
1970
1971 /* prevent displaying of the "Unable to load this DLL" message box */
1973
1975
1976 for (i = 0; i < ARRAY_SIZE(td); i++)
1977 {
1979
1980 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
1981
1982 /*trace("creating %s\n", dll_name);*/
1983 hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
1984 if (hfile == INVALID_HANDLE_VALUE)
1985 {
1986 ok(0, "could not create %s\n", dll_name);
1987 return;
1988 }
1989
1990 SetLastError(0xdeadbeef);
1991 ret = WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL);
1992 ok(ret, "WriteFile error %ld\n", GetLastError());
1993
1999
2000 section.SizeOfRawData = sizeof(section_data);
2001 section.PointerToRawData = nt_header.OptionalHeader.FileAlignment;
2003 section.Misc.VirtualSize = section.SizeOfRawData;
2004 section.Characteristics = td[i].scn_file_access;
2005 SetLastError(0xdeadbeef);
2006
2007 SetLastError(0xdeadbeef);
2008 ret = WriteFile(hfile, &nt_header, sizeof(nt_header), &dummy, NULL);
2009 ok(ret, "WriteFile error %ld\n", GetLastError());
2010
2011 ret = WriteFile(hfile, &section, sizeof(section), &dummy, NULL);
2012 ok(ret, "WriteFile error %ld\n", GetLastError());
2013
2014 /* section data */
2016 SetLastError(0xdeadbeef);
2017 ret = WriteFile(hfile, section_data, sizeof(section_data), &dummy, NULL);
2018 ok(ret, "WriteFile error %ld\n", GetLastError());
2019
2020 CloseHandle(hfile);
2021 SetLastError(0xdeadbeef);
2023 ok(hlib != 0, "LoadLibrary error %ld\n", GetLastError());
2024
2025 SetLastError(0xdeadbeef);
2026 size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info));
2027 ok(size == sizeof(info),
2028 "%d: VirtualQuery error %ld\n", i, GetLastError());
2029 ok(info.BaseAddress == (char *)hlib + section.VirtualAddress, "%d: got %p != expected %p\n", i, info.BaseAddress, (char *)hlib + section.VirtualAddress);
2030 ok(info.RegionSize == page_size, "%d: got %#Ix != expected %#lx\n", i, info.RegionSize, page_size);
2031 ok(info.Protect == td[i].scn_page_access, "%d: got %#lx != expected %#lx\n", i, info.Protect, td[i].scn_page_access);
2032 ok(info.AllocationBase == hlib, "%d: %p != %p\n", i, info.AllocationBase, hlib);
2033 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#lx != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect);
2034 ok(info.State == MEM_COMMIT, "%d: %#lx != MEM_COMMIT\n", i, info.State);
2035 ok(info.Type == SEC_IMAGE, "%d: %#lx != SEC_IMAGE\n", i, info.Type);
2036 if (info.Protect != PAGE_NOACCESS)
2037 ok(!memcmp((const char *)info.BaseAddress, section_data, section.SizeOfRawData), "wrong section data\n");
2038
2039 test_VirtualProtect(hlib, (char *)hlib + section.VirtualAddress);
2040
2041 /* Windows changes the WRITECOPY to WRITE protection on an image section write (for a changed page only) */
2042 if (is_mem_writable(info.Protect))
2043 {
2044 char *p = info.BaseAddress;
2045 *p = 0xfe;
2046 SetLastError(0xdeadbeef);
2047 size = VirtualQuery((char *)hlib + section.VirtualAddress, &info, sizeof(info));
2048 ok(size == sizeof(info), "%d: VirtualQuery error %ld\n", i, GetLastError());
2049 /* FIXME: remove the condition below once Wine is fixed */
2051 ok(info.Protect == td[i].scn_page_access_after_write, "%d: got %#lx != expected %#lx\n", i, info.Protect, td[i].scn_page_access_after_write);
2052 }
2053
2054 SetLastError(0xdeadbeef);
2055 ret = FreeLibrary(hlib);
2056 ok(ret, "FreeLibrary error %ld\n", GetLastError());
2057
2058 test_image_mapping(dll_name, td[i].scn_page_access, TRUE);
2059
2060 /* reset IMAGE_FILE_DLL otherwise CreateProcess fails */
2062 SetLastError(0xdeadbeef);
2063 hfile = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
2064 /* LoadLibrary called on an already memory-mapped file in
2065 * test_image_mapping() above leads to a file handle leak
2066 * under nt4, and inability to overwrite and delete the file
2067 * due to sharing violation error. Ignore it and skip the test,
2068 * but leave a not deletable temporary file.
2069 */
2070 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
2071 SetFilePointer(hfile, sizeof(dos_header), NULL, FILE_BEGIN);
2072 SetLastError(0xdeadbeef);
2073 ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
2074 ok(ret, "WriteFile error %ld\n", GetLastError());
2075 CloseHandle(hfile);
2076
2077 memset(&sti, 0, sizeof(sti));
2078 sti.cb = sizeof(sti);
2079 SetLastError(0xdeadbeef);
2080 ret = CreateProcessA(dll_name, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi);
2081 ok(ret, "CreateProcess() error %ld\n", GetLastError());
2082
2083 status = pNtQueryInformationProcess( pi.hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL );
2084 ok( !status, "ProcessBasicInformation got %lx\n", status );
2085 ret = ReadProcessMemory( pi.hProcess, pbi.PebBaseAddress, &child_peb, sizeof(child_peb), NULL );
2086 ok( ret, "ReadProcessMemory failed err %lu\n", GetLastError() );
2087 hlib = child_peb.ImageBaseAddress;
2088
2089 SetLastError(0xdeadbeef);
2090 size = VirtualQueryEx(pi.hProcess, (char *)hlib + section.VirtualAddress, &info, sizeof(info));
2091 ok(size == sizeof(info),
2092 "%d: VirtualQuery error %ld\n", i, GetLastError());
2093 ok(info.BaseAddress == (char *)hlib + section.VirtualAddress, "%d: got %p != expected %p\n", i, info.BaseAddress, (char *)hlib + section.VirtualAddress);
2094 ok(info.RegionSize == page_size, "%d: got %#Ix != expected %#lx\n", i, info.RegionSize, page_size);
2095 ok(info.Protect == td[i].scn_page_access, "%d: got %#lx != expected %#lx\n", i, info.Protect, td[i].scn_page_access);
2096 ok(info.AllocationBase == hlib, "%d: %p != %p\n", i, info.AllocationBase, hlib);
2097 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%d: %#lx != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect);
2098 ok(info.State == MEM_COMMIT, "%d: %#lx != MEM_COMMIT\n", i, info.State);
2099 ok(info.Type == SEC_IMAGE, "%d: %#lx != SEC_IMAGE\n", i, info.Type);
2100 if (info.Protect != PAGE_NOACCESS)
2101 {
2102 SetLastError(0xdeadbeef);
2103 ret = ReadProcessMemory(pi.hProcess, info.BaseAddress, buf, section.SizeOfRawData, NULL);
2104 ok(ret, "ReadProcessMemory() error %ld\n", GetLastError());
2105 ok(!memcmp(buf, section_data, section.SizeOfRawData), "wrong section data\n");
2106 }
2107
2108#ifdef __REACTOS__
2109 if (GetNTVersion() >= _WIN32_WINNT_VISTA) { // Crashes on WS03
2110#endif
2112 &image_info, sizeof(image_info), NULL );
2113 ok(!status, "Got unexpected status %#lx.\n", status);
2114 ok(!(image_info.ImageCharacteristics & IMAGE_FILE_DLL),
2115 "Got unexpected characteristics %#x.\n", nt_header.FileHeader.Characteristics);
2116 status = NtUnmapViewOfSection(pi.hProcess, info.BaseAddress);
2117 ok(!status, "Got unexpected status %#lx.\n", status);
2119 &image_info, sizeof(image_info), NULL );
2120 ok(!status, "Got unexpected status %#lx.\n", status);
2121 ok(!(image_info.ImageCharacteristics & IMAGE_FILE_DLL),
2122 "Got unexpected characteristics %#x.\n", nt_header.FileHeader.Characteristics);
2123#ifdef __REACTOS__
2124 }
2125#endif
2126
2127 SetLastError(0xdeadbeef);
2129 ok(ret, "TerminateProcess() error %ld\n", GetLastError());
2131 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed: %lx\n", ret);
2132
2135
2136 test_image_mapping(dll_name, td[i].scn_page_access, FALSE);
2137
2138 DeleteFileA(dll_name);
2139 }
2140}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3483
@ ProcessImageInformation
Definition: winternl.h:1919
static void test_image_mapping(const char *dll_name, DWORD scn_page_access, BOOL is_dll)
Definition: loader.c:1673
static BOOL is_mem_writable(DWORD prot)
Definition: loader.c:1777
static void test_VirtualProtect(void)
Definition: virtual.c:3269
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1310
#define PAGE_EXECUTE
Definition: nt_native.h:1309
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA
Definition: ntimage.h:232
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245

Referenced by START_TEST().

◆ test_VirtualProtect()

static void test_VirtualProtect ( void base,
void section 
)
static

Definition at line 1792 of file loader.c.

1793{
1794 static const struct test_data
1795 {
1796 DWORD prot_set, prot_get;
1797 } td[] =
1798 {
1799 { 0, 0 }, /* 0x00 */
1800 { PAGE_NOACCESS, PAGE_NOACCESS }, /* 0x01 */
1801 { PAGE_READONLY, PAGE_READONLY }, /* 0x02 */
1802 { PAGE_READONLY | PAGE_NOACCESS, 0 }, /* 0x03 */
1803 { PAGE_READWRITE, PAGE_WRITECOPY }, /* 0x04 */
1804 { PAGE_READWRITE | PAGE_NOACCESS, 0 }, /* 0x05 */
1805 { PAGE_READWRITE | PAGE_READONLY, 0 }, /* 0x06 */
1806 { PAGE_READWRITE | PAGE_READONLY | PAGE_NOACCESS, 0 }, /* 0x07 */
1807 { PAGE_WRITECOPY, PAGE_WRITECOPY }, /* 0x08 */
1808 { PAGE_WRITECOPY | PAGE_NOACCESS, 0 }, /* 0x09 */
1809 { PAGE_WRITECOPY | PAGE_READONLY, 0 }, /* 0x0a */
1810 { PAGE_WRITECOPY | PAGE_NOACCESS | PAGE_READONLY, 0 }, /* 0x0b */
1811 { PAGE_WRITECOPY | PAGE_READWRITE, 0 }, /* 0x0c */
1812 { PAGE_WRITECOPY | PAGE_READWRITE | PAGE_NOACCESS, 0 }, /* 0x0d */
1813 { PAGE_WRITECOPY | PAGE_READWRITE | PAGE_READONLY, 0 }, /* 0x0e */
1815
1816 { PAGE_EXECUTE, PAGE_EXECUTE }, /* 0x10 */
1817 { PAGE_EXECUTE_READ, PAGE_EXECUTE_READ }, /* 0x20 */
1818 { PAGE_EXECUTE_READ | PAGE_EXECUTE, 0 }, /* 0x30 */
1820 { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE, 0 }, /* 0x50 */
1821 { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ, 0 }, /* 0x60 */
1824 { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE, 0 }, /* 0x90 */
1825 { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READ, 0 }, /* 0xa0 */
1831 };
1832 DWORD ret, orig_prot, old_prot, rw_prot, exec_prot, i, j;
1834
1835 SetLastError(0xdeadbeef);
1837 ok(ret, "VirtualProtect error %ld\n", GetLastError());
1838
1839 orig_prot = old_prot;
1840
1841 for (i = 0; i < ARRAY_SIZE(td); i++)
1842 {
1843 SetLastError(0xdeadbeef);
1844 ret = VirtualQuery(section, &info, sizeof(info));
1845 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
1846 ok(info.BaseAddress == section, "%ld: got %p != expected %p\n", i, info.BaseAddress, section);
1847 ok(info.RegionSize == page_size, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, page_size);
1848 ok(info.Protect == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, info.Protect);
1849 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
1850 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%ld: %#lx != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect);
1851 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
1852 ok(info.Type == SEC_IMAGE, "%ld: %#lx != SEC_IMAGE\n", i, info.Type);
1853
1854 old_prot = 0xdeadbeef;
1855 SetLastError(0xdeadbeef);
1856 ret = VirtualProtect(section, page_size, td[i].prot_set, &old_prot);
1857 if (td[i].prot_get)
1858 {
1859 ok(ret, "%ld: VirtualProtect error %ld, requested prot %#lx\n", i, GetLastError(), td[i].prot_set);
1860 ok(old_prot == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, old_prot);
1861
1862 SetLastError(0xdeadbeef);
1863 ret = VirtualQuery(section, &info, sizeof(info));
1864 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
1865 ok(info.BaseAddress == section, "%ld: got %p != expected %p\n", i, info.BaseAddress, section);
1866 ok(info.RegionSize == page_size, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, page_size);
1867 ok(info.Protect == td[i].prot_get, "%ld: got %#lx != expected %#lx\n", i, info.Protect, td[i].prot_get);
1868 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
1869 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%ld: %#lx != PAGE_EXECUTE_WRITECOPY\n", i, info.AllocationProtect);
1870 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
1871 ok(info.Type == SEC_IMAGE, "%ld: %#lx != SEC_IMAGE\n", i, info.Type);
1872 }
1873 else
1874 {
1875 ok(!ret, "%ld: VirtualProtect should fail\n", i);
1876 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
1877 }
1878
1879 old_prot = 0xdeadbeef;
1880 SetLastError(0xdeadbeef);
1882 ok(ret, "%ld: VirtualProtect error %ld\n", i, GetLastError());
1883 if (td[i].prot_get)
1884 ok(old_prot == td[i].prot_get, "%ld: got %#lx != expected %#lx\n", i, old_prot, td[i].prot_get);
1885 else
1886 ok(old_prot == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, old_prot);
1887 }
1888
1889 exec_prot = 0;
1890
1891 for (i = 0; i <= 4; i++)
1892 {
1893 rw_prot = 0;
1894
1895 for (j = 0; j <= 4; j++)
1896 {
1897 DWORD prot = exec_prot | rw_prot;
1898
1899 SetLastError(0xdeadbeef);
1900 ret = VirtualProtect(section, page_size, prot, &old_prot);
1901 if ((rw_prot && exec_prot) || (!rw_prot && !exec_prot))
1902 {
1903 ok(!ret, "VirtualProtect(%02lx) should fail\n", prot);
1904 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
1905 }
1906 else
1907 ok(ret, "VirtualProtect(%02lx) error %ld\n", prot, GetLastError());
1908
1909 rw_prot = 1 << j;
1910 }
1911
1912 exec_prot = 1 << (i + 4);
1913 }
1914
1915 SetLastError(0xdeadbeef);
1916 ret = VirtualProtect(section, page_size, orig_prot, &old_prot);
1917 ok(ret, "VirtualProtect error %ld\n", GetLastError());
1918}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BOOL NTAPI VirtualProtect(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:135

◆ test_wow64_redirection()

static void test_wow64_redirection ( void  )
static

Definition at line 4702 of file loader.c.

4703{
4704 void *OldValue;
4705 char buffer[MAX_PATH];
4706 static const char *dlls[] = {"wlanapi.dll", "dxgi.dll", "dwrite.dll"};
4707 unsigned i;
4708
4709 if (!is_wow64)
4710 return;
4711
4712 /* Disable FS redirection, then test loading system libraries (pick ones that shouldn't
4713 * already be loaded in this process).
4714 */
4715 ok(pWow64DisableWow64FsRedirection(&OldValue), "Disabling FS redirection failed\n");
4716 for (i = 0; i < ARRAY_SIZE(dlls); i++)
4717 {
4719 /* even absolute paths to syswow64 are loaded with path to system32 */
4720 snprintf(buffer, ARRAY_SIZE(buffer), "%s\\%s", syswow_dir, dlls[i]);
4722 }
4723
4724 ok(pWow64RevertWow64FsRedirection(OldValue), "Re-enabling FS redirection failed\n");
4725 /* and results don't depend whether redirection is enabled or not */
4726 for (i = 0; i < ARRAY_SIZE(dlls); i++)
4727 {
4729 snprintf(buffer, ARRAY_SIZE(buffer), "%s\\%s", syswow_dir, dlls[i]);
4731 }
4732}
static void test_wow64_redirection_for_dll(const char *libname, BOOL will_fail)
Definition: loader.c:4672

Referenced by START_TEST().

◆ test_wow64_redirection_for_dll()

static void test_wow64_redirection_for_dll ( const char libname,
BOOL  will_fail 
)
static

Definition at line 4672 of file loader.c.

4673{
4674 HMODULE lib;
4675 char buf[256];
4676 const char *modname;
4677
4678 if (!GetModuleHandleA(libname))
4679 {
4680 lib = LoadLibraryExA(libname, NULL, 0);
4681 ok(lib != NULL, "Loading %s should succeed with WOW64 redirection disabled\n", libname);
4682 /* Win 7/2008R2 return the un-redirected path (i.e. c:\windows\system32\dwrite.dll), test loading it. */
4683 GetModuleFileNameA(lib, buf, sizeof(buf));
4684 FreeLibrary(lib);
4685 lib = LoadLibraryExA(buf, NULL, 0);
4686 ok(lib != NULL, "Loading %s from full path should succeed with WOW64 redirection disabled\n", libname);
4687 if (lib)
4688 FreeLibrary(lib);
4689 modname = strrchr(libname, '\\');
4690 modname = modname ? modname + 1 : libname;
4691 todo_wine_if(will_fail)
4692 ok(is_path_made_of(buf, system_dir, modname) ||
4693 /* Win7 report from syswow64 */ broken(is_path_made_of(buf, syswow_dir, modname)),
4694 "Unexpected loaded DLL name %s for %s\n", buf, libname);
4695 }
4696 else
4697 {
4698 skip("%s was already loaded in the process\n", libname);
4699 }
4700}
static BOOL is_path_made_of(const char *filename, const char *pfx, const char *sfx)
Definition: loader.c:4665

Referenced by test_wow64_redirection().

◆ test_Wow64Transition()

static void test_Wow64Transition ( void  )
static

Definition at line 4791 of file loader.c.

4792{
4793 char buffer[400];
4795 const WCHAR *filepart;
4796 void **pWow64Transition;
4798
4799 if (!(pWow64Transition = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "Wow64Transition")))
4800 {
4801 skip("Wow64Transition is not present\n");
4802 return;
4803 }
4804 if (!is_wow64)
4805 {
4806 skip("Wow64Transition is not patched\n");
4807 return;
4808 }
4809
4810 status = NtQueryVirtualMemory(GetCurrentProcess(), *pWow64Transition,
4812 ok(!status, "got %#lx\n", status);
4813 filepart = name->SectionFileName.Buffer + name->SectionFileName.Length / sizeof(WCHAR);
4814 while (*filepart != '\\') --filepart;
4815 ok(!wcsnicmp(filepart, L"\\wow64cpu.dll", wcslen(L"\\wow64cpu.dll")), "got file name %s\n",
4816 debugstr_wn(name->SectionFileName.Buffer, name->SectionFileName.Length / sizeof(WCHAR)));
4817}
#define wcsnicmp
Definition: compat.h:14
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
@ MemoryMappedFilenameInformation
Definition: winternl.h:2387
#define debugstr_wn
Definition: kernel32.h:33
NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN MEMORY_INFORMATION_CLASS MemoryInformationClass, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
Definition: virtual.c:4374

Referenced by START_TEST().

◆ tls_thread_fn()

static DWORD WINAPI tls_thread_fn ( void tlsidx_v)
static

Definition at line 2171 of file loader.c.

2172{
2173 int tls_index = (int)(DWORD_PTR)(tlsidx_v);
2174 const char* str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[tls_index];
2175 ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str );
2177 "tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_THREAD_ATTACH );
2178 tls_init_fn_output = 9999;
2179 return 0;
2180}
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by test_import_resolution().

◆ void()

static void ( WINAPI pLdrShutdownProcess)
static

Variable Documentation

◆ ACCESS_MASK

Definition at line 60 of file loader.c.

◆ ack_event

HANDLE ack_event
static

Definition at line 2948 of file loader.c.

Referenced by child_process(), and mutex_thread_proc().

◆ attached_thread

HANDLE attached_thread[MAX_COUNT]
static

Definition at line 2945 of file loader.c.

Referenced by child_process(), and dll_entry_point().

◆ attached_thread_count

DWORD attached_thread_count
static

Definition at line 2946 of file loader.c.

Referenced by child_process(), and dll_entry_point().

◆ BOOL

Definition at line 83 of file loader.c.

◆ cb_count

WORD cb_count
static

Definition at line 53 of file loader.c.

Referenced by encode_op_create_session(), failuredllhook(), and test_ResolveDelayLoadedAPI().

◆ cb_count_sys

WORD cb_count_sys
static

Definition at line 53 of file loader.c.

Referenced by failuresyshook(), and test_ResolveDelayLoadedAPI().

◆ child_failures

LONG* child_failures
static

Definition at line 52 of file loader.c.

Referenced by child_process(), dll_entry_point(), START_TEST(), and test_ExitProcess().

◆ cs_lock

CRITICAL_SECTION cs_lock
static

Definition at line 2949 of file loader.c.

Referenced by child_process(), dll_entry_point(), and mutex_thread_proc().

◆ cs_lock_event

HANDLE cs_lock_event
static

Definition at line 2948 of file loader.c.

Referenced by child_process(), and mutex_thread_proc().

◆ dos_header

◆ DWORD

Definition at line 67 of file loader.c.

Referenced by test_Loader().

◆ event

HANDLE event
static

Definition at line 2947 of file loader.c.

◆ filler

◆ fls_callback_count

LONG fls_callback_count
static

Definition at line 2951 of file loader.c.

Referenced by dll_entry_point(), and fls_callback().

◆ fls_list_head

LIST_ENTRY* fls_list_head
static

Definition at line 3048 of file loader.c.

Referenced by child_process(), dll_entry_point(), and test_FiberLocalStorage().

◆ HANDLE

void SIZE_T *static HANDLE

Definition at line 61 of file loader.c.

◆ heap_lock_event

HANDLE heap_lock_event
static

Definition at line 2948 of file loader.c.

Referenced by child_process(), and mutex_thread_proc().

◆ inside_cs_lock

int inside_cs_lock
static

Definition at line 2950 of file loader.c.

Referenced by child_process(), and mutex_thread_proc().

◆ inside_heap_lock

int inside_heap_lock
static

Definition at line 2950 of file loader.c.

Referenced by child_process(), and mutex_thread_proc().

◆ inside_loader_lock

int inside_loader_lock
static

Definition at line 2950 of file loader.c.

Referenced by child_process(), dll_entry_point(), and mutex_thread_proc().

◆ inside_peb_lock

int inside_peb_lock
static

Definition at line 2950 of file loader.c.

Referenced by child_process(), dll_entry_point(), and mutex_thread_proc().

◆ is_win64

BOOL is_win64 = sizeof(void *) > sizeof(int)
static

Definition at line 55 of file loader.c.

Referenced by map_image_section(), and query_image_section().

◆ is_wow64

BOOL is_wow64
static

Definition at line 56 of file loader.c.

Referenced by START_TEST(), test_Loader(), test_wow64_redirection(), and test_Wow64Transition().

◆ load_fallback_name

WCHAR load_fallback_name[MAX_PATH]
static

Definition at line 556 of file loader.c.

Referenced by delete_load_path(), init_load_path(), and map_image_section().

◆ load_path

WCHAR load_path[MAX_PATH]
static

Definition at line 557 of file loader.c.

Referenced by find_exe_file(), init_load_path(), load_library(), and map_image_section().

◆ load_test_name

WCHAR load_test_name[MAX_PATH]
static

Definition at line 556 of file loader.c.

Referenced by delete_load_path(), init_load_path(), and map_image_section().

◆ loader_lock_event

HANDLE loader_lock_event
static

Definition at line 2948 of file loader.c.

Referenced by child_process(), and mutex_thread_proc().

◆ LPCWSTR

Definition at line 76 of file loader.c.

◆ mutex

HANDLE mutex
static

Definition at line 2947 of file loader.c.

◆ nt_header_template

◆ page_size

◆ PBOOL

Definition at line 89 of file loader.c.

◆ PCIMAGE_DELAYLOAD_DESCRIPTOR

Definition at line 79 of file loader.c.

◆ PDELAYLOAD_FAILURE_DLL_CALLBACK

PDELAYLOAD_FAILURE_DLL_CALLBACK

Definition at line 80 of file loader.c.

◆ PDELAYLOAD_FAILURE_SYSTEM_ROUTINE

PDELAYLOAD_FAILURE_SYSTEM_ROUTINE

Definition at line 81 of file loader.c.

◆ peb_lock_event

HANDLE peb_lock_event
static

Definition at line 2948 of file loader.c.

Referenced by child_process(), and mutex_thread_proc().

◆ PLDR_DLL_NOTIFICATION_FUNCTION

PLDR_DLL_NOTIFICATION_FUNCTION

Definition at line 93 of file loader.c.

◆ PROCESSINFOCLASS

Definition at line 65 of file loader.c.

◆ PULONG

Definition at line 65 of file loader.c.

◆ PVOID

Definition at line 64 of file loader.c.

◆ Reserved

Definition at line 92 of file loader.c.

◆ section

Initial value:
=
{
".rodata",
{ 0 },
0,
0,
0,
0,
0,
0,
0,
}

Definition at line 164 of file loader.c.

Referenced by test_import_resolution().

◆ section_data

const char section_data[0x10] = "section data"
static

◆ SECTION_INFORMATION_CLASS

Definition at line 62 of file loader.c.

◆ semaphore

◆ SIZE_T

Definition at line 62 of file loader.c.

Referenced by query_image_section().

◆ stop_event

HANDLE stop_event
static

Definition at line 2948 of file loader.c.

Referenced by child_process(), mutex_thread_proc(), and semaphore_thread_proc().

◆ system_dir

char system_dir[MAX_PATH]
static

Definition at line 57 of file loader.c.

Referenced by START_TEST(), and test_wow64_redirection_for_dll().

◆ syswow_dir

char syswow_dir[MAX_PATH]
static

Definition at line 58 of file loader.c.

Referenced by START_TEST(), test_wow64_redirection(), and test_wow64_redirection_for_dll().

◆ test_dll_phase

int test_dll_phase
static

Definition at line 2950 of file loader.c.

Referenced by child_process(), dll_entry_point(), and START_TEST().

◆ ThunkAddress

PIMAGE_THUNK_DATA ThunkAddress

Definition at line 82 of file loader.c.

◆ tls_init_fn_output

int tls_init_fn_output
static

Definition at line 2169 of file loader.c.

Referenced by test_import_resolution(), and tls_thread_fn().

◆ ULONG

Definition at line 61 of file loader.c.

◆ ULONG_PTR

Definition at line 63 of file loader.c.

◆ wldr_nameW

const WCHAR wldr_nameW[] = {'w','l','d','r','t','e','s','t','.','d','l','l',0}
static

Definition at line 555 of file loader.c.

Referenced by init_load_path(), and map_image_section().

◆ WORD

Definition at line 83 of file loader.c.