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
65fc1c92
Commit
65fc1c92
authored
Aug 24, 2001
by
Bill Medland
Committed by
Alexandre Julliard
Aug 24, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added LOAD_WITH_ALTERED_SEARCH_PATH support to LoadLibraryEx.
parent
9d9dac09
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
199 additions
and
23 deletions
+199
-23
directory.c
files/directory.c
+103
-3
file.h
include/file.h
+8
-0
module.h
include/module.h
+1
-0
module.c
loader/module.c
+80
-17
pe_image.c
loader/pe_image.c
+7
-3
No files found.
files/directory.c
View file @
65fc1c92
...
...
@@ -582,8 +582,7 @@ DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
p
=
strrchr
(
name
,
'.'
);
if
(
p
&&
!
strchr
(
p
,
'/'
)
&&
!
strchr
(
p
,
'\\'
))
ext
=
NULL
;
/* Ignore the specified extension */
if
((
*
name
&&
(
name
[
1
]
==
':'
))
||
strchr
(
name
,
'/'
)
||
strchr
(
name
,
'\\'
))
if
(
FILE_contains_path
(
name
))
path
=
NULL
;
/* Ignore path if name already contains a path */
if
(
path
&&
!*
path
)
path
=
NULL
;
/* Ignore empty path */
...
...
@@ -604,7 +603,7 @@ DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
/* If the name contains an explicit path, everything's easy */
if
(
(
*
name
&&
(
name
[
1
]
==
':'
))
||
strchr
(
name
,
'/'
)
||
strchr
(
name
,
'\\'
))
if
(
FILE_contains_path
(
name
))
{
ret
=
DOSFS_GetFullName
(
name
,
TRUE
,
full_name
);
goto
done
;
...
...
@@ -746,3 +745,104 @@ DWORD WINAPI SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
}
/***********************************************************************
* search_alternate_path
*
*
* FIXME: should return long path names.?
*/
static
BOOL
search_alternate_path
(
LPCSTR
dll_path
,
LPCSTR
name
,
LPCSTR
ext
,
DOS_FULL_NAME
*
full_name
)
{
LPCSTR
p
;
LPSTR
tmp
=
NULL
;
BOOL
ret
=
TRUE
;
/* First check the supplied parameters */
p
=
strrchr
(
name
,
'.'
);
if
(
p
&&
!
strchr
(
p
,
'/'
)
&&
!
strchr
(
p
,
'\\'
))
ext
=
NULL
;
/* Ignore the specified extension */
/* Allocate a buffer for the file name and extension */
if
(
ext
)
{
DWORD
len
=
strlen
(
name
)
+
strlen
(
ext
);
if
(
!
(
tmp
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
+
1
)))
{
SetLastError
(
ERROR_OUTOFMEMORY
);
return
0
;
}
strcpy
(
tmp
,
name
);
strcat
(
tmp
,
ext
);
name
=
tmp
;
}
if
(
DIR_TryEnvironmentPath
(
name
,
full_name
,
dll_path
))
;
else
if
(
DOSFS_GetFullName
(
name
,
TRUE
,
full_name
))
/* current dir */
;
else
if
(
DIR_TryPath
(
&
DIR_System
,
name
,
full_name
))
/* System dir */
;
else
if
(
DIR_TryPath
(
&
DIR_Windows
,
name
,
full_name
))
/* Windows dir */
;
else
ret
=
DIR_TryEnvironmentPath
(
name
,
full_name
,
NULL
);
if
(
tmp
)
HeapFree
(
GetProcessHeap
(),
0
,
tmp
);
return
ret
;
}
/***********************************************************************
* DIR_SearchAlternatePath
*
* Searches for a specified file in the search path.
*
* PARAMS
* dll_path [I] Path to search
* name [I] Filename to search for.
* ext [I] File extension to append to file name. The first
* character must be a period. This parameter is
* specified only if the filename given does not
* contain an extension.
* buflen [I] size of buffer, in characters
* buffer [O] buffer for found filename
* lastpart [O] address of pointer to last used character in
* buffer (the final '\') (May be NULL)
*
* RETURNS
* Success: length of string copied into buffer, not including
* terminating null character. If the filename found is
* longer than the length of the buffer, the length of the
* filename is returned.
* Failure: Zero
*
* NOTES
* If the file is not found, calls SetLastError(ERROR_FILE_NOT_FOUND)
*/
DWORD
DIR_SearchAlternatePath
(
LPCSTR
dll_path
,
LPCSTR
name
,
LPCSTR
ext
,
DWORD
buflen
,
LPSTR
buffer
,
LPSTR
*
lastpart
)
{
LPSTR
p
,
res
;
DOS_FULL_NAME
full_name
;
if
(
!
search_alternate_path
(
dll_path
,
name
,
ext
,
&
full_name
))
{
SetLastError
(
ERROR_FILE_NOT_FOUND
);
return
0
;
}
lstrcpynA
(
buffer
,
full_name
.
short_name
,
buflen
);
res
=
full_name
.
long_name
+
strlen
(
DRIVE_GetRoot
(
full_name
.
short_name
[
0
]
-
'A'
));
while
(
*
res
==
'/'
)
res
++
;
if
(
buflen
)
{
if
(
buflen
>
3
)
lstrcpynA
(
buffer
+
3
,
res
,
buflen
-
3
);
for
(
p
=
buffer
;
*
p
;
p
++
)
if
(
*
p
==
'/'
)
*
p
=
'\\'
;
if
(
lastpart
)
*
lastpart
=
strrchr
(
buffer
,
'\\'
)
+
1
;
}
TRACE
(
"Returning %d
\n
"
,
strlen
(
res
)
+
3
);
return
strlen
(
res
)
+
3
;
}
include/file.h
View file @
65fc1c92
...
...
@@ -61,6 +61,12 @@ inline static char FILE_toupper( char c )
return
c
;
}
inline
static
int
FILE_contains_path
(
LPCSTR
name
)
{
return
((
*
name
&&
(
name
[
1
]
==
':'
))
||
strchr
(
name
,
'/'
)
||
strchr
(
name
,
'\\'
));
}
/* files/file.c */
extern
int
FILE_strcasecmp
(
const
char
*
str1
,
const
char
*
str2
);
extern
int
FILE_strncasecmp
(
const
char
*
str1
,
const
char
*
str2
,
int
len
);
...
...
@@ -80,6 +86,8 @@ extern LONG WINAPI WIN16_hread(HFILE16,SEGPTR,LONG);
extern
int
DIR_Init
(
void
);
extern
UINT
DIR_GetWindowsUnixDir
(
LPSTR
path
,
UINT
count
);
extern
UINT
DIR_GetSystemUnixDir
(
LPSTR
path
,
UINT
count
);
extern
DWORD
DIR_SearchAlternatePath
(
LPCSTR
dll_path
,
LPCSTR
name
,
LPCSTR
ext
,
DWORD
buflen
,
LPSTR
buffer
,
LPSTR
*
lastpart
);
extern
DWORD
DIR_SearchPath
(
LPCSTR
path
,
LPCSTR
name
,
LPCSTR
ext
,
DOS_FULL_NAME
*
full_name
,
BOOL
win32
);
...
...
include/module.h
View file @
65fc1c92
...
...
@@ -234,6 +234,7 @@ extern WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename,
DWORD
flags
,
HANDLE
hFile
,
BOOL
builtin
);
extern
void
PE_InitTls
(
void
);
extern
BOOL
PE_InitDLL
(
HMODULE
module
,
DWORD
type
,
LPVOID
lpReserved
);
extern
DWORD
PE_fixup_imports
(
WINE_MODREF
*
wm
);
/* loader/loadorder.c */
extern
void
MODULE_InitLoadOrder
(
void
);
...
...
loader/module.c
View file @
65fc1c92
...
...
@@ -1316,6 +1316,37 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
}
/***********************************************************************
* allocate_lib_dir
*
* helper for MODULE_LoadLibraryExA. Allocate space to hold the directory
* portion of the provided name and put the name in it.
*
*/
static
LPCSTR
allocate_lib_dir
(
LPCSTR
libname
)
{
LPCSTR
p
,
pmax
;
LPSTR
result
;
int
length
;
pmax
=
libname
;
if
((
p
=
strrchr
(
pmax
,
'\\'
)))
pmax
=
p
+
1
;
if
((
p
=
strrchr
(
pmax
,
'/'
)))
pmax
=
p
+
1
;
/* Naughty. MSDN says don't */
if
(
pmax
==
libname
&&
pmax
[
0
]
&&
pmax
[
1
]
==
':'
)
pmax
+=
2
;
length
=
pmax
-
libname
;
result
=
HeapAlloc
(
GetProcessHeap
(),
0
,
length
+
1
);
if
(
result
)
{
strncpy
(
result
,
libname
,
length
);
result
[
length
]
=
'\0'
;
}
return
result
;
}
/***********************************************************************
* MODULE_LoadLibraryExA (internal)
*
* Load a PE style module according to the load order.
...
...
@@ -1325,6 +1356,16 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
* ignore the parameter because it would be extremely difficult to
* integrate this with different types of module represenations.
*
* libdir is used to support LOAD_WITH_ALTERED_SEARCH_PATH during the recursion
* on this function. When first called from LoadLibraryExA it will be
* NULL but thereafter it may point to a buffer containing the path
* portion of the library name. Note that the recursion all occurs
* within a Critical section (see LoadLibraryExA) so the use of a
* static is acceptable.
* (We have to use a static variable at some point anyway, to pass the
* information from BUILTIN32_dlopen through dlopen and the builtin's
* init function into load_library).
* allocated_libdir is TRUE in the stack frame that allocated libdir
*/
WINE_MODREF
*
MODULE_LoadLibraryExA
(
LPCSTR
libname
,
HFILE
hfile
,
DWORD
flags
)
{
...
...
@@ -1334,14 +1375,30 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
enum
loadorder_type
loadorder
[
LOADORDER_NTYPES
];
LPSTR
filename
,
p
;
const
char
*
filetype
=
""
;
DWORD
found
;
BOOL
allocated_libdir
=
FALSE
;
static
LPCSTR
libdir
=
NULL
;
/* See above */
if
(
!
libname
)
return
NULL
;
filename
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAX_PATH
+
1
);
if
(
!
filename
)
return
NULL
;
RtlAcquirePebLock
();
if
((
flags
&
LOAD_WITH_ALTERED_SEARCH_PATH
)
&&
FILE_contains_path
(
libname
))
{
if
(
!
(
libdir
=
allocate_lib_dir
(
libname
)))
goto
error
;
allocated_libdir
=
TRUE
;
}
if
(
!
libdir
||
allocated_libdir
)
found
=
SearchPathA
(
NULL
,
libname
,
".dll"
,
MAX_PATH
,
filename
,
NULL
);
else
found
=
DIR_SearchAlternatePath
(
libdir
,
libname
,
".dll"
,
MAX_PATH
,
filename
,
NULL
);
/* build the modules filename */
if
(
!
SearchPathA
(
NULL
,
libname
,
".dll"
,
MAX_PATH
,
filename
,
NULL
)
)
if
(
!
found
)
{
if
(
!
GetSystemDirectoryA
(
filename
,
MAX_PATH
)
)
goto
error
;
...
...
@@ -1357,26 +1414,18 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
strcpy
(
filename
,
libname
);
else
{
if
(
strchr
(
libname
,
'\\'
)
||
strchr
(
libname
,
':'
)
||
strchr
(
libname
,
'/'
)
)
goto
error
;
else
{
strcat
(
filename
,
"
\\
"
);
strcat
(
filename
,
libname
);
}
if
(
FILE_contains_path
(
libname
))
goto
error
;
strcat
(
filename
,
"
\\
"
);
strcat
(
filename
,
libname
);
}
/* if the filename doesn't have an extension append .DLL */
if
(
!
(
p
=
strrchr
(
filename
,
'.'
))
||
strchr
(
p
,
'/'
)
||
strchr
(
p
,
'\\'
))
strcat
(
filename
,
".
DLL
"
);
strcat
(
filename
,
".
dll
"
);
}
RtlAcquirePebLock
();
/* Check for already loaded module */
if
(
!
(
pwm
=
MODULE_FindModule
(
filename
))
&&
/* no path in libpath */
!
strchr
(
libname
,
'\\'
)
&&
!
strchr
(
libname
,
':'
)
&&
!
strchr
(
libname
,
'/'
))
if
(
!
(
pwm
=
MODULE_FindModule
(
filename
))
&&
!
FILE_contains_path
(
libname
))
{
LPSTR
fn
=
HeapAlloc
(
GetProcessHeap
(),
0
,
MAX_PATH
+
1
);
if
(
fn
)
...
...
@@ -1404,11 +1453,15 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
if
((
pwm
->
flags
&
WINE_MODREF_DONT_RESOLVE_REFS
)
&&
!
(
flags
&
DONT_RESOLVE_DLL_REFERENCES
))
{
extern
DWORD
fixup_imports
(
WINE_MODREF
*
wm
);
/*FIXME*/
pwm
->
flags
&=
~
WINE_MODREF_DONT_RESOLVE_REFS
;
fixup_imports
(
pwm
);
PE_
fixup_imports
(
pwm
);
}
TRACE
(
"Already loaded module '%s' at 0x%08x, count=%d,
\n
"
,
filename
,
pwm
->
module
,
pwm
->
refCount
);
if
(
allocated_libdir
)
{
HeapFree
(
GetProcessHeap
(),
0
,
(
LPSTR
)
libdir
);
libdir
=
NULL
;
}
RtlReleasePebLock
();
HeapFree
(
GetProcessHeap
(),
0
,
filename
);
return
pwm
;
...
...
@@ -1456,6 +1509,11 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
/* decrement the dependencies through the MODULE_FreeLibrary call. */
pwm
->
refCount
++
;
if
(
allocated_libdir
)
{
HeapFree
(
GetProcessHeap
(),
0
,
(
LPSTR
)
libdir
);
libdir
=
NULL
;
}
RtlReleasePebLock
();
SetLastError
(
err
);
/* restore last error */
HeapFree
(
GetProcessHeap
(),
0
,
filename
);
...
...
@@ -1466,8 +1524,13 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
break
;
}
RtlReleasePebLock
();
error:
if
(
allocated_libdir
)
{
HeapFree
(
GetProcessHeap
(),
0
,
(
LPSTR
)
libdir
);
libdir
=
NULL
;
}
RtlReleasePebLock
();
WARN
(
"Failed to load module '%s'; error=0x%08lx,
\n
"
,
filename
,
GetLastError
());
HeapFree
(
GetProcessHeap
(),
0
,
filename
);
return
NULL
;
...
...
loader/pe_image.c
View file @
65fc1c92
...
...
@@ -17,7 +17,7 @@
* - If you want to enhance, speed up or clean up something in here, think
* twice WHY it is implemented in that strange way. There is usually a reason.
* Though sometimes it might just be lazyness ;)
* - In PE_MapImage, right before fixup_imports() all external and internal
* - In PE_MapImage, right before
PE_
fixup_imports() all external and internal
* state MUST be correct since this function can be called with the SAME image
* AGAIN. (Thats recursion for you.) That means MODREF.module and
* NE_MODULE.module32.
...
...
@@ -242,7 +242,10 @@ static FARPROC PE_FindExportedFunction(
}
}
DWORD
fixup_imports
(
WINE_MODREF
*
wm
)
/****************************************************************
* PE_fixup_imports
*/
DWORD
PE_fixup_imports
(
WINE_MODREF
*
wm
)
{
IMAGE_IMPORT_DESCRIPTOR
*
pe_imp
;
unsigned
int
load_addr
=
wm
->
module
;
...
...
@@ -633,7 +636,8 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
/* Fixup Imports */
if
(
!
(
wm
->
flags
&
WINE_MODREF_DONT_RESOLVE_REFS
)
&&
fixup_imports
(
wm
))
if
(
!
(
wm
->
flags
&
WINE_MODREF_DONT_RESOLVE_REFS
)
&&
PE_fixup_imports
(
wm
))
{
/* remove entry from modref chain */
...
...
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