Commit 4137aeca authored by Alexandre Julliard's avatar Alexandre Julliard

Changed LdrLoadDll to only search for the dll in the specified path,

using ntdll functions. Moved LOAD_WITH_ALTERED_SEARCH_PATH functionality to LoadLibraryEx where it belongs.
parent 33fee69b
......@@ -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 ))
{
......
......@@ -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;
}
......@@ -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 );
......
......@@ -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 );
}
/***********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment