- no longer using kernel32's APIs but ntdll's

- BUILTIN32_dlopen now properly returns NTDLL style status codes
This commit is contained in:
Eric Pouech 2003-03-26 01:25:19 +00:00 committed by Alexandre Julliard
parent 1d57f4b47d
commit 1c7afd87f6
5 changed files with 68 additions and 56 deletions

View File

@ -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;

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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);
@ -61,7 +61,7 @@ static const char **build_list( const WCHAR *bufferW )
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;

View File

@ -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 @@ 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("<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 @@ 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",