implemented GetModuleHandleExA/W(), LdrAddRefDll() and RtlPcToFileHeader() (untested)
authorThomas Bluemel <thomas@reactsoft.com>
Thu, 12 Jan 2006 04:31:37 +0000 (04:31 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Thu, 12 Jan 2006 04:31:37 +0000 (04:31 +0000)
svn path=/trunk/; revision=20802

reactos/include/ndk/ldrtypes.h
reactos/include/ndk/umfuncs.h
reactos/lib/kernel32/misc/ldr.c
reactos/lib/kernel32/misc/stubs.c
reactos/lib/ntdll/def/ntdll.def
reactos/lib/ntdll/ldr/utils.c

index 17fde09..9d60d20 100644 (file)
@@ -106,4 +106,9 @@ typedef struct _LDR_RESOURCE_INFO
     ULONG Language;
 } LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO;
 
     ULONG Language;
 } LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO;
 
+//
+// LdrAddRef Flags
+//
+#define LDR_PIN_MODULE                  0x00000001
+
 #endif
 #endif
index eaea783..477c75f 100644 (file)
@@ -161,6 +161,14 @@ DbgUiIssueRemoteBreakin(
 //
 // Loader Functions
 //
 //
 // Loader Functions
 //
+
+NTSTATUS
+NTAPI
+LdrAddRefDll(
+    IN ULONG Flags,
+    IN PVOID BaseAddress
+);
+
 NTSTATUS
 NTAPI
 LdrDisableThreadCalloutsForDll(
 NTSTATUS
 NTAPI
 LdrDisableThreadCalloutsForDll(
@@ -210,6 +218,13 @@ LdrLoadDll(
     OUT PVOID *BaseAddress OPTIONAL
 );
 
     OUT PVOID *BaseAddress OPTIONAL
 );
 
+PVOID
+NTAPI
+RtlPcToFileHeader(
+    IN PVOID PcValue,
+    PVOID* BaseOfImage
+);
+
 PIMAGE_BASE_RELOCATION
 NTAPI
 LdrProcessRelocationBlock(
 PIMAGE_BASE_RELOCATION
 NTAPI
 LdrProcessRelocationBlock(
index 671321d..c8dcf3e 100644 (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
  */
 /*
  * @implemented
  */
index 360bc51..ba17227 100644 (file)
@@ -1087,23 +1087,6 @@ GetFirmwareEnvironmentVariableW(
     return 0;
 }
 
     return 0;
 }
 
-
-
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-GetModuleHandleExW(
-    DWORD        dwFlags,
-    LPCWSTR     lpModuleName,
-    HMODULE*    phModule
-    )
-{
-    STUB;
-    return 0;
-}
-
 /*
  * @unimplemented
  */
 /*
  * @unimplemented
  */
@@ -1286,23 +1269,6 @@ GetFirmwareEnvironmentVariableA(
     return 0;
 }
 
     return 0;
 }
 
-
-
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-GetModuleHandleExA(
-    DWORD        dwFlags,
-    LPCSTR     lpModuleName,
-    HMODULE*    phModule
-    )
-{
-    STUB;
-    return 0;
-}
-
 /*
  * @unimplemented
  */
 /*
  * @unimplemented
  */
index 8b042ea..ef3b141 100644 (file)
@@ -35,6 +35,7 @@ KiUserApcDispatcher@16
 KiUserCallbackDispatcher@12
 KiUserExceptionDispatcher@8
 LdrAccessResource@16
 KiUserCallbackDispatcher@12
 KiUserExceptionDispatcher@8
 LdrAccessResource@16
+LdrAddRefDll@8
 LdrDisableThreadCalloutsForDll@4
 LdrEnumResources@20
 LdrFindEntryForAddress@8
 LdrDisableThreadCalloutsForDll@4
 LdrEnumResources@20
 LdrFindEntryForAddress@8
@@ -576,7 +577,7 @@ RtlOemStringToUnicodeSize@4=RtlxOemStringToUnicodeSize@4
 RtlOemStringToUnicodeString@12
 RtlOemToUnicodeN@20
 RtlOpenCurrentUser@8
 RtlOemStringToUnicodeString@12
 RtlOemToUnicodeN@20
 RtlOpenCurrentUser@8
-;RtlPcToFileHeader
+RtlPcToFileHeader@8
 RtlPinAtomInAtomTable@8
 RtlPrefixString@12
 RtlPrefixUnicodeString@12
 RtlPinAtomInAtomTable@8
 RtlPrefixString@12
 RtlPrefixUnicodeString@12
index 76cabd3..f0ece8e 100644 (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,
      {
        BoundImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
                                  RtlImageDirectoryEntryToData(Module->DllBase,
@@ -2207,7 +2207,11 @@ LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module,
 
    if (Unload)
      {
 
    if (Unload)
      {
-       LdrpDetachProcess(FALSE);
+       if (!(Module->Flags & LDRP_STATIC_LINK))
+         {
+           LdrpDetachProcess(FALSE);
+         }
+
        RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
      }
    return STATUS_SUCCESS;
        RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock);
      }
    return STATUS_SUCCESS;
@@ -2316,6 +2320,83 @@ LdrGetDllHandle(IN PWSTR DllPath OPTIONAL,
     return STATUS_DLL_NOT_FOUND;
 }
 
     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
 
 /*
  * @implemented