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
c5dc41e9
Commit
c5dc41e9
authored
Oct 03, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Move LoadLibrary functions to kernelbase.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
a5d45e9a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
307 additions
and
276 deletions
+307
-276
kernel32.spec
dlls/kernel32/kernel32.spec
+5
-5
module.c
dlls/kernel32/module.c
+0
-265
kernelbase.spec
dlls/kernelbase/kernelbase.spec
+6
-6
loader.c
dlls/kernelbase/loader.c
+296
-0
No files found.
dlls/kernel32/kernel32.spec
View file @
c5dc41e9
...
...
@@ -528,7 +528,7 @@
@ stdcall -import FreeEnvironmentStringsA(ptr)
@ stdcall -import FreeEnvironmentStringsW(ptr)
@ stub -i386 FreeLSCallback
@ stdcall FreeLibrary(long)
@ stdcall
-import
FreeLibrary(long)
@ stdcall FreeLibraryAndExitThread(long long)
@ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) ntdll.TpCallbackUnloadDllOnCompletion
@ stdcall -import FreeResource(long)
...
...
@@ -1042,10 +1042,10 @@
@ stdcall LeaveCriticalSection(ptr) ntdll.RtlLeaveCriticalSection
@ stdcall LeaveCriticalSectionWhenCallbackReturns(ptr ptr) ntdll.TpCallbackLeaveCriticalSectionOnCompletion
# @ stub LoadAppInitDlls
@ stdcall LoadLibraryA(str)
@ stdcall LoadLibraryExA( str long long)
@ stdcall LoadLibraryExW(wstr long long)
@ stdcall LoadLibraryW(wstr)
@ stdcall
-import
LoadLibraryA(str)
@ stdcall
-import
LoadLibraryExA( str long long)
@ stdcall
-import
LoadLibraryExW(wstr long long)
@ stdcall
-import
LoadLibraryW(wstr)
@ stdcall LoadModule(str ptr)
@ stdcall -import LoadResource(long long)
# @ stub LoadStringBaseExW
...
...
dlls/kernel32/module.c
View file @
c5dc41e9
...
...
@@ -47,16 +47,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
module
);
#define NE_FFLAGS_LIBMODULE 0x8000
/* to keep track of LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE file handles */
struct
exclusive_datafile
{
struct
list
entry
;
HMODULE
module
;
HANDLE
file
;
};
static
struct
list
exclusive_datafile_list
=
LIST_INIT
(
exclusive_datafile_list
);
/****************************************************************************
* GetDllDirectoryA (KERNEL32.@)
...
...
@@ -283,261 +273,6 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
return
GetBinaryTypeW
(
NtCurrentTeb
()
->
StaticUnicodeString
.
Buffer
,
lpBinaryType
);
}
/******************************************************************
* load_library_as_datafile
*/
static
BOOL
load_library_as_datafile
(
LPCWSTR
load_path
,
DWORD
flags
,
LPCWSTR
name
,
HMODULE
*
hmod
)
{
static
const
WCHAR
dotDLL
[]
=
{
'.'
,
'd'
,
'l'
,
'l'
,
0
};
WCHAR
filenameW
[
MAX_PATH
];
HANDLE
hFile
=
INVALID_HANDLE_VALUE
;
HANDLE
mapping
;
HMODULE
module
=
0
;
DWORD
protect
=
PAGE_READONLY
;
DWORD
sharing
=
FILE_SHARE_READ
|
FILE_SHARE_DELETE
;
*
hmod
=
0
;
if
(
flags
&
LOAD_LIBRARY_AS_IMAGE_RESOURCE
)
protect
|=
SEC_IMAGE
;
if
(
SearchPathW
(
load_path
,
name
,
dotDLL
,
ARRAY_SIZE
(
filenameW
),
filenameW
,
NULL
))
{
hFile
=
CreateFileW
(
filenameW
,
GENERIC_READ
,
sharing
,
NULL
,
OPEN_EXISTING
,
0
,
0
);
}
if
(
hFile
==
INVALID_HANDLE_VALUE
)
return
FALSE
;
mapping
=
CreateFileMappingW
(
hFile
,
NULL
,
protect
,
0
,
0
,
NULL
);
if
(
!
mapping
)
goto
failed
;
module
=
MapViewOfFile
(
mapping
,
FILE_MAP_READ
,
0
,
0
,
0
);
CloseHandle
(
mapping
);
if
(
!
module
)
goto
failed
;
if
(
!
(
flags
&
LOAD_LIBRARY_AS_IMAGE_RESOURCE
))
{
/* make sure it's a valid PE file */
if
(
!
RtlImageNtHeader
(
module
))
goto
failed
;
*
hmod
=
(
HMODULE
)((
char
*
)
module
+
1
);
/* set bit 0 for data file module */
if
(
flags
&
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
)
{
struct
exclusive_datafile
*
file
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
file
)
);
if
(
!
file
)
goto
failed
;
file
->
module
=
*
hmod
;
file
->
file
=
hFile
;
list_add_head
(
&
exclusive_datafile_list
,
&
file
->
entry
);
TRACE
(
"delaying close %p for module %p
\n
"
,
file
->
file
,
file
->
module
);
return
TRUE
;
}
}
else
*
hmod
=
(
HMODULE
)((
char
*
)
module
+
2
);
/* set bit 1 for image resource module */
CloseHandle
(
hFile
);
return
TRUE
;
failed:
if
(
module
)
UnmapViewOfFile
(
module
);
CloseHandle
(
hFile
);
return
FALSE
;
}
/******************************************************************
* load_library
*
* Helper for LoadLibraryExA/W.
*/
static
HMODULE
load_library
(
const
UNICODE_STRING
*
libname
,
DWORD
flags
)
{
NTSTATUS
nts
;
HMODULE
hModule
;
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
(
!
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
))
{
ULONG_PTR
magic
;
LdrLockLoaderLock
(
0
,
NULL
,
&
magic
);
if
(
!
LdrGetDllHandle
(
load_path
,
flags
,
libname
,
&
hModule
))
{
LdrAddRefDll
(
0
,
hModule
);
LdrUnlockLoaderLock
(
0
,
magic
);
goto
done
;
}
if
(
load_library_as_datafile
(
load_path
,
flags
,
libname
->
Buffer
,
&
hModule
))
{
LdrUnlockLoaderLock
(
0
,
magic
);
goto
done
;
}
LdrUnlockLoaderLock
(
0
,
magic
);
flags
|=
DONT_RESOLVE_DLL_REFERENCES
;
/* Just in case */
/* Fallback to normal behaviour */
}
nts
=
LdrLoadDll
(
load_path
,
flags
,
libname
,
&
hModule
);
if
(
nts
!=
STATUS_SUCCESS
)
{
hModule
=
0
;
if
(
nts
==
STATUS_DLL_NOT_FOUND
&&
(
GetVersion
()
&
0x80000000
))
SetLastError
(
ERROR_DLL_NOT_FOUND
);
else
SetLastError
(
RtlNtStatusToDosError
(
nts
)
);
}
done:
RtlReleasePath
(
load_path
);
return
hModule
;
}
/******************************************************************
* LoadLibraryExA (KERNEL32.@)
*
* Load a dll file into the process address space.
*
* PARAMS
* libname [I] Name of the file to load
* hfile [I] Reserved, must be 0.
* flags [I] Flags for loading the dll
*
* RETURNS
* Success: A handle to the loaded dll.
* Failure: A NULL handle. Use GetLastError() to determine the cause.
*
* NOTES
* The HFILE parameter is not used and marked reserved in the SDK. I can
* only guess that it should force a file to be mapped, but I rather
* ignore the parameter because it would be extremely difficult to
* integrate this with different types of module representations.
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryExA
(
LPCSTR
libname
,
HANDLE
hfile
,
DWORD
flags
)
{
WCHAR
*
libnameW
;
if
(
!
(
libnameW
=
FILE_name_AtoW
(
libname
,
FALSE
)))
return
0
;
return
LoadLibraryExW
(
libnameW
,
hfile
,
flags
);
}
/***********************************************************************
* LoadLibraryExW (KERNEL32.@)
*
* Unicode version of LoadLibraryExA.
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryExW
(
LPCWSTR
libnameW
,
HANDLE
hfile
,
DWORD
flags
)
{
UNICODE_STRING
wstr
;
HMODULE
res
;
if
(
!
libnameW
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
RtlInitUnicodeString
(
&
wstr
,
libnameW
);
if
(
wstr
.
Buffer
[
wstr
.
Length
/
sizeof
(
WCHAR
)
-
1
]
!=
' '
)
return
load_library
(
&
wstr
,
flags
);
/* Library name has trailing spaces */
RtlCreateUnicodeString
(
&
wstr
,
libnameW
);
while
(
wstr
.
Length
>
sizeof
(
WCHAR
)
&&
wstr
.
Buffer
[
wstr
.
Length
/
sizeof
(
WCHAR
)
-
1
]
==
' '
)
{
wstr
.
Length
-=
sizeof
(
WCHAR
);
}
wstr
.
Buffer
[
wstr
.
Length
/
sizeof
(
WCHAR
)]
=
'\0'
;
res
=
load_library
(
&
wstr
,
flags
);
RtlFreeUnicodeString
(
&
wstr
);
return
res
;
}
/***********************************************************************
* LoadLibraryA (KERNEL32.@)
*
* Load a dll file into the process address space.
*
* PARAMS
* libname [I] Name of the file to load
*
* RETURNS
* Success: A handle to the loaded dll.
* Failure: A NULL handle. Use GetLastError() to determine the cause.
*
* NOTES
* See LoadLibraryExA().
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryA
(
LPCSTR
libname
)
{
return
LoadLibraryExA
(
libname
,
0
,
0
);
}
/***********************************************************************
* LoadLibraryW (KERNEL32.@)
*
* Unicode version of LoadLibraryA.
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryW
(
LPCWSTR
libnameW
)
{
return
LoadLibraryExW
(
libnameW
,
0
,
0
);
}
/***********************************************************************
* FreeLibrary (KERNEL32.@)
*
* Free a dll loaded into the process address space.
*
* PARAMS
* hLibModule [I] Handle to the dll returned by LoadLibraryA().
*
* RETURNS
* Success: TRUE. The dll is removed if it is not still in use.
* Failure: FALSE. Use GetLastError() to determine the cause.
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
FreeLibrary
(
HINSTANCE
hLibModule
)
{
if
(
!
hLibModule
)
{
SetLastError
(
ERROR_INVALID_HANDLE
);
return
FALSE
;
}
if
((
ULONG_PTR
)
hLibModule
&
3
)
/* this is a datafile module */
{
void
*
ptr
=
(
void
*
)((
ULONG_PTR
)
hLibModule
&
~
3
);
if
(
!
RtlImageNtHeader
(
ptr
))
{
SetLastError
(
ERROR_BAD_EXE_FORMAT
);
return
FALSE
;
}
if
((
ULONG_PTR
)
hLibModule
&
1
)
{
struct
exclusive_datafile
*
file
;
ULONG_PTR
magic
;
LdrLockLoaderLock
(
0
,
NULL
,
&
magic
);
LIST_FOR_EACH_ENTRY
(
file
,
&
exclusive_datafile_list
,
struct
exclusive_datafile
,
entry
)
{
if
(
file
->
module
!=
hLibModule
)
continue
;
TRACE
(
"closing %p for module %p
\n
"
,
file
->
file
,
file
->
module
);
CloseHandle
(
file
->
file
);
list_remove
(
&
file
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
file
);
break
;
}
LdrUnlockLoaderLock
(
0
,
magic
);
}
return
UnmapViewOfFile
(
ptr
);
}
return
set_ntstatus
(
LdrUnloadDll
(
hLibModule
));
}
/***********************************************************************
* GetProcAddress (KERNEL32.@)
*
...
...
dlls/kernelbase/kernelbase.spec
View file @
c5dc41e9
...
...
@@ -394,7 +394,7 @@
@ stdcall FreeEnvironmentStringsW(ptr)
# @ stub FreeGPOListInternalA
# @ stub FreeGPOListInternalW
@ stdcall FreeLibrary(long)
kernel32.FreeLibrary
@ stdcall FreeLibrary(long)
@ stdcall FreeLibraryAndExitThread(long long)
@ stdcall FreeLibraryWhenCallbackReturns(ptr ptr) ntdll.TpCallbackUnloadDllOnCompletion
@ stdcall FreeResource(long)
...
...
@@ -618,7 +618,7 @@
# @ stub GetPreviousFgPolicyRefreshInfoInternal
@ stdcall GetPriorityClass(long)
@ stdcall GetPrivateObjectSecurity(ptr long ptr long ptr)
@ stdcall GetProcAddress(long str)
kernel32.GetProcAddress
@ stdcall GetProcAddress(long str)
# @ stub GetProcAddressForCaller
# @ stub GetProcessDefaultCpuSets
# @ stub GetProcessGroupAffinity
...
...
@@ -922,10 +922,10 @@
@ stdcall LeaveCriticalSectionWhenCallbackReturns(ptr ptr) ntdll.TpCallbackLeaveCriticalSectionOnCompletion
# @ stub LoadAppInitDlls
# @ stub LoadEnclaveData
@ stdcall LoadLibraryA(str)
kernel32.LoadLibraryA
@ stdcall LoadLibraryExA( str long long)
kernel32.LoadLibraryExA
@ stdcall LoadLibraryExW(wstr long long)
kernel32.LoadLibraryExW
@ stdcall LoadLibraryW(wstr)
kernel32.LoadLibraryW
@ stdcall LoadLibraryA(str)
@ stdcall LoadLibraryExA( str long long)
@ stdcall LoadLibraryExW(wstr long long)
@ stdcall LoadLibraryW(wstr)
# @ stub LoadPackagedLibrary
@ stdcall LoadResource(long long)
@ stdcall LoadStringA(long long ptr long)
...
...
dlls/kernelbase/loader.c
View file @
c5dc41e9
...
...
@@ -31,17 +31,161 @@
#include "winnls.h"
#include "winternl.h"
#include "kernelbase.h"
#include "wine/list.h"
#include "wine/asm.h"
#include "wine/debug.h"
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
module
);
/* to keep track of LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE file handles */
struct
exclusive_datafile
{
struct
list
entry
;
HMODULE
module
;
HANDLE
file
;
};
static
struct
list
exclusive_datafile_list
=
LIST_INIT
(
exclusive_datafile_list
);
/***********************************************************************
* Modules
***********************************************************************/
/******************************************************************
* get_proc_address
*/
FARPROC
WINAPI
get_proc_address
(
HMODULE
module
,
LPCSTR
function
)
{
FARPROC
proc
;
ANSI_STRING
str
;
if
(
!
module
)
module
=
NtCurrentTeb
()
->
Peb
->
ImageBaseAddress
;
if
((
ULONG_PTR
)
function
>>
16
)
{
RtlInitAnsiString
(
&
str
,
function
);
if
(
!
set_ntstatus
(
LdrGetProcedureAddress
(
module
,
&
str
,
0
,
(
void
**
)
&
proc
)))
return
NULL
;
}
else
if
(
!
set_ntstatus
(
LdrGetProcedureAddress
(
module
,
NULL
,
LOWORD
(
function
),
(
void
**
)
&
proc
)))
return
NULL
;
return
proc
;
}
/******************************************************************
* load_library_as_datafile
*/
static
BOOL
load_library_as_datafile
(
LPCWSTR
load_path
,
DWORD
flags
,
LPCWSTR
name
,
HMODULE
*
mod_ret
)
{
static
const
WCHAR
dotDLL
[]
=
{
'.'
,
'd'
,
'l'
,
'l'
,
0
};
WCHAR
filenameW
[
MAX_PATH
];
HANDLE
mapping
,
file
=
INVALID_HANDLE_VALUE
;
HMODULE
module
=
0
;
DWORD
protect
=
PAGE_READONLY
;
*
mod_ret
=
0
;
if
(
flags
&
LOAD_LIBRARY_AS_IMAGE_RESOURCE
)
protect
|=
SEC_IMAGE
;
if
(
SearchPathW
(
load_path
,
name
,
dotDLL
,
ARRAY_SIZE
(
filenameW
),
filenameW
,
NULL
))
{
file
=
CreateFileW
(
filenameW
,
GENERIC_READ
,
FILE_SHARE_READ
|
FILE_SHARE_DELETE
,
NULL
,
OPEN_EXISTING
,
0
,
0
);
}
if
(
file
==
INVALID_HANDLE_VALUE
)
return
FALSE
;
mapping
=
CreateFileMappingW
(
file
,
NULL
,
protect
,
0
,
0
,
NULL
);
if
(
!
mapping
)
goto
failed
;
module
=
MapViewOfFile
(
mapping
,
FILE_MAP_READ
,
0
,
0
,
0
);
CloseHandle
(
mapping
);
if
(
!
module
)
goto
failed
;
if
(
!
(
flags
&
LOAD_LIBRARY_AS_IMAGE_RESOURCE
))
{
/* make sure it's a valid PE file */
if
(
!
RtlImageNtHeader
(
module
))
goto
failed
;
*
mod_ret
=
(
HMODULE
)((
char
*
)
module
+
1
);
/* set bit 0 for data file module */
if
(
flags
&
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
)
{
struct
exclusive_datafile
*
file
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
file
)
);
if
(
!
file
)
goto
failed
;
file
->
module
=
*
mod_ret
;
file
->
file
=
file
;
list_add_head
(
&
exclusive_datafile_list
,
&
file
->
entry
);
TRACE
(
"delaying close %p for module %p
\n
"
,
file
->
file
,
file
->
module
);
return
TRUE
;
}
}
else
*
mod_ret
=
(
HMODULE
)((
char
*
)
module
+
2
);
/* set bit 1 for image resource module */
CloseHandle
(
file
);
return
TRUE
;
failed:
if
(
module
)
UnmapViewOfFile
(
module
);
CloseHandle
(
file
);
return
FALSE
;
}
/******************************************************************
* load_library
*/
static
HMODULE
load_library
(
const
UNICODE_STRING
*
libname
,
DWORD
flags
)
{
const
DWORD
unsupported_flags
=
LOAD_IGNORE_CODE_AUTHZ_LEVEL
|
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET
;
NTSTATUS
status
;
HMODULE
module
;
WCHAR
*
load_path
,
*
dummy
;
if
(
flags
&
unsupported_flags
)
FIXME
(
"unsupported flag(s) used %#08x
\n
"
,
flags
);
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
))
{
ULONG_PTR
magic
;
LdrLockLoaderLock
(
0
,
NULL
,
&
magic
);
if
(
!
LdrGetDllHandle
(
load_path
,
flags
,
libname
,
&
module
))
{
LdrAddRefDll
(
0
,
module
);
LdrUnlockLoaderLock
(
0
,
magic
);
goto
done
;
}
if
(
load_library_as_datafile
(
load_path
,
flags
,
libname
->
Buffer
,
&
module
))
{
LdrUnlockLoaderLock
(
0
,
magic
);
goto
done
;
}
LdrUnlockLoaderLock
(
0
,
magic
);
flags
|=
DONT_RESOLVE_DLL_REFERENCES
;
/* Just in case */
/* Fallback to normal behaviour */
}
status
=
LdrLoadDll
(
load_path
,
flags
,
libname
,
&
module
);
if
(
status
!=
STATUS_SUCCESS
)
{
module
=
0
;
if
(
status
==
STATUS_DLL_NOT_FOUND
&&
(
GetVersion
()
&
0x80000000
))
SetLastError
(
ERROR_DLL_NOT_FOUND
);
else
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
}
done:
RtlReleasePath
(
load_path
);
return
module
;
}
/****************************************************************************
* AddDllDirectory (kernelbase.@)
*/
...
...
@@ -84,6 +228,49 @@ BOOL WINAPI DECLSPEC_HOTPATCH DisableThreadLibraryCalls( HMODULE module )
/***********************************************************************
* FreeLibrary (kernelbase.@)
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
FreeLibrary
(
HINSTANCE
module
)
{
if
(
!
module
)
{
SetLastError
(
ERROR_INVALID_HANDLE
);
return
FALSE
;
}
if
((
ULONG_PTR
)
module
&
3
)
/* this is a datafile module */
{
void
*
ptr
=
(
void
*
)((
ULONG_PTR
)
module
&
~
3
);
if
(
!
RtlImageNtHeader
(
ptr
))
{
SetLastError
(
ERROR_BAD_EXE_FORMAT
);
return
FALSE
;
}
if
((
ULONG_PTR
)
module
&
1
)
{
struct
exclusive_datafile
*
file
;
ULONG_PTR
magic
;
LdrLockLoaderLock
(
0
,
NULL
,
&
magic
);
LIST_FOR_EACH_ENTRY
(
file
,
&
exclusive_datafile_list
,
struct
exclusive_datafile
,
entry
)
{
if
(
file
->
module
!=
module
)
continue
;
TRACE
(
"closing %p for module %p
\n
"
,
file
->
file
,
file
->
module
);
CloseHandle
(
file
->
file
);
list_remove
(
&
file
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
file
);
break
;
}
LdrUnlockLoaderLock
(
0
,
magic
);
}
return
UnmapViewOfFile
(
ptr
);
}
return
set_ntstatus
(
LdrUnloadDll
(
module
));
}
/***********************************************************************
* GetModuleFileNameA (kernelbase.@)
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetModuleFileNameA
(
HMODULE
module
,
LPSTR
filename
,
DWORD
size
)
...
...
@@ -239,6 +426,115 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetModuleHandleExW( DWORD flags, LPCWSTR name, HMO
}
/***********************************************************************
* GetProcAddress (kernelbase.@)
*/
#ifdef __x86_64__
/*
* Work around a Delphi bug on x86_64. When delay loading a symbol,
* Delphi saves rcx, rdx, r8 and r9 to the stack. It then calls
* GetProcAddress(), pops the saved registers and calls the function.
* This works fine if all of the parameters are ints. However, since
* it does not save xmm0 - 3, it relies on GetProcAddress() preserving
* these registers if the function takes floating point parameters.
* This wrapper saves xmm0 - 3 to the stack.
*/
__ASM_GLOBAL_FUNC
(
GetProcAddress
,
".byte 0x48
\n\t
"
/* hotpatch prolog */
"pushq %rbp
\n\t
"
__ASM_SEH
(
".seh_pushreg %rbp
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 8
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rbp,0
\n\t
"
)
"movq %rsp,%rbp
\n\t
"
__ASM_SEH
(
".seh_setframe %rbp,0
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa_register %rbp
\n\t
"
)
"subq $0x60,%rsp
\n\t
"
__ASM_SEH
(
".seh_stackalloc 0x60
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
"movaps %xmm0,-0x10(%rbp)
\n\t
"
"movaps %xmm1,-0x20(%rbp)
\n\t
"
"movaps %xmm2,-0x30(%rbp)
\n\t
"
"movaps %xmm3,-0x40(%rbp)
\n\t
"
"call "
__ASM_NAME
(
"get_proc_address"
)
"
\n\t
"
"movaps -0x40(%rbp), %xmm3
\n\t
"
"movaps -0x30(%rbp), %xmm2
\n\t
"
"movaps -0x20(%rbp), %xmm1
\n\t
"
"movaps -0x10(%rbp), %xmm0
\n\t
"
"leaq 0(%rbp),%rsp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa_register %rsp
\n\t
"
)
"popq %rbp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset -8
\n\t
"
)
__ASM_CFI
(
".cfi_same_value %rbp
\n\t
"
)
"ret"
)
#else
/* __x86_64__ */
FARPROC
WINAPI
DECLSPEC_HOTPATCH
GetProcAddress
(
HMODULE
module
,
LPCSTR
function
)
{
return
get_proc_address
(
module
,
function
);
}
#endif
/* __x86_64__ */
/***********************************************************************
* LoadLibraryA (kernelbase.@)
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryA
(
LPCSTR
name
)
{
return
LoadLibraryExA
(
name
,
0
,
0
);
}
/***********************************************************************
* LoadLibraryW (kernelbase.@)
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryW
(
LPCWSTR
name
)
{
return
LoadLibraryExW
(
name
,
0
,
0
);
}
/******************************************************************
* LoadLibraryExA (kernelbase.@)
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryExA
(
LPCSTR
name
,
HANDLE
file
,
DWORD
flags
)
{
WCHAR
*
nameW
;
if
(
!
(
nameW
=
file_name_AtoW
(
name
,
FALSE
)))
return
0
;
return
LoadLibraryExW
(
nameW
,
file
,
flags
);
}
/***********************************************************************
* LoadLibraryExW (kernelbase.@)
*/
HMODULE
WINAPI
DECLSPEC_HOTPATCH
LoadLibraryExW
(
LPCWSTR
name
,
HANDLE
file
,
DWORD
flags
)
{
UNICODE_STRING
str
;
HMODULE
module
;
if
(
!
name
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
RtlInitUnicodeString
(
&
str
,
name
);
if
(
str
.
Buffer
[
str
.
Length
/
sizeof
(
WCHAR
)
-
1
]
!=
' '
)
return
load_library
(
&
str
,
flags
);
/* library name has trailing spaces */
RtlCreateUnicodeString
(
&
str
,
name
);
while
(
str
.
Length
>
sizeof
(
WCHAR
)
&&
str
.
Buffer
[
str
.
Length
/
sizeof
(
WCHAR
)
-
1
]
==
' '
)
str
.
Length
-=
sizeof
(
WCHAR
);
str
.
Buffer
[
str
.
Length
/
sizeof
(
WCHAR
)]
=
0
;
module
=
load_library
(
&
str
,
flags
);
RtlFreeUnicodeString
(
&
str
);
return
module
;
}
/****************************************************************************
* RemoveDllDirectory (kernelbase.@)
*/
...
...
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