forked from Mirrors/wine-wine
kernel32: Move dll path functions to ntdll.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>stable
parent
b8ba4909ee
commit
619bd16e7a
|
@ -140,7 +140,7 @@
|
||||||
@ stdcall AddAtomW(wstr)
|
@ stdcall AddAtomW(wstr)
|
||||||
@ stdcall AddConsoleAliasA(str str str)
|
@ stdcall AddConsoleAliasA(str str str)
|
||||||
@ stdcall AddConsoleAliasW(wstr wstr wstr)
|
@ stdcall AddConsoleAliasW(wstr wstr wstr)
|
||||||
@ stdcall AddDllDirectory(wstr)
|
@ stdcall -import AddDllDirectory(wstr)
|
||||||
# @ stub AddIntegrityLabelToBoundaryDescriptor
|
# @ stub AddIntegrityLabelToBoundaryDescriptor
|
||||||
# @ stub AddLocalAlternateComputerNameA
|
# @ stub AddLocalAlternateComputerNameA
|
||||||
# @ stub AddLocalAlternateComputerNameW
|
# @ stub AddLocalAlternateComputerNameW
|
||||||
|
@ -1274,7 +1274,7 @@
|
||||||
@ stdcall ReplaceFileW(wstr wstr wstr long ptr ptr)
|
@ stdcall ReplaceFileW(wstr wstr wstr long ptr ptr)
|
||||||
# @ stub RemoveDirectoryTransactedA
|
# @ stub RemoveDirectoryTransactedA
|
||||||
# @ stub RemoveDirectoryTransactedW
|
# @ stub RemoveDirectoryTransactedW
|
||||||
@ stdcall RemoveDllDirectory(ptr)
|
@ stdcall -import RemoveDllDirectory(ptr)
|
||||||
# @ stub RemoveSecureMemoryCacheCallback
|
# @ stub RemoveSecureMemoryCacheCallback
|
||||||
# @ stub ReplacePartitionUnit
|
# @ stub ReplacePartitionUnit
|
||||||
@ stdcall RequestDeviceWakeup(long)
|
@ stdcall RequestDeviceWakeup(long)
|
||||||
|
@ -1379,7 +1379,7 @@
|
||||||
@ stub SetDaylightFlag
|
@ stub SetDaylightFlag
|
||||||
@ stdcall SetDefaultCommConfigA(str ptr long)
|
@ stdcall SetDefaultCommConfigA(str ptr long)
|
||||||
@ stdcall SetDefaultCommConfigW(wstr ptr long)
|
@ stdcall SetDefaultCommConfigW(wstr ptr long)
|
||||||
@ stdcall SetDefaultDllDirectories(long)
|
@ stdcall -import SetDefaultDllDirectories(long)
|
||||||
@ stdcall SetDllDirectoryA(str)
|
@ stdcall SetDllDirectoryA(str)
|
||||||
@ stdcall SetDllDirectoryW(wstr)
|
@ stdcall SetDllDirectoryW(wstr)
|
||||||
# @ stub SetDynamicTimeZoneInformation
|
# @ 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 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;
|
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;
|
extern BOOL NLS_IsUnicodeOnlyLcid(LCID) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* environ.c */
|
/* environ.c */
|
||||||
|
|
|
@ -49,15 +49,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(module);
|
||||||
|
|
||||||
#define NE_FFLAGS_LIBMODULE 0x8000
|
#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 */
|
/* to keep track of LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE file handles */
|
||||||
struct exclusive_datafile
|
struct exclusive_datafile
|
||||||
{
|
{
|
||||||
|
@ -67,15 +58,6 @@ struct exclusive_datafile
|
||||||
};
|
};
|
||||||
static struct list exclusive_datafile_list = LIST_INIT( exclusive_datafile_list );
|
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.@)
|
* 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.@]
|
* GetBinaryTypeW [KERNEL32.@]
|
||||||
*
|
*
|
||||||
|
@ -368,293 +283,10 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
|
||||||
return GetBinaryTypeW(NtCurrentTeb()->StaticUnicodeString.Buffer, 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
|
* 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};
|
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 (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 );
|
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;
|
NTSTATUS nts;
|
||||||
HMODULE hModule;
|
HMODULE hModule;
|
||||||
WCHAR *load_path;
|
WCHAR *load_path, *dummy;
|
||||||
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);
|
|
||||||
const DWORD unsupported_flags = (LOAD_IGNORE_CODE_AUTHZ_LEVEL |
|
const DWORD unsupported_flags = (LOAD_IGNORE_CODE_AUTHZ_LEVEL |
|
||||||
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);
|
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);
|
||||||
|
|
||||||
if( flags & unsupported_flags)
|
if( flags & unsupported_flags)
|
||||||
FIXME("unsupported flag(s) used (flags: 0x%08x)\n", flags);
|
FIXME("unsupported flag(s) used (flags: 0x%08x)\n", flags);
|
||||||
|
|
||||||
if (flags & LOAD_WITH_ALTERED_SEARCH_PATH)
|
if (!set_ntstatus( LdrGetDllPath( libname->Buffer, flags, &load_path, &dummy ))) return 0;
|
||||||
{
|
|
||||||
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 (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
|
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 );
|
LdrUnlockLoaderLock( 0, magic );
|
||||||
goto done;
|
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 );
|
LdrUnlockLoaderLock( 0, magic );
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -780,7 +392,7 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
|
||||||
SetLastError( RtlNtStatusToDosError( nts ) );
|
SetLastError( RtlNtStatusToDosError( nts ) );
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
HeapFree( GetProcessHeap(), 0, load_path );
|
RtlReleasePath( load_path );
|
||||||
return hModule;
|
return hModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1373,6 +1373,7 @@ void * CDECL __wine_kernel_init(void)
|
||||||
RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters;
|
RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters;
|
||||||
HANDLE boot_events[2];
|
HANDLE boot_events[2];
|
||||||
BOOL got_environment = TRUE;
|
BOOL got_environment = TRUE;
|
||||||
|
WCHAR *load_path, *dummy;
|
||||||
|
|
||||||
/* Initialize everything */
|
/* Initialize everything */
|
||||||
|
|
||||||
|
@ -1429,8 +1430,8 @@ void * CDECL __wine_kernel_init(void)
|
||||||
TRACE( "starting process name=%s argv[0]=%s\n",
|
TRACE( "starting process name=%s argv[0]=%s\n",
|
||||||
debugstr_w(main_exe_name), debugstr_w(__wine_main_wargv[0]) );
|
debugstr_w(main_exe_name), debugstr_w(__wine_main_wargv[0]) );
|
||||||
|
|
||||||
RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath,
|
LdrGetDllPath( main_exe_name, 0, &load_path, &dummy );
|
||||||
MODULE_get_dll_load_path( main_exe_name, -1 ));
|
RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath, load_path );
|
||||||
|
|
||||||
if (boot_events[0])
|
if (boot_events[0])
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,10 +73,14 @@ static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
|
||||||
static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
|
static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
|
||||||
static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
|
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 *pSetSearchPathMode)(DWORD);
|
||||||
static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
|
static BOOL (WINAPI *pSetDllDirectoryW)(LPCWSTR);
|
||||||
|
static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
|
||||||
static NTSTATUS (WINAPI *pRtlGetSearchPath)(LPWSTR*);
|
static NTSTATUS (WINAPI *pRtlGetSearchPath)(LPWSTR*);
|
||||||
static void (WINAPI *pRtlReleasePath)(LPWSTR);
|
static void (WINAPI *pRtlReleasePath)(LPWSTR);
|
||||||
|
static NTSTATUS (WINAPI *pLdrGetDllPath)(LPCWSTR,ULONG,LPWSTR*,LPWSTR*);
|
||||||
|
|
||||||
static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
|
static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
|
||||||
static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
|
static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
|
||||||
|
@ -2201,7 +2205,10 @@ static void init_pointers(void)
|
||||||
MAKEFUNC(NeedCurrentDirectoryForExePathA);
|
MAKEFUNC(NeedCurrentDirectoryForExePathA);
|
||||||
MAKEFUNC(NeedCurrentDirectoryForExePathW);
|
MAKEFUNC(NeedCurrentDirectoryForExePathW);
|
||||||
MAKEFUNC(SetSearchPathMode);
|
MAKEFUNC(SetSearchPathMode);
|
||||||
MAKEFUNC(SetDllDirectoryA);
|
MAKEFUNC(AddDllDirectory);
|
||||||
|
MAKEFUNC(RemoveDllDirectory);
|
||||||
|
MAKEFUNC(SetDllDirectoryW);
|
||||||
|
MAKEFUNC(SetDefaultDllDirectories);
|
||||||
MAKEFUNC(ActivateActCtx);
|
MAKEFUNC(ActivateActCtx);
|
||||||
MAKEFUNC(CreateActCtxW);
|
MAKEFUNC(CreateActCtxW);
|
||||||
MAKEFUNC(DeactivateActCtx);
|
MAKEFUNC(DeactivateActCtx);
|
||||||
|
@ -2210,6 +2217,7 @@ static void init_pointers(void)
|
||||||
MAKEFUNC(CheckNameLegalDOS8Dot3W);
|
MAKEFUNC(CheckNameLegalDOS8Dot3W);
|
||||||
MAKEFUNC(CheckNameLegalDOS8Dot3A);
|
MAKEFUNC(CheckNameLegalDOS8Dot3A);
|
||||||
mod = GetModuleHandleA("ntdll.dll");
|
mod = GetModuleHandleA("ntdll.dll");
|
||||||
|
MAKEFUNC(LdrGetDllPath);
|
||||||
MAKEFUNC(RtlGetSearchPath);
|
MAKEFUNC(RtlGetSearchPath);
|
||||||
MAKEFUNC(RtlReleasePath);
|
MAKEFUNC(RtlReleasePath);
|
||||||
#undef MAKEFUNC
|
#undef MAKEFUNC
|
||||||
|
@ -2470,12 +2478,23 @@ static void test_SetSearchPathMode(void)
|
||||||
|
|
||||||
static const WCHAR pathW[] = {'P','A','T','H',0};
|
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;
|
WCHAR *p;
|
||||||
GetModuleFileNameW( NULL, buffer, size );
|
GetModuleFileNameW( NULL, buffer, size );
|
||||||
if (!(p = wcsrchr( buffer, '\\' ))) return;
|
if (!(p = wcsrchr( buffer, '\\' ))) return;
|
||||||
*p++ = ';';
|
*p++ = ';';
|
||||||
|
if (dlldir)
|
||||||
|
{
|
||||||
|
lstrcpyW( p, dlldir );
|
||||||
|
p += lstrlenW( p );
|
||||||
|
if (*dlldir) *p++ = ';';
|
||||||
|
}
|
||||||
|
else if (!safe)
|
||||||
|
{
|
||||||
|
*p++ = '.';
|
||||||
|
*p++ = ';';
|
||||||
|
}
|
||||||
GetSystemDirectoryW( p, buffer + size - p );
|
GetSystemDirectoryW( p, buffer + size - p );
|
||||||
p = buffer + lstrlenW(buffer);
|
p = buffer + lstrlenW(buffer);
|
||||||
*p++ = ';';
|
*p++ = ';';
|
||||||
|
@ -2485,7 +2504,7 @@ static void build_search_path( WCHAR *buffer, UINT size, BOOL safe )
|
||||||
GetWindowsDirectoryW( p, buffer + size - p );
|
GetWindowsDirectoryW( p, buffer + size - p );
|
||||||
p = buffer + lstrlenW(buffer);
|
p = buffer + lstrlenW(buffer);
|
||||||
*p++ = ';';
|
*p++ = ';';
|
||||||
if (!safe)
|
if (!dlldir && safe)
|
||||||
{
|
{
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
*p++ = ';';
|
*p++ = ';';
|
||||||
|
@ -2501,7 +2520,7 @@ static BOOL path_equal( const WCHAR *path1, const WCHAR *path2 )
|
||||||
if (*path1 && *path1 != '\\' && *path1 != ';') return FALSE;
|
if (*path1 && *path1 != '\\' && *path1 != ';') return FALSE;
|
||||||
while (*path1 && (*path1 == '\\' || *path1 == ';')) path1++;
|
while (*path1 && (*path1 == '\\' || *path1 == ';')) path1++;
|
||||||
while (*path2 && (*path2 == '\\' || *path2 == ';')) path2++;
|
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;
|
NTSTATUS ret;
|
||||||
WCHAR *path;
|
WCHAR *path;
|
||||||
WCHAR buffer[2048], old_path[2048];
|
WCHAR buffer[2048], old_path[2048], dlldir[4];
|
||||||
|
|
||||||
if (!pRtlGetSearchPath)
|
if (!pRtlGetSearchPath)
|
||||||
{
|
{
|
||||||
|
@ -2518,8 +2537,10 @@ static void test_RtlGetSearchPath(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
GetEnvironmentVariableW( pathW, old_path, ARRAY_SIZE(old_path) );
|
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;
|
path = (WCHAR *)0xdeadbeef;
|
||||||
ret = pRtlGetSearchPath( &path );
|
ret = pRtlGetSearchPath( &path );
|
||||||
ok( !ret, "RtlGetSearchPath failed %x\n", ret );
|
ok( !ret, "RtlGetSearchPath failed %x\n", ret );
|
||||||
|
@ -2527,23 +2548,123 @@ static void test_RtlGetSearchPath(void)
|
||||||
pRtlReleasePath( path );
|
pRtlReleasePath( path );
|
||||||
|
|
||||||
SetEnvironmentVariableA( "PATH", "foo" );
|
SetEnvironmentVariableA( "PATH", "foo" );
|
||||||
build_search_path( buffer, ARRAY_SIZE(buffer), FALSE );
|
build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
|
||||||
path = (WCHAR *)0xdeadbeef;
|
path = (WCHAR *)0xdeadbeef;
|
||||||
ret = pRtlGetSearchPath( &path );
|
ret = pRtlGetSearchPath( &path );
|
||||||
ok( !ret, "RtlGetSearchPath failed %x\n", ret );
|
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));
|
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||||
pRtlReleasePath( path );
|
pRtlReleasePath( path );
|
||||||
|
|
||||||
if (pSetDllDirectoryA)
|
if (pSetDllDirectoryW)
|
||||||
{
|
{
|
||||||
ok( pSetDllDirectoryA( "c:\\" ), "SetDllDirectoryA failed\n" );
|
ok( pSetDllDirectoryW( dlldir ), "SetDllDirectoryW failed\n" );
|
||||||
build_search_path( buffer, ARRAY_SIZE(buffer), FALSE );
|
build_search_path( buffer, ARRAY_SIZE(buffer), NULL, TRUE );
|
||||||
path = (WCHAR *)0xdeadbeef;
|
path = (WCHAR *)0xdeadbeef;
|
||||||
ret = pRtlGetSearchPath( &path );
|
ret = pRtlGetSearchPath( &path );
|
||||||
ok( !ret, "RtlGetSearchPath failed %x\n", ret );
|
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));
|
ok( path_equal( path, buffer ), "got %s expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(buffer));
|
||||||
pRtlReleasePath( path );
|
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 );
|
SetEnvironmentVariableW( pathW, old_path );
|
||||||
|
@ -2584,4 +2705,5 @@ START_TEST(path)
|
||||||
test_CheckNameLegalDOS8Dot3();
|
test_CheckNameLegalDOS8Dot3();
|
||||||
test_SetSearchPathMode();
|
test_SetSearchPathMode();
|
||||||
test_RtlGetSearchPath();
|
test_RtlGetSearchPath();
|
||||||
|
test_LdrGetDllPath();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
@ stdcall AddAuditAccessAce(ptr long long ptr long long)
|
@ stdcall AddAuditAccessAce(ptr long long ptr long long)
|
||||||
@ stdcall AddAuditAccessAceEx(ptr long 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 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 AddMandatoryAce(ptr long long long ptr)
|
||||||
@ stdcall AddRefActCtx(ptr)
|
@ stdcall AddRefActCtx(ptr)
|
||||||
# @ stub AddResourceAttributeAce
|
# @ stub AddResourceAttributeAce
|
||||||
|
@ -1333,7 +1333,7 @@
|
||||||
@ stdcall RemapPredefinedHandleInternal(long long)
|
@ stdcall RemapPredefinedHandleInternal(long long)
|
||||||
@ stdcall RemoveDirectoryA(str) kernel32.RemoveDirectoryA
|
@ stdcall RemoveDirectoryA(str) kernel32.RemoveDirectoryA
|
||||||
@ stdcall RemoveDirectoryW(wstr) kernel32.RemoveDirectoryW
|
@ stdcall RemoveDirectoryW(wstr) kernel32.RemoveDirectoryW
|
||||||
@ stdcall RemoveDllDirectory(ptr) kernel32.RemoveDllDirectory
|
@ stdcall RemoveDllDirectory(ptr)
|
||||||
# @ stub RemovePackageStatus
|
# @ stub RemovePackageStatus
|
||||||
# @ stub RemovePackageStatusForUser
|
# @ stub RemovePackageStatusForUser
|
||||||
@ stdcall RemoveVectoredContinueHandler(ptr) ntdll.RtlRemoveVectoredContinueHandler
|
@ stdcall RemoveVectoredContinueHandler(ptr) ntdll.RtlRemoveVectoredContinueHandler
|
||||||
|
@ -1419,7 +1419,7 @@
|
||||||
@ stdcall SetCriticalSectionSpinCount(ptr long) ntdll.RtlSetCriticalSectionSpinCount
|
@ stdcall SetCriticalSectionSpinCount(ptr long) ntdll.RtlSetCriticalSectionSpinCount
|
||||||
@ stdcall SetCurrentDirectoryA(str)
|
@ stdcall SetCurrentDirectoryA(str)
|
||||||
@ stdcall SetCurrentDirectoryW(wstr)
|
@ stdcall SetCurrentDirectoryW(wstr)
|
||||||
@ stdcall SetDefaultDllDirectories(long) kernel32.SetDefaultDllDirectories
|
@ stdcall SetDefaultDllDirectories(long)
|
||||||
# @ stub SetDynamicTimeZoneInformation
|
# @ stub SetDynamicTimeZoneInformation
|
||||||
@ stdcall SetEndOfFile(long)
|
@ stdcall SetEndOfFile(long)
|
||||||
@ stub SetEnvironmentStringsW
|
@ 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.@)
|
* 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
|
* Resources
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
|
@ -72,13 +72,25 @@ const WCHAR system_dir[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
|
||||||
static const WCHAR system_path[] =
|
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','3','2',';',
|
||||||
'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',';',
|
'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 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 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 int free_lib_count; /* recursion depth of LdrUnloadDll calls */
|
||||||
static ULONG path_safe_mode; /* path mode set by RtlSetSearchPathMode */
|
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 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
|
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};
|
const WCHAR *p;
|
||||||
static const WCHAR dotW[] = {'.',';',0};
|
|
||||||
|
|
||||||
const WCHAR *mod_end = module;
|
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 ((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 + 2 && module[1] == ':') mod_end++;
|
||||||
if (mod_end == module && module[0] && module[1] == ':') mod_end += 2;
|
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;
|
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)
|
if (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) == STATUS_BUFFER_TOO_SMALL)
|
||||||
path_len = value.Length;
|
path_len = value.Length;
|
||||||
|
|
||||||
len += 2; /* current directory */
|
if (dll_dir) len += strlenW( dll_dir ) + 1;
|
||||||
if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, path_len + len * sizeof(WCHAR) )))
|
else len += 2; /* current directory */
|
||||||
|
if (!(p = ret = RtlAllocateHeap( GetProcessHeap(), 0, path_len + len * sizeof(WCHAR) )))
|
||||||
return STATUS_NO_MEMORY;
|
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;
|
value.MaximumLength = path_len;
|
||||||
|
|
||||||
while (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) == STATUS_BUFFER_TOO_SMALL)
|
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
|
* 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};
|
'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 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 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 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 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};
|
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, globalflagW, &NtCurrentTeb()->Peb->NtGlobalFlag );
|
||||||
query_dword_option( hkey, safesearchW, &path_safe_mode );
|
query_dword_option( hkey, safesearchW, &path_safe_mode );
|
||||||
|
query_dword_option( hkey, safedllmodeW, &dll_safe_mode );
|
||||||
|
|
||||||
if (!query_dword_option( hkey, critsectW, &value ))
|
if (!query_dword_option( hkey, critsectW, &value ))
|
||||||
NtCurrentTeb()->Peb->CriticalSectionTimeout.QuadPart = (ULONGLONG)value * -10000000;
|
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.@)
|
* RtlSetSearchPathMode (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -3913,8 +4137,8 @@ NTSTATUS WINAPI RtlSetSearchPathMode( ULONG flags )
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI RtlGetSearchPath( PWSTR *path )
|
NTSTATUS WINAPI RtlGetSearchPath( PWSTR *path )
|
||||||
{
|
{
|
||||||
WCHAR *module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
const WCHAR *module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
|
||||||
return get_dll_load_path( module, path_safe_mode, path );
|
return get_dll_load_path( module, NULL, path_safe_mode, path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
@ stub KiUserExceptionDispatcher
|
@ stub KiUserExceptionDispatcher
|
||||||
# @ stub LdrAccessOutOfProcessResource
|
# @ stub LdrAccessOutOfProcessResource
|
||||||
@ stdcall LdrAccessResource(long ptr ptr ptr)
|
@ stdcall LdrAccessResource(long ptr ptr ptr)
|
||||||
|
@ stdcall LdrAddDllDirectory(ptr ptr)
|
||||||
@ stdcall LdrAddRefDll(long ptr)
|
@ stdcall LdrAddRefDll(long ptr)
|
||||||
# @ stub LdrAlternateResourcesEnabled
|
# @ stub LdrAlternateResourcesEnabled
|
||||||
# @ stub LdrCreateOutOfProcessImage
|
# @ stub LdrCreateOutOfProcessImage
|
||||||
|
@ -84,9 +85,10 @@
|
||||||
# @ stub LdrFindResourceEx_U
|
# @ stub LdrFindResourceEx_U
|
||||||
@ stdcall LdrFindResource_U(long ptr long ptr)
|
@ stdcall LdrFindResource_U(long ptr long ptr)
|
||||||
@ stub LdrFlushAlternateResourceModules
|
@ stub LdrFlushAlternateResourceModules
|
||||||
|
@ stdcall LdrGetDllDirectory(ptr)
|
||||||
@ stdcall LdrGetDllHandle(wstr long ptr ptr)
|
@ stdcall LdrGetDllHandle(wstr long ptr ptr)
|
||||||
# @ stub LdrGetDllHandleEx
|
# @ stub LdrGetDllHandleEx
|
||||||
@ stdcall LdrGetDllDirectory(ptr)
|
@ stdcall LdrGetDllPath(wstr long ptr ptr)
|
||||||
@ stdcall LdrGetProcedureAddress(ptr ptr long ptr)
|
@ stdcall LdrGetProcedureAddress(ptr ptr long ptr)
|
||||||
# @ stub LdrHotPatchRoutine
|
# @ stub LdrHotPatchRoutine
|
||||||
@ stub LdrInitShimEngineDynamic
|
@ stub LdrInitShimEngineDynamic
|
||||||
|
@ -98,8 +100,10 @@
|
||||||
@ stdcall LdrQueryImageFileExecutionOptions(ptr wstr long ptr long ptr)
|
@ stdcall LdrQueryImageFileExecutionOptions(ptr wstr long ptr long ptr)
|
||||||
@ stdcall LdrQueryProcessModuleInformation(ptr long ptr)
|
@ stdcall LdrQueryProcessModuleInformation(ptr long ptr)
|
||||||
@ stdcall LdrRegisterDllNotification(long ptr ptr ptr)
|
@ stdcall LdrRegisterDllNotification(long ptr ptr ptr)
|
||||||
|
@ stdcall LdrRemoveDllDirectory(ptr)
|
||||||
@ stdcall LdrResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long)
|
@ stdcall LdrResolveDelayLoadedAPI(ptr ptr ptr ptr ptr long)
|
||||||
@ stub LdrSetAppCompatDllRedirectionCallback
|
@ stub LdrSetAppCompatDllRedirectionCallback
|
||||||
|
@ stdcall LdrSetDefaultDllDirectories(long)
|
||||||
@ stdcall LdrSetDllDirectory(ptr)
|
@ stdcall LdrSetDllDirectory(ptr)
|
||||||
@ stub LdrSetDllManifestProber
|
@ stub LdrSetDllManifestProber
|
||||||
@ stdcall LdrShutdownProcess()
|
@ stdcall LdrShutdownProcess()
|
||||||
|
|
|
@ -2309,6 +2309,7 @@ NTSYSAPI NTSTATUS WINAPI DbgUiIssueRemoteBreakin(HANDLE);
|
||||||
NTSYSAPI void WINAPI DbgUiRemoteBreakin(void*);
|
NTSYSAPI void WINAPI DbgUiRemoteBreakin(void*);
|
||||||
NTSYSAPI void WINAPI DbgUserBreakPoint(void);
|
NTSYSAPI void WINAPI DbgUserBreakPoint(void);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrAccessResource(HMODULE,const IMAGE_RESOURCE_DATA_ENTRY*,void**,PULONG);
|
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 LdrAddRefDll(ULONG,HMODULE);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE);
|
NTSYSAPI NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrFindEntryForAddress(const void*, PLDR_MODULE*);
|
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 LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrGetDllDirectory(UNICODE_STRING*);
|
NTSYSAPI NTSTATUS WINAPI LdrGetDllDirectory(UNICODE_STRING*);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*);
|
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 LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
|
NTSYSAPI NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrLockLoaderLock(ULONG,ULONG*,ULONG_PTR*);
|
NTSYSAPI NTSTATUS WINAPI LdrLockLoaderLock(ULONG,ULONG*,ULONG_PTR*);
|
||||||
IMAGE_BASE_RELOCATION * WINAPI LdrProcessRelocationBlock(void*,UINT,USHORT*,INT_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 LdrQueryImageFileExecutionOptions(const UNICODE_STRING*,LPCWSTR,ULONG,void*,ULONG,ULONG*);
|
||||||
NTSYSAPI NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, 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 NTSTATUS WINAPI LdrSetDllDirectory(const UNICODE_STRING*);
|
||||||
NTSYSAPI void WINAPI LdrShutdownProcess(void);
|
NTSYSAPI void WINAPI LdrShutdownProcess(void);
|
||||||
NTSYSAPI void WINAPI LdrShutdownThread(void);
|
NTSYSAPI void WINAPI LdrShutdownThread(void);
|
||||||
|
|
Loading…
Reference in New Issue