[APPWIZ] Update French translation
[reactos.git] / dll / ntdll / ldr / ldrapi.c
index 4b73bf9..b151163 100644 (file)
 /* INCLUDES *****************************************************************/
 
 #include <ntdll.h>
+
 #define NDEBUG
 #include <debug.h>
 
 /* GLOBALS *******************************************************************/
 
 LIST_ENTRY LdrpUnloadHead;
-LONG LdrpLoaderLockAcquisitonCount;
+LONG LdrpLoaderLockAcquisitionCount;
 BOOLEAN LdrpShowRecursiveLoads, LdrpBreakOnRecursiveDllLoads;
 UNICODE_STRING LdrApiDefaultExtension = RTL_CONSTANT_STRING(L".DLL");
 ULONG AlternateResourceModuleCount;
+extern PLDR_MANIFEST_PROBER_ROUTINE LdrpManifestProberRoutine;
 
 /* FUNCTIONS *****************************************************************/
 
+NTSTATUS
+NTAPI
+LdrFindCreateProcessManifest(IN ULONG Flags,
+                             IN PVOID Image,
+                             IN PVOID IdPath,
+                             IN ULONG IdPathLength,
+                             IN PVOID OutDataEntry)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+LdrDestroyOutOfProcessImage(IN PVOID Image)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+LdrCreateOutOfProcessImage(IN ULONG Flags,
+                           IN HANDLE ProcessHandle,
+                           IN HANDLE DllHandle,
+                           IN PVOID Unknown3)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+LdrAccessOutOfProcessResource(IN PVOID Unknown,
+                              IN PVOID Image,
+                              IN PVOID Unknown1,
+                              IN PVOID Unknown2,
+                              IN PVOID Unknown3)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+VOID
+NTAPI
+LdrSetDllManifestProber(
+    _In_ PLDR_MANIFEST_PROBER_ROUTINE Routine)
+{
+    LdrpManifestProberRoutine = Routine;
+}
+
 BOOLEAN
 NTAPI
 LdrAlternateResourcesEnabled(VOID)
@@ -31,13 +84,13 @@ LdrAlternateResourcesEnabled(VOID)
     return FALSE;
 }
 
-ULONG_PTR
 FORCEINLINE
