Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
5f938bb5
Commit
5f938bb5
authored
Oct 01, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement RtlGetSearchPath().
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
444933ae
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
189 additions
and
4 deletions
+189
-4
path.c
dlls/kernel32/tests/path.c
+95
-3
loader.c
dlls/ntdll/loader.c
+89
-0
ntdll.spec
dlls/ntdll/ntdll.spec
+2
-0
winternl.h
include/winternl.h
+3
-1
No files found.
dlls/kernel32/tests/path.c
View file @
5f938bb5
...
...
@@ -22,12 +22,15 @@
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include "wine/test.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winuser.h"
#include "winerror.h"
#include "winnls.h"
#include "wine/test.h"
#define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')
...
...
@@ -71,6 +74,9 @@ static BOOL (WINAPI *pNeedCurrentDirectoryForExePathA)(LPCSTR);
static
BOOL
(
WINAPI
*
pNeedCurrentDirectoryForExePathW
)(
LPCWSTR
);
static
BOOL
(
WINAPI
*
pSetSearchPathMode
)(
DWORD
);
static
BOOL
(
WINAPI
*
pSetDllDirectoryA
)(
LPCSTR
);
static
NTSTATUS
(
WINAPI
*
pRtlGetSearchPath
)(
LPWSTR
*
);
static
void
(
WINAPI
*
pRtlReleasePath
)(
LPWSTR
);
static
BOOL
(
WINAPI
*
pActivateActCtx
)(
HANDLE
,
ULONG_PTR
*
);
static
HANDLE
(
WINAPI
*
pCreateActCtxW
)(
PCACTCTXW
);
...
...
@@ -2187,14 +2193,15 @@ static void test_GetFullPathNameW(void)
static
void
init_pointers
(
void
)
{
HMODULE
hKernel32
=
GetModuleHandleA
(
"kernel32.dll"
);
HMODULE
mod
=
GetModuleHandleA
(
"kernel32.dll"
);
#define MAKEFUNC(f) (p##f = (void*)GetProcAddress(
hKernel32
, #f))
#define MAKEFUNC(f) (p##f = (void*)GetProcAddress(
mod
, #f))
MAKEFUNC
(
GetLongPathNameA
);
MAKEFUNC
(
GetLongPathNameW
);
MAKEFUNC
(
NeedCurrentDirectoryForExePathA
);
MAKEFUNC
(
NeedCurrentDirectoryForExePathW
);
MAKEFUNC
(
SetSearchPathMode
);
MAKEFUNC
(
SetDllDirectoryA
);
MAKEFUNC
(
ActivateActCtx
);
MAKEFUNC
(
CreateActCtxW
);
MAKEFUNC
(
DeactivateActCtx
);
...
...
@@ -2202,6 +2209,9 @@ static void init_pointers(void)
MAKEFUNC
(
ReleaseActCtx
);
MAKEFUNC
(
CheckNameLegalDOS8Dot3W
);
MAKEFUNC
(
CheckNameLegalDOS8Dot3A
);
mod
=
GetModuleHandleA
(
"ntdll.dll"
);
MAKEFUNC
(
RtlGetSearchPath
);
MAKEFUNC
(
RtlReleasePath
);
#undef MAKEFUNC
}
...
...
@@ -2458,6 +2468,87 @@ static void test_SetSearchPathMode(void)
RemoveDirectoryA
(
dir
);
}
static
const
WCHAR
pathW
[]
=
{
'P'
,
'A'
,
'T'
,
'H'
,
0
};
static
void
build_search_path
(
WCHAR
*
buffer
,
UINT
size
,
BOOL
safe
)
{
WCHAR
*
p
;
GetModuleFileNameW
(
NULL
,
buffer
,
size
);
if
(
!
(
p
=
wcsrchr
(
buffer
,
'\\'
)))
return
;
*
p
++
=
';'
;
GetSystemDirectoryW
(
p
,
buffer
+
size
-
p
);
p
=
buffer
+
lstrlenW
(
buffer
);
*
p
++
=
';'
;
GetSystemDirectoryW
(
p
,
buffer
+
size
-
p
);
p
=
buffer
+
lstrlenW
(
buffer
)
-
2
;
/* remove "32" */
*
p
++
=
';'
;
GetWindowsDirectoryW
(
p
,
buffer
+
size
-
p
);
p
=
buffer
+
lstrlenW
(
buffer
);
*
p
++
=
';'
;
if
(
!
safe
)
{
*
p
++
=
'.'
;
*
p
++
=
';'
;
}
GetEnvironmentVariableW
(
pathW
,
p
,
buffer
+
size
-
p
);
}
static
BOOL
path_equal
(
const
WCHAR
*
path1
,
const
WCHAR
*
path2
)
{
for
(;;)
{
while
(
*
path1
&&
towlower
(
*
path1
)
==
towlower
(
*
path2
))
{
path1
++
;
path2
++
;
}
if
(
*
path1
&&
*
path1
!=
'\\'
&&
*
path1
!=
';'
)
return
FALSE
;
while
(
*
path1
&&
(
*
path1
==
'\\'
||
*
path1
==
';'
))
path1
++
;
while
(
*
path2
&&
(
*
path2
==
'\\'
||
*
path2
==
';'
))
path2
++
;
if
(
!*
path1
&&
!*
path2
)
return
TRUE
;
}
}
static
void
test_RtlGetSearchPath
(
void
)
{
NTSTATUS
ret
;
WCHAR
*
path
;
WCHAR
buffer
[
2048
],
old_path
[
2048
];
if
(
!
pRtlGetSearchPath
)
{
win_skip
(
"RtlGetSearchPath isn't available
\n
"
);
return
;
}
GetEnvironmentVariableW
(
pathW
,
old_path
,
ARRAY_SIZE
(
old_path
)
);
build_search_path
(
buffer
,
ARRAY_SIZE
(
buffer
),
FALSE
);
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
);
SetEnvironmentVariableA
(
"PATH"
,
"foo"
);
build_search_path
(
buffer
,
ARRAY_SIZE
(
buffer
),
FALSE
);
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
)
{
ok
(
pSetDllDirectoryA
(
"c:
\\
"
),
"SetDllDirectoryA failed
\n
"
);
build_search_path
(
buffer
,
ARRAY_SIZE
(
buffer
),
FALSE
);
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
);
}
SetEnvironmentVariableW
(
pathW
,
old_path
);
}
START_TEST
(
path
)
{
CHAR
origdir
[
MAX_PATH
],
curdir
[
MAX_PATH
],
curDrive
,
otherDrive
;
...
...
@@ -2492,4 +2583,5 @@ START_TEST(path)
test_GetFullPathNameW
();
test_CheckNameLegalDOS8Dot3
();
test_SetSearchPathMode
();
test_RtlGetSearchPath
();
}
dlls/ntdll/loader.c
View file @
5f938bb5
...
...
@@ -68,6 +68,12 @@ typedef void (CALLBACK *LDRENUMPROC)(LDR_MODULE *, void *, BOOLEAN *);
const
WCHAR
system_dir
[]
=
{
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
'\\'
,
0
};
/* system search 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'
,
';'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
';'
,
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 */
...
...
@@ -2062,6 +2068,70 @@ static BOOL is_valid_binary( HMODULE module, const pe_image_info_t *info )
}
/******************************************************************
* get_dll_load_path
*/
static
NTSTATUS
get_dll_load_path
(
LPCWSTR
module
,
int
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
;
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
;
len
+=
(
mod_end
-
module
)
+
1
;
}
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
;
len
+=
2
;
/* current directory */
if
(
!
(
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
);
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
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
ret
,
path_len
+
len
*
sizeof
(
WCHAR
)
)))
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
ret
);
return
STATUS_NO_MEMORY
;
}
value
.
Buffer
=
new_ptr
+
(
value
.
Buffer
-
ret
);
value
.
MaximumLength
=
path_len
;
ret
=
new_ptr
;
}
value
.
Buffer
[
value
.
Length
/
sizeof
(
WCHAR
)]
=
0
;
*
path
=
ret
;
return
STATUS_SUCCESS
;
}
/***********************************************************************
* open_dll_file
*
...
...
@@ -3789,6 +3859,25 @@ NTSTATUS WINAPI RtlSetSearchPathMode( ULONG flags )
}
/******************************************************************
* RtlGetSearchPath (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlGetSearchPath
(
PWSTR
*
path
)
{
WCHAR
*
module
=
NtCurrentTeb
()
->
Peb
->
ProcessParameters
->
ImagePathName
.
Buffer
;
return
get_dll_load_path
(
module
,
path_safe_mode
,
path
);
}
/******************************************************************
* RtlReleasePath (NTDLL.@)
*/
void
WINAPI
RtlReleasePath
(
PWSTR
path
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
path
);
}
/***********************************************************************
* NtLoadDriver (NTDLL.@)
* ZwLoadDriver (NTDLL.@)
...
...
dlls/ntdll/ntdll.spec
View file @
5f938bb5
...
...
@@ -700,6 +700,7 @@
@ stdcall RtlGetProductInfo(long long long long ptr)
@ stdcall RtlGetProcessHeaps(long ptr)
@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)
@ stdcall RtlGetSearchPath(ptr)
# @ stub RtlGetSecurityDescriptorRMControl
# @ stub RtlGetSetBootStatusData
@ stdcall -ret64 RtlGetSystemTimePrecise()
...
...
@@ -879,6 +880,7 @@
@ stdcall RtlRegisterWait(ptr ptr ptr ptr long long)
@ stdcall RtlReleaseActivationContext(ptr)
@ stub RtlReleaseMemoryStream
@ stdcall RtlReleasePath(ptr)
@ stdcall RtlReleasePebLock()
@ stdcall RtlReleaseRelativeName(ptr)
@ stdcall RtlReleaseResource(ptr)
...
...
include/winternl.h
View file @
5f938bb5
...
...
@@ -2728,9 +2728,10 @@ NTSYSAPI ULONG WINAPI RtlGetNtGlobalFlags(void);
NTSYSAPI
BOOLEAN
WINAPI
RtlGetNtProductType
(
LPDWORD
);
NTSYSAPI
NTSTATUS
WINAPI
RtlGetOwnerSecurityDescriptor
(
PSECURITY_DESCRIPTOR
,
PSID
*
,
PBOOLEAN
);
NTSYSAPI
ULONG
WINAPI
RtlGetProcessHeaps
(
ULONG
,
HANDLE
*
);
NTSYSAPI
DWORD
WINAPI
RtlGetThreadErrorMode
(
void
);
NTSYSAPI
NTSTATUS
WINAPI
RtlGetSaclSecurityDescriptor
(
PSECURITY_DESCRIPTOR
,
PBOOLEAN
,
PACL
*
,
PBOOLEAN
);
NTSYSAPI
NTSTATUS
WINAPI
RtlGetSearchPath
(
PWSTR
*
);
NTSYSAPI
LONGLONG
WINAPI
RtlGetSystemTimePrecise
(
void
);
NTSYSAPI
DWORD
WINAPI
RtlGetThreadErrorMode
(
void
);
NTSYSAPI
NTSTATUS
WINAPI
RtlGetVersion
(
RTL_OSVERSIONINFOEXW
*
);
NTSYSAPI
NTSTATUS
WINAPI
RtlGUIDFromString
(
PUNICODE_STRING
,
GUID
*
);
NTSYSAPI
PSID_IDENTIFIER_AUTHORITY
WINAPI
RtlIdentifierAuthoritySid
(
PSID
);
...
...
@@ -2812,6 +2813,7 @@ NTSYSAPI ULONG WINAPI RtlRandom(PULONG);
NTSYSAPI
PVOID
WINAPI
RtlReAllocateHeap
(
HANDLE
,
ULONG
,
PVOID
,
SIZE_T
);
NTSYSAPI
NTSTATUS
WINAPI
RtlRegisterWait
(
PHANDLE
,
HANDLE
,
RTL_WAITORTIMERCALLBACKFUNC
,
PVOID
,
ULONG
,
ULONG
);
NTSYSAPI
void
WINAPI
RtlReleaseActivationContext
(
HANDLE
);
NTSYSAPI
void
WINAPI
RtlReleasePath
(
PWSTR
);
NTSYSAPI
void
WINAPI
RtlReleasePebLock
(
void
);
NTSYSAPI
void
WINAPI
RtlReleaseResource
(
LPRTL_RWLOCK
);
NTSYSAPI
void
WINAPI
RtlReleaseSRWLockExclusive
(
RTL_SRWLOCK
*
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment