mirror of
https://github.com/reactos/reactos.git
synced 2025-07-15 16:24:02 +00:00
implemented GetModuleHandleExA/W(), LdrAddRefDll() and RtlPcToFileHeader() (untested)
svn path=/trunk/; revision=20802
This commit is contained in:
parent
426c237aa6
commit
f1c20bd848
6 changed files with 228 additions and 37 deletions
|
@ -106,4 +106,9 @@ typedef struct _LDR_RESOURCE_INFO
|
|||
ULONG Language;
|
||||
} LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO;
|
||||
|
||||
//
|
||||
// LdrAddRef Flags
|
||||
//
|
||||
#define LDR_PIN_MODULE 0x00000001
|
||||
|
||||
#endif
|
||||
|
|
|
@ -161,6 +161,14 @@ DbgUiIssueRemoteBreakin(
|
|||
//
|
||||
// Loader Functions
|
||||
//
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrAddRefDll(
|
||||
IN ULONG Flags,
|
||||
IN PVOID BaseAddress
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
LdrDisableThreadCalloutsForDll(
|
||||
|
@ -210,6 +218,13 @@ LdrLoadDll(
|
|||
OUT PVOID *BaseAddress OPTIONAL
|
||||
);
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
RtlPcToFileHeader(
|
||||
IN PVOID PcValue,
|
||||
PVOID* BaseOfImage
|
||||
);
|
||||
|
||||
PIMAGE_BASE_RELOCATION
|
||||
NTAPI
|
||||
LdrProcessRelocationBlock(
|
||||
|
|
|
@ -480,6 +480,129 @@ GetModuleHandleW (LPCWSTR lpModuleName)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetModuleHandleExW(IN DWORD dwFlags,
|
||||
IN LPCWSTR lpModuleName OPTIONAL,
|
||||
OUT HMODULE* phModule)
|
||||
{
|
||||
HMODULE hModule;
|
||||
NTSTATUS Status;
|
||||
BOOL Ret = FALSE;
|
||||
|
||||
if (phModule == NULL ||
|
||||
((dwFlags & (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) ==
|
||||
(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpModuleName == NULL)
|
||||
{
|
||||
hModule = NtCurrentPeb()->ImageBaseAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
|
||||
{
|
||||
hModule = (HMODULE)RtlPcToFileHeader((PVOID)lpModuleName,
|
||||
(PVOID*)&hModule);
|
||||
if (hModule == NULL)
|
||||
{
|
||||
SetLastErrorByStatus(STATUS_DLL_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hModule = GetModuleHandleW(lpModuleName);
|
||||
}
|
||||
}
|
||||
|
||||
if (hModule != NULL)
|
||||
{
|
||||
if (!(dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
|
||||
{
|
||||
Status = LdrAddRefDll((dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) ? LDR_PIN_MODULE : 0,
|
||||
hModule);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastErrorByStatus(Status);
|
||||
hModule = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
Ret = TRUE;
|
||||
}
|
||||
|
||||
*phModule = hModule;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetModuleHandleExA(IN DWORD dwFlags,
|
||||
IN LPCSTR lpModuleName OPTIONAL,
|
||||
OUT HMODULE* phModule)
|
||||
{
|
||||
UNICODE_STRING UnicodeName;
|
||||
ANSI_STRING ModuleName;
|
||||
LPCWSTR lpModuleNameW;
|
||||
NTSTATUS Status;
|
||||
BOOL Ret;
|
||||
|
||||
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
|
||||
{
|
||||
lpModuleNameW = (LPCWSTR)lpModuleName;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitAnsiString(&ModuleName,
|
||||
(LPSTR)lpModuleName);
|
||||
|
||||
/* convert ansi (or oem) string to unicode */
|
||||
if (bIsFileApiAnsi)
|
||||
Status = RtlAnsiStringToUnicodeString(&UnicodeName,
|
||||
&ModuleName,
|
||||
TRUE);
|
||||
else
|
||||
Status = RtlOemStringToUnicodeString(&UnicodeName,
|
||||
&ModuleName,
|
||||
TRUE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lpModuleNameW = UnicodeName.Buffer;
|
||||
}
|
||||
|
||||
Ret = GetModuleHandleExW(dwFlags,
|
||||
lpModuleNameW,
|
||||
phModule);
|
||||
|
||||
if (!(dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
|
||||
{
|
||||
RtlFreeUnicodeString(&UnicodeName);
|
||||
}
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
|
@ -1087,23 +1087,6 @@ GetFirmwareEnvironmentVariableW(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetModuleHandleExW(
|
||||
DWORD dwFlags,
|
||||
LPCWSTR lpModuleName,
|
||||
HMODULE* phModule
|
||||
)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
@ -1286,23 +1269,6 @@ GetFirmwareEnvironmentVariableA(
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetModuleHandleExA(
|
||||
DWORD dwFlags,
|
||||
LPCSTR lpModuleName,
|
||||
HMODULE* phModule
|
||||
)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
|
|
@ -35,6 +35,7 @@ KiUserApcDispatcher@16
|
|||
KiUserCallbackDispatcher@12
|
||||
KiUserExceptionDispatcher@8
|
||||
LdrAccessResource@16
|
||||
LdrAddRefDll@8
|
||||
LdrDisableThreadCalloutsForDll@4
|
||||
LdrEnumResources@20
|
||||
LdrFindEntryForAddress@8
|
||||
|
@ -576,7 +577,7 @@ RtlOemStringToUnicodeSize@4=RtlxOemStringToUnicodeSize@4
|
|||
RtlOemStringToUnicodeString@12
|
||||
RtlOemToUnicodeN@20
|
||||
RtlOpenCurrentUser@8
|
||||
;RtlPcToFileHeader
|
||||
RtlPcToFileHeader@8
|
||||
RtlPinAtomInAtomTable@8
|
||||
RtlPrefixString@12
|
||||
RtlPrefixUnicodeString@12
|
||||
|
|
|
@ -2135,7 +2135,7 @@ LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module,
|
|||
{
|
||||
/* ?????????????????? */
|
||||
}
|
||||
else if (LoadCount == 1)
|
||||
else if (!(Module->Flags & LDRP_STATIC_LINK) && LoadCount == 1)
|
||||
{
|
||||
BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
|
||||
RtlImageDirectoryEntryToData(Module->DllBase,
|
||||
|
@ -2207,7 +2207,11 @@ LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module,
|
|||
|
||||
if (Unload)
|
||||
{
|
||||
LdrpDetachProcess(FALSE);
|
||||
if (!(Module->Flags & LDRP_STATIC_LINK))
|
||||
{
|
||||
LdrpDetachProcess(FALSE);
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -2316,6 +2320,83 @@ LdrGetDllHandle(IN PWSTR DllPath OPTIONAL,
|
|||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
LdrAddRefDll(IN ULONG Flags,
|
||||
IN PVOID BaseAddress)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (Flags & ~(LDR_PIN_MODULE))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = STATUS_DLL_NOT_FOUND;
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
|
||||
|
||||
if (Module->DllBase == BaseAddress)
|
||||
{
|
||||
if (Flags & LDR_PIN_MODULE)
|
||||
{
|
||||
Module->Flags |= LDRP_STATIC_LINK;
|
||||
}
|
||||
else
|
||||
{
|
||||
LdrpIncrementLoadCount(Module,
|
||||
FALSE);
|
||||
}
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID NTAPI
|
||||
RtlPcToFileHeader(IN PVOID PcValue,
|
||||
PVOID* BaseOfImage)
|
||||
{
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_DATA_TABLE_ENTRY Module;
|
||||
PVOID ImageBase = NULL;
|
||||
|
||||
RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
|
||||
|
||||
if ((ULONG_PTR)PcValue >= (ULONG_PTR)Module->DllBase &&
|
||||
(ULONG_PTR)PcValue < (ULONG_PTR)Module->DllBase + Module->SizeOfImage)
|
||||
{
|
||||
ImageBase = Module->DllBase;
|
||||
break;
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
|
||||
|
||||
*BaseOfImage = ImageBase;
|
||||
return ImageBase;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue