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
a458f3e5
Commit
a458f3e5
authored
Feb 07, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Support loading a builtin dll by specifying an explicit path to
the .so file.
parent
5d5695a2
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
34 deletions
+107
-34
loader.c
dlls/ntdll/loader.c
+107
-34
No files found.
dlls/ntdll/loader.c
View file @
a458f3e5
...
@@ -77,6 +77,7 @@ typedef struct _wine_modref
...
@@ -77,6 +77,7 @@ typedef struct _wine_modref
struct
builtin_load_info
struct
builtin_load_info
{
{
const
WCHAR
*
load_path
;
const
WCHAR
*
load_path
;
const
WCHAR
*
filename
;
NTSTATUS
status
;
NTSTATUS
status
;
WINE_MODREF
*
wm
;
WINE_MODREF
*
wm
;
};
};
...
@@ -1194,6 +1195,48 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
...
@@ -1194,6 +1195,48 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
/***********************************************************************
/***********************************************************************
* get_builtin_fullname
*
* Build the full pathname for a builtin dll.
*/
static
WCHAR
*
get_builtin_fullname
(
const
WCHAR
*
path
,
const
char
*
filename
)
{
static
const
WCHAR
soW
[]
=
{
'.'
,
's'
,
'o'
,
0
};
WCHAR
*
p
,
*
fullname
;
size_t
i
,
len
=
strlen
(
filename
);
/* check if path can correspond to the dll we have */
if
(
path
&&
(
p
=
strrchrW
(
path
,
'\\'
)))
{
p
++
;
for
(
i
=
0
;
i
<
len
;
i
++
)
if
(
tolowerW
(
p
[
i
])
!=
tolowerW
(
(
WCHAR
)
filename
[
i
])
)
break
;
if
(
i
==
len
&&
(
!
p
[
len
]
||
!
strcmpiW
(
p
+
len
,
soW
)))
{
/* the filename matches, use path as the full path */
len
+=
p
-
path
;
if
((
fullname
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
{
memcpy
(
fullname
,
path
,
len
*
sizeof
(
WCHAR
)
);
fullname
[
len
]
=
0
;
}
return
fullname
;
}
}
if
((
fullname
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
system_dir
.
MaximumLength
+
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
{
memcpy
(
fullname
,
system_dir
.
Buffer
,
system_dir
.
Length
);
p
=
fullname
+
system_dir
.
Length
/
sizeof
(
WCHAR
);
if
(
p
>
fullname
&&
p
[
-
1
]
!=
'\\'
)
*
p
++
=
'\\'
;
ascii_to_unicode
(
p
,
filename
,
len
+
1
);
}
return
fullname
;
}
/***********************************************************************
* load_builtin_callback
* load_builtin_callback
*
*
* Load a library in memory; callback function for wine_dll_register
* Load a library in memory; callback function for wine_dll_register
...
@@ -1204,7 +1247,7 @@ static void load_builtin_callback( void *module, const char *filename )
...
@@ -1204,7 +1247,7 @@ static void load_builtin_callback( void *module, const char *filename )
void
*
addr
;
void
*
addr
;
IMAGE_NT_HEADERS
*
nt
;
IMAGE_NT_HEADERS
*
nt
;
WINE_MODREF
*
wm
;
WINE_MODREF
*
wm
;
WCHAR
*
fullname
,
*
p
;
WCHAR
*
fullname
;
const
WCHAR
*
load_path
;
const
WCHAR
*
load_path
;
if
(
!
module
)
if
(
!
module
)
...
@@ -1233,17 +1276,12 @@ static void load_builtin_callback( void *module, const char *filename )
...
@@ -1233,17 +1276,12 @@ static void load_builtin_callback( void *module, const char *filename )
/* create the MODREF */
/* create the MODREF */
if
(
!
(
fullname
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
if
(
!
(
fullname
=
get_builtin_fullname
(
builtin_load_info
->
filename
,
filename
)))
system_dir
.
MaximumLength
+
(
strlen
(
filename
)
+
1
)
*
sizeof
(
WCHAR
)
)))
{
{
ERR
(
"can't load %s
\n
"
,
filename
);
ERR
(
"can't load %s
\n
"
,
filename
);
builtin_load_info
->
status
=
STATUS_NO_MEMORY
;
builtin_load_info
->
status
=
STATUS_NO_MEMORY
;
return
;
return
;
}
}
memcpy
(
fullname
,
system_dir
.
Buffer
,
system_dir
.
Length
);
p
=
fullname
+
system_dir
.
Length
/
sizeof
(
WCHAR
);
if
(
p
>
fullname
&&
p
[
-
1
]
!=
'\\'
)
*
p
++
=
'\\'
;
ascii_to_unicode
(
p
,
filename
,
strlen
(
filename
)
+
1
);
wm
=
alloc_module
(
module
,
fullname
);
wm
=
alloc_module
(
module
,
fullname
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
fullname
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
fullname
);
...
@@ -1385,13 +1423,14 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
...
@@ -1385,13 +1423,14 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file,
/***********************************************************************
/***********************************************************************
* load_builtin_dll
* load_builtin_dll
*/
*/
static
NTSTATUS
load_builtin_dll
(
LPCWSTR
load_path
,
LPCWSTR
path
,
DWORD
flags
,
WINE_MODREF
**
pwm
)
static
NTSTATUS
load_builtin_dll
(
LPCWSTR
load_path
,
LPCWSTR
path
,
HANDLE
file
,
DWORD
flags
,
WINE_MODREF
**
pwm
)
{
{
char
error
[
256
],
dllname
[
MAX_PATH
];
char
error
[
256
],
dllname
[
MAX_PATH
];
int
file_exists
;
int
file_exists
;
const
WCHAR
*
name
,
*
p
;
const
WCHAR
*
name
,
*
p
;
DWORD
len
,
i
;
DWORD
len
,
i
;
void
*
handle
;
void
*
handle
=
NULL
;
struct
builtin_load_info
info
,
*
prev_info
;
struct
builtin_load_info
info
,
*
prev_info
;
/* Fix the name in case we have a full path and extension */
/* Fix the name in case we have a full path and extension */
...
@@ -1399,28 +1438,53 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, DWORD flags,
...
@@ -1399,28 +1438,53 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, DWORD flags,
if
((
p
=
strrchrW
(
name
,
'\\'
)))
name
=
p
+
1
;
if
((
p
=
strrchrW
(
name
,
'\\'
)))
name
=
p
+
1
;
if
((
p
=
strrchrW
(
name
,
'/'
)))
name
=
p
+
1
;
if
((
p
=
strrchrW
(
name
,
'/'
)))
name
=
p
+
1
;
/* we don't want to depend on the current codepage here */
len
=
strlenW
(
name
)
+
1
;
if
(
len
>=
sizeof
(
dllname
))
return
STATUS_NAME_TOO_LONG
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
name
[
i
]
>
127
)
return
STATUS_DLL_NOT_FOUND
;
dllname
[
i
]
=
(
char
)
name
[
i
];
if
(
dllname
[
i
]
>=
'A'
&&
dllname
[
i
]
<=
'Z'
)
dllname
[
i
]
+=
'a'
-
'A'
;
}
/* load_library will modify info.status. Note also that load_library can be
/* load_library will modify info.status. Note also that load_library can be
* called several times, if the .so file we're loading has dependencies.
* called several times, if the .so file we're loading has dependencies.
* info.status will gather all the errors we may get while loading all these
* info.status will gather all the errors we may get while loading all these
* libraries
* libraries
*/
*/
info
.
load_path
=
load_path
;
info
.
load_path
=
load_path
;
info
.
filename
=
NULL
;
info
.
status
=
STATUS_SUCCESS
;
info
.
status
=
STATUS_SUCCESS
;
info
.
wm
=
NULL
;
info
.
wm
=
NULL
;
prev_info
=
builtin_load_info
;
builtin_load_info
=
&
info
;
if
(
file
)
/* we have a real file, try to load it */
handle
=
wine_dll_load
(
dllname
,
error
,
sizeof
(
error
),
&
file_exists
);
{
builtin_load_info
=
prev_info
;
UNICODE_STRING
nt_name
;
ANSI_STRING
unix_name
;
if
(
!
RtlDosPathNameToNtPathName_U
(
path
,
&
nt_name
,
NULL
,
NULL
))
return
STATUS_DLL_NOT_FOUND
;
if
(
!
wine_nt_to_unix_file_name
(
&
nt_name
,
&
unix_name
,
FILE_OPEN
,
FALSE
))
{
file_exists
=
1
;
prev_info
=
builtin_load_info
;
info
.
filename
=
nt_name
.
Buffer
+
4
;
/* skip \??\ */
builtin_load_info
=
&
info
;
handle
=
wine_dlopen
(
unix_name
.
Buffer
,
RTLD_NOW
,
error
,
sizeof
(
error
)
);
builtin_load_info
=
prev_info
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
unix_name
.
Buffer
);
}
RtlFreeUnicodeString
(
&
nt_name
);
}
else
{
/* we don't want to depend on the current codepage here */
len
=
strlenW
(
name
)
+
1
;
if
(
len
>=
sizeof
(
dllname
))
return
STATUS_NAME_TOO_LONG
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
name
[
i
]
>
127
)
return
STATUS_DLL_NOT_FOUND
;
dllname
[
i
]
=
(
char
)
name
[
i
];
if
(
dllname
[
i
]
>=
'A'
&&
dllname
[
i
]
<=
'Z'
)
dllname
[
i
]
+=
'a'
-
'A'
;
}
prev_info
=
builtin_load_info
;
builtin_load_info
=
&
info
;
handle
=
wine_dll_load
(
dllname
,
error
,
sizeof
(
error
),
&
file_exists
);
builtin_load_info
=
prev_info
;
}
if
(
!
handle
)
if
(
!
handle
)
{
{
...
@@ -1449,10 +1513,16 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, DWORD flags,
...
@@ -1449,10 +1513,16 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, DWORD flags,
info
.
wm
->
ldr
.
SectionHandle
=
handle
;
info
.
wm
->
ldr
.
SectionHandle
=
handle
;
if
(
strcmpiW
(
info
.
wm
->
ldr
.
BaseDllName
.
Buffer
,
name
))
if
(
strcmpiW
(
info
.
wm
->
ldr
.
BaseDllName
.
Buffer
,
name
))
{
{
ERR
(
"loaded .so for %s but got %s instead - probably 16-bit dll
\n
"
,
/* check without .so extension */
debugstr_w
(
name
),
debugstr_w
(
info
.
wm
->
ldr
.
BaseDllName
.
Buffer
)
);
static
const
WCHAR
soW
[]
=
{
'.'
,
's'
,
'o'
,
0
};
/* wine_dll_unload( handle );*/
DWORD
len
=
info
.
wm
->
ldr
.
BaseDllName
.
Length
/
sizeof
(
WCHAR
);
return
STATUS_INVALID_IMAGE_FORMAT
;
if
(
strncmpiW
(
info
.
wm
->
ldr
.
BaseDllName
.
Buffer
,
name
,
len
)
||
strcmpiW
(
name
+
len
,
soW
))
{
ERR
(
"loaded .so for %s but got %s instead - probably 16-bit dll
\n
"
,
debugstr_w
(
name
),
debugstr_w
(
info
.
wm
->
ldr
.
BaseDllName
.
Buffer
)
);
/* wine_dll_unload( handle );*/
return
STATUS_INVALID_IMAGE_FORMAT
;
}
}
}
*
pwm
=
info
.
wm
;
*
pwm
=
info
.
wm
;
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
...
@@ -1576,7 +1646,6 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
...
@@ -1576,7 +1646,6 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
WCHAR
buffer
[
32
];
WCHAR
buffer
[
32
];
WCHAR
*
filename
;
WCHAR
*
filename
;
ULONG
size
;
ULONG
size
;
const
char
*
filetype
=
""
;
WINE_MODREF
*
main_exe
;
WINE_MODREF
*
main_exe
;
HANDLE
handle
=
0
;
HANDLE
handle
=
0
;
NTSTATUS
nts
;
NTSTATUS
nts
;
...
@@ -1626,12 +1695,15 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
...
@@ -1626,12 +1695,15 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
TRACE
(
"Trying native dll %s
\n
"
,
debugstr_w
(
filename
));
TRACE
(
"Trying native dll %s
\n
"
,
debugstr_w
(
filename
));
if
(
!
handle
)
continue
;
/* it cannot possibly be loaded */
if
(
!
handle
)
continue
;
/* it cannot possibly be loaded */
nts
=
load_native_dll
(
load_path
,
filename
,
handle
,
flags
,
pwm
);
nts
=
load_native_dll
(
load_path
,
filename
,
handle
,
flags
,
pwm
);
filetype
=
"native"
;
if
(
nts
==
STATUS_INVALID_FILE_FOR_SECTION
)
{
/* not in PE format, maybe it's a builtin */
nts
=
load_builtin_dll
(
load_path
,
filename
,
handle
,
flags
,
pwm
);
}
break
;
break
;
case
LOADORDER_BI
:
case
LOADORDER_BI
:
TRACE
(
"Trying built-in %s
\n
"
,
debugstr_w
(
filename
));
TRACE
(
"Trying built-in %s
\n
"
,
debugstr_w
(
filename
));
nts
=
load_builtin_dll
(
load_path
,
filename
,
flags
,
pwm
);
nts
=
load_builtin_dll
(
load_path
,
filename
,
0
,
flags
,
pwm
);
filetype
=
"builtin"
;
break
;
break
;
default:
default:
nts
=
STATUS_INTERNAL_ERROR
;
nts
=
STATUS_INTERNAL_ERROR
;
...
@@ -1641,8 +1713,9 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
...
@@ -1641,8 +1713,9 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
if
(
nts
==
STATUS_SUCCESS
)
if
(
nts
==
STATUS_SUCCESS
)
{
{
/* Initialize DLL just loaded */
/* Initialize DLL just loaded */
TRACE
(
"Loaded module %s (%s) at %p
\n
"
,
TRACE
(
"Loaded module %s (%s) at %p
\n
"
,
debugstr_w
(
filename
),
debugstr_w
(
filename
),
filetype
,
(
*
pwm
)
->
ldr
.
BaseAddress
);
((
*
pwm
)
->
ldr
.
Flags
&
LDR_WINE_INTERNAL
)
?
"builtin"
:
"native"
,
(
*
pwm
)
->
ldr
.
BaseAddress
);
/* Set the ldr.LoadCount here so that an attach failure will */
/* Set the ldr.LoadCount here so that an attach failure will */
/* decrement the dependencies through the MODULE_FreeLibrary call. */
/* decrement the dependencies through the MODULE_FreeLibrary call. */
(
*
pwm
)
->
ldr
.
LoadCount
=
1
;
(
*
pwm
)
->
ldr
.
LoadCount
=
1
;
...
@@ -2169,7 +2242,7 @@ void __wine_process_init( int argc, char *argv[] )
...
@@ -2169,7 +2242,7 @@ void __wine_process_init( int argc, char *argv[] )
/* setup the load callback and create ntdll modref */
/* setup the load callback and create ntdll modref */
wine_dll_set_callback
(
load_builtin_callback
);
wine_dll_set_callback
(
load_builtin_callback
);
if
((
status
=
load_builtin_dll
(
NULL
,
kernel32W
,
0
,
&
wm
))
!=
STATUS_SUCCESS
)
if
((
status
=
load_builtin_dll
(
NULL
,
kernel32W
,
0
,
0
,
&
wm
))
!=
STATUS_SUCCESS
)
{
{
MESSAGE
(
"wine: could not load kernel32.dll, status %lx
\n
"
,
status
);
MESSAGE
(
"wine: could not load kernel32.dll, status %lx
\n
"
,
status
);
exit
(
1
);
exit
(
1
);
...
...
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