+ULONG_PTR
 LdrpMakeCookie(VOID)
 {
     /* Generate a cookie */
     return (((ULONG_PTR)NtCurrentTeb()->RealClientId.UniqueThread & 0xFFF) << 16) |
-                        (_InterlockedIncrement(&LdrpLoaderLockAcquisitonCount) & 0xFFFF);
+            (_InterlockedIncrement(&LdrpLoaderLockAcquisitionCount) & 0xFFFF);
 }
 
 /*
@@ -71,7 +124,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
 
     /* Validate the cookie */
     if ((Cookie & 0xF0000000) ||
-        ((Cookie >> 16) ^ ((ULONG)(NtCurrentTeb()->RealClientId.UniqueThread) & 0xFFF)))
+        ((Cookie >> 16) ^ (HandleToUlong(NtCurrentTeb()->RealClientId.UniqueThread) & 0xFFF)))
     {
         DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
 
@@ -159,9 +212,6 @@ LdrLockLoaderLock(IN ULONG Flags,
         return STATUS_INVALID_PARAMETER_3;
     }
 
-    /* Do or Do Not. There is no Try */
-    ASSERT((Disposition != NULL) || !(Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY));
-
     /* If the flag is set, make sure we have a valid pointer to use */
     if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Disposition))
     {
@@ -256,6 +306,7 @@ LdrLockLoaderLock(IN ULONG Flags,
  */
 NTSTATUS
 NTAPI
+DECLSPEC_HOTPATCH
 LdrLoadDll(IN PWSTR SearchPath OPTIONAL,
            IN PULONG DllCharacteristics OPTIONAL,
            IN PUNICODE_STRING DllName,
@@ -265,15 +316,13 @@ LdrLoadDll(IN PWSTR SearchPath OPTIONAL,
     UNICODE_STRING DllString1, DllString2;
     BOOLEAN RedirectedDll = FALSE;
     NTSTATUS Status;
-    ULONG Cookie;
+    ULONG_PTR Cookie;
     PUNICODE_STRING OldTldDll;
     PTEB Teb = NtCurrentTeb();
 
     /* Initialize the strings */
+    RtlInitEmptyUnicodeString(&DllString1, StringBuffer, sizeof(StringBuffer));
     RtlInitEmptyUnicodeString(&DllString2, NULL, 0);
-    DllString1.Buffer = StringBuffer;
-    DllString1.Length = 0;
-    DllString1.MaximumLength = sizeof(StringBuffer);
 
     /* Check if the SxS Assemblies specify another file */
     Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE,
@@ -304,74 +353,80 @@ LdrLoadDll(IN PWSTR SearchPath OPTIONAL,
 
     /* Check if there's a TLD DLL being loaded */
     OldTldDll = LdrpTopLevelDllBeingLoaded;
-    if (OldTldDll)
+    _SEH2_TRY
     {
-        /* This is a recursive load, do something about it? */
-        if ((ShowSnaps) || (LdrpShowRecursiveLoads) || (LdrpBreakOnRecursiveDllLoads))
+
+        if (OldTldDll)
         {
-            /* Print out debug messages */
-            DPRINT1("[%lx, %lx] LDR: Recursive DLL Load\n",
-                    Teb->RealClientId.UniqueProcess,
-                    Teb->RealClientId.UniqueThread);
-            DPRINT1("[%lx, %lx]      Previous DLL being loaded \"%wZ\"\n",
-                    Teb->RealClientId.UniqueProcess,
-                    Teb->RealClientId.UniqueThread,
-                    OldTldDll);
-            DPRINT1("[%lx, %lx]      DLL being requested \"%wZ\"\n",
-                    Teb->RealClientId.UniqueProcess,
-                    Teb->RealClientId.UniqueThread,
-                    DllName);
-
-            /* Was it initializing too? */
-            if (!LdrpCurrentDllInitializer)
+            /* This is a recursive load, do something about it? */
+            if ((ShowSnaps) || (LdrpShowRecursiveLoads) || (LdrpBreakOnRecursiveDllLoads))
             {
-                DPRINT1("[%lx, %lx] LDR: No DLL Initializer was running\n",
+                /* Print out debug messages */
+                DPRINT1("[%p, %p] LDR: Recursive DLL Load\n",
                         Teb->RealClientId.UniqueProcess,
                         Teb->RealClientId.UniqueThread);
-            }
-            else
-            {
-                DPRINT1("[%lx, %lx]      DLL whose initializer was currently running \"%wZ\"\n",
-                        Teb->ClientId.UniqueProcess,
-                        Teb->ClientId.UniqueThread,
-                        &LdrpCurrentDllInitializer->BaseDllName);
+                DPRINT1("[%p, %p]      Previous DLL being loaded \"%wZ\"\n",
+                        Teb->RealClientId.UniqueProcess,
+                        Teb->RealClientId.UniqueThread,
+                        OldTldDll);
+                DPRINT1("[%p, %p]      DLL being requested \"%wZ\"\n",
+                        Teb->RealClientId.UniqueProcess,
+                        Teb->RealClientId.UniqueThread,
+                        DllName);
+
+                /* Was it initializing too? */
+                if (!LdrpCurrentDllInitializer)
+                {
+                    DPRINT1("[%p, %p] LDR: No DLL Initializer was running\n",
+                            Teb->RealClientId.UniqueProcess,
+                            Teb->RealClientId.UniqueThread);
+                }
+                else
+                {
+                    DPRINT1("[%p, %p]      DLL whose initializer was currently running \"%wZ\"\n",
+                            Teb->ClientId.UniqueProcess,
+                            Teb->ClientId.UniqueThread,
+                            &LdrpCurrentDllInitializer->BaseDllName);
+                }
             }
         }
-    }
 
-    /* Set this one as the TLD DLL being loaded*/
-    LdrpTopLevelDllBeingLoaded = DllName;
+        /* Set this one as the TLD DLL being loaded*/
+        LdrpTopLevelDllBeingLoaded = DllName;
 
-    /* Load the DLL */
-    Status = LdrpLoadDll(RedirectedDll,
-                         SearchPath,
-                         DllCharacteristics,
-                         DllName,
-                         BaseAddress,
-                         TRUE);
-    if (NT_SUCCESS(Status))
-    {
-        Status = STATUS_SUCCESS;
+        /* Load the DLL */
+        Status = LdrpLoadDll(RedirectedDll,
+                             SearchPath,
+                             DllCharacteristics,
+                             DllName,
+                             BaseAddress,
+                             TRUE);
+        if (NT_SUCCESS(Status))
+        {
+            Status = STATUS_SUCCESS;
+        }
+        else if ((Status != STATUS_NO_SUCH_FILE) &&
+                 (Status != STATUS_DLL_NOT_FOUND) &&
+                 (Status != STATUS_OBJECT_NAME_NOT_FOUND) &&
+                 (Status != STATUS_DLL_INIT_FAILED))
+        {
+            DbgPrintEx(DPFLTR_LDR_ID,
+                       DPFLTR_WARNING_LEVEL,
+                       "LDR: %s - failing because LdrpLoadDll(%wZ) returned status %x\n",
+                       __FUNCTION__,
+                       DllName,
+                       Status);
+        }
     }
-    else if ((Status != STATUS_NO_SUCH_FILE) &&
-             (Status != STATUS_DLL_NOT_FOUND) &&
-             (Status != STATUS_OBJECT_NAME_NOT_FOUND) &&
-             (Status != STATUS_DLL_INIT_FAILED))
+    _SEH2_FINALLY
     {
-        // 85 == DPFLTR_LDR_ID;
-        DbgPrintEx(85,
-                   DPFLTR_WARNING_LEVEL,
-                   "LDR: %s - failing because LdrpLoadDll(%wZ) returned status %x\n",
-                   __FUNCTION__,
-                   DllName,
-                   Status);
-    }
+        /* Restore the old TLD DLL */
+        LdrpTopLevelDllBeingLoaded = OldTldDll;
 
-    /* Restore the old TLD DLL */
-    LdrpTopLevelDllBeingLoaded = OldTldDll;
-
-    /* Release the lock */
-    LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
+        /* Release the lock */
+        LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
+    }
+    _SEH2_END;
 
     /* Do we have a redirect string? */
     if (DllString2.Buffer) RtlFreeUnicodeString(&DllString2);
@@ -428,7 +483,7 @@ LdrFindEntryForAddress(PVOID Address,
     while (NextEntry != ListHead)
     {
         /* Get the entry and NT Headers */
-        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);
+        LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
         NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
         if (NtHeader)
         {
@@ -451,8 +506,11 @@ LdrFindEntryForAddress(PVOID Address,
     }
 
     /* Nothing found */
-    // 85 == DPFLTR_LDR_ID;
-    DbgPrintEx(85, DPFLTR_WARNING_LEVEL, "LDR: %s() exiting 0x%08lx\n", __FUNCTION__, STATUS_NO_MORE_ENTRIES);
+    DbgPrintEx(DPFLTR_LDR_ID,
+               DPFLTR_WARNING_LEVEL,
+               "LDR: %s() exiting 0x%08lx\n",
+               __FUNCTION__,
+               STATUS_NO_MORE_ENTRIES);
     return STATUS_NO_MORE_ENTRIES;
 }
 
@@ -529,7 +587,7 @@ LdrGetDllHandleEx(IN ULONG Flags,
     }
     else if (Status != STATUS_SXS_KEY_NOT_FOUND)
     {
-        /* Unrecoverable SxS failure; */
+        /* Unrecoverable SxS failure */
         goto Quickie;
     }
     else
@@ -985,7 +1043,7 @@ LdrQueryProcessModuleInformationEx(IN ULONG ProcessId,
 
                 while (InitEntry != InitListHead)
                 {
-                    InitModule = CONTAINING_RECORD(InitEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
+                    InitModule = CONTAINING_RECORD(InitEntry, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
 
                     /* Increase the index */
                     ModulePtr->InitOrderIndex++;
@@ -1066,7 +1124,7 @@ LdrEnumerateLoadedModules(IN BOOLEAN ReservedFlag,
     PLIST_ENTRY ListHead, ListEntry;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     NTSTATUS Status;
-    ULONG Cookie;
+    ULONG_PTR Cookie;
     BOOLEAN Stop = FALSE;
 
     /* Check parameters */
@@ -1181,7 +1239,7 @@ LdrAddRefDll(IN ULONG Flags,
 {
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     NTSTATUS Status = STATUS_SUCCESS;
-    ULONG Cookie;
+    ULONG_PTR Cookie;
     BOOLEAN Locked = FALSE;
 
     /* Check for invalid flags */
@@ -1247,7 +1305,7 @@ quickie:
                             (Status != STATUS_DLL_NOT_FOUND) &&
                             (Status != STATUS_OBJECT_NAME_NOT_FOUND)))
         {
-            DPRINT1("LDR: LdrAddRefDll(%p) 0x%08lx\n", BaseAddress);
+            DPRINT1("LDR: LdrAddRefDll(%p) 0x%08lx\n", BaseAddress, Status);
         }
     }
 
@@ -1333,7 +1391,7 @@ LdrUnloadDll(IN PVOID BaseAddress)
         /* Get the entry */
         LdrEntry = CONTAINING_RECORD(NextEntry,
                                      LDR_DATA_TABLE_ENTRY,
-                                     InInitializationOrderModuleList);
+                                     InInitializationOrderLinks);
         NextEntry = NextEntry->Blink;
 
         /* Remove flag */
@@ -1345,7 +1403,7 @@ LdrUnloadDll(IN PVOID BaseAddress)
             /* Show message */
             if (ShowSnaps)
             {
-                DPRINT1("(%d) [%ws] %ws (%lx) deinit %lx\n",
+                DPRINT1("(%lu) [%ws] %ws (%lx) deinit %p\n",
                         LdrpActiveUnloadCount,
                         LdrEntry->BaseDllName.Buffer,
                         LdrEntry->FullDllName.Buffer,
@@ -1353,12 +1411,17 @@ LdrUnloadDll(IN PVOID BaseAddress)
                         LdrEntry->EntryPoint);
             }
 
-            /* FIXME: Call Shim Engine and notify */
+            /* Call Shim Engine and notify */
+            if (g_ShimsEnabled)
+            {
+                VOID (NTAPI* SE_DllUnloaded)(PVOID) = RtlDecodeSystemPointer(g_pfnSE_DllUnloaded);
+                SE_DllUnloaded(LdrEntry);
+            }
 
             /* Unlink it */
             CurrentEntry = LdrEntry;
-            RemoveEntryList(&CurrentEntry->InInitializationOrderModuleList);
-            RemoveEntryList(&CurrentEntry->InMemoryOrderModuleList);
+            RemoveEntryList(&CurrentEntry->InInitializationOrderLinks);
+            RemoveEntryList(&CurrentEntry->InMemoryOrderLinks);
             RemoveEntryList(&CurrentEntry->HashLinks);
 
             /* If there's more then one active unload */
@@ -1366,7 +1429,7 @@ LdrUnloadDll(IN PVOID BaseAddress)
             {
                 /* Flush the cached DLL handle and clear the list */
                 LdrpLoadedDllHandleCache = NULL;
-                CurrentEntry->InMemoryOrderModuleList.Flink = NULL;
+                CurrentEntry->InMemoryOrderLinks.Flink = NULL;
             }
 
             /* Add the entry on the unload list */
@@ -1392,7 +1455,7 @@ LdrUnloadDll(IN PVOID BaseAddress)
         /* Set the entry and clear it from the list */
         CurrentEntry = LdrEntry;
         LdrpLoadedDllHandleCache = NULL;
-        CurrentEntry->InMemoryOrderModuleList.Flink = NULL;
+        CurrentEntry->InMemoryOrderLinks.Flink = NULL;
 
         /* Move it from the global to the local list */
         RemoveEntryList(&CurrentEntry->HashLinks);
@@ -1407,7 +1470,7 @@ LdrUnloadDll(IN PVOID BaseAddress)
             /* Show message */
             if (ShowSnaps)
             {
-                DPRINT1("LDR: Calling deinit %lx\n", EntryPoint);
+                DPRINT1("LDR: Calling deinit %p\n", EntryPoint);
             }
 
             /* Set up the Act Ctx */
@@ -1420,10 +1483,19 @@ LdrUnloadDll(IN PVOID BaseAddress)
                                                    LdrEntry->EntryPointActivationContext);
 
             /* Call the entrypoint */
-            LdrpCallInitRoutine(LdrEntry->EntryPoint,
-                                LdrEntry->DllBase,
-                                DLL_PROCESS_DETACH,
-                                NULL);
+            _SEH2_TRY
+            {
+                LdrpCallInitRoutine(LdrEntry->EntryPoint,
+                                    LdrEntry->DllBase,
+                                    DLL_PROCESS_DETACH,
+                                    NULL);
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                DPRINT1("WARNING: Exception 0x%x during LdrpCallInitRoutine(DLL_PROCESS_DETACH) for %wZ\n",
+                        _SEH2_GetExceptionCode(), &LdrEntry->BaseDllName);
+            }
+            _SEH2_END;
 
             /* Release the context */
             RtlDeactivateActivationContextUnsafeFast(&ActCtx);
@@ -1447,7 +1519,7 @@ LdrUnloadDll(IN PVOID BaseAddress)
         /* Notify Application Verifier */
         if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAIL_CHECK)
         {
-            DPRINT1("We don't support Application Verifier yet\n");
+            AVrfDllUnloadNotification(LdrEntry);
         }
 
         /* Show message */
@@ -1532,6 +1604,24 @@ LdrProcessRelocationBlock(IN ULONG_PTR Address,
     return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta);
 }
 
+/* FIXME: Add to ntstatus.mc */
+#define STATUS_MUI_FILE_NOT_FOUND        ((NTSTATUS)0xC00B0001L)
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+LdrLoadAlternateResourceModule(IN PVOID Module,
+                               IN PWSTR Buffer)
+{
+    /* Is MUI Support enabled? */
+    if (!LdrAlternateResourcesEnabled()) return STATUS_SUCCESS;
+
+    UNIMPLEMENTED;
+    return STATUS_MUI_FILE_NOT_FOUND;
+}
+
 /*
  * @implemented
  */
@@ -1542,7 +1632,7 @@ LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)
     ULONG_PTR Cookie;
 
     /* Acquire the loader lock */
-    LdrLockLoaderLock(TRUE, NULL, &Cookie);
+    LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);
 
     /* Check if there's any alternate resources loaded */
     if (AlternateResourceModuleCount)
@@ -1557,22 +1647,15 @@ LdrUnloadAlternateResourceModule(IN PVOID BaseAddress)
     return TRUE;
 }
 
-/* FIXME: Add to ntstatus.mc */
-#define STATUS_MUI_FILE_NOT_FOUND        ((NTSTATUS)0xC00B0001L)
-
 /*
- * @implemented
+ * @unimplemented
  */
-NTSTATUS
+BOOLEAN
 NTAPI
-LdrLoadAlternateResourceModule(IN PVOID Module,
-                               IN PWSTR Buffer)
+LdrFlushAlternateResourceModules(VOID)
 {
-    /* Is MUI Support enabled? */
-    if (!LdrAlternateResourcesEnabled()) return STATUS_SUCCESS;
-
     UNIMPLEMENTED;
-    return STATUS_MUI_FILE_NOT_FOUND;
+    return FALSE;
 }
 
 /* EOF */