From 1c7afd87f680f7801aa33e6c71fba711bde50092 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Wed, 26 Mar 2003 01:25:19 +0000 Subject: [PATCH] - no longer using kernel32's APIs but ntdll's - BUILTIN32_dlopen now properly returns NTDLL style status codes --- if1632/builtin.c | 3 +- include/module.h | 3 +- relay32/builtin32.c | 71 ++++++++++++++++++++++----------------------- relay32/relay386.c | 6 ++-- relay32/snoop.c | 41 +++++++++++++++++--------- 5 files changed, 68 insertions(+), 56 deletions(-) diff --git a/if1632/builtin.c b/if1632/builtin.c index 57742fee4a8..cd50297d2a9 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -202,13 +202,12 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name ) if ((descr = find_dll_descr( dllname ))) return BUILTIN_DoLoadModule16( descr ); - if ((handle = BUILTIN32_dlopen( dllname ))) + if (BUILTIN32_dlopen( dllname, &handle ) == STATUS_SUCCESS) { if ((descr = find_dll_descr( dllname ))) return BUILTIN_DoLoadModule16( descr ); ERR( "loaded .so but dll %s still not found\n", dllname ); - BUILTIN32_dlclose( handle ); } return (HMODULE16)2; diff --git a/include/module.h b/include/module.h index 200104e3f1f..c248d375ab7 100644 --- a/include/module.h +++ b/include/module.h @@ -248,8 +248,7 @@ extern void MODULE_AddLoadOrderOption( const char *option ); /* relay32/builtin.c */ extern NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, WINE_MODREF**); extern HMODULE BUILTIN32_LoadExeModule( HMODULE main ); -extern void *BUILTIN32_dlopen( const char *name ); -extern int BUILTIN32_dlclose( void *handle ); +extern NTSTATUS BUILTIN32_dlopen( const char *name, void** handle ); /* if1632/builtin.c */ extern HMODULE16 BUILTIN_LoadModule( LPCSTR name ); diff --git a/relay32/builtin32.c b/relay32/builtin32.c index e7e494ec67e..0b93b619b4f 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -35,7 +35,7 @@ #include "wine/library.h" #include "module.h" #include "file.h" -#include "winerror.h" +#include "ntdll_misc.h" #include "wine/server.h" #include "wine/debug.h" @@ -45,37 +45,37 @@ WINE_DECLARE_DEBUG_CHANNEL(relay); extern void RELAY_SetupDLL( const char *module ); static HMODULE main_module; +static NTSTATUS last_status; /* use to gather all errors in callback */ /*********************************************************************** * BUILTIN32_dlopen + * + * The loader critical section must be locked while calling this function */ -void *BUILTIN32_dlopen( const char *name ) +NTSTATUS BUILTIN32_dlopen( const char *name, void** handle) { - void *handle; char error[256]; - if (!(handle = wine_dll_load( name, error, sizeof(error) ))) + last_status = STATUS_SUCCESS; + /* load_library will modify last_status. Note also that load_library can be + * called several times, if the .so file we're loading has dependencies. + * last_status will gather all the errors we may get while loading all these + * libraries + */ + if (!(*handle = wine_dll_load( name, error, sizeof(error) ))) { if (strstr(error, "cannot open") || strstr(error, "open failed") || (strstr(error, "Shared object") && strstr(error, "not found"))) { /* The file does not exist -> WARN() */ WARN("cannot open .so lib for builtin %s: %s\n", name, error); + last_status = STATUS_NO_SUCH_FILE; } else { /* ERR() for all other errors (missing functions, ...) */ ERR("failed to load .so lib for builtin %s: %s\n", name, error ); + last_status = STATUS_PROCEDURE_NOT_FOUND; } } - return handle; -} - -/*********************************************************************** - * BUILTIN32_dlclose - */ -int BUILTIN32_dlclose( void *handle ) -{ - /* FIXME: should unregister descriptors first */ - /* wine_dll_unload( handle ); */ - return 0; + return last_status; } @@ -86,7 +86,8 @@ int BUILTIN32_dlclose( void *handle ) */ static void load_library( void *base, const char *filename ) { - HMODULE module = (HMODULE)base; + UNICODE_STRING wstr; + HMODULE module = (HMODULE)base, ret; IMAGE_NT_HEADERS *nt; WINE_MODREF *wm; char *fullname; @@ -100,6 +101,7 @@ static void load_library( void *base, const char *filename ) if (!(nt = RtlImageNtHeader( module ))) { ERR( "bad module for %s\n", filename ? filename : "main exe" ); + last_status = STATUS_INVALID_IMAGE_FORMAT; return; } @@ -110,14 +112,17 @@ static void load_library( void *base, const char *filename ) return; /* don't create the modref here, will be done later on */ } - if (GetModuleHandleA( filename )) - MESSAGE( "Warning: loading builtin %s, but native version already present. Expect trouble.\n", filename ); + RtlCreateUnicodeStringFromAsciiz(&wstr, filename); + if (LdrGetDllHandle(0, 0, &wstr, &ret) == STATUS_SUCCESS) + MESSAGE( "Warning: loading builtin %s, but native version already present. " + "Expect trouble.\n", filename ); + RtlFreeUnicodeString( &wstr ); len = GetSystemDirectoryA( NULL, 0 ); - if (!(fullname = HeapAlloc( GetProcessHeap(), 0, len + strlen(filename) + 1 ))) + if (!(fullname = RtlAllocateHeap( ntdll_get_process_heap(), 0, len + strlen(filename) + 1 ))) { ERR( "can't load %s\n", filename ); - SetLastError( ERROR_OUTOFMEMORY ); + last_status = STATUS_NO_MEMORY; return; } GetSystemDirectoryA( fullname, len ); @@ -128,12 +133,12 @@ static void load_library( void *base, const char *filename ) if (!(wm = PE_CreateModule( module, fullname, 0, 0, TRUE ))) { ERR( "can't load %s\n", filename ); - HeapFree( GetProcessHeap(), 0, fullname ); - SetLastError( ERROR_OUTOFMEMORY ); + RtlFreeHeap( ntdll_get_process_heap(), 0, fullname ); + last_status = STATUS_NO_MEMORY; return; } TRACE( "loaded %s %p %p\n", fullname, wm, module ); - HeapFree( GetProcessHeap(), 0, fullname ); + RtlFreeHeap( ntdll_get_process_heap(), 0, fullname ); /* setup relay debugging entry points */ if (TRACE_ON(relay)) RELAY_SetupDLL( (void *)module ); @@ -151,6 +156,7 @@ NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm) char dllname[20], *p; LPCSTR name; void *handle; + NTSTATUS nts; /* Fix the name in case we have a full path and extension */ name = path; @@ -164,7 +170,8 @@ NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm) if (!p) strcat( dllname, ".dll" ); for (p = dllname; *p; p++) *p = FILE_tolower(*p); - if (!(handle = BUILTIN32_dlopen( dllname ))) return STATUS_NO_SUCH_FILE; + if ((nts = BUILTIN32_dlopen( dllname, &handle )) != STATUS_SUCCESS) + return nts; if (!((*pwm) = MODULE_FindModule( path ))) *pwm = MODULE_FindModule( dllname ); if (!*pwm) @@ -186,20 +193,12 @@ NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm) HMODULE BUILTIN32_LoadExeModule( HMODULE main ) { main_module = main; + last_status = STATUS_SUCCESS; wine_dll_set_callback( load_library ); if (!main_module) MESSAGE( "No built-in EXE module loaded! Did you create a .spec file?\n" ); + if (last_status != STATUS_SUCCESS) + MESSAGE( "Error while processing initial modules\n"); + return main_module; } - - -/*********************************************************************** - * BUILTIN32_RegisterDLL - * - * Register a built-in DLL descriptor. - */ -void BUILTIN32_RegisterDLL( const IMAGE_NT_HEADERS *header, const char *filename ) -{ - extern void __wine_dll_register( const IMAGE_NT_HEADERS *header, const char *filename ); - __wine_dll_register( header, filename ); -} diff --git a/relay32/relay386.c b/relay32/relay386.c index 263b3a1e464..35f1c2f2c85 100644 --- a/relay32/relay386.c +++ b/relay32/relay386.c @@ -25,12 +25,12 @@ #include #include -#include "windef.h" #include "winternl.h" #include "stackframe.h" #include "module.h" #include "wine/unicode.h" #include "wine/debug.h" +#include "ntdll_misc.h" WINE_DEFAULT_DEBUG_CHANNEL(relay); WINE_DECLARE_DEBUG_CHANNEL(snoop); @@ -57,11 +57,11 @@ static const char **build_list( const WCHAR *bufferW ) while ((p = strchr( p, ';' ))) { - count++; + count++; p++; } /* allocate count+1 pointers, plus the space for a copy of the string */ - if ((ret = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(char*) + strlen(buffer) + 1 ))) + if ((ret = RtlAllocateHeap( ntdll_get_process_heap(), 0, (count+1) * sizeof(char*) + strlen(buffer) + 1 ))) { char *str = (char *)(ret + count + 1); char *p = str; diff --git a/relay32/snoop.c b/relay32/snoop.c index 0cc471283d5..b09ce591aff 100644 --- a/relay32/snoop.c +++ b/relay32/snoop.c @@ -24,14 +24,12 @@ #include #include #include -#include "winbase.h" -#include "winnt.h" #include "winternl.h" #include "snoop.h" -#include "stackframe.h" #include "wine/debug.h" #include "wine/exception.h" #include "excpt.h" +#include "ntdll_misc.h" WINE_DEFAULT_DEBUG_CHANNEL(snoop); WINE_DECLARE_DEBUG_CHANNEL(seh); @@ -143,6 +141,8 @@ void SNOOP_RegisterDLL(HMODULE hmod,LPCSTR name,DWORD ordbase,DWORD nrofordinals) { SNOOP_DLL **dll = &(firstdll); char *s; + void *addr; + SIZE_T size; TRACE("hmod=%p, name=%s, ordbase=%ld, nrofordinals=%ld\n", hmod, name, ordbase, nrofordinals); @@ -152,25 +152,32 @@ SNOOP_RegisterDLL(HMODULE hmod,LPCSTR name,DWORD ordbase,DWORD nrofordinals) { if ((*dll)->hmod == hmod) { /* another dll, loaded at the same address */ - VirtualFree((*dll)->funs, (*dll)->nrofordinals*sizeof(SNOOP_FUN), MEM_RELEASE); + addr = (*dll)->funs; + size = (*dll)->nrofordinals * sizeof(SNOOP_FUN); + NtFreeVirtualMemory(GetCurrentProcess(), &addr, &size, MEM_RELEASE); break; } dll = &((*dll)->next); } - *dll = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *dll, sizeof(SNOOP_DLL)+strlen(name)); + *dll = RtlReAllocateHeap(ntdll_get_process_heap(), + HEAP_ZERO_MEMORY, *dll, + sizeof(SNOOP_DLL) + strlen(name)); (*dll)->hmod = hmod; (*dll)->ordbase = ordbase; (*dll)->nrofordinals = nrofordinals; strcpy( (*dll)->name, name ); if ((s=strrchr((*dll)->name,'.'))) *s='\0'; - (*dll)->funs = VirtualAlloc(NULL,nrofordinals*sizeof(SNOOP_FUN),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); - memset((*dll)->funs,0,nrofordinals*sizeof(SNOOP_FUN)); - if (!(*dll)->funs) { - HeapFree(GetProcessHeap(),0,*dll); + size = nrofordinals * sizeof(SNOOP_FUN); + NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size, + MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (!addr) { + RtlFreeHeap(ntdll_get_process_heap(),0,*dll); FIXME("out of memory\n"); return; } + (*dll)->funs = addr; + memset((*dll)->funs,0,size); } FARPROC @@ -201,7 +208,7 @@ SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) { fun = dll->funs+ordinal; if (!fun->name) { - fun->name = HeapAlloc(GetProcessHeap(),0,strlen(name)+1); + fun->name = RtlAllocateHeap(ntdll_get_process_heap(),0,strlen(name)+1); strcpy( fun->name, name ); fun->lcall = 0xe8; /* NOTE: origreturn struct member MUST come directly after snoopentry */ @@ -299,7 +306,14 @@ void WINAPI SNOOP_DoEntry( CONTEXT86 *context ) rets = &((*rets)->next); } if (!*rets) { - *rets = VirtualAlloc(NULL,4096,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); + SIZE_T size = 4096; + VOID* addr; + + NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + if (!addr) return; + *rets = addr; memset(*rets,0,4096); i = 0; /* entry 0 is free */ } @@ -328,7 +342,8 @@ void WINAPI SNOOP_DoEntry( CONTEXT86 *context ) DPRINTF(" ..."); } else if (fun->nrofargs<0) { DPRINTF(""); - ret->args = HeapAlloc(GetProcessHeap(),0,16*sizeof(DWORD)); + ret->args = RtlAllocateHeap(ntdll_get_process_heap(), + 0,16*sizeof(DWORD)); memcpy(ret->args,(LPBYTE)(context->Esp + 4),sizeof(DWORD)*16); } DPRINTF(") ret=%08lx\n",(DWORD)ret->origreturn); @@ -363,7 +378,7 @@ void WINAPI SNOOP_DoReturn( CONTEXT86 *context ) } DPRINTF(") retval = %08lx ret=%08lx\n", context->Eax,(DWORD)ret->origreturn ); - HeapFree(GetProcessHeap(),0,ret->args); + RtlFreeHeap(ntdll_get_process_heap(),0,ret->args); ret->args = NULL; } else DPRINTF("%04lx:RET %s.%ld: %s() retval = %08lx ret=%08lx\n",