Modified: trunk/reactos/include/ndk/ldrtypes.h
Modified: trunk/reactos/include/ndk/umfuncs.h
Modified: trunk/reactos/lib/kernel32/misc/ldr.c
Modified: trunk/reactos/lib/kernel32/misc/stubs.c
Modified: trunk/reactos/lib/ntdll/def/ntdll.def
Modified: trunk/reactos/lib/ntdll/ldr/utils.c
--- trunk/reactos/include/ndk/ldrtypes.h 2006-01-12 01:16:57 UTC (rev 20801)
+++ trunk/reactos/include/ndk/ldrtypes.h 2006-01-12 04:31:37 UTC (rev 20802)
@@ -106,4 +106,9 @@
ULONG Language;
} LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO;
+//
+// LdrAddRef Flags
+//
+#define LDR_PIN_MODULE 0x00000001
+
#endif
--- trunk/reactos/include/ndk/umfuncs.h 2006-01-12 01:16:57 UTC (rev 20801)
+++ trunk/reactos/include/ndk/umfuncs.h 2006-01-12 04:31:37 UTC (rev 20802)
@@ -161,8 +161,16 @@
//
// Loader Functions
//
+
NTSTATUS
NTAPI
+LdrAddRefDll(
+ IN ULONG Flags,
+ IN PVOID BaseAddress
+);
+
+NTSTATUS
+NTAPI
LdrDisableThreadCalloutsForDll(
IN PVOID BaseAddress
);
@@ -210,6 +218,13 @@
OUT PVOID *BaseAddress OPTIONAL
);
+PVOID
+NTAPI
+RtlPcToFileHeader(
+ IN PVOID PcValue,
+ PVOID* BaseOfImage
+);
+
PIMAGE_BASE_RELOCATION
NTAPI
LdrProcessRelocationBlock(
--- trunk/reactos/lib/kernel32/misc/ldr.c 2006-01-12 01:16:57 UTC (rev 20801)
+++ trunk/reactos/lib/kernel32/misc/ldr.c 2006-01-12 04:31:37 UTC (rev 20802)
@@ -483,6 +483,129 @@
/*
* @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
+ */
DWORD
STDCALL
LoadModule (
--- trunk/reactos/lib/kernel32/misc/stubs.c 2006-01-12 01:16:57 UTC (rev 20801)
+++ trunk/reactos/lib/kernel32/misc/stubs.c 2006-01-12 04:31:37 UTC (rev 20802)
@@ -1087,28 +1087,11 @@
return 0;
}
-
-
/*
* @unimplemented
*/
BOOL
STDCALL
-GetModuleHandleExW(
- DWORD dwFlags,
- LPCWSTR lpModuleName,
- HMODULE* phModule
- )
-{
- STUB;
- return 0;
-}
-
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
GetVolumePathNameW(
LPCWSTR lpszFileName,
LPWSTR lpszVolumePathName,
@@ -1286,28 +1269,11 @@
return 0;
}
-
-
/*
* @unimplemented
*/
BOOL
STDCALL
-GetModuleHandleExA(
- DWORD dwFlags,
- LPCSTR lpModuleName,
- HMODULE* phModule
- )
-{
- STUB;
- return 0;
-}
-
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
GetVolumeNameForVolumeMountPointA(
LPCSTR lpszVolumeMountPoint,
LPSTR lpszVolumeName,
--- trunk/reactos/lib/ntdll/def/ntdll.def 2006-01-12 01:16:57 UTC (rev 20801)
+++ trunk/reactos/lib/ntdll/def/ntdll.def 2006-01-12 04:31:37 UTC (rev 20802)
@@ -35,6 +35,7 @@
KiUserCallbackDispatcher@12
KiUserExceptionDispatcher@8
LdrAccessResource@16
+LdrAddRefDll@8
LdrDisableThreadCalloutsForDll@4
LdrEnumResources@20
LdrFindEntryForAddress@8
@@ -576,7 +577,7 @@
RtlOemStringToUnicodeString@12
RtlOemToUnicodeN@20
RtlOpenCurrentUser@8
-;RtlPcToFileHeader
+RtlPcToFileHeader@8
RtlPinAtomInAtomTable@8
RtlPrefixString@12
RtlPrefixUnicodeString@12
--- trunk/reactos/lib/ntdll/ldr/utils.c 2006-01-12 01:16:57 UTC (rev 20801)
+++ trunk/reactos/lib/ntdll/ldr/utils.c 2006-01-12 04:31:37 UTC (rev 20802)
@@ -2135,7 +2135,7 @@
{
/* ?????????????????? */
}
- 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 @@
if (Unload)
{
- LdrpDetachProcess(FALSE);
+ if (!(Module->Flags & LDRP_STATIC_LINK))
+ {
+ LdrpDetachProcess(FALSE);
+ }
+
RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
}
return STATUS_SUCCESS;
@@ -2316,10 +2320,87 @@
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
+ */
NTSTATUS NTAPI
LdrGetProcedureAddress (IN PVOID BaseAddress,
IN PANSI_STRING Name,