- no longer using kernel32's APIs but ntdll's
- BUILTIN32_dlopen now properly returns NTDLL style status codes
This commit is contained in:
parent
1d57f4b47d
commit
1c7afd87f6
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue