Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
41057a17
Commit
41057a17
authored
Sep 11, 2013
by
Nikolay Sivov
Committed by
Alexandre Julliard
Sep 12, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Support activation context in SearchPath().
parent
ce81f080
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
195 additions
and
12 deletions
+195
-12
path.c
dlls/kernel32/path.c
+153
-7
path.c
dlls/kernel32/tests/path.c
+42
-5
No files found.
dlls/kernel32/path.c
View file @
41057a17
...
...
@@ -724,6 +724,97 @@ static inline BOOL contains_pathW (LPCWSTR name)
return
(
name
[
1
]
==
'.'
&&
(
name
[
2
]
==
'/'
||
name
[
2
]
==
'\\'
));
}
/***********************************************************************
* find_actctx_dllpath
*
* Find the path (if any) of the dll from the activation context.
* Returned path doesn't include a name.
*/
static
NTSTATUS
find_actctx_dllpath
(
const
WCHAR
*
libname
,
WCHAR
**
path
)
{
static
const
WCHAR
winsxsW
[]
=
{
'\\'
,
'w'
,
'i'
,
'n'
,
's'
,
'x'
,
's'
,
'\\'
};
static
const
WCHAR
dotManifestW
[]
=
{
'.'
,
'm'
,
'a'
,
'n'
,
'i'
,
'f'
,
'e'
,
's'
,
't'
,
0
};
ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION
*
info
;
ACTCTX_SECTION_KEYED_DATA
data
;
UNICODE_STRING
nameW
;
NTSTATUS
status
;
SIZE_T
needed
,
size
=
1024
;
WCHAR
*
p
;
RtlInitUnicodeString
(
&
nameW
,
libname
);
data
.
cbSize
=
sizeof
(
data
);
status
=
RtlFindActivationContextSectionString
(
FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
,
NULL
,
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION
,
&
nameW
,
&
data
);
if
(
status
!=
STATUS_SUCCESS
)
return
status
;
for
(;;)
{
if
(
!
(
info
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
)))
{
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
status
=
RtlQueryInformationActivationContext
(
0
,
data
.
hActCtx
,
&
data
.
ulAssemblyRosterIndex
,
AssemblyDetailedInformationInActivationContext
,
info
,
size
,
&
needed
);
if
(
status
==
STATUS_SUCCESS
)
break
;
if
(
status
!=
STATUS_BUFFER_TOO_SMALL
)
goto
done
;
HeapFree
(
GetProcessHeap
(),
0
,
info
);
size
=
needed
;
/* restart with larger buffer */
}
if
(
!
info
->
lpAssemblyManifestPath
||
!
info
->
lpAssemblyDirectoryName
)
{
status
=
STATUS_SXS_KEY_NOT_FOUND
;
goto
done
;
}
if
((
p
=
strrchrW
(
info
->
lpAssemblyManifestPath
,
'\\'
)))
{
DWORD
dirlen
=
info
->
ulAssemblyDirectoryNameLength
/
sizeof
(
WCHAR
);
p
++
;
if
(
strncmpiW
(
p
,
info
->
lpAssemblyDirectoryName
,
dirlen
)
||
strcmpiW
(
p
+
dirlen
,
dotManifestW
))
{
/* manifest name does not match directory name, so it's not a global
* windows/winsxs manifest; use the manifest directory name instead */
dirlen
=
p
-
info
->
lpAssemblyManifestPath
;
needed
=
(
dirlen
+
1
)
*
sizeof
(
WCHAR
);
if
(
!
(
*
path
=
p
=
HeapAlloc
(
GetProcessHeap
(),
0
,
needed
)))
{
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
memcpy
(
p
,
info
->
lpAssemblyManifestPath
,
dirlen
*
sizeof
(
WCHAR
)
);
*
(
p
+
dirlen
)
=
0
;
goto
done
;
}
}
needed
=
(
strlenW
(
DIR_Windows
)
*
sizeof
(
WCHAR
)
+
sizeof
(
winsxsW
)
+
info
->
ulAssemblyDirectoryNameLength
+
2
*
sizeof
(
WCHAR
));
if
(
!
(
*
path
=
p
=
HeapAlloc
(
GetProcessHeap
(),
0
,
needed
)))
{
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
strcpyW
(
p
,
DIR_Windows
);
p
+=
strlenW
(
p
);
memcpy
(
p
,
winsxsW
,
sizeof
(
winsxsW
)
);
p
+=
sizeof
(
winsxsW
)
/
sizeof
(
WCHAR
);
memcpy
(
p
,
info
->
lpAssemblyDirectoryName
,
info
->
ulAssemblyDirectoryNameLength
);
p
+=
info
->
ulAssemblyDirectoryNameLength
/
sizeof
(
WCHAR
);
*
p
++
=
'\\'
;
*
p
=
0
;
done:
HeapFree
(
GetProcessHeap
(),
0
,
info
);
RtlReleaseActivationContext
(
data
.
hActCtx
);
return
status
;
}
/***********************************************************************
* SearchPathW [KERNEL32.@]
...
...
@@ -802,20 +893,75 @@ DWORD WINAPI SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext, DWORD buflen,
ret
=
RtlDosSearchPath_U
(
path
,
name
,
ext
,
buflen
*
sizeof
(
WCHAR
),
buffer
,
lastpart
)
/
sizeof
(
WCHAR
);
}
else
/* search in
the
default path */
else
/* search in
active context and
default path */
{
WCHAR
*
dll_path
=
MODULE_get_dll_load_path
(
NULL
);
WCHAR
*
dll_path
=
NULL
,
*
search
=
NULL
;
DWORD
req_len
,
name_len
;
if
(
dll_path
)
req_len
=
name_len
=
strlenW
(
name
);
if
(
strchrW
(
name
,
'.'
))
ext
=
NULL
;
if
(
ext
)
{
ret
=
RtlDosSearchPath_U
(
dll_path
,
name
,
ext
,
buflen
*
sizeof
(
WCHAR
),
buffer
,
lastpart
)
/
sizeof
(
WCHAR
);
DWORD
ext_len
=
strlenW
(
ext
);
req_len
+=
ext_len
;
name_len
+=
ext_len
;
search
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
name_len
+
ext_len
+
1
)
*
sizeof
(
WCHAR
)
);
if
(
!
search
)
{
SetLastError
(
ERROR_OUTOFMEMORY
);
HeapFree
(
GetProcessHeap
(),
0
,
dll_path
);
return
0
;
}
strcpyW
(
search
,
name
);
strcatW
(
search
,
ext
);
name
=
search
;
/* now that we have combined name we don't need extension any more */
}
/* When file is found with activation context no attempt is made
to check if it's really exist, path is returned only basing on context info. */
if
(
find_actctx_dllpath
(
name
,
&
dll_path
)
==
STATUS_SUCCESS
)
{
DWORD
path_len
;
path_len
=
strlenW
(
dll_path
);
req_len
+=
path_len
;
if
(
lastpart
)
*
lastpart
=
NULL
;
/* count null termination char too */
if
(
req_len
+
1
<=
buflen
)
{
memcpy
(
buffer
,
dll_path
,
path_len
*
sizeof
(
WCHAR
)
);
memcpy
(
&
buffer
[
path_len
],
name
,
name_len
*
sizeof
(
WCHAR
)
);
buffer
[
req_len
]
=
0
;
if
(
lastpart
)
*
lastpart
=
buffer
+
path_len
;
ret
=
req_len
;
}
else
ret
=
req_len
+
1
;
HeapFree
(
GetProcessHeap
(),
0
,
dll_path
);
HeapFree
(
GetProcessHeap
(),
0
,
search
);
}
else
{
SetLastError
(
ERROR_OUTOFMEMORY
);
return
0
;
if
((
dll_path
=
MODULE_get_dll_load_path
(
NULL
)))
{
ret
=
RtlDosSearchPath_U
(
dll_path
,
name
,
NULL
,
buflen
*
sizeof
(
WCHAR
),
buffer
,
lastpart
)
/
sizeof
(
WCHAR
);
HeapFree
(
GetProcessHeap
(),
0
,
dll_path
);
HeapFree
(
GetProcessHeap
(),
0
,
search
);
}
else
{
SetLastError
(
ERROR_OUTOFMEMORY
);
return
0
;
}
}
}
...
...
dlls/kernel32/tests/path.c
View file @
41057a17
...
...
@@ -1639,6 +1639,7 @@ static HANDLE test_create(const char *file)
static
void
test_SearchPathA
(
void
)
{
static
const
CHAR
testdepA
[]
=
"testdep.dll"
;
static
const
CHAR
testdeprelA
[]
=
"./testdep.dll"
;
static
const
CHAR
kernel32A
[]
=
"kernel32.dll"
;
static
const
CHAR
fileA
[]
=
""
;
CHAR
pathA
[
MAX_PATH
],
buffA
[
MAX_PATH
],
path2A
[
MAX_PATH
];
...
...
@@ -1691,13 +1692,28 @@ static void test_SearchPathA(void)
/* works when activated */
ret
=
pSearchPathA
(
NULL
,
testdepA
,
NULL
,
sizeof
(
buffA
)
/
sizeof
(
CHAR
),
buffA
,
NULL
);
todo_wine
ok
(
ret
&&
ret
==
strlen
(
buffA
),
"got %d
\n
"
,
ret
);
/* path is redirect for wellknown names too */
ret
=
pSearchPathA
(
NULL
,
"testdep.dll"
,
".ext"
,
sizeof
(
buffA
)
/
sizeof
(
CHAR
),
buffA
,
NULL
);
ok
(
ret
&&
ret
==
strlen
(
buffA
),
"got %d
\n
"
,
ret
);
ret
=
pSearchPathA
(
NULL
,
"testdep"
,
".dll"
,
sizeof
(
buffA
)
/
sizeof
(
CHAR
),
buffA
,
NULL
);
ok
(
ret
&&
ret
==
strlen
(
buffA
),
"got %d
\n
"
,
ret
);
ret
=
pSearchPathA
(
NULL
,
"testdep"
,
".ext"
,
sizeof
(
buffA
)
/
sizeof
(
CHAR
),
buffA
,
NULL
);
ok
(
!
ret
,
"got %d
\n
"
,
ret
);
/* name contains path */
ret
=
pSearchPathA
(
NULL
,
testdeprelA
,
NULL
,
sizeof
(
buffA
)
/
sizeof
(
CHAR
),
buffA
,
NULL
);
ok
(
!
ret
,
"got %d
\n
"
,
ret
);
/* fails with specified path that doesn't contain this file */
ret
=
pSearchPathA
(
pathA
,
testdepA
,
NULL
,
sizeof
(
buffA
)
/
sizeof
(
CHAR
),
buffA
,
NULL
);
ok
(
!
ret
,
"got %d
\n
"
,
ret
);
/* path is redirected for wellknown names too */
ret
=
pSearchPathA
(
NULL
,
kernel32A
,
NULL
,
sizeof
(
buffA
)
/
sizeof
(
CHAR
),
buffA
,
NULL
);
ok
(
ret
&&
ret
==
strlen
(
buffA
),
"got %d
\n
"
,
ret
);
todo_wine
ok
(
strcmp
(
buffA
,
path2A
),
"got wrong path %s, %s
\n
"
,
buffA
,
path2A
);
ret
=
pDeactivateActCtx
(
0
,
cookie
);
...
...
@@ -1707,8 +1723,12 @@ todo_wine
static
void
test_SearchPathW
(
void
)
{
static
const
WCHAR
testdeprelW
[]
=
{
'.'
,
'/'
,
't'
,
'e'
,
's'
,
't'
,
'd'
,
'e'
,
'p'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
};
static
const
WCHAR
testdepW
[]
=
{
't'
,
'e'
,
's'
,
't'
,
'd'
,
'e'
,
'p'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
};
static
const
WCHAR
testdep1W
[]
=
{
't'
,
'e'
,
's'
,
't'
,
'd'
,
'e'
,
'p'
,
0
};
static
const
WCHAR
kernel32W
[]
=
{
'k'
,
'e'
,
'r'
,
'n'
,
'e'
,
'l'
,
'3'
,
'2'
,
'.'
,
'd'
,
'l'
,
'l'
,
0
};
static
const
WCHAR
extW
[]
=
{
'.'
,
'e'
,
'x'
,
't'
,
0
};
static
const
WCHAR
dllW
[]
=
{
'.'
,
'd'
,
'l'
,
'l'
,
0
};
static
const
WCHAR
fileW
[]
=
{
0
};
WCHAR
pathW
[
MAX_PATH
],
buffW
[
MAX_PATH
],
path2W
[
MAX_PATH
];
WCHAR
*
ptrW
=
NULL
;
...
...
@@ -1728,6 +1748,8 @@ if (0)
pSearchPathW
(
pathW
,
NULL
,
NULL
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
&
ptrW
);
}
GetWindowsDirectoryW
(
pathW
,
sizeof
(
pathW
)
/
sizeof
(
WCHAR
));
/* empty filename */
SetLastError
(
0xdeadbeef
);
ret
=
pSearchPathW
(
pathW
,
fileW
,
NULL
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
&
ptrW
);
...
...
@@ -1757,13 +1779,28 @@ if (0)
/* works when activated */
ret
=
pSearchPathW
(
NULL
,
testdepW
,
NULL
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
NULL
);
todo_wine
ok
(
ret
&&
ret
==
lstrlenW
(
buffW
),
"got %d
\n
"
,
ret
);
ret
=
pSearchPathW
(
NULL
,
testdepW
,
extW
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
NULL
);
ok
(
ret
&&
ret
==
lstrlenW
(
buffW
),
"got %d
\n
"
,
ret
);
ret
=
pSearchPathW
(
NULL
,
testdep1W
,
dllW
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
NULL
);
ok
(
ret
&&
ret
==
lstrlenW
(
buffW
),
"got %d
\n
"
,
ret
);
ret
=
pSearchPathW
(
NULL
,
testdep1W
,
extW
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
NULL
);
ok
(
!
ret
,
"got %d
\n
"
,
ret
);
/* name contains path */
ret
=
pSearchPathW
(
NULL
,
testdeprelW
,
NULL
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
NULL
);
ok
(
!
ret
,
"got %d
\n
"
,
ret
);
/* fails with specified path that doesn't contain this file */
ret
=
pSearchPathW
(
pathW
,
testdepW
,
NULL
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
NULL
);
ok
(
!
ret
,
"got %d
\n
"
,
ret
);
/* path is redirect for wellknown names too */
ret
=
pSearchPathW
(
NULL
,
kernel32W
,
NULL
,
sizeof
(
buffW
)
/
sizeof
(
WCHAR
),
buffW
,
NULL
);
ok
(
ret
&&
ret
==
lstrlenW
(
buffW
),
"got %d
\n
"
,
ret
);
todo_wine
ok
(
lstrcmpW
(
buffW
,
path2W
),
"got wrong path %s, %s
\n
"
,
wine_dbgstr_w
(
buffW
),
wine_dbgstr_w
(
path2W
));
ret
=
pDeactivateActCtx
(
0
,
cookie
);
...
...
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