ReactOS 0.4.16-dev-338-g34e76ad
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 "winuser.h"
#include "wine/test.h"
#include "delayloadhandler.h"
#include "pshpack1.h"
#include "poppack.h"
Include dependency graph for loader.c:

Go to the source code of this file.

Classes

struct  PROCESS_BASIC_INFORMATION_PRIVATE
 

Macros

#define NONAMELESSUNION
 
#define NONAMELESSSTRUCT
 
#define WIN32_NO_STATUS
 
#define PROCESS_ALL_ACCESS_NT4   (PROCESS_ALL_ACCESS & ~0xf000)
 
#define ALIGN_SIZE(size, alignment)   (((size) + (alignment - 1)) & ~((alignment - 1)))
 
#define DATA_RVA(ptr)   (page_size + ((char *)(ptr) - (char *)&data))
 
#define MAX_COUNT   10
 

Functions

static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *
 
static void (WINAPI *pLdrShutdownProcess)(void)
 
static BOOLEAN (WINAPI *pRtlDllShutdownInProgress)(void)
 
static PVOID (WINAPI *pResolveDelayLoadedAPI)(PVOID
 
static ULONG *static DWORD (WINAPI *pFlsAlloc)(PFLS_CALLBACK_FUNCTION)
 
static BOOL (WINAPI *pFlsSetValue)(DWORD
 
static PVOID RVAToAddr (DWORD_PTR rva, HMODULE module)
 
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 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_FakeDLL (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 test_import_resolution (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 BOOL WINAPI dll_entry_point (HINSTANCE hinst, DWORD reason, LPVOID param)
 
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 void test_ResolveDelayLoadedAPI (void)
 
static void test_InMemoryOrderModuleList (void)
 
static WCHAR toupperW (WCHAR c)
 
static ULONG hash_basename (const WCHAR *basename)
 
static void test_HashLinks (void)
 
 START_TEST (loader)
 

Variables

static LONGchild_failures
 
static WORD cb_count
 
static DWORD page_size
 
static BOOL is_win64 = sizeof(void *) > sizeof(int)
 
static BOOL is_wow64
 
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 PVOID
 
static PROCESSINFOCLASS
 
static PULONG
 
static DWORD
 
static ULONG ULONG_PTR *static ULONG_PTR
 
static PCIMAGE_DELAYLOAD_DESCRIPTOR
 
static PDELAYLOAD_FAILURE_DLL_CALLBACK
 
static PIMAGE_THUNK_DATA ThunkAddress
 
static BOOL
 
static WORD
 
static PBOOL
 
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 HANDLE attached_thread [MAX_COUNT]
 
static DWORD attached_thread_count
 
HANDLE stop_event
 
HANDLE event
 
HANDLE mutex
 
HANDLE semaphore
 
HANDLE loader_lock_event
 
HANDLE peb_lock_event
 
HANDLE heap_lock_event
 
HANDLE ack_event
 
static int test_dll_phase
 
static int inside_loader_lock
 
static int inside_peb_lock
 
static int inside_heap_lock
 
static LONG fls_callback_count
 

Macro Definition Documentation

◆ ALIGN_SIZE

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

Definition at line 39 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 2137 of file loader.c.

◆ NONAMELESSSTRUCT

#define NONAMELESSSTRUCT

Definition at line 22 of file loader.c.

◆ NONAMELESSUNION

#define NONAMELESSUNION

Definition at line 21 of file loader.c.

◆ PROCESS_ALL_ACCESS_NT4

#define PROCESS_ALL_ACCESS_NT4   (PROCESS_ALL_ACCESS & ~0xf000)

Definition at line 37 of file loader.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 28 of file loader.c.

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pFlsSetValue)
static

◆ BOOLEAN()

static BOOLEAN ( WINAPI pRtlDllShutdownInProgress)
static

◆ child_process()

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

Definition at line 2586 of file loader.c.

2587{
2588 void *target;
2589 DWORD ret, dummy, i, code, expected_code;
2591 HMODULE hmod;
2594
2595 trace("phase %d: writing %p at %#x\n", test_dll_phase, dll_entry_point, target_offset);
2596
2597 SetLastError(0xdeadbeef);
2599 ok(mutex != 0, "CreateMutex error %d\n", GetLastError());
2600
2601 SetLastError(0xdeadbeef);
2603 ok(semaphore != 0, "CreateSemaphore error %d\n", GetLastError());
2604
2605 SetLastError(0xdeadbeef);
2606 event = CreateEventW(NULL, TRUE, FALSE, NULL);
2607 ok(event != 0, "CreateEvent error %d\n", GetLastError());
2608
2609 SetLastError(0xdeadbeef);
2611 ok(loader_lock_event != 0, "CreateEvent error %d\n", GetLastError());
2612
2613 SetLastError(0xdeadbeef);
2615 ok(peb_lock_event != 0, "CreateEvent error %d\n", GetLastError());
2616
2617 SetLastError(0xdeadbeef);
2619 ok(heap_lock_event != 0, "CreateEvent error %d\n", GetLastError());
2620
2621 SetLastError(0xdeadbeef);
2623 ok(ack_event != 0, "CreateEvent error %d\n", GetLastError());
2624
2627 {
2628 ok(0, "could not open %s\n", dll_name);
2629 return;
2630 }
2631 SetFilePointer(file, target_offset, NULL, FILE_BEGIN);
2632 SetLastError(0xdeadbeef);
2634 ret = WriteFile(file, &target, sizeof(target), &dummy, NULL);
2635 ok(ret, "WriteFile error %d\n", GetLastError());
2637
2638 SetLastError(0xdeadbeef);
2639 hmod = LoadLibraryA(dll_name);
2640 ok(hmod != 0, "LoadLibrary error %d\n", GetLastError());
2641
2642 SetLastError(0xdeadbeef);
2644 ok(stop_event != 0, "CreateEvent error %d\n", GetLastError());
2645
2646 SetLastError(0xdeadbeef);
2648 ok(thread != 0, "CreateThread error %d\n", GetLastError());
2651
2653
2654 SetLastError(0xdeadbeef);
2656 ok(thread != 0, "CreateThread error %d\n", GetLastError());
2659
2661 Sleep(100);
2662
2663 ok(attached_thread_count == 2, "attached thread count should be 2\n");
2664 for (i = 0; i < attached_thread_count; i++)
2665 {
2667 trace("child: GetExitCodeThread(%u) => %d,%u\n", i, ret, code);
2668 ok(ret == 1, "GetExitCodeThread returned %d, expected 1\n", ret);
2669 ok(code == STILL_ACTIVE, "expected thread exit code STILL_ACTIVE, got %u\n", code);
2670 }
2671
2673 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2675 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2676
2678 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2680 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2682 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2683
2684 ret = pRtlDllShutdownInProgress();
2685 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2686
2687 SetLastError(0xdeadbeef);
2689 ok(process != NULL, "OpenProcess error %d\n", GetLastError());
2690
2691 SetLastError(0xdeadbeef);
2692 ret = TerminateProcess(0, 195);
2693 ok(!ret, "TerminateProcess(0) should fail\n");
2694 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
2695
2696 Sleep(100);
2697
2698 affinity = 1;
2699 ret = pNtSetInformationProcess(process, ProcessAffinityMask, &affinity, sizeof(affinity));
2700 ok(!ret, "NtSetInformationProcess error %#x\n", ret);
2701
2702 switch (test_dll_phase)
2703 {
2704 case 0:
2705 ret = pRtlDllShutdownInProgress();
2706 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2707
2708 trace("call NtTerminateProcess(0, 195)\n");
2709 ret = pNtTerminateProcess(0, 195);
2710 ok(!ret, "NtTerminateProcess error %#x\n", ret);
2711
2712 memset(&pbi, 0, sizeof(pbi));
2713 ret = pNtQueryInformationProcess(process, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
2714 ok(!ret, "NtQueryInformationProcess error %#x\n", ret);
2715 ok(pbi.ExitStatus == STILL_ACTIVE || pbi.ExitStatus == 195,
2716 "expected STILL_ACTIVE, got %lu\n", pbi.ExitStatus);
2717 affinity = 1;
2718 ret = pNtSetInformationProcess(process, ProcessAffinityMask, &affinity, sizeof(affinity));
2719 ok(!ret, "NtSetInformationProcess error %#x\n", ret);
2720
2721 ret = pRtlDllShutdownInProgress();
2722 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2723
2724 hmod = GetModuleHandleA(dll_name);
2725 ok(hmod != 0, "DLL should not be unloaded\n");
2726
2727 SetLastError(0xdeadbeef);
2729 ok(!thread || broken(thread != 0) /* before win7 */, "CreateThread should fail\n");
2730 if (!thread)
2731 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
2732 else
2733 {
2735 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2737 }
2738
2739 trace("call LdrShutdownProcess()\n");
2740 pLdrShutdownProcess();
2741
2742 ret = pRtlDllShutdownInProgress();
2743 ok(ret, "RtlDllShutdownInProgress returned %d\n", ret);
2744
2745 hmod = GetModuleHandleA(dll_name);
2746 ok(hmod != 0, "DLL should not be unloaded\n");
2747
2748 memset(&pbi, 0, sizeof(pbi));
2749 ret = pNtQueryInformationProcess(process, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
2750 ok(!ret, "NtQueryInformationProcess error %#x\n", ret);
2751 ok(pbi.ExitStatus == STILL_ACTIVE || pbi.ExitStatus == 195,
2752 "expected STILL_ACTIVE, got %lu\n", pbi.ExitStatus);
2753 affinity = 1;
2754 ret = pNtSetInformationProcess(process, ProcessAffinityMask, &affinity, sizeof(affinity));
2755 ok(!ret, "NtSetInformationProcess error %#x\n", ret);
2756 break;
2757
2758 case 1: /* normal ExitProcess */
2759 ret = pRtlDllShutdownInProgress();
2760 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2761 break;
2762
2763 case 2: /* ExitProcess will be called by the PROCESS_DETACH handler */
2764 ret = pRtlDllShutdownInProgress();
2765 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2766
2767 trace("call FreeLibrary(%p)\n", hmod);
2768 SetLastError(0xdeadbeef);
2769 ret = FreeLibrary(hmod);
2770 ok(ret, "FreeLibrary error %d\n", GetLastError());
2771 hmod = GetModuleHandleA(dll_name);
2772 ok(!hmod, "DLL should be unloaded\n");
2773
2774 if (test_dll_phase == 2)
2775 ok(0, "FreeLibrary+ExitProcess should never return\n");
2776
2777 ret = pRtlDllShutdownInProgress();
2778 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2779
2780 break;
2781
2782 case 3:
2783 trace("signalling thread exit\n");
2785 break;
2786
2787 case 4:
2788 trace("setting loader_lock_event\n");
2791 ok(inside_loader_lock != 0, "inside_loader_lock is not set\n");
2792
2793 /* calling NtTerminateProcess should not cause a deadlock */
2794 trace("call NtTerminateProcess(0, 198)\n");
2795 ret = pNtTerminateProcess(0, 198);
2796 ok(!ret, "NtTerminateProcess error %#x\n", ret);
2797
2799
2800 /* Windows fails to release loader lock acquired from another thread,
2801 * so the LdrUnlockLoaderLock call fails here and ExitProcess deadlocks
2802 * later on, so NtTerminateProcess is used instead.
2803 */
2804 trace("call NtTerminateProcess(GetCurrentProcess(), 198)\n");
2805 pNtTerminateProcess(GetCurrentProcess(), 198);
2806 ok(0, "NtTerminateProcess should not return\n");
2807 break;
2808
2809 case 5:
2810 trace("setting peb_lock_event\n");
2813 ok(inside_peb_lock != 0, "inside_peb_lock is not set\n");
2814
2816
2817 /* calling ExitProcess should cause a deadlock */
2818 trace("call ExitProcess(198)\n");
2819 ExitProcess(198);
2820 ok(0, "ExitProcess should not return\n");
2821 break;
2822
2823 case 6:
2824 trace("setting heap_lock_event\n");
2827 ok(inside_heap_lock != 0, "inside_heap_lock is not set\n");
2828
2830
2831 /* calling ExitProcess should cause a deadlock */
2832 trace("call ExitProcess(1)\n");
2833 ExitProcess(1);
2834 ok(0, "ExitProcess should not return\n");
2835 break;
2836
2837 default:
2838 assert(0);
2839 break;
2840 }
2841
2842 if (test_dll_phase == 0) expected_code = 195;
2843 else if (test_dll_phase == 3) expected_code = 196;
2844 else if (test_dll_phase == 4) expected_code = 198;
2845 else expected_code = STILL_ACTIVE;
2846
2847 if (expected_code == STILL_ACTIVE)
2848 {
2850 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2852 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2853 }
2854 else
2855 {
2857 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2859 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2860 }
2861
2862 for (i = 0; i < attached_thread_count; i++)
2863 {
2865 trace("child: GetExitCodeThread(%u) => %d,%u\n", i, ret, code);
2866 ok(ret == 1, "GetExitCodeThread returned %d, expected 1\n", ret);
2867 ok(code == expected_code, "expected thread exit code %u, got %u\n", expected_code, code);
2868 }
2869
2871
2872 trace("call ExitProcess(195)\n");
2873 ExitProcess(195);
2874}
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
static HANDLE thread
Definition: service.c:33
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#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:1487
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
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(x)
Definition: debug.h:53
KAFFINITY affinity
Definition: wave.h:2
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _cl_event * event
Definition: glext.h:7739
GLenum target
Definition: glext.h:7315
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
@ ProcessBasicInformation
Definition: winternl.h:394
@ ProcessAffinityMask
Definition: winternl.h:877
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static int inside_loader_lock
Definition: loader.c:2141
static int test_dll_phase
Definition: loader.c:2141
HANDLE peb_lock_event
Definition: loader.c:2140
HANDLE semaphore
Definition: loader.c:2140
static DWORD WINAPI noop_thread_proc(void *param)
Definition: loader.c:2213
static LONG * child_failures
Definition: loader.c:51
#define PROCESS_ALL_ACCESS_NT4
Definition: loader.c:37
HANDLE heap_lock_event
Definition: loader.c:2140
static HANDLE attached_thread[MAX_COUNT]
Definition: loader.c:2138
static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
Definition: loader.c:2231
HANDLE loader_lock_event
Definition: loader.c:2140
HANDLE ack_event
Definition: loader.c:2140
HANDLE stop_event
Definition: loader.c:2140
static int inside_heap_lock
Definition: loader.c:2141
static int inside_peb_lock
Definition: loader.c:2141
static DWORD WINAPI semaphore_thread_proc(void *param)
Definition: loader.c:2193
static DWORD attached_thread_count
Definition: loader.c:2139
static DWORD WINAPI mutex_thread_proc(void *param)
Definition: loader.c:2144
#define GENERIC_WRITE
Definition: nt_native.h:90
LONG winetest_get_failures(void)
#define memset(x, y, z)
Definition: compat.h:39
Definition: inflate.c:139
Definition: fci.c:127
Definition: module.h:456
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
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
int ret
#define STILL_ACTIVE
Definition: winbase.h:259
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define WAIT_OBJECT_0
Definition: winbase.h:432
_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 170 of file loader.c.

172{
173 char temp_path[MAX_PATH];
174 DWORD dummy, size, file_align;
175 HANDLE hfile;
176 BOOL ret;
177
179 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
180
181 hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
182 ok( hfile != INVALID_HANDLE_VALUE, "failed to create %s err %u\n", dll_name, GetLastError() );
183 if (hfile == INVALID_HANDLE_VALUE) return 0;
184
185 SetLastError(0xdeadbeef);
186 ret = WriteFile(hfile, dos_header, dos_size, &dummy, NULL);
187 ok(ret, "WriteFile error %d\n", GetLastError());
188
189 SetLastError(0xdeadbeef);
190 ret = WriteFile(hfile, nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
191 ok(ret, "WriteFile error %d\n", GetLastError());
192
194 {
195 SetLastError(0xdeadbeef);
197 sizeof(IMAGE_OPTIONAL_HEADER),
198 &dummy, NULL);
199 ok(ret, "WriteFile error %d\n", GetLastError());
201 {
203 assert(file_align < sizeof(filler));
204 SetLastError(0xdeadbeef);
205 ret = WriteFile(hfile, filler, file_align, &dummy, NULL);
206 ok(ret, "WriteFile error %d\n", GetLastError());
207 }
208 }
209
212 {
214
215 section.SizeOfRawData = 10;
216
218 {
219 section.PointerToRawData = dos_size;
221 section.Misc.VirtualSize = section.SizeOfRawData * 10;
222 }
223 else
224 {
225 section.PointerToRawData = nt_header->OptionalHeader.SizeOfHeaders;
227 section.Misc.VirtualSize = 5;
228 }
229
230 SetLastError(0xdeadbeef);
231 ret = WriteFile(hfile, &section, sizeof(section), &dummy, NULL);
232 ok(ret, "WriteFile error %d\n", GetLastError());
233
234 /* section data */
235 SetLastError(0xdeadbeef);
236 ret = WriteFile(hfile, section_data, sizeof(section_data), &dummy, NULL);
237 ok(ret, "WriteFile error %d\n", GetLastError());
238 }
239
240 /* Minimal PE image that Windows7+ is able to load: 268 bytes */
241 size = GetFileSize(hfile, NULL);
242 if (size < 268)
243 {
244 file_align = 268 - size;
245 SetLastError(0xdeadbeef);
246 ret = WriteFile(hfile, filler, file_align, &dummy, NULL);
247 ok(ret, "WriteFile error %d\n", GetLastError());
248 }
249
250 size = GetFileSize(hfile, NULL);
251 CloseHandle(hfile);
252 return size;
253}
#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
unsigned int BOOL
Definition: ntddk_ex.h:94
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:167
static IMAGE_DOS_HEADER dos_header
Definition: loader.c:90
static const char section_data[0x10]
Definition: loader.c:168
static DWORD page_size
Definition: loader.c:53
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 255 of file loader.c.

258{
259 char temp_path[MAX_PATH];
260 DWORD dummy, i, size;
261 HANDLE hfile;
262 BOOL ret;
263
265 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
266
267 hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
268 ok( hfile != INVALID_HANDLE_VALUE, "failed to create %s err %u\n", dll_name, GetLastError() );
269 if (hfile == INVALID_HANDLE_VALUE) return 0;
270
271 SetLastError(0xdeadbeef);
272 ret = WriteFile(hfile, dos_header, sizeof(*dos_header), &dummy, NULL);
273 ok(ret, "WriteFile error %d\n", GetLastError());
274
275 SetLastError(0xdeadbeef);
277 ok(ret, "WriteFile error %d\n", GetLastError());
278
279 SetLastError(0xdeadbeef);
281 &dummy, NULL);
282 ok(ret, "WriteFile error %d\n", GetLastError());
283
284 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
285 {
286 SetFilePointer(hfile, sections[i].PointerToRawData, NULL, FILE_BEGIN);
287 SetLastError(0xdeadbeef);
288 ret = WriteFile(hfile, section_data, sections[i].SizeOfRawData, &dummy, NULL);
289 ok(ret, "WriteFile error %d\n", GetLastError());
290 }
291 size = GetFileSize(hfile, NULL);
292 CloseHandle(hfile);
293 return size;
294}
struct section sections[2]
Definition: diskspace.c:792
#define offsetof(TYPE, MEMBER)

Referenced by map_image_section().

◆ dll_entry_point()

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

Definition at line 2231 of file loader.c.

2232{
2233 static LONG noop_thread_started;
2234 static DWORD fls_index = FLS_OUT_OF_INDEXES;
2235 static int fls_count = 0;
2236 static int thread_detach_count = 0;
2237 DWORD ret;
2238
2239 ok(!inside_loader_lock, "inside_loader_lock should not be set\n");
2240 ok(!inside_peb_lock, "inside_peb_lock should not be set\n");
2241
2242 switch (reason)
2243 {
2244 case DLL_PROCESS_ATTACH:
2245 trace("dll: %p, DLL_PROCESS_ATTACH, %p\n", hinst, param);
2246
2247 ret = pRtlDllShutdownInProgress();
2248 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2249
2250 /* Set up the FLS slot, if FLS is available */
2251 if (pFlsGetValue)
2252 {
2253 void* value;
2254 BOOL bret;
2255 ret = pFlsAlloc(&fls_callback);
2256 ok(ret != FLS_OUT_OF_INDEXES, "FlsAlloc returned %d\n", ret);
2257 fls_index = ret;
2258 SetLastError(0xdeadbeef);
2259 value = pFlsGetValue(fls_index);
2260 ok(!value, "FlsGetValue returned %p, expected NULL\n", value);
2261 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %u\n", GetLastError());
2262 bret = pFlsSetValue(fls_index, (void*) 0x31415);
2263 ok(bret, "FlsSetValue failed\n");
2264 fls_count++;
2265 }
2266
2267 break;
2268 case DLL_PROCESS_DETACH:
2269 {
2270 DWORD code, expected_code, i;
2272 void *addr;
2273 SIZE_T size;
2275 DEBUG_EVENT de;
2276
2277 trace("dll: %p, DLL_PROCESS_DETACH, %p\n", hinst, param);
2278
2279 if (test_dll_phase == 4 || test_dll_phase == 5)
2280 {
2281 ok(0, "dll_entry_point(DLL_PROCESS_DETACH) should not be called\n");
2282 break;
2283 }
2284
2285 /* The process should already deadlock at this point */
2286 if (test_dll_phase == 6)
2287 {
2288 /* In reality, code below never gets executed, probably some other
2289 * code tries to access process heap and deadlocks earlier, even XP
2290 * doesn't call the DLL entry point on process detach either.
2291 */
2293 ok(0, "dll_entry_point: process should already deadlock\n");
2294 break;
2295 }
2296
2297 if (test_dll_phase == 0 || test_dll_phase == 1 || test_dll_phase == 3)
2298 ok(param != NULL, "dll: param %p\n", param);
2299 else
2300 ok(!param, "dll: param %p\n", param);
2301
2302 if (test_dll_phase == 0 || test_dll_phase == 1) expected_code = 195;
2303 else if (test_dll_phase == 3) expected_code = 196;
2304 else expected_code = STILL_ACTIVE;
2305
2306 if (test_dll_phase == 3)
2307 {
2308 ret = pRtlDllShutdownInProgress();
2309 ok(ret, "RtlDllShutdownInProgress returned %d\n", ret);
2310 }
2311 else
2312 {
2313 ret = pRtlDllShutdownInProgress();
2314
2315 /* FIXME: remove once Wine is fixed */
2316 todo_wine_if (!(expected_code == STILL_ACTIVE || expected_code == 196))
2317 ok(!ret || broken(ret) /* before Vista */, "RtlDllShutdownInProgress returned %d\n", ret);
2318 }
2319
2320 /* In the case that the process is terminating, FLS slots should still be accessible, but
2321 * the callback should be already run for this thread and the contents already NULL.
2322 * Note that this is broken for Win2k3, which runs the callbacks *after* the DLL entry
2323 * point has already run.
2324 */
2325 if (param && pFlsGetValue)
2326 {
2327 void* value;
2328 SetLastError(0xdeadbeef);
2329 value = pFlsGetValue(fls_index);
2330 todo_wine
2331 {
2332 ok(broken(value == (void*) 0x31415) || /* Win2k3 */
2333 value == NULL, "FlsGetValue returned %p, expected NULL\n", value);
2334 }
2335 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %u\n", GetLastError());
2336 todo_wine
2337 {
2338 ok(broken(fls_callback_count == thread_detach_count) || /* Win2k3 */
2339 fls_callback_count == thread_detach_count + 1,
2340 "wrong FLS callback count %d, expected %d\n", fls_callback_count, thread_detach_count + 1);
2341 }
2342 }
2343 if (pFlsFree)
2344 {
2345 BOOL ret;
2346 /* Call FlsFree now and run the remaining callbacks from uncleanly terminated threads */
2347 ret = pFlsFree(fls_index);
2348 ok(ret, "FlsFree failed with error %u\n", GetLastError());
2349 fls_index = FLS_OUT_OF_INDEXES;
2350 todo_wine
2351 {
2352 ok(fls_callback_count == fls_count,
2353 "wrong FLS callback count %d, expected %d\n", fls_callback_count, fls_count);
2354 }
2355 }
2356
2357 ok(attached_thread_count >= 2, "attached thread count should be >= 2\n");
2358
2359 for (i = 0; i < attached_thread_count; i++)
2360 {
2361 /* Calling GetExitCodeThread() without waiting for thread termination
2362 * leads to different results due to a race condition.
2363 */
2364 if (expected_code != STILL_ACTIVE)
2365 {
2367 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2368 }
2370 trace("dll: GetExitCodeThread(%u) => %d,%u\n", i, ret, code);
2371 ok(ret == 1, "GetExitCodeThread returned %d, expected 1\n", ret);
2372 ok(code == expected_code, "expected thread exit code %u, got %u\n", expected_code, code);
2373 }
2374
2376 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2377
2379 if (expected_code == STILL_ACTIVE)
2380 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2381 else
2382 ok(ret == WAIT_ABANDONED, "expected WAIT_ABANDONED, got %#x\n", ret);
2383
2384 /* semaphore is not abandoned on thread termination */
2386 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2387
2388 if (expected_code == STILL_ACTIVE)
2389 {
2391 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2393 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2394 }
2395 else
2396 {
2398 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2400 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2401 }
2402
2403 /* win7 doesn't allow creating a thread during process shutdown but
2404 * earlier Windows versions allow it.
2405 */
2406 noop_thread_started = 0;
2407 SetLastError(0xdeadbeef);
2408 handle = CreateThread(NULL, 0, noop_thread_proc, &noop_thread_started, 0, &ret);
2409 if (param)
2410 {
2411 ok(!handle || broken(handle != 0) /* before win7 */, "CreateThread should fail\n");
2412 if (!handle)
2413 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
2414 else
2415 {
2417 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2419 }
2420 }
2421 else
2422 {
2423 ok(handle != 0, "CreateThread error %d\n", GetLastError());
2425 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2426 ok(!noop_thread_started || broken(noop_thread_started) /* XP64 */, "thread shouldn't start yet\n");
2428 }
2429
2430 SetLastError(0xdeadbeef);
2432 ok(process != NULL, "OpenProcess error %d\n", GetLastError());
2433
2434 noop_thread_started = 0;
2435 SetLastError(0xdeadbeef);
2436 handle = CreateRemoteThread(process, NULL, 0, noop_thread_proc, &noop_thread_started, 0, &ret);
2437 if (param)
2438 {
2439 ok(!handle || broken(handle != 0) /* before win7 */, "CreateRemoteThread should fail\n");
2440 if (!handle)
2441 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
2442 else
2443 {
2445 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2447 }
2448 }
2449 else
2450 {
2451 ok(handle != 0, "CreateRemoteThread error %d\n", GetLastError());
2453 ok(ret == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %#x\n", ret);
2454 ok(!noop_thread_started || broken(noop_thread_started) /* XP64 */, "thread shouldn't start yet\n");
2456 }
2457
2458 SetLastError(0xdeadbeef);
2460 ok(handle != 0, "CreateFileMapping error %d\n", GetLastError());
2461
2462 offset.u.LowPart = 0;
2463 offset.u.HighPart = 0;
2464 addr = NULL;
2465 size = 0;
2466 ret = pNtMapViewOfSection(handle, process, &addr, 0, 0, &offset,
2467 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
2468 ok(ret == STATUS_SUCCESS, "NtMapViewOfSection error %#x\n", ret);
2469 ret = pNtUnmapViewOfSection(process, addr);
2470 ok(ret == STATUS_SUCCESS, "NtUnmapViewOfSection error %#x\n", ret);
2471
2474
2475 handle = GetModuleHandleA("winver.exe");
2476 ok(!handle, "winver.exe shouldn't be loaded yet\n");
2477 SetLastError(0xdeadbeef);
2478 handle = LoadLibraryA("winver.exe");
2479 ok(handle != 0, "LoadLibrary error %d\n", GetLastError());
2480 SetLastError(0xdeadbeef);
2482 ok(ret, "FreeLibrary error %d\n", GetLastError());
2483 handle = GetModuleHandleA("winver.exe");
2484 if (param)
2485 ok(handle != 0, "winver.exe should not be unloaded\n");
2486 else
2487 todo_wine
2488 ok(!handle || broken(handle != 0) /* before win7 */, "winver.exe should be unloaded\n");
2489
2490 SetLastError(0xdeadbeef);
2491 ret = WaitForDebugEvent(&de, 0);
2492 ok(!ret, "WaitForDebugEvent should fail\n");
2494 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
2495
2496 SetLastError(0xdeadbeef);
2498 ok(!ret, "DebugActiveProcess should fail\n");
2499 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
2500
2501 SetLastError(0xdeadbeef);
2502 ret = WaitForDebugEvent(&de, 0);
2503 ok(!ret, "WaitForDebugEvent should fail\n");
2504 ok(GetLastError() == ERROR_SEM_TIMEOUT, "expected ERROR_SEM_TIMEOUT, got %d\n", GetLastError());
2505
2506 if (test_dll_phase == 2)
2507 {
2508 trace("dll: call ExitProcess()\n");
2510 ExitProcess(197);
2511 }
2512 trace("dll: %p, DLL_PROCESS_DETACH, %p => DONE\n", hinst, param);
2513 break;
2514 }
2515 case DLL_THREAD_ATTACH:
2516 trace("dll: %p, DLL_THREAD_ATTACH, %p\n", hinst, param);
2517
2518 ret = pRtlDllShutdownInProgress();
2519 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2520
2522 {
2526 }
2527
2528 /* Make sure the FLS slot is empty, if FLS is available */
2529 if (pFlsGetValue)
2530 {
2531 void* value;
2532 BOOL ret;
2533 SetLastError(0xdeadbeef);
2534 value = pFlsGetValue(fls_index);
2535 ok(!value, "FlsGetValue returned %p, expected NULL\n", value);
2536 todo_wine
2537 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %u\n", GetLastError());
2538 ret = pFlsSetValue(fls_index, (void*) 0x31415);
2539 ok(ret, "FlsSetValue failed\n");
2540 fls_count++;
2541 }
2542
2543 break;
2544 case DLL_THREAD_DETACH:
2545 trace("dll: %p, DLL_THREAD_DETACH, %p\n", hinst, param);
2546 thread_detach_count++;
2547
2548 ret = pRtlDllShutdownInProgress();
2549 /* win7 doesn't allow creating a thread during process shutdown but
2550 * earlier Windows versions allow it. In that case DLL_THREAD_DETACH is
2551 * sent on thread exit, but DLL_THREAD_ATTACH is never received.
2552 */
2553 if (noop_thread_started)
2554 ok(ret, "RtlDllShutdownInProgress returned %d\n", ret);
2555 else
2556 ok(!ret, "RtlDllShutdownInProgress returned %d\n", ret);
2557
2558 /* FLS data should already be destroyed, if FLS is available.
2559 * Note that this is broken for Win2k3, which runs the callbacks *after* the DLL entry
2560 * point has already run.
2561 */
2562 if (pFlsGetValue && fls_index != FLS_OUT_OF_INDEXES)
2563 {
2564 void* value;
2565 SetLastError(0xdeadbeef);
2566 value = pFlsGetValue(fls_index);
2567 todo_wine
2568 {
2569 ok(broken(value == (void*) 0x31415) || /* Win2k3 */
2570 !value, "FlsGetValue returned %p, expected NULL\n", value);
2571 }
2572 ok(GetLastError() == ERROR_SUCCESS, "FlsGetValue failed with error %u\n", GetLastError());
2573 }
2574
2575 break;
2576 default:
2577 trace("dll: %p, %d, %p\n", hinst, reason, param);
2578 break;
2579 }
2580
2582
2583 return TRUE;
2584}
#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
GLdouble n
Definition: glext.h:7729
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat param
Definition: glext.h:5796
GLintptr offset
Definition: glext.h:5920
BOOL WINAPI HeapLock(HANDLE hHeap)
Definition: heapmem.c:123
NTSYSAPI BOOLEAN WINAPI RtlDllShutdownInProgress(void)
Definition: ldrapi.c:1557
#define d
Definition: ke_i.h:81
if(dx< 0)
Definition: linetemp.h:194
static HINSTANCE hinst
Definition: edit.c:551
static VOID WINAPI fls_callback(PVOID lpFlsData)
Definition: loader.c:2225
static LONG fls_callback_count
Definition: loader.c:2142
#define MAX_COUNT
Definition: loader.c:2137
#define todo_wine_if(is_todo)
Definition: custom.c:86
#define todo_wine
Definition: custom.c:89
#define PAGE_READWRITE
Definition: nt_native.h:1304
long LONG
Definition: pedump.c:60
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG_PTR SIZE_T
Definition: typedefs.h:80
Definition: pdh_main.c:94
#define WAIT_ABANDONED
Definition: winbase.h:438
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:602
#define ERROR_SEM_TIMEOUT
Definition: winerror.h:193
#define DUPLICATE_SAME_ACCESS

Referenced by child_process(), and test_ExitProcess().

◆ DWORD()

static ULONG *static DWORD ( WINAPI pFlsAlloc)
static

◆ failuredllhook()

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

Definition at line 3339 of file loader.c.

3340{
3341 ok(ul == 4, "expected 4, got %u\n", ul);
3342 ok(!!pd, "no delayload info supplied\n");
3343 if (pd)
3344 {
3345 ok(pd->Size == sizeof(*pd), "got %u\n", pd->Size);
3346 ok(!!pd->DelayloadDescriptor, "no DelayloadDescriptor supplied\n");
3347 if (pd->DelayloadDescriptor)
3348 {
3350 "expected 1, got %u\n", pd->DelayloadDescriptor->Attributes.AllAttributes);
3351 ok(pd->DelayloadDescriptor->DllNameRVA == 0x2000,
3352 "expected 0x2000, got %x\n", pd->DelayloadDescriptor->DllNameRVA);
3353 ok(pd->DelayloadDescriptor->ModuleHandleRVA == 0x201a,
3354 "expected 0x201a, got %x\n", pd->DelayloadDescriptor->ModuleHandleRVA);
3356 "expected %x > %x\n", pd->DelayloadDescriptor->ImportAddressTableRVA,
3359 "expected %x > %x\n", pd->DelayloadDescriptor->ImportNameTableRVA,
3362 "expected 0, got %x\n", pd->DelayloadDescriptor->BoundImportAddressTableRVA);
3364 "expected 0, got %x\n", pd->DelayloadDescriptor->UnloadInformationTableRVA);
3366 "expected 0, got %x\n", pd->DelayloadDescriptor->TimeDateStamp);
3367 }
3368
3369 ok(!!pd->ThunkAddress, "no ThunkAddress supplied\n");
3370 if (pd->ThunkAddress)
3371 ok(pd->ThunkAddress->u1.Ordinal, "no ThunkAddress value supplied\n");
3372
3373 ok(!!pd->TargetDllName, "no TargetDllName supplied\n");
3374 if (pd->TargetDllName)
3375 ok(!strcmp(pd->TargetDllName, "secur32.dll"),
3376 "expected \"secur32.dll\", got \"%s\"\n", pd->TargetDllName);
3377
3379 "expected 0, got %x\n", pd->TargetApiDescriptor.ImportDescribedByName);
3382 "expected 0, got %x\n", pd->TargetApiDescriptor.Description.Ordinal);
3383
3384 ok(!!pd->TargetModuleBase, "no TargetModuleBase supplied\n");
3385 ok(pd->Unused == NULL, "expected NULL, got %p\n", pd->Unused);
3386 ok(pd->LastError, "no LastError supplied\n");
3387 }
3388 cb_count++;
3389 return (void*)0xdeadbeef;
3390}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static WORD cb_count
Definition: loader.c:52
PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor
DELAYLOAD_PROC_DESCRIPTOR TargetApiDescriptor
PIMAGE_THUNK_DATA ThunkAddress
union _DELAYLOAD_PROC_DESCRIPTOR::@2901 Description
union _IMAGE_DELAYLOAD_DESCRIPTOR::@4208 Attributes
union _IMAGE_THUNK_DATA32::@2143 u1

Referenced by test_ResolveDelayLoadedAPI().

◆ fls_callback()

static VOID WINAPI fls_callback ( PVOID  lpFlsData)
static

Definition at line 2225 of file loader.c.

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

Referenced by dll_entry_point().

◆ hash_basename()

static ULONG hash_basename ( const WCHAR basename)
static

Definition at line 3678 of file loader.c.

3679{
3682 ULONG hash = 0;
3683
3684 if (version >= 0x0602)
3685 {
3686 for (; *basename; basename++)
3687 hash = hash * 65599 + toupperW(*basename);
3688 }
3689 else if (version == 0x0601)
3690 {
3691 for (; *basename; basename++)
3692 hash = hash + 65599 * toupperW(*basename);
3693 }
3694 else
3695 hash = toupperW(basename[0]) - 'A';
3696
3697 return hash & 31;
3698}
static const WCHAR version[]
Definition: asmname.c:66
PPEB Peb
Definition: dllmain.c:27
static void basename(LPCWSTR path, LPWSTR name)
Definition: profile.c:38
unsigned short WORD
Definition: ntddk_ex.h:93
#define NtCurrentTeb
#define toupperW(n)
Definition: unicode.h:51
ULONG OSMinorVersion
Definition: ntddk_ex.h:301
ULONG OSMajorVersion
Definition: ntddk_ex.h:300
Definition: _hash_fun.h:40
#define MAKEWORD(a, b)
Definition: typedefs.h:248
uint32_t ULONG
Definition: typedefs.h:59

Referenced by test_HashLinks().

◆ is_mem_writable()

static BOOL is_mem_writable ( DWORD  prot)
static

Definition at line 1651 of file loader.c.

1652{
1653 switch (prot & 0xff)
1654 {
1655 case PAGE_READWRITE:
1656 case PAGE_WRITECOPY:
1659 return TRUE;
1660
1661 default:
1662 return FALSE;
1663 }
1664}
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308

Referenced by test_section_access().

◆ 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 500 of file loader.c.

502{
503 char dll_name[MAX_PATH];
505 HANDLE file, map;
508 BOOL has_code;
509 HMODULE mod;
510
512
514 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
515
516 size.QuadPart = file_size;
519 if (!status)
520 {
522 SIZE_T info_size = 0xdeadbeef;
523 NTSTATUS ret = pNtQuerySection( map, SectionBasicInformation, &info, sizeof(info), &info_size );
524 ok( !ret, "NtQuerySection failed err %x\n", ret );
525 ok( info_size == sizeof(info), "NtQuerySection wrong size %lu\n", info_size );
526 ok( info.Attributes == (SEC_IMAGE | SEC_FILE), "NtQuerySection wrong attr %x\n", info.Attributes );
527 ok( info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", info.BaseAddress );
528 ok( info.Size.QuadPart == file_size, "NtQuerySection wrong size %x%08x / %08x\n",
529 info.Size.u.HighPart, info.Size.u.LowPart, file_size );
530 has_code = query_image_section( line, dll_name, nt_header, section_data );
531 /* test loading dll of wrong 32/64 bitness */
534 {
535 SetLastError( 0xdeadbeef );
538 {
539 BOOL il_only = FALSE;
540 if (((const IMAGE_NT_HEADERS32 *)nt_header)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
541 {
542 const IMAGE_COR20_HEADER *cor_header = section_data;
543 il_only = (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) != 0;
544 }
545 ok( mod != NULL || broken(il_only), /* <= win7 */
546 "%u: loading failed err %u\n", line, GetLastError() );
547 }
548 else
549 {
550 ok( !mod, "%u: loading succeeded\n", line );
551 ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "%u: wrong error %u\n", line, GetLastError() );
552 }
553 if (mod) FreeLibrary( mod );
554 }
555 }
556 if (map) CloseHandle( map );
557 CloseHandle( file );
558 DeleteFileA( dll_name );
559 return status;
560}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:66
LONG NTSTATUS
Definition: precomp.h:26
Definition: _map.h:48
#define SECTION_MAP_READ
Definition: compat.h:139
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
static BOOL query_image_section(int id, const char *dll_name, const IMAGE_NT_HEADERS *nt_header, const void *section_data)
Definition: loader.c:296
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:255
static BOOL is_win64
Definition: loader.c:54
#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:1287
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
#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
static unsigned int file_size
Definition: regtests2xml.c:47
Definition: parser.c:49
Definition: ps.c:97
#define DONT_RESOLVE_DLL_REFERENCES
Definition: winbase.h:367
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:251
@ COMIMAGE_FLAGS_ILONLY
Definition: winnt_old.h:3291

Referenced by test_Loader().

◆ mutex_thread_proc()

static DWORD WINAPI mutex_thread_proc ( void param)
static

Definition at line 2144 of file loader.c.

2145{
2146 HANDLE wait_list[4];
2147 DWORD ret;
2148
2150 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2151
2152 SetEvent(param);
2153
2154 wait_list[0] = stop_event;
2155 wait_list[1] = loader_lock_event;
2156 wait_list[2] = peb_lock_event;
2157 wait_list[3] = heap_lock_event;
2158
2159 trace("%04x: mutex_thread_proc: starting\n", GetCurrentThreadId());
2160 while (1)
2161 {
2162 ret = WaitForMultipleObjects(sizeof(wait_list)/sizeof(wait_list[0]), wait_list, FALSE, 50);
2163 if (ret == WAIT_OBJECT_0) break;
2164 else if (ret == WAIT_OBJECT_0 + 1)
2165 {
2166 ULONG_PTR loader_lock_magic;
2167 trace("%04x: mutex_thread_proc: Entering loader lock\n", GetCurrentThreadId());
2168 ret = pLdrLockLoaderLock(0, NULL, &loader_lock_magic);
2169 ok(!ret, "LdrLockLoaderLock error %#x\n", ret);
2172 }
2173 else if (ret == WAIT_OBJECT_0 + 2)
2174 {
2175 trace("%04x: mutex_thread_proc: Entering PEB lock\n", GetCurrentThreadId());
2176 pRtlAcquirePebLock();
2179 }
2180 else if (ret == WAIT_OBJECT_0 + 3)
2181 {
2182 trace("%04x: mutex_thread_proc: Entering heap lock\n", GetCurrentThreadId());
2186 }
2187 }
2188
2189 trace("%04x: mutex_thread_proc: exiting\n", GetCurrentThreadId());
2190 return 196;
2191}
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
uint32_t ULONG_PTR
Definition: typedefs.h:65
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 2213 of file loader.c.

2214{
2215 if (param)
2216 {
2217 LONG *noop_thread_started = param;
2218 InterlockedIncrement(noop_thread_started);
2219 }
2220
2221 trace("%04x: noop_thread_proc: exiting\n", GetCurrentThreadId());
2222 return 195;
2223}

Referenced by child_process(), and dll_entry_point().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pNtCreateSection)
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 296 of file loader.c.

