diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 9901da89af2..60e1ccd09f4 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -125,6 +125,7 @@ extern BOOL build_command_line( char **argv ); extern void RELAY_InitDebugLists(void); extern void SHELL_LoadRegistry(void); extern void VERSION_Init( const char *appname ); +extern void MODULE_InitLoadPath(void); /*********************************************************************** * get_basename @@ -561,6 +562,9 @@ void __wine_process_init( int argc, char *argv[] ) TRACE( "starting process name=%s file=%p argv[0]=%s\n", debugstr_a(main_exe_name), main_exe_file, debugstr_a(argv[0]) ); + MODULE_InitLoadPath(); + VERSION_Init( main_exe_name ); + if (!main_exe_file) /* no file handle -> Winelib app */ { TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) ); @@ -569,7 +573,6 @@ void __wine_process_init( int argc, char *argv[] ) MESSAGE( "%s: cannot open builtin library for '%s': %s\n", argv0, main_exe_name, error ); ExitProcess(1); } - VERSION_Init( main_exe_name ); switch( MODULE_GetBinaryType( main_exe_file )) { diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index a2e206131b4..edce7f6ca60 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1109,44 +1109,13 @@ static void load_builtin_callback( void *module, const char *filename ) } -/*********************************************************************** - * allocate_lib_dir - * - * helper for MODULE_LoadLibraryExA. Allocate space to hold the directory - * portion of the provided name and put the name in it. - * - */ -static WCHAR *allocate_lib_dir(LPCWSTR libname) -{ - LPCWSTR p, pmax; - LPWSTR result; - int length; - - pmax = libname; - 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 (GetProcessHeap(), 0, (length+1) * sizeof(WCHAR) ); - - if (result) - { - memcpy( result, libname, length * sizeof(WCHAR) ); - result [length] = '\0'; - } - return result; -} - - /****************************************************************************** * load_native_dll (internal) */ -static NTSTATUS load_native_dll( LPCWSTR name, DWORD flags, WINE_MODREF** pwm ) +static NTSTATUS load_native_dll( LPCWSTR name, HANDLE file, DWORD flags, WINE_MODREF** pwm ) { void *module; - HANDLE file, mapping; + HANDLE mapping; OBJECT_ATTRIBUTES attr; LARGE_INTEGER size; IMAGE_NT_HEADERS *nt; @@ -1155,14 +1124,6 @@ static NTSTATUS load_native_dll( LPCWSTR name, DWORD flags, WINE_MODREF** pwm ) NTSTATUS status; UINT drive_type; - 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_DLL_NOT_FOUND : STATUS_INTERNAL_ERROR; - } - TRACE( "loading %s\n", debugstr_w(name) ); attr.Length = sizeof(attr); @@ -1175,21 +1136,17 @@ static NTSTATUS load_native_dll( LPCWSTR name, DWORD flags, WINE_MODREF** pwm ) status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, &attr, &size, 0, SEC_IMAGE, file ); - if (status != STATUS_SUCCESS) goto done; + if (status != STATUS_SUCCESS) return status; module = NULL; status = NtMapViewOfSection( mapping, GetCurrentProcess(), &module, 0, 0, &size, &len, ViewShare, 0, PAGE_READONLY ); NtClose( mapping ); - if (status != STATUS_SUCCESS) goto done; + if (status != STATUS_SUCCESS) return status; /* create the MODREF */ - if (!(wm = alloc_module( module, name ))) - { - status = STATUS_NO_MEMORY; - goto done; - } + if (!(wm = alloc_module( module, name ))) return STATUS_NO_MEMORY; /* fixup imports */ @@ -1208,7 +1165,7 @@ static NTSTATUS load_native_dll( LPCWSTR name, DWORD flags, WINE_MODREF** pwm ) * around with no problems, so we don't care. * As these might reference our wm, we don't free it. */ - goto done; + return status; } } else wm->ldr.Flags |= LDR_DONT_RESOLVE_REFS; @@ -1236,67 +1193,7 @@ static NTSTATUS load_native_dll( LPCWSTR name, DWORD flags, WINE_MODREF** pwm ) if (TRACE_ON(snoop)) SNOOP_SetupDLL( module ); *pwm = wm; - status = STATUS_SUCCESS; -done: - NtClose( file ); - return status; -} - - -/*************************************************************************** - * 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; + return STATUS_SUCCESS; } @@ -1365,103 +1262,53 @@ static NTSTATUS load_builtin_dll( LPCWSTR path, DWORD flags, WINE_MODREF** pwm ) * load_dll (internal) * * Load a PE style module according to the load order. - * - * libdir is used to support LOAD_WITH_ALTERED_SEARCH_PATH during the recursion - * on this function. When first called from LoadLibraryExA it will be - * NULL but thereafter it may point to a buffer containing the path - * portion of the library name. Note that the recursion all occurs - * within a Critical section (see LoadLibraryExA) so the use of a - * static is acceptable. - * (We have to use a static variable at some point anyway, to pass the - * 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( LPCWSTR libname, DWORD flags, WINE_MODREF** pwm ) { int i; enum loadorder_type loadorder[LOADORDER_NTYPES]; - WCHAR *filename; + WCHAR *filename, *file_part; const char *filetype = ""; - DWORD found; WINE_MODREF *main_exe; - BOOL allocated_libdir = FALSE; - static WCHAR *libdir = NULL; /* See above */ + HANDLE handle = INVALID_HANDLE_VALUE; NTSTATUS nts = STATUS_DLL_NOT_FOUND; + const WCHAR *load_path; *pwm = NULL; - filename = RtlAllocateHeap ( GetProcessHeap(), 0, (MAX_PATH + 1) * sizeof(WCHAR) ); + filename = RtlAllocateHeap ( GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) ); if ( !filename ) return STATUS_NO_MEMORY; - *filename = 0; /* Just in case we don't set it before goto error */ - if ((flags & LOAD_WITH_ALTERED_SEARCH_PATH) && contains_path(libname)) + if (!(load_path = current_load_path)) + load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; + + TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) ); + + if (RtlDosSearchPath_U( load_path, libname, dllW, MAX_PATH * sizeof(WCHAR), filename, &file_part )) { - if (!(libdir = allocate_lib_dir(libname))) + if ((*pwm = find_module( filename )) != NULL) goto found; + + /* check for already loaded module in a different path */ + if (!contains_path( libname )) { - nts = STATUS_NO_MEMORY; - goto error; + if ((*pwm = find_module( file_part )) != NULL) goto found; } - allocated_libdir = TRUE; + handle = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); } - - if (!libdir || allocated_libdir) - found = SearchPathW(NULL, libname, dllW, MAX_PATH, filename, NULL); - else - found = DIR_SearchAlternatePath(libdir, libname, dllW, MAX_PATH, filename); - - /* build the modules filename */ - if (!found) + else /* we didn't find the file */ { - if (!get_builtin_path( libname, filename, MAX_PATH )) + if (contains_path( libname )) { - nts = STATUS_INTERNAL_ERROR; - goto error; + RtlGetFullPathName_U( libname, MAX_PATH * sizeof(WCHAR), filename, &file_part ); + if ((*pwm = find_module( filename )) != NULL) goto found; } - } - - /* Check for already loaded module */ - if (!(*pwm = find_module(filename)) && !contains_path(libname)) - { - LPWSTR fn = RtlAllocateHeap ( GetProcessHeap(), 0, (MAX_PATH + 1) * sizeof(WCHAR) ); - if (fn) + else { - /* since the default loading mechanism uses a more detailed algorithm - * than SearchPath (like using PATH, which can even be modified between - * two attempts of loading the same DLL), the look-up above (with - * SearchPath) can have put the file in system directory, whereas it - * has already been loaded but with a different path. So do a specific - * look-up with filename (without any path) - */ - strcpyW ( fn, libname ); - /* if the filename doesn't have an extension append .DLL */ - if (!strrchrW( fn, '.')) strcatW( fn, dllW ); - if ((*pwm = find_module( fn )) != NULL) - strcpyW( filename, fn ); - RtlFreeHeap( GetProcessHeap(), 0, fn ); + if ((*pwm = find_module( libname )) != NULL) goto found; + strcpyW( filename, libname ); + file_part = filename; } - } - - if (*pwm) - { - if ((*pwm)->ldr.LoadCount != -1) (*pwm)->ldr.LoadCount++; - - if (((*pwm)->ldr.Flags & LDR_DONT_RESOLVE_REFS) && - !(flags & DONT_RESOLVE_DLL_REFERENCES)) - { - (*pwm)->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS; - fixup_imports( *pwm ); - } - if (allocated_libdir) - { - RtlFreeHeap( GetProcessHeap(), 0, libdir ); - libdir = NULL; - } - 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; + if (!strchrW( file_part, '.' )) strcatW( file_part, dllW ); } main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress ); @@ -1475,7 +1322,8 @@ static NTSTATUS load_dll( LPCWSTR libname, DWORD flags, WINE_MODREF** pwm ) { case LOADORDER_DLL: TRACE("Trying native dll %s\n", debugstr_w(filename)); - nts = load_native_dll(filename, flags, pwm); + if (handle != INVALID_HANDLE_VALUE) + nts = load_native_dll(filename, handle, flags, pwm); filetype = "native"; break; case LOADORDER_BI: @@ -1498,33 +1346,32 @@ static NTSTATUS load_dll( LPCWSTR libname, DWORD flags, WINE_MODREF** pwm ) /* 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( GetProcessHeap(), 0, libdir ); - libdir = NULL; - } + if (handle != INVALID_HANDLE_VALUE) NtClose( handle ); RtlFreeHeap( GetProcessHeap(), 0, filename ); return nts; } - - if (nts != STATUS_DLL_NOT_FOUND) - { - WARN("Loading of %s DLL %s failed (status %lx).\n", - filetype, debugstr_w(filename), nts); - break; - } + if (nts != STATUS_DLL_NOT_FOUND) break; } - error: - if (allocated_libdir) - { - RtlFreeHeap( GetProcessHeap(), 0, libdir ); - libdir = NULL; - } - WARN("Failed to load module %s; status=%lx\n", debugstr_w(filename), nts); + WARN("Failed to load module %s; status=%lx\n", debugstr_w(libname), nts); + if (handle != INVALID_HANDLE_VALUE) NtClose( handle ); RtlFreeHeap( GetProcessHeap(), 0, filename ); return nts; + + found: + if ((*pwm)->ldr.LoadCount != -1) (*pwm)->ldr.LoadCount++; + + if (((*pwm)->ldr.Flags & LDR_DONT_RESOLVE_REFS) && + !(flags & DONT_RESOLVE_DLL_REFERENCES)) + { + (*pwm)->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS; + fixup_imports( *pwm ); + } + TRACE("Found loaded module %s for %s at %p, count=%d\n", + debugstr_w((*pwm)->ldr.FullDllName.Buffer), debugstr_w(libname), + (*pwm)->ldr.BaseAddress, (*pwm)->ldr.LoadCount); + RtlFreeHeap( GetProcessHeap(), 0, filename ); + return STATUS_SUCCESS; } /****************************************************************** diff --git a/files/directory.c b/files/directory.c index bf869d3f96e..8734a98ce13 100644 --- a/files/directory.c +++ b/files/directory.c @@ -987,99 +987,3 @@ DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext, RtlFreeUnicodeString(&extW); return ret; } - - -/*********************************************************************** - * search_alternate_path - * - * - * FIXME: should return long path names.? - */ -static BOOL search_alternate_path(LPCWSTR dll_path, LPCWSTR name, LPCWSTR ext, - DOS_FULL_NAME *full_name) -{ - LPCWSTR p; - LPWSTR tmp = NULL; - BOOL ret = TRUE; - - /* First check the supplied parameters */ - - p = strrchrW( name, '.' ); - if (p && !strchrW( p, '/' ) && !strchrW( p, '\\' )) - ext = NULL; /* Ignore the specified extension */ - - /* Allocate a buffer for the file name and extension */ - - if (ext) - { - DWORD len = strlenW(name) + strlenW(ext); - if (!(tmp = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) - { - SetLastError( ERROR_OUTOFMEMORY ); - return 0; - } - strcpyW( tmp, name ); - strcatW( tmp, ext ); - name = tmp; - } - - if (DIR_TryEnvironmentPath (name, full_name, dll_path)) - ; - else if (DOSFS_GetFullName (name, TRUE, full_name)) /* current dir */ - ; - else if (DIR_TryPath (&DIR_System, name, full_name)) /* System dir */ - ; - else if (DIR_TryPath (&DIR_Windows, name, full_name)) /* Windows dir */ - ; - else - ret = DIR_TryEnvironmentPath( name, full_name, NULL ); - - if (tmp) HeapFree( GetProcessHeap(), 0, tmp ); - return ret; -} - - -/*********************************************************************** - * DIR_SearchAlternatePath - * - * Searches for a specified file in the search path. - * - * PARAMS - * dll_path [I] Path to search - * name [I] Filename to search for. - * ext [I] File extension to append to file name. The first - * character must be a period. This parameter is - * specified only if the filename given does not - * contain an extension. - * buflen [I] size of buffer, in characters - * buffer [O] buffer for found filename - * - * RETURNS - * Success: length of string copied into buffer, not including - * terminating null character. If the filename found is - * longer than the length of the buffer, the length of the - * filename is returned. - * Failure: Zero - * - * NOTES - * If the file is not found, calls SetLastError(ERROR_FILE_NOT_FOUND) - * - * FIXME: convert to unicode - */ -DWORD DIR_SearchAlternatePath( LPCWSTR dll_path, LPCWSTR name, LPCWSTR ext, - DWORD buflen, LPWSTR buffer ) -{ - DOS_FULL_NAME full_name; - DWORD ret = 0; - - if (search_alternate_path( dll_path, name, ext, &full_name)) - { - lstrcpynW( buffer, full_name.short_name, buflen ); - ret = strlenW(buffer); - } - else - SetLastError(ERROR_FILE_NOT_FOUND); - - TRACE("Returning %ld\n", ret ); - return ret; -} diff --git a/include/file.h b/include/file.h index 0f06f6dfb30..ebf09468855 100644 --- a/include/file.h +++ b/include/file.h @@ -91,8 +91,6 @@ 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( 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 ); diff --git a/loader/module.c b/loader/module.c index f32e13bcbcf..47673379798 100644 --- a/loader/module.c +++ b/loader/module.c @@ -515,6 +515,125 @@ DWORD WINAPI GetModuleFileNameW( HMODULE hModule, LPWSTR lpFileName, DWORD size return strlenW(lpFileName); } + +/*********************************************************************** + * get_dll_system_path + */ +static const WCHAR *get_dll_system_path(void) +{ + static WCHAR *path; + + if (!path) + { + WCHAR *p, *exe_name; + int len = 3; + + exe_name = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer; + if (!(p = strrchrW( exe_name, '\\' ))) p = exe_name; + /* include trailing backslash only on drive root */ + if (p == exe_name + 2 && exe_name[1] == ':') p++; + len += p - exe_name; + len += GetSystemDirectoryW( NULL, 0 ); + len += GetWindowsDirectoryW( NULL, 0 ); + path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + memcpy( path, exe_name, (p - exe_name) * sizeof(WCHAR) ); + p = path + (p - exe_name); + *p++ = ';'; + *p++ = '.'; + *p++ = ';'; + GetSystemDirectoryW( p, path + len - p); + p += strlenW(p); + *p++ = ';'; + GetWindowsDirectoryW( p, path + len - p); + } + return path; +} + + +/****************************************************************** + * get_dll_load_path + * + * Compute the load path to use for a given dll. + * Returned pointer must be freed by caller. + */ +static WCHAR *get_dll_load_path( LPCWSTR module ) +{ + static const WCHAR pathW[] = {'P','A','T','H',0}; + + const WCHAR *system_path = get_dll_system_path(); + const WCHAR *mod_end = NULL; + UNICODE_STRING name, value; + WCHAR *p, *ret; + int len = 0, path_len = 0; + + /* adjust length for module name */ + + if (module) + { + mod_end = module; + if ((p = strrchrW( mod_end, '\\' ))) mod_end = p; + if ((p = strrchrW( mod_end, '/' ))) mod_end = p; + if (mod_end == module + 2 && module[1] == ':') mod_end++; + if (mod_end == module && module[0] && module[1] == ':') mod_end += 2; + len += (mod_end - module); + system_path = strchrW( system_path, ';' ); + } + len += strlenW( system_path ) + 2; + + /* get the PATH variable */ + + RtlInitUnicodeString( &name, pathW ); + value.Length = 0; + value.MaximumLength = 0; + value.Buffer = NULL; + if (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) == STATUS_BUFFER_TOO_SMALL) + path_len = value.Length; + + if (!(ret = HeapAlloc( GetProcessHeap(), 0, path_len + len * sizeof(WCHAR) ))) return NULL; + p = ret; + if (module) + { + memcpy( ret, module, (mod_end - module) * sizeof(WCHAR) ); + p += (mod_end - module); + } + strcpyW( p, system_path ); + p += strlenW(p); + *p++ = ';'; + value.Buffer = p; + value.MaximumLength = path_len; + + while (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) == STATUS_BUFFER_TOO_SMALL) + { + WCHAR *new_ptr; + + /* grow the buffer and retry */ + path_len = value.Length; + if (!(new_ptr = HeapReAlloc( GetProcessHeap(), 0, ret, path_len + len * sizeof(WCHAR) ))) + { + HeapFree( GetProcessHeap(), 0, ret ); + return NULL; + } + value.Buffer = new_ptr + (value.Buffer - ret); + value.MaximumLength = path_len; + ret = new_ptr; + } + value.Buffer[value.Length / sizeof(WCHAR)] = 0; + return ret; +} + + +/****************************************************************** + * MODULE_InitLoadPath + * + * Create the initial dll load path. + */ +void MODULE_InitLoadPath(void) +{ + WCHAR *path = get_dll_load_path( NULL ); + RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath, path ); +} + + /****************************************************************** * load_library_as_datafile */ @@ -555,6 +674,40 @@ static BOOL load_library_as_datafile( LPCWSTR name, HMODULE* hmod) return TRUE; } + +/****************************************************************** + * load_library + * + * Helper for LoadLibraryExA/W. + */ +static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags ) +{ + NTSTATUS nts; + HMODULE hModule; + WCHAR *load_path; + + if (flags & LOAD_LIBRARY_AS_DATAFILE) + { + /* The method in load_library_as_datafile allows searching for the + * 'native' libraries only + */ + if (load_library_as_datafile( libname->Buffer, &hModule )) return hModule; + flags |= DONT_RESOLVE_DLL_REFERENCES; /* Just in case */ + /* Fallback to normal behaviour */ + } + + load_path = get_dll_load_path( flags & LOAD_WITH_ALTERED_SEARCH_PATH ? libname->Buffer : NULL ); + nts = LdrLoadDll( load_path, flags, libname, &hModule ); + HeapFree( GetProcessHeap(), 0, load_path ); + if (nts != STATUS_SUCCESS) + { + hModule = 0; + SetLastError( RtlNtStatusToDosError( nts ) ); + } + return hModule; +} + + /****************************************************************** * LoadLibraryExA (KERNEL32.@) * @@ -578,7 +731,6 @@ static BOOL load_library_as_datafile( LPCWSTR name, HMODULE* hmod) HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) { UNICODE_STRING wstr; - NTSTATUS nts; HMODULE hModule; if (!libname) @@ -587,29 +739,8 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) return 0; } RtlCreateUnicodeStringFromAsciiz( &wstr, libname ); - - if (flags & LOAD_LIBRARY_AS_DATAFILE) - { - /* The method in load_library_as_datafile allows searching for the - * 'native' libraries only - */ - if (load_library_as_datafile( wstr.Buffer, &hModule)) - { - RtlFreeUnicodeString( &wstr ); - return hModule; - } - flags |= DONT_RESOLVE_DLL_REFERENCES; /* Just in case */ - /* Fallback to normal behaviour */ - } - - nts = LdrLoadDll(NULL, flags, &wstr, &hModule); - if (nts != STATUS_SUCCESS) - { - hModule = 0; - SetLastError( RtlNtStatusToDosError( nts ) ); - } + hModule = load_library( &wstr, flags ); RtlFreeUnicodeString( &wstr ); - return hModule; } @@ -621,33 +752,14 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) HMODULE WINAPI LoadLibraryExW(LPCWSTR libnameW, HANDLE hfile, DWORD flags) { UNICODE_STRING wstr; - NTSTATUS nts; - HMODULE hModule; if (!libnameW) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } - - if (flags & LOAD_LIBRARY_AS_DATAFILE) - { - /* The method in load_library_as_datafile allows searching for the - * 'native' libraries only - */ - if (load_library_as_datafile(libnameW, &hModule)) return hModule; - flags |= DONT_RESOLVE_DLL_REFERENCES; /* Just in case */ - /* Fallback to normal behaviour */ - } - RtlInitUnicodeString( &wstr, libnameW ); - nts = LdrLoadDll(NULL, flags, &wstr, &hModule); - if (nts != STATUS_SUCCESS) - { - hModule = 0; - SetLastError( RtlNtStatusToDosError( nts ) ); - } - return hModule; + return load_library( &wstr, flags ); } /***********************************************************************