kernel32: Move dll path functions to ntdll.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-10-03 14:14:36 +02:00
parent b8ba4909ee
commit 619bd16e7a
10 changed files with 436 additions and 440 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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])
{

View File

@ -73,10 +73,14 @@ static DWORD (WINAPI *pGetLongPathNameW)(LPWSTR,LPWSTR,DWORD);
static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
static BOOL (WINAPI *pNeedCurrentDirectoryForExePathW)(LPCWSTR);
static BOOL (WINAPI *pSetSearchPathMode)(DWORD);
static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
static DLL_DIRECTORY_COOKIE (WINAPI *pAddDllDirectory)(const WCHAR*);
static BOOL (WINAPI *pRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
static BOOL (WINAPI *pSetSearchPathMode)(DWORD);
static BOOL (WINAPI *pSetDllDirectoryW)(LPCWSTR);
static BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
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 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();
}

View File

@ -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

View File

@ -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
***********************************************************************/

View File

@ -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
{
@ -2078,25 +2090,54 @@ static BOOL is_valid_binary( HMODULE module, const pe_image_info_t *info )
}
/******************************************************************
* 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 ((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, int safe_mode, WCHAR **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};
static const WCHAR dotW[] = {'.',';',0};
const WCHAR *mod_end = module;
UNICODE_STRING name, value;
WCHAR *p, *ret;
int len = ARRAY_SIZE(system_path), path_len = 0;
int len = ARRAY_SIZE(system_path) + 1, 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;
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 );
}

View File

@ -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()

View File

@ -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);