298{
299 static BOOL is_winxp;
302 const IMAGE_COR20_HEADER *cor_header = NULL;
303 SIZE_T info_size = (SIZE_T)0xdeadbeef << 16;
307 LARGE_INTEGER map_size;
308 SIZE_T max_stack, commit_stack;
309 void *entry_point;
310
311 /* truncated header is not handled correctly in windows <= w2k3 */
312 BOOL truncated;
313
315 NULL, OPEN_EXISTING, 0, 0 );
316 ok( file != INVALID_HANDLE_VALUE, "%u: CreateFile error %d\n", id, GetLastError() );
318
321 ok( !status, "%u: NtCreateSection failed err %x\n", id, status );
322 if (status)
323 {
324 CloseHandle( file );
325 return FALSE;
326 }
327 status = pNtQuerySection( mapping, SectionImageInformation, &image, sizeof(image), &info_size );
328 ok( !status, "%u: NtQuerySection failed err %x\n", id, status );
329 ok( info_size == sizeof(image), "%u: NtQuerySection wrong size %lu\n", id, info_size );
332 {
337 if (!truncated &&
340 cor_header = section_data;
341 }
343 {
344 const IMAGE_NT_HEADERS64 *nt64 = (const IMAGE_NT_HEADERS64 *)nt_header;
345 max_stack = 0x100000;
346 commit_stack = 0x10000;
347 entry_point = (void *)0x81231234;
349 if (!truncated &&
352 cor_header = section_data;
353 }
354 else
355 {
356 const IMAGE_NT_HEADERS32 *nt32 = (const IMAGE_NT_HEADERS32 *)nt_header;
357 max_stack = nt32->OptionalHeader.SizeOfStackReserve;
358 commit_stack = nt32->OptionalHeader.SizeOfStackCommit;
359 entry_point = (char *)(ULONG_PTR)nt32->OptionalHeader.ImageBase + nt32->OptionalHeader.AddressOfEntryPoint;
361 if (!truncated &&
364 cor_header = section_data;
365 }
366 ok( (char *)image.TransferAddress == (char *)entry_point ||
367 (S(U(image)).ImageDynamicallyRelocated && LOWORD(image.TransferAddress) == LOWORD(entry_point)),
368 "%u: TransferAddress wrong %p / %p (%08x)\n", id,
369 image.TransferAddress, entry_point, nt_header->OptionalHeader.AddressOfEntryPoint );
370 ok( image.ZeroBits == 0, "%u: ZeroBits wrong %08x\n", id, image.ZeroBits );
371 ok( image.MaximumStackSize == max_stack || broken(truncated),
372 "%u: MaximumStackSize wrong %lx / %lx\n", id, image.MaximumStackSize, max_stack );
373 ok( image.CommittedStackSize == commit_stack || broken(truncated),
374 "%u: CommittedStackSize wrong %lx / %lx\n", id, image.CommittedStackSize, commit_stack );
375 if (truncated)
376 ok( !image.SubSystemType || broken(truncated),
377 "%u: SubSystemType wrong %08x / 00000000\n", id, image.SubSystemType );
378 else
379 ok( image.SubSystemType == nt_header->OptionalHeader.Subsystem,
380 "%u: SubSystemType wrong %08x / %08x\n", id,
381 image.SubSystemType, nt_header->OptionalHeader.Subsystem );
382 ok( image.SubsystemVersionLow == nt_header->OptionalHeader.MinorSubsystemVersion,
383 "%u: SubsystemVersionLow wrong %04x / %04x\n", id,
384 image.SubsystemVersionLow, nt_header->OptionalHeader.MinorSubsystemVersion );
385 ok( image.SubsystemVersionHigh == nt_header->OptionalHeader.MajorSubsystemVersion,
386 "%u: SubsystemVersionHigh wrong %04x / %04x\n", id,
387 image.SubsystemVersionHigh, nt_header->OptionalHeader.MajorSubsystemVersion );
388 ok( image.ImageCharacteristics == nt_header->FileHeader.Characteristics,
389 "%u: ImageCharacteristics wrong %04x / %04x\n", id,
390 image.ImageCharacteristics, nt_header->FileHeader.Characteristics );
391 ok( image.DllCharacteristics == nt_header->OptionalHeader.DllCharacteristics || broken(truncated),
392 "%u: DllCharacteristics wrong %04x / %04x\n", id,
393 image.DllCharacteristics, nt_header->OptionalHeader.DllCharacteristics );
394 ok( image.Machine == nt_header->FileHeader.Machine, "%u: Machine wrong %04x / %04x\n", id,
395 image.Machine, nt_header->FileHeader.Machine );
396 ok( image.LoaderFlags == (cor_header != NULL), "%u: LoaderFlags wrong %08x\n", id, image.LoaderFlags );
397 ok( image.ImageFileSize == file_size || broken(!image.ImageFileSize), /* winxpsp1 */
398 "%u: ImageFileSize wrong %08x / %08x\n", id, image.ImageFileSize, file_size );
399 ok( image.CheckSum == nt_header->OptionalHeader.CheckSum || broken(truncated),
400 "%u: CheckSum wrong %08x / %08x\n", id,
402
404 ok( image.ImageContainsCode == TRUE, "%u: ImageContainsCode wrong %u\n", id,
405 image.ImageContainsCode );
408 (section.Characteristics & IMAGE_SCN_MEM_EXECUTE)))
409 ok( image.ImageContainsCode == TRUE || broken(!image.ImageContainsCode), /* <= win8 */
410 "%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode );
411 else
412 ok( !image.ImageContainsCode, "%u: ImageContainsCode wrong %u\n", id, image.ImageContainsCode );
413
414 if (cor_header &&
415 (cor_header->Flags & COMIMAGE_FLAGS_ILONLY) &&
416 (cor_header->MajorRuntimeVersion > 2 ||
417 (cor_header->MajorRuntimeVersion == 2 && cor_header->MinorRuntimeVersion >= 5)))
418 {
419 ok( S(U(image)).ComPlusILOnly || broken(is_winxp),
420 "%u: wrong ComPlusILOnly flags %02x\n", id, U(image).ImageFlags );
422 !(cor_header->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
423 ok( S(U(image)).ComPlusNativeReady || broken(is_winxp),
424 "%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags );
425 else
426 ok( !S(U(image)).ComPlusNativeReady,
427 "%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags );
428 }
429 else
430 {
431 ok( !S(U(image)).ComPlusILOnly, "%u: wrong ComPlusILOnly flags %02x\n", id, U(image).ImageFlags );
432 ok( !S(U(image)).ComPlusNativeReady, "%u: wrong ComPlusNativeReady flags %02x\n", id, U(image).ImageFlags );
433 }
435 ok( !S(U(image)).ImageMappedFlat, "%u: wrong ImageMappedFlat flags %02x\n", id, U(image).ImageFlags );
436 else
437 {
438 /* winxp doesn't support any of the loader flags */
439 if (!S(U(image)).ImageMappedFlat) is_winxp = TRUE;
440 ok( S(U(image)).ImageMappedFlat || broken(is_winxp),
441 "%u: wrong ImageMappedFlat flags %02x\n", id, U(image).ImageFlags );
442 }
444 ok( !S(U(image)).ImageDynamicallyRelocated || broken( S(U(image)).ComPlusILOnly ), /* <= win7 */
445 "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
446 else if (image.ImageContainsCode && !cor_header)
447 ok( S(U(image)).ImageDynamicallyRelocated || broken(is_winxp),
448 "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
449 else
450 ok( !S(U(image)).ImageDynamicallyRelocated || broken(TRUE), /* <= win8 */
451 "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
452 ok( !S(U(image)).BaseBelow4gb, "%u: wrong BaseBelow4gb flags %02x\n", id, U(image).ImageFlags );
453
454 /* FIXME: needs more work: */
455 /* image.GpValue */
456
457 map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1);
458 status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
459 ok( !status, "NtQuerySection failed err %x\n", status );
460 ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
461 info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
463
464 map_size.QuadPart = (nt_header->OptionalHeader.SizeOfImage + page_size - 1) & ~(page_size - 1);
466 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
467 ok( !status, "%u: NtCreateSection failed err %x\n", id, status );
468 status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
469 ok( !status, "NtQuerySection failed err %x\n", status );
470 ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
471 info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
473
474 map_size.QuadPart++;
476 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
477 ok( status == STATUS_SECTION_TOO_BIG, "%u: NtCreateSection failed err %x\n", id, status );
478
479 SetFilePointerEx( file, map_size, NULL, FILE_BEGIN );
482 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
483 ok( status == STATUS_SECTION_TOO_BIG, "%u: NtCreateSection failed err %x\n", id, status );
484
485 map_size.QuadPart = 1;
487 NULL, &map_size, PAGE_READONLY, SEC_IMAGE, file );
488 ok( !status, "%u: NtCreateSection failed err %x\n", id, status );
489 status = pNtQuerySection( mapping, SectionBasicInformation, &info, sizeof(info), NULL );
490 ok( !status, "NtQuerySection failed err %x\n", status );
491 ok( info.Size.QuadPart == map_size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
492 info.Size.u.HighPart, info.Size.u.LowPart, map_size.u.HighPart, map_size.u.LowPart );
494
495 CloseHandle( file );
496 return image.ImageContainsCode && (!cor_header || !(cor_header->Flags & COMIMAGE_FLAGS_ILONLY));
497}
#define U(x)
Definition: wordpad.c:45
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
struct _IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER32
ImageFlags
Definition: gdiplusenums.h:332
GLeglImageOES image
Definition: gl.h:2204
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
static void SIZE_T
Definition: loader.c:59
@ SectionImageInformation
Definition: mmtypes.h:196
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
struct _IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER64
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
Definition: ntimage.h:455
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:300
#define LOWORD(l)
Definition: pedump.c:82
#define S(x)
Definition: test.h:220
Definition: movable.cpp:9
IMAGE_OPTIONAL_HEADER64 OptionalHeader
Definition: ntimage.h:396
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
LONGLONG QuadPart
Definition: typedefs.h:114
struct _LARGE_INTEGER::@2304 u
@ COMIMAGE_FLAGS_32BITREQUIRED
Definition: winnt_old.h:3292

Referenced by map_image_section(), and test_Loader().

◆ RVAToAddr()

static PVOID RVAToAddr ( DWORD_PTR  rva,
HMODULE  module 
)
static

Definition at line 83 of file loader.c.

84{
85 if (rva == 0)
86 return NULL;
87 return ((char*) module) + rva;
88}

Referenced by test_FakeDLL(), test_ImportDescriptors(), and test_ResolveDelayLoadedAPI().

◆ semaphore_thread_proc()

static DWORD WINAPI semaphore_thread_proc ( void param)
static

Definition at line 2193 of file loader.c.

2194{
2195 DWORD ret;
2196
2198 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %#x\n", ret);
2199
2200 SetEvent(param);
2201
2202 while (1)
2203 {
2204 if (winetest_debug > 1)
2205 trace("%04x: semaphore_thread_proc: still alive\n", GetCurrentThreadId());
2206 if (WaitForSingleObject(stop_event, 50) != WAIT_TIMEOUT) break;
2207 }
2208
2209 trace("%04x: semaphore_thread_proc: exiting\n", GetCurrentThreadId());
2210 return 196;
2211}
int winetest_debug

Referenced by child_process().

◆ START_TEST()

START_TEST ( loader  )

Definition at line 3744 of file loader.c.

3745{
3746 int argc;
3747 char **argv;
3748 HANDLE ntdll, mapping, kernel32;
3749 SYSTEM_INFO si;
3750
3751 ntdll = GetModuleHandleA("ntdll.dll");
3752 kernel32 = GetModuleHandleA("kernel32.dll");
3753 pNtCreateSection = (void *)GetProcAddress(ntdll, "NtCreateSection");
3754 pNtQuerySection = (void *)GetProcAddress(ntdll, "NtQuerySection");
3755 pNtMapViewOfSection = (void *)GetProcAddress(ntdll, "NtMapViewOfSection");
3756 pNtUnmapViewOfSection = (void *)GetProcAddress(ntdll, "NtUnmapViewOfSection");
3757 pNtTerminateProcess = (void *)GetProcAddress(ntdll, "NtTerminateProcess");
3758 pNtQueryInformationProcess = (void *)GetProcAddress(ntdll, "NtQueryInformationProcess");
3759 pNtSetInformationProcess = (void *)GetProcAddress(ntdll, "NtSetInformationProcess");
3760 pLdrShutdownProcess = (void *)GetProcAddress(ntdll, "LdrShutdownProcess");
3761 pRtlDllShutdownInProgress = (void *)GetProcAddress(ntdll, "RtlDllShutdownInProgress");
3762 pNtAllocateVirtualMemory = (void *)GetProcAddress(ntdll, "NtAllocateVirtualMemory");
3763 pNtFreeVirtualMemory = (void *)GetProcAddress(ntdll, "NtFreeVirtualMemory");
3764 pLdrLockLoaderLock = (void *)GetProcAddress(ntdll, "LdrLockLoaderLock");
3765 pLdrUnlockLoaderLock = (void *)GetProcAddress(ntdll, "LdrUnlockLoaderLock");
3766 pRtlAcquirePebLock = (void *)GetProcAddress(ntdll, "RtlAcquirePebLock");
3767 pRtlReleasePebLock = (void *)GetProcAddress(ntdll, "RtlReleasePebLock");
3768 pRtlImageDirectoryEntryToData = (void *)GetProcAddress(ntdll, "RtlImageDirectoryEntryToData");
3769 pFlsAlloc = (void *)GetProcAddress(kernel32, "FlsAlloc");
3770 pFlsSetValue = (void *)GetProcAddress(kernel32, "FlsSetValue");
3771 pFlsGetValue = (void *)GetProcAddress(kernel32, "FlsGetValue");
3772 pFlsFree = (void *)GetProcAddress(kernel32, "FlsFree");
3773 pIsWow64Process = (void *)GetProcAddress(kernel32, "IsWow64Process");
3774 pResolveDelayLoadedAPI = (void *)GetProcAddress(kernel32, "ResolveDelayLoadedAPI");
3775
3776 if (pIsWow64Process) pIsWow64Process( GetCurrentProcess(), &is_wow64 );
3777 GetSystemInfo( &si );
3778 page_size = si.dwPageSize;
3780 dos_header.e_lfanew = sizeof(dos_header);
3781
3782 mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_loader");
3783 ok(mapping != 0, "CreateFileMapping failed\n");
3785 if (*child_failures == -1)
3786 {
3787 *child_failures = 0;
3788 }
3789 else
3790 *child_failures = -1;
3791
3793 if (argc > 4)
3794 {
3795 test_dll_phase = atoi(argv[4]);
3796 child_process(argv[2], atol(argv[3]));
3797 return;
3798 }
3799
3800 test_Loader();
3801 test_FakeDLL();
3810}
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
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
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
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
static void test_HashLinks(void)
Definition: loader.c:3700
static void test_ImportDescriptors(void)
Definition: loader.c:1493
static BOOL is_wow64
Definition: loader.c:55
static void test_ExitProcess(void)
Definition: loader.c:2876
static void test_ResolveDelayLoadedAPI(void)
Definition: loader.c:3392
static void test_Loader(void)
Definition: loader.c:563
static void test_section_access(void)
Definition: loader.c:1794
static void test_InMemoryOrderModuleList(void)
Definition: loader.c:3650
static void test_FakeDLL(void)
Definition: loader.c:1398
static void test_filenames(void)
Definition: loader.c:1319
static void test_import_resolution(void)
Definition: loader.c:2003
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:1198
#define FILE_MAP_WRITE
Definition: winbase.h:155

◆ test_ExitProcess()

static void test_ExitProcess ( void  )
static

Definition at line 2876 of file loader.c.

2877{
2878#include "pshpack1.h"
2879#ifdef __x86_64__
2880 static struct section_data
2881 {
2882 BYTE mov_rax[2];
2883 void *target;
2884 BYTE jmp_rax[2];
2885 } section_data = { { 0x48,0xb8 }, dll_entry_point, { 0xff,0xe0 } };
2886#else
2887 static struct section_data
2888 {
2889 BYTE mov_eax;
2890 void *target;
2891 BYTE jmp_eax[2];
2892 } section_data = { 0xb8, dll_entry_point, { 0xff,0xe0 } };
2893#endif
2894#include "poppack.h"
2895 DWORD dummy, file_align;
2896 HANDLE file, thread, process, hmap, hmap_dup;
2897 char temp_path[MAX_PATH], dll_name[MAX_PATH], cmdline[MAX_PATH * 2];
2898 DWORD ret, target_offset, old_prot;
2899 char **argv, buf[256];
2901 STARTUPINFOA si = { sizeof(si) };
2902 CONTEXT ctx;
2906 void *addr;
2908 SIZE_T size;
2910
2911#if !defined(__i386__) && !defined(__x86_64__)
2912 skip("x86 specific ExitProcess test\n");
2913 return;
2914#endif
2915
2916 if (!pRtlDllShutdownInProgress)
2917 {
2918 win_skip("RtlDllShutdownInProgress is not available on this platform (XP+)\n");
2919 return;
2920 }
2921 if (!pNtQueryInformationProcess || !pNtSetInformationProcess)
2922 {
2923 win_skip("NtQueryInformationProcess/NtSetInformationProcess are not available on this platform\n");
2924 return;
2925 }
2926 if (!pNtAllocateVirtualMemory || !pNtFreeVirtualMemory)
2927 {
2928 win_skip("NtAllocateVirtualMemory/NtFreeVirtualMemory are not available on this platform\n");
2929 return;
2930 }
2931
2932 /* prevent displaying of the "Unable to load this DLL" message box */
2934
2936 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
2937
2938 /*trace("creating %s\n", dll_name);*/
2939 file = CreateFileA(dll_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
2941 {
2942 ok(0, "could not create %s\n", dll_name);
2943 return;
2944 }
2945
2946 SetLastError(0xdeadbeef);
2947 ret = WriteFile(file, &dos_header, sizeof(dos_header), &dummy, NULL);
2948 ok(ret, "WriteFile error %d\n", GetLastError());
2949
2954
2958 nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + 0x1000;
2960 SetLastError(0xdeadbeef);
2961 ret = WriteFile(file, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
2962 ok(ret, "WriteFile error %d\n", GetLastError());
2963 SetLastError(0xdeadbeef);
2965 ok(ret, "WriteFile error %d\n", GetLastError());
2966
2967 section.SizeOfRawData = sizeof(section_data);
2968 section.PointerToRawData = nt_header.OptionalHeader.FileAlignment;
2970 section.Misc.VirtualSize = sizeof(section_data);
2972 SetLastError(0xdeadbeef);
2973 ret = WriteFile(file, &section, sizeof(section), &dummy, NULL);
2974 ok(ret, "WriteFile error %d\n", GetLastError());
2975
2977 assert(file_align < sizeof(filler));
2978 SetLastError(0xdeadbeef);
2979 ret = WriteFile(file, filler, file_align, &dummy, NULL);
2980 ok(ret, "WriteFile error %d\n", GetLastError());
2981
2982 target_offset = SetFilePointer(file, 0, NULL, FILE_CURRENT) + FIELD_OFFSET(struct section_data, target);
2983
2984 /* section data */
2985 SetLastError(0xdeadbeef);
2987 ok(ret, "WriteFile error %d\n", GetLastError());
2988
2990
2992
2993 /* phase 0 */
2994 *child_failures = -1;
2995 sprintf(cmdline, "\"%s\" loader %s %u 0", argv[0], dll_name, target_offset);
2996 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
2997 ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
2998 ret = WaitForSingleObject(pi.hProcess, 10000);
2999 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3000 if (ret != WAIT_OBJECT_0) TerminateProcess(pi.hProcess, 0);
3001 GetExitCodeProcess(pi.hProcess, &ret);
3002 ok(ret == 195, "expected exit code 195, got %u\n", ret);
3003 if (*child_failures)
3004 {
3005 trace("%d failures in child process\n", *child_failures);
3007 }
3008 CloseHandle(pi.hThread);
3009 CloseHandle(pi.hProcess);
3010
3011 /* phase 1 */
3012 *child_failures = -1;
3013 sprintf(cmdline, "\"%s\" loader %s %u 1", argv[0], dll_name, target_offset);
3014 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3015 ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
3016 ret = WaitForSingleObject(pi.hProcess, 10000);
3017 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3018 if (ret != WAIT_OBJECT_0) TerminateProcess(pi.hProcess, 0);
3019 GetExitCodeProcess(pi.hProcess, &ret);
3020 ok(ret == 195, "expected exit code 195, got %u\n", ret);
3021 if (*child_failures)
3022 {
3023 trace("%d failures in child process\n", *child_failures);
3025 }
3026 CloseHandle(pi.hThread);
3027 CloseHandle(pi.hProcess);
3028
3029 /* phase 2 */
3030 *child_failures = -1;
3031 sprintf(cmdline, "\"%s\" loader %s %u 2", argv[0], dll_name, target_offset);
3032 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3033 ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
3034 ret = WaitForSingleObject(pi.hProcess, 10000);
3035 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3036 if (ret != WAIT_OBJECT_0) TerminateProcess(pi.hProcess, 0);
3037 GetExitCodeProcess(pi.hProcess, &ret);
3038 ok(ret == 197, "expected exit code 197, got %u\n", ret);
3039 if (*child_failures)
3040 {
3041 trace("%d failures in child process\n", *child_failures);
3043 }
3044 CloseHandle(pi.hThread);
3045 CloseHandle(pi.hProcess);
3046
3047 /* phase 3 */
3048 *child_failures = -1;
3049 sprintf(cmdline, "\"%s\" loader %s %u 3", argv[0], dll_name, target_offset);
3050 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3051 ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
3052 ret = WaitForSingleObject(pi.hProcess, 10000);
3053 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3054 if (ret != WAIT_OBJECT_0) TerminateProcess(pi.hProcess, 0);
3055 GetExitCodeProcess(pi.hProcess, &ret);
3056 ok(ret == 195, "expected exit code 195, got %u\n", ret);
3057 if (*child_failures)
3058 {
3059 trace("%d failures in child process\n", *child_failures);
3061 }
3062 CloseHandle(pi.hThread);
3063 CloseHandle(pi.hProcess);
3064
3065 /* phase 4 */
3066 if (pLdrLockLoaderLock && pLdrUnlockLoaderLock)
3067 {
3068 *child_failures = -1;
3069 sprintf(cmdline, "\"%s\" loader %s %u 4", argv[0], dll_name, target_offset);
3070 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3071 ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
3072 ret = WaitForSingleObject(pi.hProcess, 10000);
3073 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3074 if (ret != WAIT_OBJECT_0) TerminateProcess(pi.hProcess, 0);
3075 GetExitCodeProcess(pi.hProcess, &ret);
3076 ok(ret == 198, "expected exit code 198, got %u\n", ret);
3077 if (*child_failures)
3078 {
3079 trace("%d failures in child process\n", *child_failures);
3081 }
3082 CloseHandle(pi.hThread);
3083 CloseHandle(pi.hProcess);
3084 }
3085 else
3086 win_skip("LdrLockLoaderLock/LdrUnlockLoaderLock are not available on this platform\n");
3087
3088 /* phase 5 */
3089 if (pRtlAcquirePebLock && pRtlReleasePebLock)
3090 {
3091 *child_failures = -1;
3092 sprintf(cmdline, "\"%s\" loader %s %u 5", argv[0], dll_name, target_offset);
3093 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3094 ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
3095 ret = WaitForSingleObject(pi.hProcess, 5000);
3096 ok(ret == WAIT_TIMEOUT, "child process should fail to terminate\n");
3097 if (ret != WAIT_OBJECT_0)
3098 {
3099 trace("terminating child process\n");
3100 TerminateProcess(pi.hProcess, 199);
3101 }
3102 ret = WaitForSingleObject(pi.hProcess, 1000);
3103 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3104 GetExitCodeProcess(pi.hProcess, &ret);
3105 ok(ret == 199, "expected exit code 199, got %u\n", ret);
3106 if (*child_failures)
3107 {
3108 trace("%d failures in child process\n", *child_failures);
3110 }
3111 CloseHandle(pi.hThread);
3112 CloseHandle(pi.hProcess);
3113 }
3114 else
3115 win_skip("RtlAcquirePebLock/RtlReleasePebLock are not available on this platform\n");
3116
3117 /* phase 6 */
3118 *child_failures = -1;
3119 sprintf(cmdline, "\"%s\" loader %s %u 6", argv[0], dll_name, target_offset);
3120 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
3121 ok(ret, "CreateProcess(%s) error %d\n", cmdline, GetLastError());
3122 ret = WaitForSingleObject(pi.hProcess, 5000);
3123 ok(ret == WAIT_TIMEOUT || broken(ret == WAIT_OBJECT_0) /* XP */, "child process should fail to terminate\n");
3124 if (ret != WAIT_OBJECT_0)
3125 {
3126 trace("terminating child process\n");
3127 TerminateProcess(pi.hProcess, 201);
3128 }
3129 ret = WaitForSingleObject(pi.hProcess, 1000);
3130 ok(ret == WAIT_OBJECT_0, "child process failed to terminate\n");
3131 GetExitCodeProcess(pi.hProcess, &ret);
3132 ok(ret == 201 || broken(ret == 1) /* XP */, "expected exit code 201, got %u\n", ret);
3133 if (*child_failures)
3134 {
3135 trace("%d failures in child process\n", *child_failures);
3137 }
3138 CloseHandle(pi.hThread);
3139 CloseHandle(pi.hProcess);
3140
3141 /* test remote process termination */
3142 SetLastError(0xdeadbeef);
3144 ok(ret, "CreateProcess(%s) error %d\n", argv[0], GetLastError());
3145
3146 SetLastError(0xdeadbeef);
3147 addr = VirtualAllocEx(pi.hProcess, NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
3148 ok(addr != NULL, "VirtualAllocEx error %d\n", GetLastError());
3149 SetLastError(0xdeadbeef);
3150 ret = VirtualProtectEx(pi.hProcess, addr, 4096, PAGE_READONLY, &old_prot);
3151 ok(ret, "VirtualProtectEx error %d\n", GetLastError());
3152 ok(old_prot == PAGE_READWRITE, "expected PAGE_READWRITE, got %#x\n", old_prot);
3153 SetLastError(0xdeadbeef);
3154 size = VirtualQueryEx(pi.hProcess, NULL, &mbi, sizeof(mbi));
3155 ok(size == sizeof(mbi), "VirtualQueryEx error %d\n", GetLastError());
3156
3157 SetLastError(0xdeadbeef);
3158 ret = ReadProcessMemory(pi.hProcess, addr, buf, 4, &size);
3159 ok(ret, "ReadProcessMemory error %d\n", GetLastError());
3160 ok(size == 4, "expected 4, got %lu\n", size);
3161
3162 SetLastError(0xdeadbeef);
3164 ok(hmap != 0, "CreateFileMapping error %d\n", GetLastError());
3165
3166 SetLastError(0xdeadbeef);
3167 ret = DuplicateHandle(GetCurrentProcess(), hmap, pi.hProcess, &hmap_dup,
3169 ok(ret, "DuplicateHandle error %d\n", GetLastError());
3170
3171 offset.u.LowPart = 0;
3172 offset.u.HighPart = 0;
3173 addr = NULL;
3174 size = 0;
3175 ret = pNtMapViewOfSection(hmap, pi.hProcess, &addr, 0, 0, &offset,
3176 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
3177 ok(!ret, "NtMapViewOfSection error %#x\n", ret);
3178 ret = pNtUnmapViewOfSection(pi.hProcess, addr);
3179 ok(!ret, "NtUnmapViewOfSection error %#x\n", ret);
3180
3181 SetLastError(0xdeadbeef);
3182 thread = CreateRemoteThread(pi.hProcess, NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret);
3183 ok(thread != 0, "CreateRemoteThread error %d\n", GetLastError());
3184 SetLastError(0xdeadbeef);
3185 ctx.ContextFlags = CONTEXT_INTEGER;
3187 ok(ret, "GetThreadContext error %d\n", GetLastError());
3188 SetLastError(0xdeadbeef);
3189 ctx.ContextFlags = CONTEXT_INTEGER;
3191 ok(ret, "SetThreadContext error %d\n", GetLastError());
3192 SetLastError(0xdeadbeef);
3194 ok(ret, "SetThreadPriority error %d\n", GetLastError());
3195
3196 SetLastError(0xdeadbeef);
3197 ret = TerminateThread(thread, 199);
3198 ok(ret, "TerminateThread error %d\n", GetLastError());
3199 /* Calling GetExitCodeThread() without waiting for thread termination
3200 * leads to different results due to a race condition.
3201 */
3203 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed: %x\n", ret);
3205 ok(ret == 199, "expected exit code 199, got %u\n", ret);
3206
3207 SetLastError(0xdeadbeef);
3208 ret = TerminateProcess(pi.hProcess, 198);
3209 ok(ret, "TerminateProcess error %d\n", GetLastError());
3210 /* Checking process state without waiting for process termination
3211 * leads to different results due to a race condition.
3212 */
3213 ret = WaitForSingleObject(pi.hProcess, 1000);
3214 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed: %x\n", ret);
3215
3216 SetLastError(0xdeadbeef);
3218 ok(process != NULL, "OpenProcess error %d\n", GetLastError());
3220
3221 memset(&pbi, 0, sizeof(pbi));
3222 ret = pNtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
3223 ok(!ret, "NtQueryInformationProcess error %#x\n", ret);
3224 ok(pbi.ExitStatus == 198, "expected 198, got %lu\n", pbi.ExitStatus);
3225 affinity = 1;
3226 ret = pNtSetInformationProcess(pi.hProcess, ProcessAffinityMask, &affinity, sizeof(affinity));
3227 ok(ret == STATUS_PROCESS_IS_TERMINATING, "expected STATUS_PROCESS_IS_TERMINATING, got %#x\n", ret);
3228
3229 SetLastError(0xdeadbeef);
3230 ctx.ContextFlags = CONTEXT_INTEGER;
3232 ok(!ret || broken(ret) /* XP 64-bit */, "GetThreadContext should fail\n");
3233 if (!ret)
3235 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
3236 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */,
3237 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3238 SetLastError(0xdeadbeef);
3239 ctx.ContextFlags = CONTEXT_INTEGER;
3241 ok(!ret || broken(ret) /* XP 64-bit */, "SetThreadContext should fail\n");
3242 if (!ret)
3244 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
3245 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */,
3246 "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3247 SetLastError(0xdeadbeef);
3249 ok(ret, "SetThreadPriority error %d\n", GetLastError());
3251
3252 SetLastError(0xdeadbeef);
3253 ctx.ContextFlags = CONTEXT_INTEGER;
3254 ret = GetThreadContext(pi.hThread, &ctx);
3255 ok(!ret || broken(ret) /* XP 64-bit */, "GetThreadContext should fail\n");
3256 if (!ret)
3258 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
3259 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */,
3260 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3261 SetLastError(0xdeadbeef);
3262 ctx.ContextFlags = CONTEXT_INTEGER;
3263 ret = SetThreadContext(pi.hThread, &ctx);
3264 ok(!ret || broken(ret) /* XP 64-bit */, "SetThreadContext should fail\n");
3265 if (!ret)
3267 GetLastError() == ERROR_GEN_FAILURE /* win7 64-bit */ ||
3268 GetLastError() == ERROR_INVALID_FUNCTION /* vista 64-bit */,
3269 "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3270 SetLastError(0xdeadbeef);
3271 ret = VirtualProtectEx(pi.hProcess, addr, 4096, PAGE_READWRITE, &old_prot);
3272 ok(!ret, "VirtualProtectEx should fail\n");
3273 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3274 SetLastError(0xdeadbeef);
3275 size = 0;
3276 ret = ReadProcessMemory(pi.hProcess, addr, buf, 4, &size);
3277 ok(!ret, "ReadProcessMemory should fail\n");
3279 "expected ERROR_PARTIAL_COPY, got %d\n", GetLastError());
3280 ok(!size, "expected 0, got %lu\n", size);
3281 SetLastError(0xdeadbeef);
3282 ret = VirtualFreeEx(pi.hProcess, addr, 0, MEM_RELEASE);
3283 ok(!ret, "VirtualFreeEx should fail\n");
3284 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3285 SetLastError(0xdeadbeef);
3286 addr = VirtualAllocEx(pi.hProcess, NULL, 4096, MEM_COMMIT, PAGE_READWRITE);
3287 ok(!addr, "VirtualAllocEx should fail\n");
3288 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3289 SetLastError(0xdeadbeef);
3290 size = VirtualQueryEx(pi.hProcess, NULL, &mbi, sizeof(mbi));
3291 ok(!size, "VirtualQueryEx should fail\n");
3292 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3293
3294 /* CloseHandle() call below leads to premature process termination
3295 * under some Windows versions.
3296 */
3297if (0)
3298{
3299 SetLastError(0xdeadbeef);
3300 ret = CloseHandle(hmap_dup);
3301 ok(ret, "CloseHandle should not fail\n");
3302}
3303
3304 SetLastError(0xdeadbeef);
3305 ret = DuplicateHandle(GetCurrentProcess(), hmap, pi.hProcess, &hmap_dup,
3307 ok(!ret, "DuplicateHandle should fail\n");
3308 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3309
3310 offset.u.LowPart = 0;
3311 offset.u.HighPart = 0;
3312 addr = NULL;
3313 size = 0;
3314 ret = pNtMapViewOfSection(hmap, pi.hProcess, &addr, 0, 0, &offset,
3315 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
3316 ok(ret == STATUS_PROCESS_IS_TERMINATING, "expected STATUS_PROCESS_IS_TERMINATING, got %#x\n", ret);
3317
3318 SetLastError(0xdeadbeef);
3319 thread = CreateRemoteThread(pi.hProcess, NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret);
3320 ok(!thread, "CreateRemoteThread should fail\n");
3321 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3322
3323 SetLastError(0xdeadbeef);
3324 ret = DebugActiveProcess(pi.dwProcessId);
3325 ok(!ret, "DebugActiveProcess should fail\n");
3326 ok(GetLastError() == ERROR_ACCESS_DENIED /* 64-bit */ || GetLastError() == ERROR_NOT_SUPPORTED /* 32-bit */,
3327 "ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3328
3329 GetExitCodeProcess(pi.hProcess, &ret);
3330 ok(ret == 198 || broken(ret != 198) /* some 32-bit XP version in a VM returns random exit code */,
3331 "expected exit code 198, got %u\n", ret);
3332 CloseHandle(pi.hThread);
3333 CloseHandle(pi.hProcess);
3334
3335 ret = DeleteFileA(dll_name);
3336 ok(ret, "DeleteFile error %d\n", GetLastError());
3337}
#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:4747
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
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const IMAGE_NT_HEADERS nt_header_template
Definition: loader.c:92
static refpint_t pi[]
Definition: server.c:96
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define CONTEXT_INTEGER
Definition: nt_native.h:1370
#define MEM_RELEASE
Definition: nt_native.h:1316
#define MEM_COMMIT
Definition: nt_native.h:1313
#define IMAGE_SCN_CNT_CODE
Definition: ntimage.h:230
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define IMAGE_FILE_EXECUTABLE_IMAGE
Definition: pedump.c:160
#define IMAGE_FILE_DLL
Definition: pedump.c:169
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
struct _IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER
#define win_skip
Definition: test.h:163
void winetest_add_failures(LONG new_failures)
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:114
#define CREATE_SUSPENDED
Definition: winbase.h:181
#define ERROR_PARTIAL_COPY
Definition: winerror.h:303
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
unsigned char BYTE
Definition: xxhash.c:193

Referenced by START_TEST().

◆ test_FakeDLL()

static void test_FakeDLL ( void  )
static

Definition at line 1398 of file loader.c.

1399{
1400#if defined(__i386__) || defined(__x86_64__)
1401 NTSTATUS (WINAPI *pNtSetEvent)(HANDLE, ULONG *) = NULL;
1403 HMODULE module = GetModuleHandleA("ntdll.dll");
1404 HANDLE file, map, event;
1406 DWORD *names, *funcs;
1407 WORD *ordinals;
1408 ULONG size;
1409 void *ptr;
1410 int i;
1411
1413
1415 ok(file != INVALID_HANDLE_VALUE, "Failed to open %s (error %u)\n", wine_dbgstr_w(path), GetLastError());
1416
1418 ok(map != NULL, "CreateFileMapping failed with error %u\n", GetLastError());
1420 ok(ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError());
1421
1423 ok(dir != NULL, "RtlImageDirectoryEntryToData failed\n");
1424
1425 names = RVAToAddr(dir->AddressOfNames, ptr);
1426 ordinals = RVAToAddr(dir->AddressOfNameOrdinals, ptr);
1427 funcs = RVAToAddr(dir->AddressOfFunctions, ptr);
1428 ok(dir->NumberOfNames > 0, "Could not find any exported functions\n");
1429
1430 for (i = 0; i < dir->NumberOfNames; i++)
1431 {
1432 DWORD map_rva, dll_rva, map_offset, dll_offset;
1433 char *func_name = RVAToAddr(names[i], ptr);
1434 BYTE *dll_func, *map_func;
1435
1436 /* check only Nt functions for now */
1437 if (strncmp(func_name, "Zw", 2) && strncmp(func_name, "Nt", 2))
1438 continue;
1439
1440 dll_func = (BYTE *)GetProcAddress(module, func_name);
1441 ok(dll_func != NULL, "%s: GetProcAddress returned NULL\n", func_name);
1442#if defined(__i386__)
1443 if (dll_func[0] == 0x90 && dll_func[1] == 0x90 &&
1444 dll_func[2] == 0x90 && dll_func[3] == 0x90)
1445#elif defined(__x86_64__)
1446 if (dll_func[0] == 0x48 && dll_func[1] == 0x83 &&
1447 dll_func[2] == 0xec && dll_func[3] == 0x08)
1448#endif
1449 {
1450 todo_wine ok(0, "%s: Export is a stub-function, skipping\n", func_name);
1451 continue;
1452 }
1453
1454 /* check position in memory */
1455 dll_rva = (DWORD_PTR)dll_func - (DWORD_PTR)module;
1456 map_rva = funcs[ordinals[i]];
1457 ok(map_rva == dll_rva, "%s: Rva of mapped function (0x%x) does not match dll (0x%x)\n",
1458 func_name, dll_rva, map_rva);
1459
1460 /* check position in file */
1461 map_offset = (DWORD_PTR)RtlImageRvaToVa(RtlImageNtHeader(ptr), ptr, map_rva, NULL) - (DWORD_PTR)ptr;
1463 ok(map_offset == dll_offset, "%s: File offset of mapped function (0x%x) does not match dll (0x%x)\n",
1464 func_name, map_offset, dll_offset);
1465
1466 /* check function content */
1467 map_func = RVAToAddr(map_rva, ptr);
1468 ok(!memcmp(map_func, dll_func, 0x20), "%s: Function content does not match!\n", func_name);
1469
1470 if (!strcmp(func_name, "NtSetEvent"))
1471 pNtSetEvent = (void *)map_func;
1472 }
1473
1474 ok(pNtSetEvent != NULL, "Could not find NtSetEvent export\n");
1475 if (pNtSetEvent)
1476 {
1477 event = CreateEventA(NULL, TRUE, FALSE, NULL);
1478 ok(event != NULL, "CreateEvent failed with error %u\n", GetLastError());
1479 pNtSetEvent(event, 0);
1480 ok(WaitForSingleObject(event, 0) == WAIT_OBJECT_0, "Event was not signaled\n");
1481 pNtSetEvent(event, 0);
1482 ok(WaitForSingleObject(event, 0) == WAIT_OBJECT_0, "Event was not signaled\n");
1484 }
1485
1489#endif
1490}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
unsigned int dir
Definition: maze.c:112
#define NTSTATUS
Definition: precomp.h:19
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define UnmapViewOfFile
Definition: compat.h:746
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define RtlImageRvaToVa
Definition: compat.h:807
#define RtlImageNtHeader
Definition: compat.h:806
#define CreateFileW
Definition: compat.h:741
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
GLuint GLuint * names
Definition: glext.h:11545
#define wine_dbgstr_w
Definition: kernel32.h:34
static PVOID ptr
Definition: dispmode.c:27
static const OBJECT_ATTRIBUTES const LARGE_INTEGER HANDLE
Definition: loader.c:58
HANDLE event
Definition: loader.c:2140
static PVOID RVAToAddr(DWORD_PTR rva, HMODULE module)
Definition: loader.c:83
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define GENERIC_EXECUTE
Definition: nt_native.h:91
void func_name(void)
static struct __wine_debug_functions funcs
Definition: debug.c:59
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
#define DWORD_PTR
Definition: treelist.c:76
#define FILE_MAP_EXECUTE
Definition: winbase.h:158
#define WINAPI
Definition: msvc.h:6
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ test_filenames()

static void test_filenames ( void  )
static

Definition at line 1319 of file loader.c.

1320{
1322 char dll_name[MAX_PATH], long_path[MAX_PATH], short_path[MAX_PATH], buffer[MAX_PATH];
1323 HMODULE mod, mod2;
1324 BOOL ret;
1325
1328
1334
1335 create_test_dll( &dos_header, sizeof(dos_header), &nt_header, dll_name );
1336 strcpy( long_path, dll_name );
1337 strcpy( strrchr( long_path, '\\' ), "\\this-is-a-long-name.dll" );
1338 ret = MoveFileA( dll_name, long_path );
1339 ok( ret, "MoveFileA failed err %u\n", GetLastError() );
1340 GetShortPathNameA( long_path, short_path, MAX_PATH );
1341
1342 mod = LoadLibraryA( short_path );
1343 ok( mod != NULL, "loading failed err %u\n", GetLastError() );
1345 ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path );
1346 mod2 = GetModuleHandleA( short_path );
1347 ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path );
1348 mod2 = GetModuleHandleA( long_path );
1349 ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
1350 mod2 = LoadLibraryA( long_path );
1351 ok( mod2 != NULL, "loading failed err %u\n", GetLastError() );
1352 ok( mod == mod2, "library loaded twice\n" );
1354 ok( !lstrcmpiA( buffer, short_path ), "got wrong path %s / %s\n", buffer, short_path );
1355 FreeLibrary( mod2 );
1356 FreeLibrary( mod );
1357
1358 mod = LoadLibraryA( long_path );
1359 ok( mod != NULL, "loading failed err %u\n", GetLastError() );
1361 ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path );
1362 mod2 = GetModuleHandleA( short_path );
1363 ok( mod == mod2, "wrong module %p for %s\n", mod2, short_path );
1364 mod2 = GetModuleHandleA( long_path );
1365 ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
1366 mod2 = LoadLibraryA( short_path );
1367 ok( mod2 != NULL, "loading failed err %u\n", GetLastError() );
1368 ok( mod == mod2, "library loaded twice\n" );
1370 ok( !lstrcmpiA( buffer, long_path ), "got wrong path %s / %s\n", buffer, long_path );
1371 FreeLibrary( mod2 );
1372 FreeLibrary( mod );
1373
1374 strcpy( dll_name, long_path );
1375 strcpy( strrchr( dll_name, '\\' ), "\\this-is-another-name.dll" );
1376 ret = CreateHardLinkA( dll_name, long_path, NULL );
1377 ok( ret, "CreateHardLinkA failed err %u\n", GetLastError() );
1378 if (ret)
1379 {
1380 mod = LoadLibraryA( dll_name );
1381 ok( mod != NULL, "loading failed err %u\n", GetLastError() );
1383 ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, dll_name );
1384 mod2 = GetModuleHandleA( long_path );
1385 ok( mod == mod2, "wrong module %p for %s\n", mod2, long_path );
1386 mod2 = LoadLibraryA( long_path );
1387 ok( mod2 != NULL, "loading failed err %u\n", GetLastError() );
1388 ok( mod == mod2, "library loaded twice\n" );
1390 ok( !lstrcmpiA( buffer, dll_name ), "got wrong path %s / %s\n", buffer, short_path );
1391 FreeLibrary( mod2 );
1392 FreeLibrary( mod );
1393 DeleteFileA( dll_name );
1394 }
1395 DeleteFileA( long_path );
1396}
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define mod2(n)
Definition: vgavideo.h:71
BOOL WINAPI MoveFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName)
Definition: move.c:1137
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
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:4224
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:170
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT
Definition: ntimage.h:457
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)

Referenced by START_TEST().

◆ test_HashLinks()

static void test_HashLinks ( void  )
static

Definition at line 3700 of file loader.c.

3701{
3702 static WCHAR ntdllW[] = {'n','t','d','l','l','.','d','l','l',0};
3703 static WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
3704
3705 LIST_ENTRY *hash_map, *entry, *mark;
3707 BOOL found;
3708
3709 entry = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
3710 entry = entry->Flink;
3711
3712 module = CONTAINING_RECORD(entry, LDR_MODULE, InLoadOrderModuleList);
3713 entry = module->HashLinks.Blink;
3714
3715 hash_map = entry - hash_basename(module->BaseDllName.Buffer);
3716
3717 mark = &hash_map[hash_basename(ntdllW)];
3718 found = FALSE;
3719 for (entry = mark->Flink; entry != mark; entry = entry->Flink)
3720 {
3722 if (!lstrcmpiW(module->BaseDllName.Buffer, ntdllW))
3723 {
3724 found = TRUE;
3725 break;
3726 }
3727 }
3728 ok(found, "Could not find ntdll\n");
3729
3730 mark = &hash_map[hash_basename(kernel32W)];
3731 found = FALSE;
3732 for (entry = mark->Flink; entry != mark; entry = entry->Flink)
3733 {
3735 if (!lstrcmpiW(module->BaseDllName.Buffer, kernel32W))
3736 {
3737 found = TRUE;
3738 break;
3739 }
3740 }
3741 ok(found, "Could not find kernel32\n");
3742}
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
uint32_t entry
Definition: isohybrid.c:63
static ULONG hash_basename(const WCHAR *basename)
Definition: loader.c:3678
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

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 1547 of file loader.c.

1548{
1549 HANDLE hfile, hmap;
1552 SIZE_T size;
1553 void *addr1, *addr2;
1555
1556 if (!pNtMapViewOfSection) return;
1557
1558 SetLastError(0xdeadbeef);
1559 hfile = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1560 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
1561
1562 SetLastError(0xdeadbeef);
1563 hmap = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, 0);
1564 ok(hmap != 0, "CreateFileMapping error %d\n", GetLastError());
1565
1566 offset.u.LowPart = 0;
1567 offset.u.HighPart = 0;
1568
1569 addr1 = NULL;
1570 size = 0;
1571 status = pNtMapViewOfSection(hmap, GetCurrentProcess(), &addr1, 0, 0, &offset,
1572 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
1573 ok(status == STATUS_SUCCESS, "NtMapViewOfSection error %x\n", status);
1574 ok(addr1 != 0, "mapped address should be valid\n");
1575
1576 SetLastError(0xdeadbeef);
1577 size = VirtualQuery((char *)addr1 + section.VirtualAddress, &info, sizeof(info));
1578 ok(size == sizeof(info), "VirtualQuery error %d\n", GetLastError());
1579 ok(info.BaseAddress == (char *)addr1 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr1 + section.VirtualAddress);
1580 ok(info.RegionSize == page_size, "got %#lx != expected %#x\n", info.RegionSize, page_size);
1581 ok(info.Protect == scn_page_access, "got %#x != expected %#x\n", info.Protect, scn_page_access);
1582 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
1583 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#x != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
1584 ok(info.State == MEM_COMMIT, "%#x != MEM_COMMIT\n", info.State);
1585 ok(info.Type == SEC_IMAGE, "%#x != SEC_IMAGE\n", info.Type);
1586
1587 addr2 = NULL;
1588 size = 0;
1589 status = pNtMapViewOfSection(hmap, GetCurrentProcess(), &addr2, 0, 0, &offset,
1590 &size, 1 /* ViewShare */, 0, PAGE_READONLY);
1591 ok(status == STATUS_IMAGE_NOT_AT_BASE, "expected STATUS_IMAGE_NOT_AT_BASE, got %x\n", status);
1592 ok(addr2 != 0, "mapped address should be valid\n");
1593 ok(addr2 != addr1, "mapped addresses should be different\n");
1594
1595 SetLastError(0xdeadbeef);
1596 size = VirtualQuery((char *)addr2 + section.VirtualAddress, &info, sizeof(info));
1597 ok(size == sizeof(info), "VirtualQuery error %d\n", GetLastError());
1598 ok(info.BaseAddress == (char *)addr2 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr2 + section.VirtualAddress);
1599 ok(info.RegionSize == page_size, "got %#lx != expected %#x\n", info.RegionSize, page_size);
1600 ok(info.Protect == scn_page_access, "got %#x != expected %#x\n", info.Protect, scn_page_access);
1601 ok(info.AllocationBase == addr2, "%p != %p\n", info.AllocationBase, addr2);
1602 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#x != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
1603 ok(info.State == MEM_COMMIT, "%#x != MEM_COMMIT\n", info.State);
1604 ok(info.Type == SEC_IMAGE, "%#x != SEC_IMAGE\n", info.Type);
1605
1606 status = pNtUnmapViewOfSection(GetCurrentProcess(), addr2);
1607 ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection error %x\n", status);
1608
1609 addr2 = MapViewOfFile(hmap, 0, 0, 0, 0);
1610 ok(addr2 != 0, "mapped address should be valid\n");
1611 ok(addr2 != addr1, "mapped addresses should be different\n");
1612
1613 SetLastError(0xdeadbeef);
1614 size = VirtualQuery((char *)addr2 + section.VirtualAddress, &info, sizeof(info));
1615 ok(size == sizeof(info), "VirtualQuery error %d\n", GetLastError());
1616 ok(info.BaseAddress == (char *)addr2 + section.VirtualAddress, "got %p != expected %p\n", info.BaseAddress, (char *)addr2 + section.VirtualAddress);
1617 ok(info.RegionSize == page_size, "got %#lx != expected %#x\n", info.RegionSize, page_size);
1618 ok(info.Protect == scn_page_access, "got %#x != expected %#x\n", info.Protect, scn_page_access);
1619 ok(info.AllocationBase == addr2, "%p != %p\n", info.AllocationBase, addr2);
1620 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%#x != PAGE_EXECUTE_WRITECOPY\n", info.AllocationProtect);
1621 ok(info.State == MEM_COMMIT, "%#x != MEM_COMMIT\n", info.State);
1622 ok(info.Type == SEC_IMAGE, "%#x != SEC_IMAGE\n", info.Type);
1623
1624 UnmapViewOfFile(addr2);
1625
1626 SetLastError(0xdeadbeef);
1627 addr2 = LoadLibraryA(dll_name);
1628 if (is_dll)
1629 {
1630 ok(!addr2, "LoadLibrary should fail, is_dll %d\n", is_dll);
1631 ok(GetLastError() == ERROR_INVALID_ADDRESS, "expected ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1632 }
1633 else
1634 {
1635 BOOL ret;
1636 ok(addr2 != 0, "LoadLibrary error %d, is_dll %d\n", GetLastError(), is_dll);
1637 ok(addr2 != addr1, "mapped addresses should be different\n");
1638
1639 SetLastError(0xdeadbeef);
1640 ret = FreeLibrary(addr2);
1641 ok(ret, "FreeLibrary error %d\n", GetLastError());
1642 }
1643
1644 status = pNtUnmapViewOfSection(GetCurrentProcess(), addr1);
1645 ok(status == STATUS_SUCCESS, "NtUnmapViewOfSection error %x\n", status);
1646
1647 CloseHandle(hmap);
1648 CloseHandle(hfile);
1649}
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:117
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 2003 of file loader.c.

2004{
2005 char temp_path[MAX_PATH];
2006 char dll_name[MAX_PATH];
2007 DWORD dummy;
2008 void *expect;
2009 char *str;
2010 HANDLE hfile;
2011 HMODULE mod, mod2;
2012 struct imports
2013 {
2015 IMAGE_THUNK_DATA original_thunks[2];
2016 IMAGE_THUNK_DATA thunks[2];
2017 char module[16];
2018 struct { WORD hint; char name[32]; } function;
2020 char tls_data[16];
2022 } data, *ptr;
2025 int test;
2026
2027 for (test = 0; test < 3; test++)
2028 {
2029#define DATA_RVA(ptr) (page_size + ((char *)(ptr) - (char *)&data))
2037 nt.OptionalHeader.ImageBase = 0x12340000;
2046
2047 memset( &data, 0, sizeof(data) );
2048 U(data.descr[0]).OriginalFirstThunk = DATA_RVA( data.original_thunks );
2049 data.descr[0].FirstThunk = DATA_RVA( data.thunks );
2050 data.descr[0].Name = DATA_RVA( data.module );
2051 strcpy( data.module, "kernel32.dll" );
2052 strcpy( data.function.name, "CreateEventA" );
2053 data.original_thunks[0].u1.AddressOfData = DATA_RVA( &data.function );
2054 data.thunks[0].u1.AddressOfData = 0xdeadbeef;
2055
2056 data.tls.StartAddressOfRawData = nt.OptionalHeader.ImageBase + DATA_RVA( data.tls_data );
2057 data.tls.EndAddressOfRawData = data.tls.StartAddressOfRawData + sizeof(data.tls_data);
2058 data.tls.AddressOfIndex = nt.OptionalHeader.ImageBase + DATA_RVA( &data.tls_index );
2059 strcpy( data.tls_data, "hello world" );
2060 data.tls_index = 9999;
2061
2063 GetTempFileNameA(temp_path, "ldr", 0, dll_name);
2064
2065 hfile = CreateFileA(dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
2066 ok( hfile != INVALID_HANDLE_VALUE, "creation failed\n" );
2067
2068 memset( &section, 0, sizeof(section) );
2069 memcpy( section.Name, ".text", sizeof(".text") );
2070 section.PointerToRawData = nt.OptionalHeader.FileAlignment;
2071 section.VirtualAddress = nt.OptionalHeader.SectionAlignment;
2072 section.Misc.VirtualSize = sizeof(data);
2073 section.SizeOfRawData = sizeof(data);
2075
2076 WriteFile(hfile, &dos_header, sizeof(dos_header), &dummy, NULL);
2077 WriteFile(hfile, &nt, sizeof(nt), &dummy, NULL);
2078 WriteFile(hfile, &section, sizeof(section), &dummy, NULL);
2079
2080 SetFilePointer( hfile, section.PointerToRawData, NULL, SEEK_SET );
2081 WriteFile(hfile, &data, sizeof(data), &dummy, NULL);
2082
2083 CloseHandle( hfile );
2084
2085 switch (test)
2086 {
2087 case 0: /* normal load */
2088 mod = LoadLibraryA( dll_name );
2089 ok( mod != NULL, "failed to load err %u\n", GetLastError() );
2090 if (!mod) break;
2091 ptr = (struct imports *)((char *)mod + page_size);
2092 expect = GetProcAddress( GetModuleHandleA( data.module ), data.function.name );
2093 ok( (void *)ptr->thunks[0].u1.Function == expect, "thunk %p instead of %p for %s.%s\n",
2094 (void *)ptr->thunks[0].u1.Function, expect, data.module, data.function.name );
2095 ok( ptr->tls_index < 32 || broken(ptr->tls_index == 9999), /* before vista */
2096 "wrong tls index %d\n", ptr->tls_index );
2097 if (ptr->tls_index != 9999)
2098 {
2099 str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[ptr->tls_index];
2100 ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str );
2101 }
2102 FreeLibrary( mod );
2103 break;
2104 case 1: /* load with DONT_RESOLVE_DLL_REFERENCES doesn't resolve imports */
2106 ok( mod != NULL, "failed to load err %u\n", GetLastError() );
2107 if (!mod) break;
2108 ptr = (struct imports *)((char *)mod + page_size);
2109 ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
2110 (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
2111 ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
2112
2113 mod2 = LoadLibraryA( dll_name );
2114 ok( mod2 == mod, "loaded twice %p / %p\n", mod, mod2 );
2115 ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
2116 (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
2117 ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
2118 FreeLibrary( mod2 );
2119 FreeLibrary( mod );
2120 break;
2121 case 2: /* load without IMAGE_FILE_DLL doesn't resolve imports */
2122 mod = LoadLibraryA( dll_name );
2123 ok( mod != NULL, "failed to load err %u\n", GetLastError() );
2124 if (!mod) break;
2125 ptr = (struct imports *)((char *)mod + page_size);
2126 ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
2127 (void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
2128 ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
2129 FreeLibrary( mod );
2130 break;
2131 }
2132 DeleteFileA( dll_name );
2133#undef DATA_RVA
2134 }
2135}
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#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
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static IMAGE_SECTION_HEADER section
Definition: loader.c:152
#define DATA_RVA(ptr)
IMAGE_NT_HEADERS nt
Definition: module.c:50
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define IMAGE_SCN_CNT_INITIALIZED_DATA
Definition: ntimage.h:231
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
short SHORT
Definition: pedump.c:59
#define IMAGE_DIRECTORY_ENTRY_TLS
Definition: pedump.c:268
#define IMAGE_FILE_32BIT_MACHINE
Definition: pedump.c:164
#define test
Definition: rosglue.h:37
const WCHAR * str
DWORD tls_index
const char * descr
Definition: boot.c:45
static DWORD tls
Definition: sock.c:229
char * name
Definition: compiler.c:66
Definition: name.c:39
DWORD hint
Definition: vfdcmd.c:88

Referenced by START_TEST().

◆ test_ImportDescriptors()

static void test_ImportDescriptors ( void  )
static

Definition at line 1493 of file loader.c.

1494{
1495 HMODULE kernel32_module = NULL;
1496 PIMAGE_DOS_HEADER d_header;
1497 PIMAGE_NT_HEADERS nt_headers;
1498 DWORD import_dir_size;
1499 DWORD_PTR dir_offset;
1500 PIMAGE_IMPORT_DESCRIPTOR import_chunk;
1501
1502 /* Load kernel32 module */
1503 kernel32_module = GetModuleHandleA("kernel32.dll");
1504 assert( kernel32_module != NULL );
1505
1506 /* Get PE header info from module image */
1507 d_header = (PIMAGE_DOS_HEADER) kernel32_module;
1508 nt_headers = (PIMAGE_NT_HEADERS) (((char*) d_header) +
1509 d_header->e_lfanew);
1510
1511 /* Get size of import entry directory */
1512 import_dir_size = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
1513 if (!import_dir_size)
1514 {
1515 skip("Unable to continue testing due to missing import directory.\n");
1516 return;
1517 }
1518
1519 /* Get address of first import chunk */
1521 import_chunk = RVAToAddr(dir_offset, kernel32_module);
1522 ok(import_chunk != 0, "Invalid import_chunk: %p\n", import_chunk);
1523 if (!import_chunk) return;
1524
1525 /* Iterate through import descriptors and verify set name,
1526 * OriginalFirstThunk, and FirstThunk. Core Windows DLLs, such as
1527 * kernel32.dll, don't use Borland-style linking, where the table of
1528 * imported names is stored directly in FirstThunk and overwritten
1529 * by the relocation, instead of being stored in OriginalFirstThunk.
1530 * */
1531 for (; import_chunk->FirstThunk; import_chunk++)
1532 {
1533 LPCSTR module_name = RVAToAddr(import_chunk->Name, kernel32_module);
1534 PIMAGE_THUNK_DATA name_table = RVAToAddr(
1535 U(*import_chunk).OriginalFirstThunk, kernel32_module);
1537 import_chunk->FirstThunk, kernel32_module);
1538 ok(module_name != NULL, "Imported module name should not be NULL\n");
1539 ok(name_table != NULL,
1540 "Name table for imported module %s should not be NULL\n",
1541 module_name);
1542 ok(iat != NULL, "IAT for imported module %s should not be NULL\n",
1543 module_name);
1544 }
1545}
static LPCWSTR LPCWSTR module_name
Definition: db.cpp:170
PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS
Definition: ntddk_ex.h:187
struct _IMAGE_DOS_HEADER * PIMAGE_DOS_HEADER
const char * LPCSTR
Definition: xmlstorage.h:183

Referenced by START_TEST().

◆ test_InMemoryOrderModuleList()

static void test_InMemoryOrderModuleList ( void  )
static

Definition at line 3650 of file loader.c.

3651{
3652 PEB_LDR_DATA *ldr = NtCurrentTeb()->Peb->LdrData;
3653 LIST_ENTRY *entry1, *mark1 = &ldr->InLoadOrderModuleList;
3654 LIST_ENTRY *entry2, *mark2 = &ldr->InMemoryOrderModuleList;
3655 LDR_MODULE *module1, *module2;
3656
3657 ok(ldr->Initialized == TRUE, "expected TRUE, got %u\n", ldr->Initialized);
3658
3659 for (entry1 = mark1->Flink, entry2 = mark2->Flink;
3660 entry1 != mark1 && entry2 != mark2;
3661 entry1 = entry1->Flink, entry2 = entry2->Flink)
3662 {
3663 module1 = CONTAINING_RECORD(entry1, LDR_MODULE, InLoadOrderModuleList);
3664 module2 = CONTAINING_RECORD(entry2, LDR_MODULE, InMemoryOrderModuleList);
3665 ok(module1 == module2, "expected module1 == module2, got %p and %p\n", module1, module2);
3666 }
3667 ok(entry1 == mark1, "expected entry1 == mark1, got %p and %p\n", entry1, mark1);
3668 ok(entry2 == mark2, "expected entry2 == mark2, got %p and %p\n", entry2, mark2);
3669}
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
BOOLEAN Initialized
Definition: ntddk_ex.h:222

Referenced by START_TEST().

◆ test_Loader()

static void test_Loader ( void  )
static

Definition at line 563 of file loader.c.

564{
565 static const struct test_data
566 {
567 DWORD size_of_dos_header;
568 WORD number_of_sections, size_of_optional_header;
569 DWORD section_alignment, file_alignment;
570 DWORD size_of_image, size_of_headers;
571 DWORD errors[4]; /* 0 means LoadLibrary should succeed */
572 } td[] =
573 {
574 { sizeof(dos_header),
575 1, 0, 0, 0, 0, 0,
577 },
578 { sizeof(dos_header),
579 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000,
580 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0xe00,
581 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
582 { ERROR_BAD_EXE_FORMAT } /* XP doesn't like too small image size */
583 },
584 { sizeof(dos_header),
585 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000,
586 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
587 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
588 { ERROR_SUCCESS }
589 },
590 { sizeof(dos_header),
591 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x1000,
592 0x1f00,
593 0x1000,
594 { ERROR_SUCCESS }
595 },
596 { sizeof(dos_header),
597 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x200, 0x200,
598 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x200,
599 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
600 { ERROR_SUCCESS, ERROR_INVALID_ADDRESS } /* vista is more strict */
601 },
602 { sizeof(dos_header),
603 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x200, 0x1000,
604 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
605 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
606 { ERROR_BAD_EXE_FORMAT } /* XP doesn't like alignments */
607 },
608 { sizeof(dos_header),
609 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x200,
610 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
611 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER),
612 { ERROR_SUCCESS }
613 },
614 { sizeof(dos_header),
615 1, sizeof(IMAGE_OPTIONAL_HEADER), 0x1000, 0x200,
616 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
617 0x200,
618 { ERROR_SUCCESS }
619 },
620 /* Mandatory are all fields up to SizeOfHeaders, everything else
621 * is really optional (at least that's true for XP).
622 */
623#if 0 /* 32-bit Windows 8 crashes inside of LoadLibrary */
624 { sizeof(dos_header),
625 1, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
626 sizeof(dos_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum) + sizeof(IMAGE_SECTION_HEADER) + 0x10,
627 sizeof(dos_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum) + sizeof(IMAGE_SECTION_HEADER),
630 },
631#endif
632 { sizeof(dos_header),
633 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
634 0xd0, /* beyond of the end of file */
635 0xc0, /* beyond of the end of file */
636 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
637 },
638 { sizeof(dos_header),
639 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
640 0x1000,
641 0,
642 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
643 },
644 { sizeof(dos_header),
645 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
646 1,
647 0,
648 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
649 },
650#if 0 /* not power of 2 alignments need more test cases */
651 { sizeof(dos_header),
652 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x300, 0x300,
653 1,
654 0,
655 { ERROR_BAD_EXE_FORMAT } /* alignment is not power of 2 */
656 },
657#endif
658 { sizeof(dos_header),
659 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 4, 4,
660 1,
661 0,
662 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
663 },
664 { sizeof(dos_header),
665 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 1, 1,
666 1,
667 0,
668 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
669 },
670 { sizeof(dos_header),
671 0, FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, CheckSum), 0x200, 0x200,
672 0,
673 0,
674 { ERROR_BAD_EXE_FORMAT } /* image size == 0 -> failure */
675 },
676 /* the following data mimics the PE image which upack creates */
677 { 0x10,
678 1, 0x148, 0x1000, 0x200,
679 sizeof(dos_header) + sizeof(nt_header_template) + sizeof(IMAGE_SECTION_HEADER) + 0x1000,
680 0x200,
681 { ERROR_SUCCESS }
682 },
683 /* Minimal PE image that XP is able to load: 92 bytes */
684 { 0x04,
686 0x04 /* also serves as e_lfanew in the truncated MZ header */, 0x04,
687 1,
688 0,
689 { ERROR_SUCCESS, ERROR_BAD_EXE_FORMAT } /* vista is more strict */
690 },
691 /* Minimal PE image that Windows7 is able to load: 268 bytes */
692 { 0x04,
693 0, 0xf0, /* optional header size just forces 0xf0 bytes to be written,
694 0 or another number don't change the behaviour, what really
695 matters is file size regardless of values in the headers */
696 0x04 /* also serves as e_lfanew in the truncated MZ header */, 0x04,
697 0x40, /* minimal image size that Windows7 accepts */
698 0,
699 { ERROR_SUCCESS }
700 },
701 /* the following data mimics the PE image which 8k demos have */
702 { 0x04,
703 0, 0x08,
704 0x04 /* also serves as e_lfanew in the truncated MZ header */, 0x04,
705 0x200000,
706 0x40,
707 { ERROR_SUCCESS }
708 }
709 };
710 int i;
712 HANDLE h;
713 HMODULE hlib, hlib_as_data_file;
714 char dll_name[MAX_PATH];
715 SIZE_T size;
716 BOOL ret;
718 WORD alt_machine, orig_machine = nt_header_template.FileHeader.Machine;
720 IMAGE_COR20_HEADER cor_header;
721
722 /* prevent displaying of the "Unable to load this DLL" message box */
724
725 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
726 {
728 nt_header.FileHeader.NumberOfSections = td[i].number_of_sections;
729 nt_header.FileHeader.SizeOfOptionalHeader = td[i].size_of_optional_header;
730
731 nt_header.OptionalHeader.SectionAlignment = td[i].section_alignment;
732 nt_header.OptionalHeader.FileAlignment = td[i].file_alignment;