- BUILTIN32_dlopen and BUILTIN32_dlclose now properly return NTDLL style status codes
A+ -- Eric Pouech
diff -u -x '*~' -x '.#*' if163212/builtin.c if1632/builtin.c --- if163212/builtin.c 2003-03-21 21:59:24.000000000 +0100 +++ if1632/builtin.c 2003-03-21 21:56:04.000000000 +0100 @@ -202,7 +202,7 @@ 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 ); diff -u -x '*~' -x '.#*' include12/module.h include/module.h --- include12/module.h 2003-03-21 22:35:29.000000000 +0100 +++ include/module.h 2003-03-23 09:09:39.000000000 +0100 @@ -248,8 +248,8 @@ /* 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 ); +extern NTSTATUS BUILTIN32_dlclose( void *handle ); /* if1632/builtin.c */ extern HMODULE16 BUILTIN_LoadModule( LPCSTR name ); diff -u -x '*~' -x '.#*' relay3212/builtin32.c relay32/builtin32.c --- relay3212/builtin32.c 2003-03-21 19:20:44.000000000 +0100 +++ relay32/builtin32.c 2003-03-23 19:26:24.000000000 +0100 @@ -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,47 @@ 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; + return last_status; } /*********************************************************************** * BUILTIN32_dlclose */ -int BUILTIN32_dlclose( void *handle ) +NTSTATUS BUILTIN32_dlclose( void *handle ) { /* FIXME: should unregister descriptors first */ /* wine_dll_unload( handle ); */ - return 0; + return STATUS_SUCCESS; } @@ -86,7 +96,8 @@ */ 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 +111,7 @@ if (!(nt = RtlImageNtHeader( module ))) { ERR( "bad module for %s\n", filename ? filename : "main exe" ); + last_status = STATUS_INVALID_IMAGE_FORMAT; return; } @@ -110,14 +122,17 @@ 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 +143,12 @@ 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 +166,7 @@ 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 +180,8 @@ 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 +203,13 @@ 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 ); -} Common subdirectories: relay3212/CVS and relay32/CVS diff -u -x '*~' -x '.#*' relay3212/relay386.c relay32/relay386.c --- relay3212/relay386.c 2003-03-21 19:20:44.000000000 +0100 +++ relay32/relay386.c 2003-03-23 09:17:58.000000000 +0100 @@ -25,12 +25,12 @@ #include <string.h> #include <stdio.h> -#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 @@ 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 -u -x '*~' -x '.#*' relay3212/snoop.c relay32/snoop.c --- relay3212/snoop.c 2003-03-21 19:20:44.000000000 +0100 +++ relay32/snoop.c 2003-03-23 09:17:35.000000000 +0100 @@ -24,14 +24,12 @@ #include <assert.h> #include <stdio.h> #include <string.h> -#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 @@ 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 @@ 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 @@ 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 @@ 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 @@ DPRINTF(" ..."); } else if (fun->nrofargs<0) { DPRINTF("<unknown, check return>"); - 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 @@ } 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",