kernel32: Move dll path functions to ntdll.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b8ba4909ee
commit
619bd16e7a
|
@ -140,7 +140,7 @@
|
|||
@ stdcall AddAtomW(wstr)
|
||||
@ stdcall AddConsoleAliasA(str str str)
|
||||
@ stdcall AddConsoleAliasW(wstr wstr wstr)
|
||||
@ stdcall AddDllDirectory(wstr)
|
||||
@ stdcall -import AddDllDirectory(wstr)
|
||||
# @ stub AddIntegrityLabelToBoundaryDescriptor
|
||||
# @ stub AddLocalAlternateComputerNameA
|
||||
# @ stub AddLocalAlternateComputerNameW
|
||||
|
@ -1274,7 +1274,7 @@
|
|||
@ stdcall ReplaceFileW(wstr wstr wstr long ptr ptr)
|
||||
# @ stub RemoveDirectoryTransactedA
|
||||
# @ stub RemoveDirectoryTransactedW
|
||||
@ stdcall RemoveDllDirectory(ptr)
|
||||
@ stdcall -import RemoveDllDirectory(ptr)
|
||||
# @ stub RemoveSecureMemoryCacheCallback
|
||||
# @ stub ReplacePartitionUnit
|
||||
@ stdcall RequestDeviceWakeup(long)
|
||||
|
@ -1379,7 +1379,7 @@
|
|||
@ stub SetDaylightFlag
|
||||
@ stdcall SetDefaultCommConfigA(str ptr long)
|
||||
@ stdcall SetDefaultCommConfigW(wstr ptr long)
|
||||
@ stdcall SetDefaultDllDirectories(long)
|
||||
@ stdcall -import SetDefaultDllDirectories(long)
|
||||
@ stdcall SetDllDirectoryA(str)
|
||||
@ stdcall SetDllDirectoryW(wstr)
|
||||
# @ stub SetDynamicTimeZoneInformation
|
||||
|
|
|
@ -65,9 +65,6 @@ extern void FILE_SetDosError(void) DECLSPEC_HIDDEN;
|
|||
extern WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc ) DECLSPEC_HIDDEN;
|
||||
extern DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* module.c */
|
||||
extern WCHAR *MODULE_get_dll_load_path( LPCWSTR module, int safe_mode ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL NLS_IsUnicodeOnlyLcid(LCID) DECLSPEC_HIDDEN;
|
||||
|
||||
/* environ.c */
|
||||
|
|
|
@ -49,15 +49,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(module);
|
|||
|
||||
#define NE_FFLAGS_LIBMODULE 0x8000
|
||||
|
||||
struct dll_dir_entry
|
||||
{
|
||||
struct list entry;
|
||||
WCHAR dir[1];
|
||||
};
|
||||
|
||||
static struct list dll_dir_list = LIST_INIT( dll_dir_list ); /* extra dirs from AddDllDirectory */
|
||||
static DWORD default_search_flags; /* default flags set by SetDefaultDllDirectories */
|
||||
|
||||
/* to keep track of LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE file handles */
|
||||
struct exclusive_datafile
|
||||
{
|
||||
|
@ -67,15 +58,6 @@ struct exclusive_datafile
|
|||
};
|
||||
static struct list exclusive_datafile_list = LIST_INIT( exclusive_datafile_list );
|
||||
|
||||
static CRITICAL_SECTION dlldir_section;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
{
|
||||
0, 0, &dlldir_section,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": dlldir_section") }
|
||||
};
|
||||
static CRITICAL_SECTION dlldir_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/****************************************************************************
|
||||
* GetDllDirectoryA (KERNEL32.@)
|
||||
*/
|
||||
|
@ -163,73 +145,6 @@ BOOL WINAPI SetDllDirectoryW( LPCWSTR dir )
|
|||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* AddDllDirectory (KERNEL32.@)
|
||||
*/
|
||||
DLL_DIRECTORY_COOKIE WINAPI AddDllDirectory( const WCHAR *dir )
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
DWORD len;
|
||||
struct dll_dir_entry *ptr;
|
||||
DOS_PATHNAME_TYPE type = RtlDetermineDosPathNameType_U( dir );
|
||||
|
||||
if (type != ABSOLUTE_PATH && type != ABSOLUTE_DRIVE_PATH)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
}
|
||||
if (!(len = GetFullPathNameW( dir, MAX_PATH, path, NULL ))) return NULL;
|
||||
if (GetFileAttributesW( path ) == INVALID_FILE_ATTRIBUTES) return NULL;
|
||||
|
||||
if (!(ptr = HeapAlloc( GetProcessHeap(), 0, offsetof(struct dll_dir_entry, dir[++len] )))) return NULL;
|
||||
memcpy( ptr->dir, path, len * sizeof(WCHAR) );
|
||||
TRACE( "%s\n", debugstr_w( ptr->dir ));
|
||||
|
||||
RtlEnterCriticalSection( &dlldir_section );
|
||||
list_add_head( &dll_dir_list, &ptr->entry );
|
||||
RtlLeaveCriticalSection( &dlldir_section );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* RemoveDllDirectory (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI RemoveDllDirectory( DLL_DIRECTORY_COOKIE cookie )
|
||||
{
|
||||
struct dll_dir_entry *ptr = cookie;
|
||||
|
||||
TRACE( "%s\n", debugstr_w( ptr->dir ));
|
||||
|
||||
RtlEnterCriticalSection( &dlldir_section );
|
||||
list_remove( &ptr->entry );
|
||||
HeapFree( GetProcessHeap(), 0, ptr );
|
||||
RtlLeaveCriticalSection( &dlldir_section );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* SetDefaultDllDirectories (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI SetDefaultDllDirectories( DWORD flags )
|
||||
{
|
||||
/* LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR doesn't make sense in default dirs */
|
||||
const DWORD load_library_search_flags = (LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32 |
|
||||
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
|
||||
if (!flags || (flags & ~load_library_search_flags))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
default_search_flags = flags;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetBinaryTypeW [KERNEL32.@]
|
||||
*
|
||||
|
@ -368,293 +283,10 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
|
|||
return GetBinaryTypeW(NtCurrentTeb()->StaticUnicodeString.Buffer, lpBinaryType);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_dll_system_path
|
||||
*/
|
||||
static const WCHAR *get_dll_system_path(void)
|
||||
{
|
||||
static WCHAR *cached_path;
|
||||
|
||||
if (!cached_path)
|
||||
{
|
||||
WCHAR *p, *path;
|
||||
int len = 1;
|
||||
|
||||
len += 2 * GetSystemDirectoryW( NULL, 0 );
|
||||
len += GetWindowsDirectoryW( NULL, 0 );
|
||||
p = path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
||||
GetSystemDirectoryW( p, path + len - p);
|
||||
p += strlenW(p);
|
||||
/* if system directory ends in "32" add 16-bit version too */
|
||||
if (p[-2] == '3' && p[-1] == '2')
|
||||
{
|
||||
*p++ = ';';
|
||||
GetSystemDirectoryW( p, path + len - p);
|
||||
p += strlenW(p) - 2;
|
||||
}
|
||||
*p++ = ';';
|
||||
GetWindowsDirectoryW( p, path + len - p);
|
||||
cached_path = path;
|
||||
}
|
||||
return cached_path;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_dll_safe_mode
|
||||
*/
|
||||
static BOOL get_dll_safe_mode(void)
|
||||
{
|
||||
static const WCHAR keyW[] = {'\\','R','e','g','i','s','t','r','y','\\',
|
||||
'M','a','c','h','i','n','e','\\',
|
||||
'S','y','s','t','e','m','\\',
|
||||
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
|
||||
'C','o','n','t','r','o','l','\\',
|
||||
'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r',0};
|
||||
static const WCHAR valueW[] = {'S','a','f','e','D','l','l','S','e','a','r','c','h','M','o','d','e',0};
|
||||
|
||||
static int safe_mode = -1;
|
||||
|
||||
if (safe_mode == -1)
|
||||
{
|
||||
char buffer[offsetof(KEY_VALUE_PARTIAL_INFORMATION, Data[sizeof(DWORD)])];
|
||||
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
HANDLE hkey;
|
||||
DWORD size = sizeof(buffer);
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
safe_mode = 1;
|
||||
RtlInitUnicodeString( &nameW, keyW );
|
||||
if (!NtOpenKey( &hkey, KEY_READ, &attr ))
|
||||
{
|
||||
RtlInitUnicodeString( &nameW, valueW );
|
||||
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, buffer, size, &size ) &&
|
||||
info->Type == REG_DWORD && info->DataLength == sizeof(DWORD))
|
||||
safe_mode = !!*(DWORD *)info->Data;
|
||||
NtClose( hkey );
|
||||
}
|
||||
if (!safe_mode) TRACE( "SafeDllSearchMode disabled through the registry\n" );
|
||||
}
|
||||
return safe_mode;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* get_module_path_end
|
||||
*
|
||||
* Returns the end of the directory component of the module path.
|
||||
*/
|
||||
static inline const WCHAR *get_module_path_end(const WCHAR *module)
|
||||
{
|
||||
const WCHAR *p;
|
||||
const WCHAR *mod_end = module;
|
||||
if (!module) return mod_end;
|
||||
|
||||
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;
|
||||
|
||||
return mod_end;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* append_path_len
|
||||
*
|
||||
* Append a counted string to the load path. Helper for MODULE_get_dll_load_path.
|
||||
*/
|
||||
static inline WCHAR *append_path_len( WCHAR *p, const WCHAR *str, DWORD len )
|
||||
{
|
||||
if (!len) return p;
|
||||
memcpy( p, str, len * sizeof(WCHAR) );
|
||||
p[len] = ';';
|
||||
return p + len + 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* append_path
|
||||
*
|
||||
* Append a string to the load path. Helper for MODULE_get_dll_load_path.
|
||||
*/
|
||||
static inline WCHAR *append_path( WCHAR *p, const WCHAR *str )
|
||||
{
|
||||
return append_path_len( p, str, strlenW(str) );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* MODULE_get_dll_load_path
|
||||
*
|
||||
* Compute the load path to use for a given dll.
|
||||
* Returned pointer must be freed by caller.
|
||||
*/
|
||||
WCHAR *MODULE_get_dll_load_path( LPCWSTR module, int safe_mode )
|
||||
{
|
||||
static const WCHAR pathW[] = {'P','A','T','H',0};
|
||||
static const WCHAR dotW[] = {'.',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, dlldir_len;
|
||||
|
||||
/* adjust length for module name */
|
||||
|
||||
if (module)
|
||||
mod_end = get_module_path_end( module );
|
||||
/* if module is NULL or doesn't contain a path, fall back to directory
|
||||
* process was loaded from */
|
||||
if (module == mod_end)
|
||||
{
|
||||
module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||
mod_end = get_module_path_end( module );
|
||||
}
|
||||
len += (mod_end - module) + 1;
|
||||
|
||||
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;
|
||||
|
||||
dlldir_len = GetDllDirectoryW( 0, NULL );
|
||||
|
||||
if (safe_mode == -1) safe_mode = get_dll_safe_mode();
|
||||
if (dlldir_len > 1) len += dlldir_len;
|
||||
else len += 2; /* current directory */
|
||||
if ((p = ret = HeapAlloc( GetProcessHeap(), 0, path_len + len * sizeof(WCHAR) )))
|
||||
{
|
||||
if (module) p = append_path_len( p, module, mod_end - module );
|
||||
|
||||
if (dlldir_len > 1)
|
||||
{
|
||||
GetDllDirectoryW( len - (p - ret), p );
|
||||
p += strlenW(p);
|
||||
*p++ = ';';
|
||||
}
|
||||
else if (!safe_mode) p = append_path( p, dotW );
|
||||
|
||||
p = append_path( p, system_path );
|
||||
|
||||
if (dlldir_len <= 1 && safe_mode) p = append_path( p, dotW );
|
||||
}
|
||||
if (!ret) return NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* get_dll_load_path_search_flags
|
||||
*/
|
||||
static WCHAR *get_dll_load_path_search_flags( LPCWSTR module, DWORD flags )
|
||||
{
|
||||
const WCHAR *image = NULL, *mod_end, *image_end;
|
||||
struct dll_dir_entry *dir;
|
||||
WCHAR *p, *ret;
|
||||
int len = 1;
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)
|
||||
flags |= (LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)
|
||||
{
|
||||
DWORD type = RtlDetermineDosPathNameType_U( module );
|
||||
if (type != ABSOLUTE_DRIVE_PATH && type != ABSOLUTE_PATH)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
}
|
||||
mod_end = get_module_path_end( module );
|
||||
len += (mod_end - module) + 1;
|
||||
}
|
||||
else module = NULL;
|
||||
|
||||
RtlEnterCriticalSection( &dlldir_section );
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
|
||||
{
|
||||
image = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||
image_end = get_module_path_end( image );
|
||||
len += (image_end - image) + 1;
|
||||
}
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_USER_DIRS)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( dir, &dll_dir_list, struct dll_dir_entry, entry )
|
||||
len += strlenW( dir->dir ) + 1;
|
||||
len += GetDllDirectoryW( 0, NULL );
|
||||
}
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_SYSTEM32) len += GetSystemDirectoryW( NULL, 0 );
|
||||
|
||||
if ((p = ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
|
||||
{
|
||||
if (module) p = append_path_len( p, module, mod_end - module );
|
||||
if (image) p = append_path_len( p, image, image_end - image );
|
||||
if (flags & LOAD_LIBRARY_SEARCH_USER_DIRS)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( dir, &dll_dir_list, struct dll_dir_entry, entry )
|
||||
p = append_path( p, dir->dir );
|
||||
GetDllDirectoryW( ret + len - p, p );
|
||||
if (*p)
|
||||
{
|
||||
p += strlenW(p);
|
||||
*p++ = ';';
|
||||
}
|
||||
}
|
||||
if (flags & LOAD_LIBRARY_SEARCH_SYSTEM32) GetSystemDirectoryW( p, ret + len - p );
|
||||
else
|
||||
{
|
||||
if (p > ret) p--;
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection( &dlldir_section );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* load_library_as_datafile
|
||||
*/
|
||||
static BOOL load_library_as_datafile( LPCWSTR name, HMODULE *hmod, DWORD flags )
|
||||
static BOOL load_library_as_datafile( LPCWSTR load_path, DWORD flags, LPCWSTR name, HMODULE *hmod )
|
||||
{
|
||||
static const WCHAR dotDLL[] = {'.','d','l','l',0};
|
||||
|
||||
|
@ -669,7 +301,7 @@ static BOOL load_library_as_datafile( LPCWSTR name, HMODULE *hmod, DWORD flags )
|
|||
|
||||
if (flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE) protect |= SEC_IMAGE;
|
||||
|
||||
if (SearchPathW( NULL, name, dotDLL, ARRAY_SIZE( filenameW ), filenameW, NULL ))
|
||||
if (SearchPathW( load_path, name, dotDLL, ARRAY_SIZE( filenameW ), filenameW, NULL ))
|
||||
{
|
||||
hFile = CreateFileW( filenameW, GENERIC_READ, sharing, NULL, OPEN_EXISTING, 0, 0 );
|
||||
}
|
||||
|
@ -720,34 +352,14 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
|
|||
{
|
||||
NTSTATUS nts;
|
||||
HMODULE hModule;
|
||||
WCHAR *load_path;
|
||||
const DWORD load_library_search_flags = (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
|
||||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32 |
|
||||
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
WCHAR *load_path, *dummy;
|
||||
const DWORD unsupported_flags = (LOAD_IGNORE_CODE_AUTHZ_LEVEL |
|
||||
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);
|
||||
|
||||
if( flags & unsupported_flags)
|
||||
FIXME("unsupported flag(s) used (flags: 0x%08x)\n", flags);
|
||||
|
||||
if (flags & LOAD_WITH_ALTERED_SEARCH_PATH)
|
||||
{
|
||||
if (flags & load_library_search_flags)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (default_search_flags) flags |= default_search_flags | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
|
||||
}
|
||||
else if (!(flags & load_library_search_flags)) flags |= default_search_flags;
|
||||
|
||||
if (flags & load_library_search_flags)
|
||||
load_path = get_dll_load_path_search_flags( libname->Buffer, flags );
|
||||
else
|
||||
load_path = MODULE_get_dll_load_path( flags & LOAD_WITH_ALTERED_SEARCH_PATH ? libname->Buffer : NULL, -1 );
|
||||
if (!load_path) return 0;
|
||||
if (!set_ntstatus( LdrGetDllPath( libname->Buffer, flags, &load_path, &dummy ))) return 0;
|
||||
|
||||
if (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
|
||||
{
|
||||
|
@ -760,7 +372,7 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
|
|||
LdrUnlockLoaderLock( 0, magic );
|
||||
goto done;
|
||||
}
|
||||
if (load_library_as_datafile( libname->Buffer, &hModule, flags ))
|
||||
if (load_library_as_datafile( load_path, flags, libname->Buffer, &hModule ))
|
||||
{
|
||||
LdrUnlockLoaderLock( 0, magic );
|
||||
goto done;
|
||||
|
@ -780,7 +392,7 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
|
|||
SetLastError( RtlNtStatusToDosError( nts ) );
|
||||
}
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, load_path );
|
||||
RtlReleasePath( load_path );
|
||||
return hModule;
|
||||
}
|
||||
|
||||
|
|
|
@ -1373,6 +1373,7 @@ void * CDECL __wine_kernel_init(void)
|
|||
RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters;
|
||||
HANDLE boot_events[2];
|
||||
BOOL got_environment = TRUE;
|
||||
WCHAR *load_path, *dummy;
|
||||
|
||||
/* Initialize everything */
|
||||
|
||||
|
@ -1429,8 +1430,8 @@ void * CDECL __wine_kernel_init(void)
|
|||
TRACE( "starting process name=%s argv[0]=%s\n",
|
||||
debugstr_w(main_exe_name), debugstr_w(__wine_main_wargv[0]) );
|
||||
|
||||
RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath,
|
||||
MODULE_get_dll_load_path( main_exe_name, -1 ));
|
||||
LdrGetDllPath( main_exe_name, 0, &load_path, &dummy );
|
||||
RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath, load_path );
|
||||
|
||||
if (boot_events[0])
|
||||
{
|
||||
|
|
|
@ -73,10 +73,14 @@ static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
|
|||
static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
|
||||
static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
|
||||
|
||||
static DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*);
|
||||
static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
|
||||
static BOOL (WINAPI *pSetSearchPathMode)(DWORD);
|
||||
static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
|
||||
static BOOL (WINAPI *pSetDllDirectoryW)(LPCWSTR);
|
||||
static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
|
||||
static NTSTATUS (WINAPI *pRtlGetSearchPath)(LPWSTR*);
|
||||
static void (WINAPI *pRtlReleasePath)(LPWSTR);
|
||||
static NTSTATUS (WINAPI *pLdrGetDllPath)(LPCWSTR,ULONG,LPWSTR*,LPWSTR*);
|
||||
|
||||
static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
|
||||
static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
|
||||
|
@ -2201,7 +2205,10 @@ static void init_pointers(void)
|
|||
MAKEFUNC(NeedCurrentDirectoryForExePathA);
|
||||
MAKEFUNC(NeedCurrentDirectoryForExePathW);
|
||||
MAKEFUNC(SetSearchPathMode);
|
||||
MAKEFUNC(SetDllDirectoryA);
|
||||
MAKEFUNC(AddDllDirectory);
|
||||
MAKEFUNC(RemoveDllDirectory);
|
||||
MAKEFUNC(SetDllDirectoryW);
|
||||
MAKEFUNC(SetDefaultDllDirectories);
|
||||
MAKEFUNC(ActivateActCtx);
|
||||
MAKEFUNC(CreateActCtxW);
|
||||
MAKEFUNC(DeactivateActCtx);
|
||||
|
@ -2210,6 +2217,7 @@ static void init_pointers(void)
|
|||
MAKEFUNC(CheckNameLegalDOS8Dot3W);
|
||||
MAKEFUNC(CheckNameLegalDOS8Dot3A);
|
||||
mod = GetModuleHandleA("ntdll.dll");
|
||||
MAKEFUNC(LdrGetDllPath);
|
||||
MAKEFUNC(RtlGetSearchPath);
|
||||
MAKEFUNC(RtlReleasePath);
|
||||
#undef MAKEFUNC
|
||||
|
@ -2470,12 +2478,23 @@ static void test_SetSearchPathMode(void)
|
|||
|
||||
static const WCHAR pathW[] = {'P','A','T','H',0};
|
||||
|
||||
static void build_search_path( WCHAR *buffer, UINT size, BOOL safe )
|
||||
static void build_search_path( WCHAR *buffer, UINT size, const WCHAR *dlldir, BOOL safe )
|
||||
{
|
||||
WCHAR *p;
|
||||
GetModuleFileNameW( NULL, buffer, size );
|
||||
if (!(p = wcsrchr( buffer, '\\' ))) return;
|
||||
*p++ = ';';
|
||||
if (dlldir)
|
||||
{
|
||||
lstrcpyW( p, dlldir );
|
||||
p += lstrlenW( p );
|
||||
if (*dlldir) *p++ = ';';
|
||||
}
|
||||
else if (!safe)
|
||||
{
|
||||
*p++ = '.';
|
||||
*p++ = ';';
|
||||
}
|
||||
GetSystemDirectoryW( p, buffer + size - p );
|
||||
p = buffer + lstrlenW(buffer);
|
||||
*p++ = ';';
|
||||
|
@ -2485,7 +2504,7 @@ static void build_search_path( WCHAR *buffer, UINT size, BOOL safe )
|
|||
GetWindowsDirectoryW( p, buffer + size - p );
|
||||
p = buffer + lstrlenW(buffer);
|
||||
*p++ = ';';
|
||||
if (!safe)
|
||||
if (!dlldir && safe)
|
||||
{
|
||||
*p++ = '.';
|
||||
*p++ = ';';
|
||||
|
@ -2501,7 +2520,7 @@ static BOOL path_equal( const WCHAR *path1, const WCHAR *path2 )
|
|||
if (*path1 && *path1 != '\\' && *path1 != ';') return FALSE;
|
||||
while (*path1 && (*path1 == '\\' || *path1 == ';')) path1++;
|
||||
while (*path2 && (*path2 == '\\' || *path2 == ';')) path2++;
|
||||
if (!*path1 && !*path2) return TRUE;
|
||||
if (!*path1 || !*path2) return !*path1 && !*path2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2509,7 +2528,7 @@ static void test_RtlGetSearchPath(void)
|
|||
{
|
||||
NTSTATUS ret;
|
||||
WCHAR *path;
|
||||
WCHAR buffer[2048], old_path[2048];
|
||||
WCHAR buffer[2048], old_path[2048], dlldir[4];
|
||||
|
||||
if (!pRtlGetSearchPath)
|
||||
{
|
||||
|
@ -2518,8 +2537,10 @@ static void test_RtlGetSearchPath(void)
|
|||
}
|
||||
|
||||
GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
|
||||
GetWindowsDirectoryW( buffer, ARRAY_SIZE(buffer) );
|
||||
lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
|
||||
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), FALSE );
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
|
||||
path = (WCHAR *)0xdeadbeef;
|
||||
ret = pRtlGetSearchPath( &path );
|
||||
ok( !ret, "RtlGetSearchPath failed %x\n", ret );
|
||||
|
@ -2527,23 +2548,123 @@ static void test_RtlGetSearchPath(void)
|
|||
pRtlReleasePath( path );
|
||||
|
||||
SetEnvironmentVariableA( "PATH", "foo" );
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), FALSE );
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
|
||||
path = (WCHAR *)0xdeadbeef;
|
||||
ret = pRtlGetSearchPath( &path );
|
||||
ok( !ret, "RtlGetSearchPath failed %x\n", ret );
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
|
||||
if (pSetDllDirectoryA)
|
||||
if (pSetDllDirectoryW)
|
||||
{
|
||||
ok( pSetDllDirectoryA( "c:\\" ), "SetDllDirectoryA failed\n" );
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), FALSE );
|
||||
ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
|
||||
path = (WCHAR *)0xdeadbeef;
|
||||
ret = pRtlGetSearchPath( &path );
|
||||
ok( !ret, "RtlGetSearchPath failed %x\n", ret );
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
pSetDllDirectoryA( NULL );
|
||||
pSetDllDirectoryW( NULL );
|
||||
}
|
||||
|
||||
SetEnvironmentVariableW( pathW, old_path );
|
||||
}
|
||||
|
||||
static void test_LdrGetDllPath(void)
|
||||
{
|
||||
static const WCHAR fooW[] = {'f','o','o',0};
|
||||
NTSTATUS ret;
|
||||
WCHAR *path, *unknown_ptr, *p;
|
||||
WCHAR buffer[2048], old_path[2048], dlldir[4];
|
||||
|
||||
if (!pLdrGetDllPath)
|
||||
{
|
||||
win_skip( "LdrGetDllPath isn't available\n" );
|
||||
return;
|
||||
}
|
||||
GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
|
||||
GetWindowsDirectoryW( buffer, ARRAY_SIZE(buffer) );
|
||||
lstrcpynW( dlldir, buffer, ARRAY_SIZE(dlldir) );
|
||||
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
|
||||
|
||||
path = unknown_ptr = (WCHAR *)0xdeadbeef;
|
||||
ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
|
||||
SetEnvironmentVariableA( "PATH", "foo" );
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
|
||||
ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
|
||||
if (pSetDllDirectoryW)
|
||||
{
|
||||
ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
|
||||
build_search_path( buffer, ARRAY_SIZE(buffer), dlldir, TRUE );
|
||||
ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
pSetDllDirectoryW( NULL );
|
||||
}
|
||||
|
||||
ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_SYSTEM32, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
GetSystemDirectoryW( buffer, ARRAY_SIZE(buffer) );
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
|
||||
ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
GetModuleFileNameW( NULL, buffer, ARRAY_SIZE(buffer) );
|
||||
if ((p = wcsrchr( buffer, '\\' ))) *p = 0;
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
|
||||
ret = pLdrGetDllPath( fooW, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
|
||||
ok( ret == STATUS_INVALID_PARAMETER, "LdrGetDllPath failed %x\n", ret );
|
||||
|
||||
lstrcpyW( buffer, dlldir );
|
||||
p = buffer + lstrlenW(buffer);
|
||||
*p++ = '\\';
|
||||
lstrcpyW( p, fooW );
|
||||
ret = pLdrGetDllPath( buffer, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
ok( path_equal( path, dlldir ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
|
||||
pRtlReleasePath( path );
|
||||
|
||||
if (pAddDllDirectory)
|
||||
{
|
||||
DLL_DIRECTORY_COOKIE cookie = pAddDllDirectory( dlldir );
|
||||
ok( !!cookie, "AddDllDirectory failed\n" );
|
||||
ret = pLdrGetDllPath( 0, LOAD_LIBRARY_SEARCH_USER_DIRS, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
ok( path_equal( path, dlldir ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(dlldir));
|
||||
pRtlReleasePath( path );
|
||||
pRemoveDllDirectory( cookie );
|
||||
}
|
||||
|
||||
if (pSetDefaultDllDirectories)
|
||||
{
|
||||
pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_SYSTEM32 );
|
||||
ret = pLdrGetDllPath( 0, 0, &path, &unknown_ptr );
|
||||
ok( !ret, "LdrGetDllPath failed %x\n", ret );
|
||||
ok( !unknown_ptr, "unknown ptr %p\n", unknown_ptr );
|
||||
GetSystemDirectoryW( buffer, ARRAY_SIZE(buffer) );
|
||||
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||
pRtlReleasePath( path );
|
||||
pSetDefaultDllDirectories( 0 );
|
||||
}
|
||||
|
||||
SetEnvironmentVariableW( pathW, old_path );
|
||||
|
@ -2584,4 +2705,5 @@ START_TEST(path)
|
|||
test_CheckNameLegalDOS8Dot3();
|
||||
test_SetSearchPathMode();
|
||||
test_RtlGetSearchPath();
|
||||
test_LdrGetDllPath();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
@ stdcall AddAuditAccessAce(ptr long long ptr long long)
|
||||
@ stdcall AddAuditAccessAceEx(ptr long long long ptr long long)
|
||||
@ stdcall AddAuditAccessObjectAce(ptr long long long ptr ptr ptr long long)
|
||||
@ stdcall AddDllDirectory(wstr) kernel32.AddDllDirectory
|
||||
@ stdcall AddDllDirectory(wstr)
|
||||
@ stdcall AddMandatoryAce(ptr long long long ptr)
|
||||
@ stdcall AddRefActCtx(ptr)
|
||||
# @ stub AddResourceAttributeAce
|
||||
|
@ -1333,7 +1333,7 @@
|
|||
@ stdcall RemapPredefinedHandleInternal(long long)
|
||||
@ stdcall RemoveDirectoryA(str) kernel32.RemoveDirectoryA
|
||||
@ stdcall RemoveDirectoryW(wstr) kernel32.RemoveDirectoryW
|
||||
@ stdcall RemoveDllDirectory(ptr) kernel32.RemoveDllDirectory
|
||||
@ stdcall RemoveDllDirectory(ptr)
|
||||
# @ stub RemovePackageStatus
|
||||
# @ stub RemovePackageStatusForUser
|
||||
@ stdcall RemoveVectoredContinueHandler(ptr) ntdll.RtlRemoveVectoredContinueHandler
|
||||
|
@ -1419,7 +1419,7 @@
|
|||
@ stdcall SetCriticalSectionSpinCount(ptr long) ntdll.RtlSetCriticalSectionSpinCount
|
||||
@ stdcall SetCurrentDirectoryA(str)
|
||||
@ stdcall SetCurrentDirectoryW(wstr)
|
||||
@ stdcall SetDefaultDllDirectories(long) kernel32.SetDefaultDllDirectories
|
||||
@ stdcall SetDefaultDllDirectories(long)
|
||||
# @ stub SetDynamicTimeZoneInformation
|
||||
@ stdcall SetEndOfFile(long)
|
||||
@ stub SetEnvironmentStringsW
|
||||
|
|
|
@ -42,6 +42,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(module);
|
|||
***********************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* AddDllDirectory (kernelbase.@)
|
||||
*/
|
||||
DLL_DIRECTORY_COOKIE WINAPI DECLSPEC_HOTPATCH AddDllDirectory( const WCHAR *dir )
|
||||
{
|
||||
UNICODE_STRING str;
|
||||
void *cookie;
|
||||
|
||||
RtlInitUnicodeString( &str, dir );
|
||||
if (!set_ntstatus( LdrAddDllDirectory( &str, &cookie ))) return NULL;
|
||||
return cookie;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DelayLoadFailureHook (kernelbase.@)
|
||||
*/
|
||||
|
@ -225,6 +239,24 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExW( DWORD flags, LPCWSTR name, HMO
|
|||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* RemoveDllDirectory (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH RemoveDllDirectory( DLL_DIRECTORY_COOKIE cookie )
|
||||
{
|
||||
return set_ntstatus( LdrRemoveDllDirectory( cookie ));
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* SetDefaultDllDirectories (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI DECLSPEC_HOTPATCH SetDefaultDllDirectories( DWORD flags )
|
||||
{
|
||||
return set_ntstatus( LdrSetDefaultDllDirectories( flags ));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Resources
|
||||
***********************************************************************/
|
||||
|
|
|
@ -72,13 +72,25 @@ const WCHAR system_dir[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
|
|||
static const WCHAR system_path[] =
|
||||
{'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m','3','2',';',
|
||||
'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',';',
|
||||
'C',':','\\','w','i','n','d','o','w','s',';',0};
|
||||
'C',':','\\','w','i','n','d','o','w','s',0};
|
||||
|
||||
static const WCHAR dotW[] = {'.',0};
|
||||
|
||||
static BOOL imports_fixup_done = FALSE; /* set once the imports have been fixed up, before attaching them */
|
||||
static BOOL process_detaching = FALSE; /* set on process detach to avoid deadlocks with thread detach */
|
||||
static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
|
||||
static ULONG path_safe_mode; /* path mode set by RtlSetSearchPathMode */
|
||||
static ULONG dll_safe_mode = 1; /* dll search mode */
|
||||
static UNICODE_STRING dll_directory; /* extra path for LdrSetDllDirectory */
|
||||
static DWORD default_search_flags; /* default flags set by LdrSetDefaultDllDirectories */
|
||||
|
||||
struct dll_dir_entry
|
||||
{
|
||||
struct list entry;
|
||||
WCHAR dir[1];
|
||||
};
|
||||
|
||||
static struct list dll_dir_list = LIST_INIT( dll_dir_list ); /* extra dirs from LdrAddDllDirectory */
|
||||
|
||||
struct ldr_notification
|
||||
{
|
||||
|
@ -2079,24 +2091,53 @@ static BOOL is_valid_binary( HMODULE module, const pe_image_info_t *info )
|
|||
|
||||
|
||||
/******************************************************************
|
||||
* get_dll_load_path
|
||||
* get_module_path_end
|
||||
*
|
||||
* Returns the end of the directory component of the module path.
|
||||
*/
|
||||
static NTSTATUS get_dll_load_path( LPCWSTR module, int safe_mode, WCHAR **path )
|
||||
static inline const WCHAR *get_module_path_end( const WCHAR *module )
|
||||
{
|
||||
static const WCHAR pathW[] = {'P','A','T','H',0};
|
||||
static const WCHAR dotW[] = {'.',';',0};
|
||||
|
||||
const WCHAR *p;
|
||||
const WCHAR *mod_end = module;
|
||||
UNICODE_STRING name, value;
|
||||
WCHAR *p, *ret;
|
||||
int len = ARRAY_SIZE(system_path), path_len = 0;
|
||||
|
||||
if (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;
|
||||
return mod_end;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* append_path
|
||||
*
|
||||
* Append a counted string to the load path. Helper for get_dll_load_path.
|
||||
*/
|
||||
static inline WCHAR *append_path( WCHAR *p, const WCHAR *str, int len )
|
||||
{
|
||||
if (len == -1) len = strlenW(str);
|
||||
if (!len) return p;
|
||||
memcpy( p, str, len * sizeof(WCHAR) );
|
||||
p[len] = ';';
|
||||
return p + len + 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* get_dll_load_path
|
||||
*/
|
||||
static NTSTATUS get_dll_load_path( LPCWSTR module, LPCWSTR dll_dir, ULONG safe_mode, WCHAR **path )
|
||||
{
|
||||
static const WCHAR pathW[] = {'P','A','T','H',0};
|
||||
|
||||
const WCHAR *mod_end = module;
|
||||
UNICODE_STRING name, value;
|
||||
WCHAR *p, *ret;
|
||||
int len = ARRAY_SIZE(system_path) + 1, path_len = 0;
|
||||
|
||||
if (module)
|
||||
{
|
||||
mod_end = get_module_path_end( module );
|
||||
len += (mod_end - module) + 1;
|
||||
}
|
||||
|
||||
|
@ -2107,18 +2148,18 @@ static NTSTATUS get_dll_load_path( LPCWSTR module, int safe_mode, WCHAR **path )
|
|||
if (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) == STATUS_BUFFER_TOO_SMALL)
|
||||
path_len = value.Length;
|
||||
|
||||
len += 2; /* current directory */
|
||||
if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, path_len + len * sizeof(WCHAR) )))
|
||||
if (dll_dir) len += strlenW( dll_dir ) + 1;
|
||||
else len += 2; /* current directory */
|
||||
if (!(p = ret = RtlAllocateHeap( GetProcessHeap(), 0, path_len + len * sizeof(WCHAR) )))
|
||||
return STATUS_NO_MEMORY;
|
||||
memcpy( ret, module, (mod_end - module) * sizeof(WCHAR) );
|
||||
p = ret + (mod_end - module);
|
||||
if (p > ret) *p++ = ';';
|
||||
*p = 0;
|
||||
if (!safe_mode) strcatW( ret, dotW );
|
||||
strcatW( ret, system_path );
|
||||
if (safe_mode) strcatW( ret, dotW );
|
||||
|
||||
value.Buffer = ret + strlenW(ret);
|
||||
p = append_path( p, module, mod_end - module );
|
||||
if (dll_dir) p = append_path( p, dll_dir, -1 );
|
||||
else if (!safe_mode) p = append_path( p, dotW, -1 );
|
||||
p = append_path( p, system_path, -1 );
|
||||
if (!dll_dir && safe_mode) p = append_path( p, dotW, -1 );
|
||||
|
||||
value.Buffer = p;
|
||||
value.MaximumLength = path_len;
|
||||
|
||||
while (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) == STATUS_BUFFER_TOO_SMALL)
|
||||
|
@ -2142,6 +2183,69 @@ static NTSTATUS get_dll_load_path( LPCWSTR module, int safe_mode, WCHAR **path )
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* get_dll_load_path_search_flags
|
||||
*/
|
||||
static NTSTATUS get_dll_load_path_search_flags( LPCWSTR module, DWORD flags, WCHAR **path )
|
||||
{
|
||||
const WCHAR *image = NULL, *mod_end, *image_end;
|
||||
struct dll_dir_entry *dir;
|
||||
WCHAR *p, *ret;
|
||||
int len = 1;
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)
|
||||
flags |= (LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)
|
||||
{
|
||||
DWORD type = RtlDetermineDosPathNameType_U( module );
|
||||
if (type != ABSOLUTE_DRIVE_PATH && type != ABSOLUTE_PATH)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
mod_end = get_module_path_end( module );
|
||||
len += (mod_end - module) + 1;
|
||||
}
|
||||
else module = NULL;
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
|
||||
{
|
||||
image = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||
image_end = get_module_path_end( image );
|
||||
len += (image_end - image) + 1;
|
||||
}
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_USER_DIRS)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( dir, &dll_dir_list, struct dll_dir_entry, entry )
|
||||
len += strlenW( dir->dir + 4 /* \??\ */ ) + 1;
|
||||
if (dll_directory.Length) len += dll_directory.Length / sizeof(WCHAR) + 1;
|
||||
}
|
||||
|
||||
if (flags & LOAD_LIBRARY_SEARCH_SYSTEM32) len += strlenW( system_dir );
|
||||
|
||||
if ((p = ret = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
|
||||
{
|
||||
if (module) p = append_path( p, module, mod_end - module );
|
||||
if (image) p = append_path( p, image, image_end - image );
|
||||
if (flags & LOAD_LIBRARY_SEARCH_USER_DIRS)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( dir, &dll_dir_list, struct dll_dir_entry, entry )
|
||||
p = append_path( p, dir->dir + 4 /* \??\ */, -1 );
|
||||
p = append_path( p, dll_directory.Buffer, dll_directory.Length / sizeof(WCHAR) );
|
||||
}
|
||||
if (flags & LOAD_LIBRARY_SEARCH_SYSTEM32) strcpyW( p, system_dir );
|
||||
else
|
||||
{
|
||||
if (p > ret) p--;
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
*path = ret;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* open_dll_file
|
||||
*
|
||||
|
@ -3701,6 +3805,7 @@ static void load_global_options(void)
|
|||
'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r',0};
|
||||
static const WCHAR globalflagW[] = {'G','l','o','b','a','l','F','l','a','g',0};
|
||||
static const WCHAR safesearchW[] = {'S','a','f','e','P','r','o','c','e','s','s','S','e','a','r','c','h','M','o','d','e',0};
|
||||
static const WCHAR safedllmodeW[] = {'S','a','f','e','D','l','l','S','e','a','r','c','h','M','o','d','e',0};
|
||||
static const WCHAR critsectW[] = {'C','r','i','t','i','c','a','l','S','e','c','t','i','o','n','T','i','m','e','o','u','t',0};
|
||||
static const WCHAR heapresW[] = {'H','e','a','p','S','e','g','m','e','n','t','R','e','s','e','r','v','e',0};
|
||||
static const WCHAR heapcommitW[] = {'H','e','a','p','S','e','g','m','e','n','t','C','o','m','m','i','t',0};
|
||||
|
@ -3724,6 +3829,7 @@ static void load_global_options(void)
|
|||
|
||||
query_dword_option( hkey, globalflagW, &NtCurrentTeb()->Peb->NtGlobalFlag );
|
||||
query_dword_option( hkey, safesearchW, &path_safe_mode );
|
||||
query_dword_option( hkey, safedllmodeW, &dll_safe_mode );
|
||||
|
||||
if (!query_dword_option( hkey, critsectW, &value ))
|
||||
NtCurrentTeb()->Peb->CriticalSectionTimeout.QuadPart = (ULONGLONG)value * -10000000;
|
||||
|
@ -3876,6 +3982,124 @@ NTSTATUS WINAPI LdrSetDllDirectory( const UNICODE_STRING *dir )
|
|||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* LdrAddDllDirectory (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI LdrAddDllDirectory( const UNICODE_STRING *dir, void **cookie )
|
||||
{
|
||||
FILE_BASIC_INFORMATION info;
|
||||
UNICODE_STRING nt_name;
|
||||
NTSTATUS status;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
DWORD len;
|
||||
struct dll_dir_entry *ptr;
|
||||
DOS_PATHNAME_TYPE type = RtlDetermineDosPathNameType_U( dir->Buffer );
|
||||
|
||||
if (type != ABSOLUTE_PATH && type != ABSOLUTE_DRIVE_PATH)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
status = RtlDosPathNameToNtPathName_U_WithStatus( dir->Buffer, &nt_name, NULL, NULL );
|
||||
if (status) return status;
|
||||
len = nt_name.Length / sizeof(WCHAR);
|
||||
if (!(ptr = RtlAllocateHeap( GetProcessHeap(), 0, offsetof(struct dll_dir_entry, dir[++len] ))))
|
||||
return STATUS_NO_MEMORY;
|
||||
memcpy( ptr->dir, nt_name.Buffer, len * sizeof(WCHAR) );
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
attr.ObjectName = &nt_name;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
status = NtQueryAttributesFile( &attr, &info );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
|
||||
if (!status)
|
||||
{
|
||||
TRACE( "%s\n", debugstr_w( ptr->dir ));
|
||||
RtlEnterCriticalSection( &dlldir_section );
|
||||
list_add_head( &dll_dir_list, &ptr->entry );
|
||||
RtlLeaveCriticalSection( &dlldir_section );
|
||||
*cookie = ptr;
|
||||
}
|
||||
else RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* LdrRemoveDllDirectory (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI LdrRemoveDllDirectory( void *cookie )
|
||||
{
|
||||
struct dll_dir_entry *ptr = cookie;
|
||||
|
||||
TRACE( "%s\n", debugstr_w( ptr->dir ));
|
||||
|
||||
RtlEnterCriticalSection( &dlldir_section );
|
||||
list_remove( &ptr->entry );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
RtlLeaveCriticalSection( &dlldir_section );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* LdrSetDefaultDllDirectories (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI LdrSetDefaultDllDirectories( ULONG flags )
|
||||
{
|
||||
/* LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR doesn't make sense in default dirs */
|
||||
const ULONG load_library_search_flags = (LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32 |
|
||||
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
|
||||
if (!flags || (flags & ~load_library_search_flags)) return STATUS_INVALID_PARAMETER;
|
||||
default_search_flags = flags;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* LdrGetDllPath (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI LdrGetDllPath( PCWSTR module, ULONG flags, PWSTR *path, PWSTR *unknown )
|
||||
{
|
||||
NTSTATUS status;
|
||||
const ULONG load_library_search_flags = (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
|
||||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR |
|
||||
LOAD_LIBRARY_SEARCH_USER_DIRS |
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32 |
|
||||
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
|
||||
if (flags & LOAD_WITH_ALTERED_SEARCH_PATH)
|
||||
{
|
||||
if (flags & load_library_search_flags) return STATUS_INVALID_PARAMETER;
|
||||
if (default_search_flags) flags |= default_search_flags | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
|
||||
}
|
||||
else if (!(flags & load_library_search_flags)) flags |= default_search_flags;
|
||||
|
||||
RtlEnterCriticalSection( &dlldir_section );
|
||||
|
||||
if (flags & load_library_search_flags)
|
||||
{
|
||||
status = get_dll_load_path_search_flags( module, flags, path );
|
||||
}
|
||||
else
|
||||
{
|
||||
const WCHAR *dlldir = dll_directory.Length ? dll_directory.Buffer : NULL;
|
||||
if (!(flags & LOAD_WITH_ALTERED_SEARCH_PATH))
|
||||
module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||
status = get_dll_load_path( module, dlldir, dll_safe_mode, path );
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection( &dlldir_section );
|
||||
*unknown = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* RtlSetSearchPathMode (NTDLL.@)
|
||||
*/
|
||||
|
@ -3913,8 +4137,8 @@ NTSTATUS WINAPI RtlSetSearchPathMode( ULONG flags )
|
|||
*/
|
||||
NTSTATUS WINAPI RtlGetSearchPath( PWSTR *path )
|
||||
{
|
||||
WCHAR *module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||
return get_dll_load_path( module, path_safe_mode, path );
|
||||
const WCHAR *module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||
return get_dll_load_path( module, NULL, path_safe_mode, path );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
@ stub KiUserExceptionDispatcher
|
||||
# @ stub LdrAccessOutOfProcessResource
|
||||
@ stdcall LdrAccessResource(long ptr ptr ptr)
|
||||
@ stdcall LdrAddDllDirectory(ptr ptr)
|
||||
@ stdcall LdrAddRefDll(long ptr)
|
||||
# @ stub LdrAlternateResourcesEnabled
|
||||
# @ stub LdrCreateOutOfProcessImage
|
||||
|
@ -84,9 +85,10 @@
|
|||
# @ stub LdrFindResourceEx_U
|
||||
@ stdcall LdrFindResource_U(long ptr long ptr)
|
||||
@ stub LdrFlushAlternateResourceModules
|
||||
@ stdcall LdrGetDllDirectory(ptr)
|
||||
@ stdcall LdrGetDllHandle(wstr long ptr ptr)
|
||||
# @ stub LdrGetDllHandleEx
|
||||
@ stdcall LdrGetDllDirectory(ptr)
|
||||
@ stdcall LdrGetDllPath(wstr long ptr ptr)
|
||||
@ stdcall LdrGetProcedureAddress(ptr ptr long ptr)
|
||||
# @ stub LdrHotPatchRoutine
|
||||
@ stub LdrInitShimEngineDynamic
|
||||
|
@ -98,8 +100,10 @@
|
|||
@ stdcall LdrQueryImageFileExecutionOptions(ptr wstr long ptr long ptr)
|
||||
@ stdcall LdrQueryProcessModuleInformation(ptr long ptr)
|
||||
@ stdcall LdrRegisterDllNotification(long ptr ptr ptr)
|
||||
@ stdcall LdrRemoveDllDirectory(ptr)
|
||||
@ stdcall LdrResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long)
|
||||
@ stub LdrSetAppCompatDllRedirectionCallback
|
||||
@ stdcall LdrSetDefaultDllDirectories(long)
|
||||
@ stdcall LdrSetDllDirectory(ptr)
|
||||
@ stub LdrSetDllManifestProber
|
||||
@ stdcall LdrShutdownProcess()
|
||||
|
|
|
@ -2309,6 +2309,7 @@ NTSYSAPI NTSTATUS WINAPI DbgUiIssueRemoteBreakin(HANDLE);
|
|||
NTSYSAPI void WINAPI DbgUiRemoteBreakin(void*);
|
||||
NTSYSAPI void WINAPI DbgUserBreakPoint(void);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrAccessResource(HMODULE,const IMAGE_RESOURCE_DATA_ENTRY*,void**,PULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrAddDllDirectory(const UNICODE_STRING*,void**);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrAddRefDll(ULONG,HMODULE);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrFindEntryForAddress(const void*, PLDR_MODULE*);
|
||||
|
@ -2316,12 +2317,15 @@ NTSYSAPI NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_
|
|||
NTSYSAPI NTSTATUS WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrGetDllDirectory(UNICODE_STRING*);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrGetDllPath(PCWSTR,ULONG,PWSTR*,PWSTR*);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrLockLoaderLock(ULONG,ULONG*,ULONG_PTR*);
|
||||
IMAGE_BASE_RELOCATION * WINAPI LdrProcessRelocationBlock(void*,UINT,USHORT*,INT_PTR);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrQueryImageFileExecutionOptions(const UNICODE_STRING*,LPCWSTR,ULONG,void*,ULONG,ULONG*);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, ULONG, ULONG*);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrRemoveDllDirectory(void*);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrSetDefaultDllDirectories(ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI LdrSetDllDirectory(const UNICODE_STRING*);
|
||||
NTSYSAPI void WINAPI LdrShutdownProcess(void);
|
||||
NTSYSAPI void WINAPI LdrShutdownThread(void);
|
||||
|
|
Loading…
Reference in New Issue