Converted most of the loader code to Unicode.
This commit is contained in:
parent
1bb7a9f736
commit
f80b869939
|
@ -34,6 +34,7 @@
|
|||
#include "selectors.h"
|
||||
#include "builtin16.h"
|
||||
#include "kernel_private.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -76,6 +77,15 @@ DWORD WINAPI CALL32_CBClientEx( FARPROC proc, LPWORD args, DWORD *esi, INT *nArg
|
|||
#endif
|
||||
|
||||
|
||||
/* compare an ASCII and a Unicode string without depending on the current codepage */
|
||||
inline static int strncmpiAW( const char *strA, const WCHAR *strW, int n )
|
||||
{
|
||||
int ret = 0;
|
||||
for ( ; n > 0; n--, strA++, strW++)
|
||||
if ((ret = toupperW((unsigned char)*strA) - toupperW(*strW)) || !*strA) break;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RELAY_ShowDebugmsgRelay
|
||||
*
|
||||
|
@ -84,12 +94,12 @@ DWORD WINAPI CALL32_CBClientEx( FARPROC proc, LPWORD args, DWORD *esi, INT *nArg
|
|||
*/
|
||||
static int RELAY_ShowDebugmsgRelay(const char *func)
|
||||
{
|
||||
/* from relay32/relay386.c */
|
||||
extern const char **debug_relay_excludelist,**debug_relay_includelist;
|
||||
/* from dlls/ntdll/relay.c (FIXME) */
|
||||
extern const WCHAR **debug_relay_excludelist,**debug_relay_includelist;
|
||||
|
||||
if(debug_relay_excludelist || debug_relay_includelist) {
|
||||
const char *term = strchr(func, ':');
|
||||
const char **listitem;
|
||||
const WCHAR **listitem;
|
||||
int len, len2, itemlen, show;
|
||||
|
||||
if(debug_relay_excludelist) {
|
||||
|
@ -105,14 +115,12 @@ static int RELAY_ShowDebugmsgRelay(const char *func)
|
|||
len2 = strchr(func, '.') - func;
|
||||
assert(len2 && len2 > 0 && len2 < 64);
|
||||
term += 2;
|
||||
for(; *listitem; listitem++) {
|
||||
itemlen = strlen(*listitem);
|
||||
if((itemlen == len && !strncasecmp(*listitem, func, len)) ||
|
||||
(itemlen == len2 && !strncasecmp(*listitem, func, len2)) ||
|
||||
!strcasecmp(*listitem, term)) {
|
||||
show = !show;
|
||||
break;
|
||||
}
|
||||
for(; *listitem; listitem++)
|
||||
{
|
||||
itemlen = strlenW(*listitem);
|
||||
if (itemlen == len && !strncmpiAW(func, *listitem, len)) return !show;
|
||||
if (itemlen == len2 && !strncmpiAW(func, *listitem, len2)) return !show;
|
||||
if (!strncmpiAW(term, *listitem, itemlen) && !term[itemlen]) return !show;
|
||||
}
|
||||
return show;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,6 @@ struct _wine_modref
|
|||
int nDeps;
|
||||
struct _wine_modref **deps;
|
||||
char *filename;
|
||||
char *modname;
|
||||
char data[1]; /* space for storing filename and modname */
|
||||
};
|
||||
|
||||
|
@ -93,8 +92,9 @@ static CRITICAL_SECTION loader_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
|||
static WINE_MODREF *cached_modref;
|
||||
static WINE_MODREF *current_modref;
|
||||
static NTSTATUS last_builtin_status; /* use to gather all errors in callback */
|
||||
static const WCHAR *current_load_path;
|
||||
|
||||
static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm );
|
||||
static NTSTATUS load_dll( LPCWSTR libname, DWORD flags, WINE_MODREF** pwm );
|
||||
static FARPROC find_named_export( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||
DWORD exp_size, const char *name, int hint );
|
||||
|
||||
|
@ -104,6 +104,18 @@ inline static void *get_rva( HMODULE module, DWORD va )
|
|||
return (void *)((char *)module + va);
|
||||
}
|
||||
|
||||
/* check whether the file name contains a path */
|
||||
inline static int contains_path( LPCWSTR name )
|
||||
{
|
||||
return ((*name && (name[1] == ':')) || strchrW(name, '/') || strchrW(name, '\\'));
|
||||
}
|
||||
|
||||
/* convert from straight ASCII to Unicode without depending on the current codepage */
|
||||
inline static void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
|
||||
{
|
||||
while (len--) *dst++ = (unsigned char)*src++;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* get_modref
|
||||
*
|
||||
|
@ -133,29 +145,29 @@ static WINE_MODREF *get_modref( HMODULE hmod )
|
|||
* find_module
|
||||
*
|
||||
* Find a (loaded) win32 module depending on path
|
||||
* LPCSTR path: [in] pathname of module/library to be found
|
||||
* path: [in] pathname of module/library to be found
|
||||
*
|
||||
* The loader_section must be locked while calling this function
|
||||
* RETURNS
|
||||
* the module handle if found
|
||||
* 0 if not
|
||||
*/
|
||||
static WINE_MODREF *find_module( LPCSTR path )
|
||||
static WINE_MODREF *find_module( LPCWSTR path )
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
WINE_MODREF *wm;
|
||||
PLIST_ENTRY mark, entry;
|
||||
PLDR_MODULE mod;
|
||||
char dllname[260], *p;
|
||||
WCHAR dllname[260], *p;
|
||||
|
||||
/* Append .DLL to name if no extension present */
|
||||
strcpy( dllname, path );
|
||||
if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
|
||||
strcat( dllname, ".DLL" );
|
||||
strcpyW( dllname, path );
|
||||
if (!(p = strrchrW( dllname, '.')) || strchrW( p, '/' ) || strchrW( p, '\\'))
|
||||
strcatW( dllname, dllW );
|
||||
|
||||
if ((wm = cached_modref) != NULL)
|
||||
{
|
||||
if ( !FILE_strcasecmp( dllname, wm->modname ) ) return wm;
|
||||
if ( !FILE_strcasecmp( dllname, wm->filename ) ) return wm;
|
||||
if ( !strcmpiW( dllname, wm->ldr.BaseDllName.Buffer ) ) return wm;
|
||||
if ( !strcmpiW( dllname, wm->ldr.FullDllName.Buffer ) ) return wm;
|
||||
}
|
||||
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||
|
@ -164,8 +176,8 @@ static WINE_MODREF *find_module( LPCSTR path )
|
|||
mod = CONTAINING_RECORD(entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
|
||||
|
||||
if ( !FILE_strcasecmp( dllname, wm->modname ) ) break;
|
||||
if ( !FILE_strcasecmp( dllname, wm->filename ) ) break;
|
||||
if ( !strcmpiW( dllname, wm->ldr.BaseDllName.Buffer ) ) break;
|
||||
if ( !strcmpiW( dllname, wm->ldr.FullDllName.Buffer ) ) break;
|
||||
}
|
||||
if (entry == mark) wm = NULL;
|
||||
|
||||
|
@ -185,19 +197,19 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward )
|
|||
IMAGE_EXPORT_DIRECTORY *exports;
|
||||
DWORD exp_size;
|
||||
WINE_MODREF *wm;
|
||||
char mod_name[256];
|
||||
WCHAR mod_name[256];
|
||||
char *end = strchr(forward, '.');
|
||||
FARPROC proc = NULL;
|
||||
|
||||
if (!end) return NULL;
|
||||
if (end - forward >= sizeof(mod_name)) return NULL;
|
||||
memcpy( mod_name, forward, end - forward );
|
||||
mod_name[end-forward] = 0;
|
||||
if (end - forward >= sizeof(mod_name)/sizeof(WCHAR)) return NULL;
|
||||
ascii_to_unicode( mod_name, forward, end - forward );
|
||||
mod_name[end - forward] = 0;
|
||||
|
||||
if (!(wm = find_module( mod_name )))
|
||||
{
|
||||
ERR("module not found for forward '%s' used by '%s'\n",
|
||||
forward, get_modref(module)->filename );
|
||||
ERR("module not found for forward '%s' used by %s\n",
|
||||
forward, debugstr_w(get_modref(module)->ldr.FullDllName.Buffer) );
|
||||
return NULL;
|
||||
}
|
||||
if ((exports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
||||
|
@ -206,9 +218,10 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward )
|
|||
|
||||
if (!proc)
|
||||
{
|
||||
ERR("function not found for forward '%s' used by '%s'."
|
||||
" If you are using builtin '%s', try using the native one instead.\n",
|
||||
forward, get_modref(module)->filename, get_modref(module)->modname );
|
||||
ERR("function not found for forward '%s' used by %s."
|
||||
" If you are using builtin %s, try using the native one instead.\n",
|
||||
forward, debugstr_w(get_modref(module)->ldr.FullDllName.Buffer),
|
||||
debugstr_w(get_modref(module)->ldr.BaseDllName.Buffer) );
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
@ -246,7 +259,8 @@ static FARPROC find_ordinal_export( HMODULE module, IMAGE_EXPORT_DIRECTORY *expo
|
|||
}
|
||||
if (TRACE_ON(relay) && current_modref)
|
||||
{
|
||||
proc = RELAY_GetProcAddress( module, exports, exp_size, proc, current_modref->modname );
|
||||
proc = RELAY_GetProcAddress( module, exports, exp_size, proc,
|
||||
current_modref->ldr.BaseDllName.Buffer );
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
@ -302,17 +316,32 @@ static WINE_MODREF *import_dll( HMODULE module, IMAGE_IMPORT_DESCRIPTOR *descr )
|
|||
IMAGE_EXPORT_DIRECTORY *exports;
|
||||
DWORD exp_size;
|
||||
IMAGE_THUNK_DATA *import_list, *thunk_list;
|
||||
WCHAR buffer[32];
|
||||
char *name = get_rva( module, descr->Name );
|
||||
DWORD len = strlen(name) + 1;
|
||||
|
||||
if (len * sizeof(WCHAR) <= sizeof(buffer))
|
||||
{
|
||||
ascii_to_unicode( buffer, name, len );
|
||||
status = load_dll( buffer, 0, &wmImp );
|
||||
}
|
||||
else /* need to allocate a larger buffer */
|
||||
{
|
||||
WCHAR *ptr = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
||||
if (!ptr) return NULL;
|
||||
ascii_to_unicode( ptr, name, len );
|
||||
status = load_dll( ptr, 0, &wmImp );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
|
||||
status = load_dll( name, 0, &wmImp );
|
||||
if (status)
|
||||
{
|
||||
if (status == STATUS_NO_SUCH_FILE)
|
||||
if (status == STATUS_DLL_NOT_FOUND)
|
||||
ERR("Module (file) %s (which is needed by %s) not found\n",
|
||||
name, current_modref->filename);
|
||||
name, debugstr_w(current_modref->ldr.FullDllName.Buffer));
|
||||
else
|
||||
ERR("Loading module (file) %s (which is needed by %s) failed (error %lx).\n",
|
||||
name, current_modref->filename, status);
|
||||
name, debugstr_w(current_modref->ldr.FullDllName.Buffer), status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -339,7 +368,7 @@ static WINE_MODREF *import_dll( HMODULE module, IMAGE_IMPORT_DESCRIPTOR *descr )
|
|||
if (!thunk_list->u1.Function)
|
||||
{
|
||||
ERR("No implementation for %s.%d imported from %s, setting to 0xdeadbeef\n",
|
||||
name, ordinal, current_modref->filename );
|
||||
name, ordinal, debugstr_w(current_modref->ldr.FullDllName.Buffer) );
|
||||
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +382,7 @@ static WINE_MODREF *import_dll( HMODULE module, IMAGE_IMPORT_DESCRIPTOR *descr )
|
|||
if (!thunk_list->u1.Function)
|
||||
{
|
||||
ERR("No implementation for %s.%s imported from %s, setting to 0xdeadbeef\n",
|
||||
name, pe_name->Name, current_modref->filename );
|
||||
name, pe_name->Name, debugstr_w(current_modref->ldr.FullDllName.Buffer) );
|
||||
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
|
||||
}
|
||||
}
|
||||
|
@ -412,77 +441,104 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm )
|
|||
|
||||
|
||||
/*************************************************************************
|
||||
* MODULE_AllocModRef
|
||||
* alloc_module
|
||||
*
|
||||
* Allocate a WINE_MODREF structure and add it to the process list
|
||||
* The loader_section must be locked while calling this function.
|
||||
*/
|
||||
WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
||||
static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
WCHAR *p;
|
||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
|
||||
PLIST_ENTRY entry, mark;
|
||||
BOOLEAN linked = FALSE;
|
||||
DWORD len = strlen( filename ) + 1;
|
||||
DWORD len;
|
||||
|
||||
if ((wm = RtlAllocateHeap( ntdll_get_process_heap(), HEAP_ZERO_MEMORY, sizeof(*wm) + len )))
|
||||
RtlUnicodeToMultiByteSize( &len, filename, (strlenW(filename) + 1) * sizeof(WCHAR) );
|
||||
if (!(wm = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*wm) + len )))
|
||||
return NULL;
|
||||
|
||||
wm->dlhandle = NULL;
|
||||
wm->nDeps = 0;
|
||||
wm->deps = NULL;
|
||||
wm->filename = (char *)(wm + 1);
|
||||
RtlUnicodeToMultiByteN( wm->filename, len, NULL,
|
||||
filename, (strlenW(filename) + 1) * sizeof(WCHAR) );
|
||||
|
||||
wm->ldr.BaseAddress = hModule;
|
||||
wm->ldr.EntryPoint = (nt->OptionalHeader.AddressOfEntryPoint) ?
|
||||
((char *)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
|
||||
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
|
||||
wm->ldr.Flags = 0;
|
||||
wm->ldr.LoadCount = 0;
|
||||
wm->ldr.TlsIndex = -1;
|
||||
wm->ldr.SectionHandle = NULL;
|
||||
wm->ldr.CheckSum = 0;
|
||||
wm->ldr.TimeDateStamp = 0;
|
||||
|
||||
RtlCreateUnicodeString( &wm->ldr.FullDllName, filename );
|
||||
if ((p = strrchrW( wm->ldr.FullDllName.Buffer, '\\' ))) p++;
|
||||
else p = wm->ldr.FullDllName.Buffer;
|
||||
RtlInitUnicodeString( &wm->ldr.BaseDllName, p );
|
||||
|
||||
/* this is a bit ugly, but we need to have app module first in LoadOrder
|
||||
* list, But in wine, ntdll is loaded first, so by inserting DLLs at the tail
|
||||
* and app module at the head we insure that order
|
||||
*/
|
||||
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
||||
{
|
||||
wm->filename = (char *)(wm + 1);
|
||||
memcpy( wm->filename, filename, len );
|
||||
if ((wm->modname = strrchr( wm->filename, '\\' ))) wm->modname++;
|
||||
else wm->modname = wm->filename;
|
||||
|
||||
wm->ldr.BaseAddress = hModule;
|
||||
wm->ldr.EntryPoint = (nt->OptionalHeader.AddressOfEntryPoint) ?
|
||||
((char *)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
|
||||
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
|
||||
RtlCreateUnicodeStringFromAsciiz( &wm->ldr.FullDllName, wm->filename);
|
||||
RtlCreateUnicodeStringFromAsciiz( &wm->ldr.BaseDllName, wm->modname);
|
||||
wm->ldr.Flags = 0;
|
||||
wm->ldr.LoadCount = 0;
|
||||
wm->ldr.TlsIndex = -1;
|
||||
wm->ldr.SectionHandle = NULL;
|
||||
wm->ldr.CheckSum = 0;
|
||||
wm->ldr.TimeDateStamp = 0;
|
||||
|
||||
/* this is a bit ugly, but we need to have app module first in LoadOrder
|
||||
* list, But in wine, ntdll is loaded first, so by inserting DLLs at the tail
|
||||
* and app module at the head we insure that order
|
||||
*/
|
||||
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
||||
/* is first loaded module a DLL or an exec ? */
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||
if (mark->Flink == mark ||
|
||||
(CONTAINING_RECORD(mark->Flink, LDR_MODULE, InLoadOrderModuleList)->Flags & LDR_IMAGE_IS_DLL))
|
||||
{
|
||||
/* is first loaded module a DLL or an exec ? */
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||
if (mark->Flink == mark ||
|
||||
(CONTAINING_RECORD(mark->Flink, LDR_MODULE, InLoadOrderModuleList)->Flags & LDR_IMAGE_IS_DLL))
|
||||
{
|
||||
InsertHeadList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
linked = TRUE;
|
||||
}
|
||||
}
|
||||
else wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
||||
|
||||
if (!linked)
|
||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
InsertHeadList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
|
||||
/* insert module in MemoryList, sorted in increasing base addresses */
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
||||
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||
{
|
||||
if (CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList)->BaseAddress > wm->ldr.BaseAddress)
|
||||
break;
|
||||
linked = TRUE;
|
||||
}
|
||||
entry->Blink->Flink = &wm->ldr.InMemoryOrderModuleList;
|
||||
wm->ldr.InMemoryOrderModuleList.Blink = entry->Blink;
|
||||
wm->ldr.InMemoryOrderModuleList.Flink = entry;
|
||||
entry->Blink = &wm->ldr.InMemoryOrderModuleList;
|
||||
|
||||
/* wait until init is called for inserting into this list */
|
||||
wm->ldr.InInitializationOrderModuleList.Flink = NULL;
|
||||
wm->ldr.InInitializationOrderModuleList.Blink = NULL;
|
||||
}
|
||||
else wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
||||
|
||||
if (!linked)
|
||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
|
||||
/* insert module in MemoryList, sorted in increasing base addresses */
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
||||
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||
{
|
||||
if (CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList)->BaseAddress > wm->ldr.BaseAddress)
|
||||
break;
|
||||
}
|
||||
entry->Blink->Flink = &wm->ldr.InMemoryOrderModuleList;
|
||||
wm->ldr.InMemoryOrderModuleList.Blink = entry->Blink;
|
||||
wm->ldr.InMemoryOrderModuleList.Flink = entry;
|
||||
entry->Blink = &wm->ldr.InMemoryOrderModuleList;
|
||||
|
||||
/* wait until init is called for inserting into this list */
|
||||
wm->ldr.InInitializationOrderModuleList.Flink = NULL;
|
||||
wm->ldr.InInitializationOrderModuleList.Blink = NULL;
|
||||
return wm;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* MODULE_AllocModRef
|
||||
*
|
||||
* Allocate a WINE_MODREF structure and add it to the process list
|
||||
* The loader_section must be locked while calling this function.
|
||||
*
|
||||
* FIXME: should be removed.
|
||||
*/
|
||||
WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
UNICODE_STRING strW;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz( &strW, filename );
|
||||
wm = alloc_module( hModule, strW.Buffer );
|
||||
RtlFreeUnicodeString( &strW );
|
||||
return wm;
|
||||
}
|
||||
|
||||
|
@ -607,7 +663,7 @@ static void call_tls_callbacks( HMODULE module, UINT reason )
|
|||
*/
|
||||
static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
|
||||
{
|
||||
char mod_name[32];
|
||||
WCHAR mod_name[32];
|
||||
BOOL retv = TRUE;
|
||||
DLLENTRYPROC entry = wm->ldr.EntryPoint;
|
||||
void *module = wm->ldr.BaseAddress;
|
||||
|
@ -620,13 +676,15 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
|
|||
|
||||
if (TRACE_ON(relay))
|
||||
{
|
||||
size_t len = max( strlen(wm->modname), sizeof(mod_name)-1 );
|
||||
memcpy( mod_name, wm->modname, len );
|
||||
mod_name[len] = 0;
|
||||
DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p (%s),reason=%s,res=%p)\n",
|
||||
GetCurrentThreadId(), entry, module, mod_name, reason_names[reason], lpReserved );
|
||||
size_t len = max( wm->ldr.BaseDllName.Length, sizeof(mod_name)-sizeof(WCHAR) );
|
||||
memcpy( mod_name, wm->ldr.BaseDllName.Buffer, len );
|
||||
mod_name[len / sizeof(WCHAR)] = 0;
|
||||
DPRINTF("%04lx:Call PE DLL (proc=%p,module=%p %s,reason=%s,res=%p)\n",
|
||||
GetCurrentThreadId(), entry, module, debugstr_w(mod_name),
|
||||
reason_names[reason], lpReserved );
|
||||
}
|
||||
else TRACE("(%p (%s),%s,%p) - CALL\n", module, wm->modname, reason_names[reason], lpReserved );
|
||||
else TRACE("(%p %s,%s,%p) - CALL\n", module, debugstr_w(wm->ldr.BaseDllName.Buffer),
|
||||
reason_names[reason], lpReserved );
|
||||
|
||||
retv = entry( module, reason, lpReserved );
|
||||
|
||||
|
@ -634,8 +692,9 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
|
|||
to the dll. We cannot assume that this module has not been
|
||||
deleted. */
|
||||
if (TRACE_ON(relay))
|
||||
DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p (%s),reason=%s,res=%p) retval=%x\n",
|
||||
GetCurrentThreadId(), entry, module, mod_name, reason_names[reason], lpReserved, retv );
|
||||
DPRINTF("%04lx:Ret PE DLL (proc=%p,module=%p %s,reason=%s,res=%p) retval=%x\n",
|
||||
GetCurrentThreadId(), entry, module, debugstr_w(mod_name),
|
||||
reason_names[reason], lpReserved, retv );
|
||||
else TRACE("(%p,%s,%p) - RETURN %d\n", module, reason_names[reason], lpReserved, retv );
|
||||
|
||||
return retv;
|
||||
|
@ -698,7 +757,7 @@ NTSTATUS MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
|
|||
|| ( wm->ldr.Flags & LDR_PROCESS_ATTACHED ) )
|
||||
goto done;
|
||||
|
||||
TRACE("(%s,%p) - START\n", wm->modname, lpReserved );
|
||||
TRACE("(%s,%p) - START\n", debugstr_w(wm->ldr.BaseDllName.Buffer), lpReserved );
|
||||
|
||||
/* Tag current MODREF to prevent recursive loop */
|
||||
wm->ldr.Flags |= LDR_LOAD_IN_PROGRESS;
|
||||
|
@ -728,7 +787,7 @@ NTSTATUS MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
|
|||
/* Remove recursion flag */
|
||||
wm->ldr.Flags &= ~LDR_LOAD_IN_PROGRESS;
|
||||
|
||||
TRACE("(%s,%p) - END\n", wm->modname, lpReserved );
|
||||
TRACE("(%s,%p) - END\n", debugstr_w(wm->ldr.BaseDllName.Buffer), lpReserved );
|
||||
|
||||
done:
|
||||
RtlLeaveCriticalSection( &loader_section );
|
||||
|
@ -899,7 +958,7 @@ NTSTATUS WINAPI LdrUnlockLoaderLock( ULONG flags, ULONG magic )
|
|||
/******************************************************************
|
||||
* LdrGetDllHandle (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI LdrGetDllHandle(ULONG x, ULONG y, PUNICODE_STRING name, HMODULE *base)
|
||||
NTSTATUS WINAPI LdrGetDllHandle(ULONG x, ULONG y, const UNICODE_STRING *name, HMODULE *base)
|
||||
{
|
||||
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
||||
WCHAR dllname[MAX_PATH+4], *p;
|
||||
|
@ -957,7 +1016,8 @@ done:
|
|||
/******************************************************************
|
||||
* LdrGetProcedureAddress (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, PANSI_STRING name, ULONG ord, PVOID *address)
|
||||
NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
|
||||
ULONG ord, PVOID *address)
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY *exports;
|
||||
DWORD exp_size;
|
||||
|
@ -996,7 +1056,7 @@ static void load_builtin_callback( void *module, const char *filename )
|
|||
{
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
WINE_MODREF *wm;
|
||||
char *fullname;
|
||||
WCHAR *fullname, *p;
|
||||
DWORD len;
|
||||
|
||||
if (!module)
|
||||
|
@ -1018,25 +1078,22 @@ static void load_builtin_callback( void *module, const char *filename )
|
|||
return; /* don't create the modref here, will be done later on */
|
||||
}
|
||||
|
||||
if (find_module( filename ))
|
||||
MESSAGE( "Warning: loading builtin %s, but native version already present. "
|
||||
"Expect trouble.\n", filename );
|
||||
|
||||
/* create the MODREF */
|
||||
|
||||
len = GetSystemDirectoryA( NULL, 0 );
|
||||
if (!(fullname = RtlAllocateHeap( ntdll_get_process_heap(), 0, len + strlen(filename) + 1 )))
|
||||
len = GetSystemDirectoryW( NULL, 0 );
|
||||
if (!(fullname = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
(len + strlen(filename) + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
ERR( "can't load %s\n", filename );
|
||||
last_builtin_status = STATUS_NO_MEMORY;
|
||||
return;
|
||||
}
|
||||
GetSystemDirectoryA( fullname, len );
|
||||
strcat( fullname, "\\" );
|
||||
strcat( fullname, filename );
|
||||
p = fullname + GetSystemDirectoryW( fullname, len );
|
||||
*p++ = '\\';
|
||||
ascii_to_unicode( p, filename, strlen(filename) + 1 );
|
||||
|
||||
wm = MODULE_AllocModRef( module, fullname );
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, fullname );
|
||||
wm = alloc_module( module, fullname );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, fullname );
|
||||
if (!wm)
|
||||
{
|
||||
ERR( "can't load %s\n", filename );
|
||||
|
@ -1085,27 +1142,26 @@ static void load_builtin_callback( void *module, const char *filename )
|
|||
* portion of the provided name and put the name in it.
|
||||
*
|
||||
*/
|
||||
static LPCSTR allocate_lib_dir(LPCSTR libname)
|
||||
static WCHAR *allocate_lib_dir(LPCWSTR libname)
|
||||
{
|
||||
LPCSTR p, pmax;
|
||||
LPSTR result;
|
||||
LPCWSTR p, pmax;
|
||||
LPWSTR result;
|
||||
int length;
|
||||
|
||||
pmax = libname;
|
||||
if ((p = strrchr( pmax, '\\' ))) pmax = p + 1;
|
||||
if ((p = strrchr( pmax, '/' ))) pmax = p + 1; /* Naughty. MSDN says don't */
|
||||
if ((p = strrchrW( pmax, '\\' ))) pmax = p + 1;
|
||||
if ((p = strrchrW( pmax, '/' ))) pmax = p + 1; /* Naughty. MSDN says don't */
|
||||
if (pmax == libname && pmax[0] && pmax[1] == ':') pmax += 2;
|
||||
|
||||
length = pmax - libname;
|
||||
|
||||
result = RtlAllocateHeap (ntdll_get_process_heap(), 0, length+1);
|
||||
result = RtlAllocateHeap (GetProcessHeap(), 0, (length+1) * sizeof(WCHAR) );
|
||||
|
||||
if (result)
|
||||
{
|
||||
strncpy (result, libname, length);
|
||||
memcpy( result, libname, length * sizeof(WCHAR) );
|
||||
result [length] = '\0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1113,7 +1169,7 @@ static LPCSTR allocate_lib_dir(LPCSTR libname)
|
|||
/******************************************************************************
|
||||
* load_native_dll (internal)
|
||||
*/
|
||||
static NTSTATUS load_native_dll( LPCSTR name, DWORD flags, WINE_MODREF** pwm )
|
||||
static NTSTATUS load_native_dll( LPCWSTR name, DWORD flags, WINE_MODREF** pwm )
|
||||
{
|
||||
void *module;
|
||||
HANDLE file, mapping;
|
||||
|
@ -1125,15 +1181,15 @@ static NTSTATUS load_native_dll( LPCSTR name, DWORD flags, WINE_MODREF** pwm )
|
|||
NTSTATUS status;
|
||||
UINT drive_type;
|
||||
|
||||
file = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
|
||||
file = CreateFileW( name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* keep it that way until we transform CreateFile into NtCreateFile */
|
||||
return (GetLastError() == ERROR_FILE_NOT_FOUND) ?
|
||||
STATUS_NO_SUCH_FILE : STATUS_INTERNAL_ERROR;
|
||||
STATUS_DLL_NOT_FOUND : STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
TRACE( "loading %s\n", debugstr_a(name) );
|
||||
TRACE( "loading %s\n", debugstr_w(name) );
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
|
@ -1155,7 +1211,7 @@ static NTSTATUS load_native_dll( LPCSTR name, DWORD flags, WINE_MODREF** pwm )
|
|||
|
||||
/* create the MODREF */
|
||||
|
||||
if (!(wm = MODULE_AllocModRef( module, name )))
|
||||
if (!(wm = alloc_module( module, name )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
|
@ -1186,7 +1242,7 @@ static NTSTATUS load_native_dll( LPCSTR name, DWORD flags, WINE_MODREF** pwm )
|
|||
/* send DLL load event */
|
||||
|
||||
nt = RtlImageNtHeader( module );
|
||||
drive_type = GetDriveTypeA( wm->filename );
|
||||
drive_type = GetDriveTypeW( wm->ldr.FullDllName.Buffer );
|
||||
|
||||
SERVER_START_REQ( load_dll )
|
||||
{
|
||||
|
@ -1213,28 +1269,89 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* get_builtin_path
|
||||
*
|
||||
* Get the path of a builtin module when the native file does not exist.
|
||||
*/
|
||||
static BOOL get_builtin_path( const WCHAR *libname, WCHAR *filename, UINT size )
|
||||
{
|
||||
WCHAR *p;
|
||||
BOOL ret = FALSE;
|
||||
UINT len = GetSystemDirectoryW( filename, size );
|
||||
|
||||
if (contains_path( libname ))
|
||||
{
|
||||
WCHAR *tmp;
|
||||
|
||||
/* if the library name contains a path and can not be found,
|
||||
* return an error.
|
||||
* exception: if the path is the system directory, proceed,
|
||||
* so that modules which are not PE modules can be loaded.
|
||||
* If the library name does not contain a path and can not
|
||||
* be found, assume the system directory is meant */
|
||||
|
||||
if (strlenW(libname) >= size) return FALSE; /* too long */
|
||||
if (strchrW( libname, '/' )) /* need to convert slashes */
|
||||
{
|
||||
if (!(tmp = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
(strlenW(libname)+1) * sizeof(WCHAR) ))) return FALSE;
|
||||
strcpyW( tmp, libname );
|
||||
for (p = tmp; *p; p++) if (*p == '/') *p = '\\';
|
||||
}
|
||||
else tmp = (WCHAR *)libname;
|
||||
|
||||
if (!strncmpiW( filename, tmp, len ) && tmp[len] == '\\')
|
||||
{
|
||||
strcpyW( filename, tmp );
|
||||
ret = TRUE;
|
||||
}
|
||||
if (tmp != libname) RtlFreeHeap( GetProcessHeap(), 0, tmp );
|
||||
if (!ret) return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlenW(libname) >= size - len - 1) return FALSE;
|
||||
filename[len] = '\\';
|
||||
strcpyW( filename+len+1, libname );
|
||||
}
|
||||
|
||||
/* if the filename doesn't have an extension, append ".dll" */
|
||||
if (!(p = strrchrW( filename, '.')) || strchrW( p, '/' ) || strchrW( p, '\\'))
|
||||
{
|
||||
if (strlenW(filename) + 3 >= size) return FALSE;
|
||||
strcatW( filename, dllW );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* load_builtin_dll
|
||||
*/
|
||||
static NTSTATUS load_builtin_dll( LPCSTR path, DWORD flags, WINE_MODREF** pwm )
|
||||
static NTSTATUS load_builtin_dll( LPCWSTR path, DWORD flags, WINE_MODREF** pwm )
|
||||
{
|
||||
char error[256], dllname[MAX_PATH], *p;
|
||||
char error[256], dllname[MAX_PATH];
|
||||
int file_exists;
|
||||
LPCSTR name;
|
||||
const WCHAR *name, *p;
|
||||
DWORD len, i;
|
||||
void *handle;
|
||||
WINE_MODREF *wm;
|
||||
|
||||
/* Fix the name in case we have a full path and extension */
|
||||
name = path;
|
||||
if ((p = strrchr( name, '\\' ))) name = p + 1;
|
||||
if ((p = strrchr( name, '/' ))) name = p + 1;
|
||||
if ((p = strrchrW( name, '\\' ))) name = p + 1;
|
||||
if ((p = strrchrW( name, '/' ))) name = p + 1;
|
||||
|
||||
if (strlen(name) >= sizeof(dllname)-4) return STATUS_NO_SUCH_FILE;
|
||||
|
||||
strcpy( dllname, name );
|
||||
p = strrchr( dllname, '.' );
|
||||
if (!p) strcat( dllname, ".dll" );
|
||||
for (p = dllname; *p; p++) *p = FILE_tolower(*p);
|
||||
/* we don't want to depend on the current codepage here */
|
||||
len = strlenW( name ) + 1;
|
||||
if (len >= sizeof(dllname)) return STATUS_NAME_TOO_LONG;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (name[i] > 127) return STATUS_DLL_NOT_FOUND;
|
||||
dllname[i] = (char)name[i];
|
||||
if (dllname[i] >= 'A' && dllname[i] <= 'Z') dllname[i] += 'a' - 'A';
|
||||
}
|
||||
|
||||
last_builtin_status = STATUS_SUCCESS;
|
||||
/* load_library will modify last_builtin_status. Note also that load_library can be
|
||||
|
@ -1247,19 +1364,20 @@ static NTSTATUS load_builtin_dll( LPCSTR path, DWORD flags, WINE_MODREF** pwm )
|
|||
if (!file_exists)
|
||||
{
|
||||
/* The file does not exist -> WARN() */
|
||||
WARN("cannot open .so lib for builtin %s: %s\n", name, error);
|
||||
return STATUS_NO_SUCH_FILE;
|
||||
WARN("cannot open .so lib for builtin %s: %s\n", debugstr_w(name), error);
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
/* ERR() for all other errors (missing functions, ...) */
|
||||
ERR("failed to load .so lib for builtin %s: %s\n", name, error );
|
||||
ERR("failed to load .so lib for builtin %s: %s\n", debugstr_w(name), error );
|
||||
return STATUS_PROCEDURE_NOT_FOUND;
|
||||
}
|
||||
if (last_builtin_status != STATUS_SUCCESS) return last_builtin_status;
|
||||
|
||||
if (!(wm = find_module( path ))) wm = find_module( dllname );
|
||||
if (!(wm = find_module( path ))) wm = find_module( name );
|
||||
if (!wm)
|
||||
{
|
||||
ERR( "loaded .so but dll %s still not found - 16-bit dll or version conflict.\n", dllname );
|
||||
ERR( "loaded .so but dll %s still not found - 16-bit dll or version conflict.\n",
|
||||
debugstr_w(name) );
|
||||
/* wine_dll_unload( handle );*/
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
|
@ -1284,29 +1402,27 @@ static NTSTATUS load_builtin_dll( LPCSTR path, DWORD flags, WINE_MODREF** pwm )
|
|||
* information from BUILTIN32_dlopen through dlopen and the builtin's
|
||||
* init function into load_library).
|
||||
* allocated_libdir is TRUE in the stack frame that allocated libdir
|
||||
*
|
||||
* The loader_section must be locked while calling this function.
|
||||
*/
|
||||
static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
||||
static NTSTATUS load_dll( LPCWSTR libname, DWORD flags, WINE_MODREF** pwm )
|
||||
{
|
||||
int i;
|
||||
enum loadorder_type loadorder[LOADORDER_NTYPES];
|
||||
LPSTR filename;
|
||||
WCHAR *filename;
|
||||
const char *filetype = "";
|
||||
DWORD found;
|
||||
WINE_MODREF *main_exe;
|
||||
BOOL allocated_libdir = FALSE;
|
||||
static LPCSTR libdir = NULL; /* See above */
|
||||
NTSTATUS nts = STATUS_NO_SUCH_FILE;
|
||||
static WCHAR *libdir = NULL; /* See above */
|
||||
NTSTATUS nts = STATUS_DLL_NOT_FOUND;
|
||||
|
||||
*pwm = NULL;
|
||||
if ( !libname ) return STATUS_DLL_NOT_FOUND; /* FIXME ? */
|
||||
|
||||
filename = RtlAllocateHeap ( ntdll_get_process_heap(), 0, MAX_PATH + 1 );
|
||||
filename = RtlAllocateHeap ( GetProcessHeap(), 0, (MAX_PATH + 1) * sizeof(WCHAR) );
|
||||
if ( !filename ) return STATUS_NO_MEMORY;
|
||||
*filename = 0; /* Just in case we don't set it before goto error */
|
||||
|
||||
RtlEnterCriticalSection( &loader_section );
|
||||
|
||||
if ((flags & LOAD_WITH_ALTERED_SEARCH_PATH) && FILE_contains_path(libname))
|
||||
if ((flags & LOAD_WITH_ALTERED_SEARCH_PATH) && contains_path(libname))
|
||||
{
|
||||
if (!(libdir = allocate_lib_dir(libname)))
|
||||
{
|
||||
|
@ -1317,14 +1433,14 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
}
|
||||
|
||||
if (!libdir || allocated_libdir)
|
||||
found = SearchPathA(NULL, libname, ".dll", MAX_PATH, filename, NULL);
|
||||
found = SearchPathW(NULL, libname, dllW, MAX_PATH, filename, NULL);
|
||||
else
|
||||
found = DIR_SearchAlternatePath(libdir, libname, ".dll", MAX_PATH, filename, NULL);
|
||||
found = DIR_SearchAlternatePath(libdir, libname, dllW, MAX_PATH, filename);
|
||||
|
||||
/* build the modules filename */
|
||||
if (!found)
|
||||
{
|
||||
if (!MODULE_GetBuiltinPath( libname, ".dll", filename, MAX_PATH ))
|
||||
if (!get_builtin_path( libname, filename, MAX_PATH ))
|
||||
{
|
||||
nts = STATUS_INTERNAL_ERROR;
|
||||
goto error;
|
||||
|
@ -1332,9 +1448,9 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
}
|
||||
|
||||
/* Check for already loaded module */
|
||||
if (!(*pwm = find_module(filename)) && !FILE_contains_path(libname))
|
||||
if (!(*pwm = find_module(filename)) && !contains_path(libname))
|
||||
{
|
||||
LPSTR fn = RtlAllocateHeap ( ntdll_get_process_heap(), 0, MAX_PATH + 1 );
|
||||
LPWSTR fn = RtlAllocateHeap ( GetProcessHeap(), 0, (MAX_PATH + 1) * sizeof(WCHAR) );
|
||||
if (fn)
|
||||
{
|
||||
/* since the default loading mechanism uses a more detailed algorithm
|
||||
|
@ -1344,14 +1460,15 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
* has already been loaded but with a different path. So do a specific
|
||||
* look-up with filename (without any path)
|
||||
*/
|
||||
strcpy ( fn, libname );
|
||||
strcpyW ( fn, libname );
|
||||
/* if the filename doesn't have an extension append .DLL */
|
||||
if (!strrchr( fn, '.')) strcat( fn, ".dll" );
|
||||
if (!strrchrW( fn, '.')) strcatW( fn, dllW );
|
||||
if ((*pwm = find_module( fn )) != NULL)
|
||||
strcpy( filename, fn );
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, fn );
|
||||
strcpyW( filename, fn );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, fn );
|
||||
}
|
||||
}
|
||||
|
||||
if (*pwm)
|
||||
{
|
||||
if ((*pwm)->ldr.LoadCount != -1) (*pwm)->ldr.LoadCount++;
|
||||
|
@ -1362,19 +1479,19 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
(*pwm)->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
|
||||
fixup_imports( *pwm );
|
||||
}
|
||||
TRACE("Already loaded module '%s' at %p, count=%d\n", filename, (*pwm)->ldr.BaseAddress, (*pwm)->ldr.LoadCount);
|
||||
if (allocated_libdir)
|
||||
{
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, (LPSTR)libdir );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, libdir );
|
||||
libdir = NULL;
|
||||
}
|
||||
RtlLeaveCriticalSection( &loader_section );
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, filename );
|
||||
TRACE("Already loaded module %s at %p, count=%d\n",
|
||||
debugstr_w(filename), (*pwm)->ldr.BaseAddress, (*pwm)->ldr.LoadCount);
|
||||
RtlFreeHeap( GetProcessHeap(), 0, filename );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
|
||||
MODULE_GetLoadOrderA( loadorder, main_exe->ldr.BaseDllName.Buffer, filename, TRUE);
|
||||
MODULE_GetLoadOrderW( loadorder, main_exe->ldr.BaseDllName.Buffer, filename, TRUE);
|
||||
|
||||
for (i = 0; i < LOADORDER_NTYPES; i++)
|
||||
{
|
||||
|
@ -1383,12 +1500,12 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
switch (loadorder[i])
|
||||
{
|
||||
case LOADORDER_DLL:
|
||||
TRACE("Trying native dll '%s'\n", filename);
|
||||
TRACE("Trying native dll %s\n", debugstr_w(filename));
|
||||
nts = load_native_dll(filename, flags, pwm);
|
||||
filetype = "native";
|
||||
break;
|
||||
case LOADORDER_BI:
|
||||
TRACE("Trying built-in '%s'\n", filename);
|
||||
TRACE("Trying built-in %s\n", debugstr_w(filename));
|
||||
nts = load_builtin_dll(filename, flags, pwm);
|
||||
filetype = "builtin";
|
||||
break;
|
||||
|
@ -1400,27 +1517,27 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
if (nts == STATUS_SUCCESS)
|
||||
{
|
||||
/* Initialize DLL just loaded */
|
||||
TRACE("Loaded module '%s' (%s) at %p\n", filename, filetype, (*pwm)->ldr.BaseAddress);
|
||||
TRACE("Loaded module %s (%s) at %p\n",
|
||||
debugstr_w(filename), filetype, (*pwm)->ldr.BaseAddress);
|
||||
if (!TRACE_ON(module))
|
||||
TRACE_(loaddll)("Loaded module '%s' : %s\n", filename, filetype);
|
||||
TRACE_(loaddll)("Loaded module %s : %s\n", debugstr_w(filename), filetype);
|
||||
/* Set the ldr.LoadCount here so that an attach failure will */
|
||||
/* decrement the dependencies through the MODULE_FreeLibrary call. */
|
||||
(*pwm)->ldr.LoadCount = 1;
|
||||
|
||||
if (allocated_libdir)
|
||||
{
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, (LPSTR)libdir );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, libdir );
|
||||
libdir = NULL;
|
||||
}
|
||||
RtlLeaveCriticalSection( &loader_section );
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, filename );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, filename );
|
||||
return nts;
|
||||
}
|
||||
|
||||
if (nts != STATUS_NO_SUCH_FILE)
|
||||
if (nts != STATUS_DLL_NOT_FOUND)
|
||||
{
|
||||
WARN("Loading of %s DLL %s failed (status %lx).\n",
|
||||
filetype, filename, nts);
|
||||
filetype, debugstr_w(filename), nts);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1428,52 +1545,44 @@ static NTSTATUS load_dll( LPCSTR libname, DWORD flags, WINE_MODREF** pwm )
|
|||
error:
|
||||
if (allocated_libdir)
|
||||
{
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, (LPSTR)libdir );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, libdir );
|
||||
libdir = NULL;
|
||||
}
|
||||
RtlLeaveCriticalSection( &loader_section );
|
||||
WARN("Failed to load module '%s'; status=%lx\n", filename, nts);
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, filename );
|
||||
WARN("Failed to load module %s; status=%lx\n", debugstr_w(filename), nts);
|
||||
RtlFreeHeap( GetProcessHeap(), 0, filename );
|
||||
return nts;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* LdrLoadDll (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_name, DWORD flags, PUNICODE_STRING libname, HMODULE* hModule)
|
||||
NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_name, DWORD flags,
|
||||
const UNICODE_STRING *libname, HMODULE* hModule)
|
||||
{
|
||||
WINE_MODREF *wm;
|
||||
NTSTATUS nts = STATUS_SUCCESS;
|
||||
STRING str;
|
||||
|
||||
RtlUnicodeStringToAnsiString(&str, libname, TRUE);
|
||||
NTSTATUS nts;
|
||||
const WCHAR *prev_load_path;
|
||||
|
||||
RtlEnterCriticalSection( &loader_section );
|
||||
|
||||
switch (nts = load_dll( str.Buffer, flags, &wm ))
|
||||
prev_load_path = current_load_path;
|
||||
current_load_path = path_name;
|
||||
nts = load_dll( libname->Buffer, flags, &wm );
|
||||
current_load_path = prev_load_path;
|
||||
|
||||
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
|
||||
{
|
||||
case STATUS_SUCCESS:
|
||||
nts = MODULE_DllProcessAttach( wm, NULL );
|
||||
if (nts != STATUS_SUCCESS)
|
||||
{
|
||||
WARN("Attach failed for module '%s'.\n", str.Buffer);
|
||||
WARN("Attach failed for module %s\n", debugstr_w(libname->Buffer));
|
||||
LdrUnloadDll(wm->ldr.BaseAddress);
|
||||
wm = NULL;
|
||||
}
|
||||
break;
|
||||
case STATUS_NO_SUCH_FILE:
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
break;
|
||||
default: /* keep error code as it is (memory...) */
|
||||
break;
|
||||
}
|
||||
|
||||
*hModule = (wm) ? wm->ldr.BaseAddress : NULL;
|
||||
|
||||
|
||||
RtlLeaveCriticalSection( &loader_section );
|
||||
|
||||
RtlFreeAnsiString(&str);
|
||||
|
||||
return nts;
|
||||
}
|
||||
|
||||
|
@ -1595,27 +1704,29 @@ static void MODULE_FlushModrefs(void)
|
|||
wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
|
||||
|
||||
prev = entry->Blink;
|
||||
if (wm->ldr.LoadCount) continue;
|
||||
if (mod->LoadCount) continue;
|
||||
|
||||
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
||||
RemoveEntryList(&wm->ldr.InMemoryOrderModuleList);
|
||||
RemoveEntryList(&wm->ldr.InInitializationOrderModuleList);
|
||||
RemoveEntryList(&mod->InLoadOrderModuleList);
|
||||
RemoveEntryList(&mod->InMemoryOrderModuleList);
|
||||
RemoveEntryList(&mod->InInitializationOrderModuleList);
|
||||
|
||||
TRACE(" unloading %s\n", wm->filename);
|
||||
TRACE(" unloading %s\n", debugstr_w(mod->FullDllName.Buffer));
|
||||
if (!TRACE_ON(module))
|
||||
TRACE_(loaddll)("Unloaded module '%s' : %s\n", wm->filename,
|
||||
TRACE_(loaddll)("Unloaded module %s : %s\n",
|
||||
debugstr_w(mod->FullDllName.Buffer),
|
||||
wm->dlhandle ? "builtin" : "native" );
|
||||
|
||||
SERVER_START_REQ( unload_dll )
|
||||
{
|
||||
req->base = wm->ldr.BaseAddress;
|
||||
req->base = mod->BaseAddress;
|
||||
wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (wm->dlhandle) wine_dll_unload( wm->dlhandle );
|
||||
else NtUnmapViewOfSection( GetCurrentProcess(), wm->ldr.BaseAddress );
|
||||
else NtUnmapViewOfSection( GetCurrentProcess(), mod->BaseAddress );
|
||||
if (cached_modref == wm) cached_modref = NULL;
|
||||
RtlFreeUnicodeString( &mod->FullDllName );
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, wm->deps );
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, wm );
|
||||
}
|
||||
|
@ -1637,7 +1748,7 @@ static void MODULE_DecRefCount( WINE_MODREF *wm )
|
|||
return;
|
||||
|
||||
--wm->ldr.LoadCount;
|
||||
TRACE("(%s) ldr.LoadCount: %d\n", wm->modname, wm->ldr.LoadCount );
|
||||
TRACE("(%s) ldr.LoadCount: %d\n", debugstr_w(wm->ldr.BaseDllName.Buffer), wm->ldr.LoadCount );
|
||||
|
||||
if ( wm->ldr.LoadCount == 0 )
|
||||
{
|
||||
|
@ -1674,7 +1785,7 @@ NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
|
|||
free_lib_count++;
|
||||
if ((wm = get_modref( hModule )) != NULL)
|
||||
{
|
||||
TRACE("(%s) - START\n", wm->modname);
|
||||
TRACE("(%s) - START\n", debugstr_w(wm->ldr.BaseDllName.Buffer));
|
||||
|
||||
/* Recursively decrement reference counts */
|
||||
MODULE_DecRefCount( wm );
|
||||
|
|
|
@ -41,7 +41,7 @@ extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handl
|
|||
|
||||
/* module handling */
|
||||
extern FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||
DWORD exp_size, FARPROC proc, const char *user );
|
||||
DWORD exp_size, FARPROC proc, const WCHAR *user );
|
||||
extern FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
|
||||
FARPROC origfun, DWORD ordinal );
|
||||
extern void RELAY_SetupDLL( HMODULE hmod );
|
||||
|
|
|
@ -41,46 +41,59 @@ WINE_DEFAULT_DEBUG_CHANNEL(relay);
|
|||
WINE_DECLARE_DEBUG_CHANNEL(snoop);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(seh);
|
||||
|
||||
const char **debug_relay_excludelist = NULL;
|
||||
const char **debug_relay_includelist = NULL;
|
||||
const char **debug_snoop_excludelist = NULL;
|
||||
const char **debug_snoop_includelist = NULL;
|
||||
const WCHAR **debug_relay_excludelist = NULL;
|
||||
const WCHAR **debug_relay_includelist = NULL;
|
||||
const WCHAR **debug_snoop_excludelist = NULL;
|
||||
const WCHAR **debug_snoop_includelist = NULL;
|
||||
|
||||
static const char **debug_from_relay_excludelist;
|
||||
static const char **debug_from_relay_includelist;
|
||||
static const WCHAR **debug_from_relay_excludelist;
|
||||
static const WCHAR **debug_from_relay_includelist;
|
||||
|
||||
/* compare an ASCII and a Unicode string without depending on the current codepage */
|
||||
inline static int strcmpAW( const char *strA, const WCHAR *strW )
|
||||
{
|
||||
while (*strA && ((unsigned char)*strA == *strW)) { strA++; strW++; }
|
||||
return (unsigned char)*strA - *strW;
|
||||
}
|
||||
|
||||
/* compare an ASCII and a Unicode string without depending on the current codepage */
|
||||
inline static int strncmpiAW( const char *strA, const WCHAR *strW, int n )
|
||||
{
|
||||
int ret = 0;
|
||||
for ( ; n > 0; n--, strA++, strW++)
|
||||
if ((ret = toupperW((unsigned char)*strA) - toupperW(*strW)) || !*strA) break;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* build_list
|
||||
*
|
||||
* Build a function list from a ';'-separated string.
|
||||
*/
|
||||
static const char **build_list( const WCHAR *bufferW )
|
||||
static const WCHAR **build_list( const WCHAR *buffer )
|
||||
{
|
||||
int count = 1;
|
||||
char buffer[1024];
|
||||
const char *p = buffer;
|
||||
const char **ret;
|
||||
const WCHAR *p = buffer;
|
||||
const WCHAR **ret;
|
||||
|
||||
RtlUnicodeToMultiByteN( buffer, sizeof(buffer), NULL,
|
||||
bufferW, (strlenW(bufferW)+1) * sizeof(WCHAR) );
|
||||
|
||||
while ((p = strchr( p, ';' )))
|
||||
while ((p = strchrW( p, ';' )))
|
||||
{
|
||||
count++;
|
||||
count++;
|
||||
p++;
|
||||
}
|
||||
/* allocate count+1 pointers, plus the space for a copy of the string */
|
||||
if ((ret = RtlAllocateHeap( ntdll_get_process_heap(), 0, (count+1) * sizeof(char*) + strlen(buffer) + 1 )))
|
||||
if ((ret = RtlAllocateHeap( GetProcessHeap(), 0,
|
||||
(count+1) * sizeof(WCHAR*) + (strlenW(buffer)+1) * sizeof(WCHAR) )))
|
||||
{
|
||||
char *str = (char *)(ret + count + 1);
|
||||
char *p = str;
|
||||
WCHAR *str = (WCHAR *)(ret + count + 1);
|
||||
WCHAR *p = str;
|
||||
|
||||
strcpy( str, buffer );
|
||||
strcpyW( str, buffer );
|
||||
count = 0;
|
||||
for (;;)
|
||||
{
|
||||
ret[count++] = p;
|
||||
if (!(p = strchr( p, ';' ))) break;
|
||||
if (!(p = strchrW( p, ';' ))) break;
|
||||
*p++ = 0;
|
||||
}
|
||||
ret[count++] = NULL;
|
||||
|
@ -253,7 +266,7 @@ static WINE_EXCEPTION_FILTER(page_fault)
|
|||
*/
|
||||
static BOOL check_relay_include( const char *module, const char *func )
|
||||
{
|
||||
const char **listitem;
|
||||
const WCHAR **listitem;
|
||||
BOOL show;
|
||||
|
||||
if (!debug_relay_excludelist && !debug_relay_includelist) return TRUE;
|
||||
|
@ -269,16 +282,17 @@ static BOOL check_relay_include( const char *module, const char *func )
|
|||
}
|
||||
for(; *listitem; listitem++)
|
||||
{
|
||||
char *p = strrchr( *listitem, '.' );
|
||||
WCHAR *p = strrchrW( *listitem, '.' );
|
||||
if (p && p > *listitem) /* check module and function */
|
||||
{
|
||||
int len = p - *listitem;
|
||||
if (strncasecmp( *listitem, module, len-1 ) || module[len]) continue;
|
||||
if (!strcmp( p + 1, func ) || !strcmp( p + 1, "*" )) return !show;
|
||||
if (strncmpiAW( module, *listitem, len-1 ) || module[len]) continue;
|
||||
if (p[1] == '*' && !p[2]) return !show;
|
||||
if (!strcmpAW( func, p + 1 )) return !show;
|
||||
}
|
||||
else /* function only */
|
||||
{
|
||||
if (!strcmp( *listitem, func )) return !show;
|
||||
if (!strcmpAW( func, *listitem )) return !show;
|
||||
}
|
||||
}
|
||||
return show;
|
||||
|
@ -290,9 +304,10 @@ static BOOL check_relay_include( const char *module, const char *func )
|
|||
*
|
||||
* Check if calls from a given module must be included in the relay output.
|
||||
*/
|
||||
static BOOL check_relay_from_module( const char *module )
|
||||
static BOOL check_relay_from_module( const WCHAR *module )
|
||||
{
|
||||
const char **listitem;
|
||||
static const WCHAR dllW[] = {'.','d','l','l',0 };
|
||||
const WCHAR **listitem;
|
||||
BOOL show;
|
||||
|
||||
if (!debug_from_relay_excludelist && !debug_from_relay_includelist) return TRUE;
|
||||
|
@ -310,9 +325,9 @@ static BOOL check_relay_from_module( const char *module )
|
|||
{
|
||||
int len;
|
||||
|
||||
if (!strcasecmp( *listitem, module )) return !show;
|
||||
len = strlen( *listitem );
|
||||
if (!strncasecmp( *listitem, module, len ) && !strcasecmp( module + len, ".dll" ))
|
||||
if (!strcmpiW( *listitem, module )) return !show;
|
||||
len = strlenW( *listitem );
|
||||
if (!strncmpiW( *listitem, module, len ) && !strcmpiW( module + len, dllW ))
|
||||
return !show;
|
||||
}
|
||||
return show;
|
||||
|
@ -676,7 +691,7 @@ static BOOL is_register_entry_point( const BYTE *addr )
|
|||
* Return the proc address to use for a given function.
|
||||
*/
|
||||
FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||
DWORD exp_size, FARPROC proc, const char *user )
|
||||
DWORD exp_size, FARPROC proc, const WCHAR *user )
|
||||
{
|
||||
DEBUG_ENTRY_POINT *debug = (DEBUG_ENTRY_POINT *)proc;
|
||||
DEBUG_ENTRY_POINT *list = (DEBUG_ENTRY_POINT *)((char *)exports + exp_size);
|
||||
|
@ -749,10 +764,10 @@ void RELAY_SetupDLL( HMODULE module )
|
|||
* Simple function to decide if a particular debugging message is
|
||||
* wanted.
|
||||
*/
|
||||
int SNOOP_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) {
|
||||
|
||||
int SNOOP_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname)
|
||||
{
|
||||
if(debug_snoop_excludelist || debug_snoop_includelist) {
|
||||
const char **listitem;
|
||||
const WCHAR **listitem;
|
||||
char buf[80];
|
||||
int len, len2, itemlen, show;
|
||||
|
||||
|
@ -767,14 +782,13 @@ int SNOOP_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) {
|
|||
assert(len < 64);
|
||||
sprintf(buf, "%s.%d", dll, ord);
|
||||
len2 = strlen(buf);
|
||||
for(; *listitem; listitem++) {
|
||||
itemlen = strlen(*listitem);
|
||||
if((itemlen == len && !strncasecmp(*listitem, buf, len)) ||
|
||||
(itemlen == len2 && !strncasecmp(*listitem, buf, len2)) ||
|
||||
!strcasecmp(*listitem, fname)) {
|
||||
show = !show;
|
||||
break;
|
||||
}
|
||||
for(; *listitem; listitem++)
|
||||
{
|
||||
itemlen = strlenW(*listitem);
|
||||
if((itemlen == len && !strncmpiAW( buf, *listitem, len)) ||
|
||||
(itemlen == len2 && !strncmpiAW(buf, *listitem, len2)) ||
|
||||
!strcmpAW(fname, *listitem))
|
||||
return !show;
|
||||
}
|
||||
return show;
|
||||
}
|
||||
|
@ -1089,7 +1103,7 @@ __ASM_GLOBAL_FUNC( SNOOP_Return,
|
|||
#else /* __i386__ */
|
||||
|
||||
FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
|
||||
DWORD exp_size, FARPROC proc, const char *user )
|
||||
DWORD exp_size, FARPROC proc, const WCHAR *user )
|
||||
{
|
||||
return proc;
|
||||
}
|
||||
|
|
|
@ -1053,8 +1053,6 @@ static BOOL search_alternate_path(LPCWSTR dll_path, LPCWSTR name, LPCWSTR ext,
|
|||
* contain an extension.
|
||||
* buflen [I] size of buffer, in characters
|
||||
* buffer [O] buffer for found filename
|
||||
* lastpart [O] address of pointer to last used character in
|
||||
* buffer (the final '\') (May be NULL)
|
||||
*
|
||||
* RETURNS
|
||||
* Success: length of string copied into buffer, not including
|
||||
|
@ -1068,39 +1066,20 @@ static BOOL search_alternate_path(LPCWSTR dll_path, LPCWSTR name, LPCWSTR ext,
|
|||
*
|
||||
* FIXME: convert to unicode
|
||||
*/
|
||||
DWORD DIR_SearchAlternatePath( LPCSTR dll_path, LPCSTR name, LPCSTR ext,
|
||||
DWORD buflen, LPSTR buffer, LPSTR *lastpart )
|
||||
DWORD DIR_SearchAlternatePath( LPCWSTR dll_path, LPCWSTR name, LPCWSTR ext,
|
||||
DWORD buflen, LPWSTR buffer )
|
||||
{
|
||||
LPSTR p;
|
||||
DOS_FULL_NAME full_name;
|
||||
DWORD ret = 0;
|
||||
UNICODE_STRING dll_pathW, nameW, extW;
|
||||
|
||||
if (dll_path) RtlCreateUnicodeStringFromAsciiz(&dll_pathW, dll_path);
|
||||
else dll_pathW.Buffer = NULL;
|
||||
if (name) RtlCreateUnicodeStringFromAsciiz(&nameW, name);
|
||||
else nameW.Buffer = NULL;
|
||||
if (ext) RtlCreateUnicodeStringFromAsciiz(&extW, ext);
|
||||
else extW.Buffer = NULL;
|
||||
|
||||
if (search_alternate_path( dll_pathW.Buffer, nameW.Buffer, extW.Buffer, &full_name))
|
||||
if (search_alternate_path( dll_path, name, ext, &full_name))
|
||||
{
|
||||
ret = WideCharToMultiByte(CP_ACP, 0, full_name.short_name, -1, NULL, 0, NULL, NULL);
|
||||
if (buflen >= ret)
|
||||
{
|
||||
WideCharToMultiByte(CP_ACP, 0, full_name.short_name, -1, buffer, buflen, NULL, NULL);
|
||||
for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
|
||||
if (lastpart) *lastpart = strrchr( buffer, '\\' ) + 1;
|
||||
ret--; /* length without 0 */
|
||||
}
|
||||
lstrcpynW( buffer, full_name.short_name, buflen );
|
||||
ret = strlenW(buffer);
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
|
||||
RtlFreeUnicodeString(&dll_pathW);
|
||||
RtlFreeUnicodeString(&nameW);
|
||||
RtlFreeUnicodeString(&extW);
|
||||
|
||||
TRACE("Returning %ld\n", ret );
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -91,8 +91,8 @@ extern LONG WINAPI WIN16_hread(HFILE16,SEGPTR,LONG);
|
|||
extern int DIR_Init(void);
|
||||
extern UINT DIR_GetWindowsUnixDir( LPSTR path, UINT count );
|
||||
extern UINT DIR_GetSystemUnixDir( LPSTR path, UINT count );
|
||||
extern DWORD DIR_SearchAlternatePath( LPCSTR dll_path, LPCSTR name, LPCSTR ext,
|
||||
DWORD buflen, LPSTR buffer, LPSTR *lastpart);
|
||||
extern DWORD DIR_SearchAlternatePath( LPCWSTR dll_path, LPCWSTR name, LPCWSTR ext,
|
||||
DWORD buflen, LPWSTR buffer);
|
||||
extern DWORD DIR_SearchPath( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
|
||||
DOS_FULL_NAME *full_name, BOOL win32 );
|
||||
|
||||
|
|
|
@ -950,6 +950,9 @@ void WINAPIV DbgPrint(LPCSTR fmt, ...);
|
|||
NTSTATUS WINAPI LdrAccessResource(HMODULE,const IMAGE_RESOURCE_DATA_ENTRY*,void**,PULONG);
|
||||
NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DIRECTORY**);
|
||||
NTSTATUS WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**);
|
||||
NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, const UNICODE_STRING*, HMODULE*);
|
||||
NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**);
|
||||
NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
|
||||
void WINAPI LdrShutdownProcess(void);
|
||||
void WINAPI LdrShutdownThread(void);
|
||||
NTSTATUS WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_MAPPING,PPRIVILEGE_SET,PULONG,PULONG,PBOOLEAN);
|
||||
|
@ -1404,9 +1407,6 @@ typedef struct _SYSTEM_MODULE_INFORMATION
|
|||
|
||||
NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE);
|
||||
NTSTATUS WINAPI LdrFindEntryForAddress(const void*, PLDR_MODULE*);
|
||||
NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, PUNICODE_STRING, HMODULE*);
|
||||
NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, PANSI_STRING, ULONG, void**);
|
||||
NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, PUNICODE_STRING, HMODULE*);
|
||||
NTSTATUS WINAPI LdrLockLoaderLock(ULONG,ULONG*,ULONG*);
|
||||
NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, ULONG, ULONG*);
|
||||
NTSTATUS WINAPI LdrUnloadDll(HMODULE);
|
||||
|
|
Loading…
Reference in New Issue