implemented GetModuleHandleExA/W(), LdrAddRefDll() and RtlPcToFileHeader() (untested)

svn path=/trunk/; revision=20802
This commit is contained in:
Thomas Bluemel 2006-01-12 04:31:37 +00:00
parent 426c237aa6
commit f1c20bd848
6 changed files with 228 additions and 37 deletions

View file

@ -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

View file

@ -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(

View file

@ -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
*/

View file

@ -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
*/

View file

@ -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

View file

@ -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