[CMAKE]
[reactos.git] / dll / ntdll / ldr / utils.c
index 6a141eb..1cfb8c8 100644 (file)
@@ -5,6 +5,7 @@
  * PURPOSE:         Process startup for PE executables
  * PROGRAMMERS:     Jean Michault
  *                  Rex Jolliff (rex@lvcablemodem.com)
+ *                  Michael Martin
  */
 
 /*
@@ -60,6 +61,10 @@ static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
                                OUT PVOID *BaseAddress OPTIONAL);
 static NTSTATUS LdrpAttachProcess(VOID);
 static VOID LdrpDetachProcess(BOOLEAN UnloadAll);
+static NTSTATUS LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module, BOOLEAN Unload);
+
+NTSTATUS find_actctx_dll( LPCWSTR libname, WCHAR *fulldosname );
+NTSTATUS create_module_activation_context( LDR_DATA_TABLE_ENTRY *module );
 
 /* FUNCTIONS *****************************************************************/
 
@@ -83,10 +88,10 @@ static __inline LONG LdrpDecrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEA
        RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
      }
    LoadCount = Module->LoadCount;
-   if (Module->LoadCount > 0 && Module->LoadCount != LDRP_PROCESS_CREATION_TIME)
-     {
+    if (Module->LoadCount > 0 && Module->LoadCount != LDRP_PROCESS_CREATION_TIME)
+    {
        Module->LoadCount--;
-     }
+    }
    if (!Locked)
      {
        RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
@@ -102,10 +107,10 @@ static __inline LONG LdrpIncrementLoadCount(PLDR_DATA_TABLE_ENTRY Module, BOOLEA
        RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock);
      }
    LoadCount = Module->LoadCount;
-   if (Module->LoadCount != LDRP_PROCESS_CREATION_TIME)
-     {
+    if (Module->LoadCount != LDRP_PROCESS_CREATION_TIME)
+    {
        Module->LoadCount++;
-     }
+    }
    if (!Locked)
      {
        RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
@@ -251,7 +256,7 @@ LdrpQueryAppPaths(IN PCWSTR ImageName)
     /* Copy it to the heap allocd memory */
     Path = RtlAllocateHeap(RtlGetProcessHeap(),
                            0,
-                           wcslen(SearchPathBuffer) * sizeof(WCHAR));
+                           (wcslen(SearchPathBuffer) + 1) * sizeof(WCHAR));
 
     if (!Path)
     {
@@ -656,9 +661,12 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
                     IN BOOLEAN MapAsDataFile,
                     OUT PHANDLE SectionHandle)
 {
-  WCHAR                 SearchPathBuffer[MAX_PATH];
+  WCHAR                 *SearchPathBuffer = NULL;
+  WCHAR                 *ImagePathNameBufferPtr = NULL;
   WCHAR                 DosName[MAX_PATH];
   UNICODE_STRING        FullNtFileName;
+  UNICODE_STRING        PathEnvironmentVar_U;
+  UNICODE_STRING        PathName_U;
   OBJECT_ATTRIBUTES     FileObjectAttributes;
   HANDLE                FileHandle;
   char                  BlockBuffer [1024];
@@ -667,28 +675,84 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
   IO_STATUS_BLOCK       IoStatusBlock;
   NTSTATUS              Status;
   ULONG                 len;
+  ULONG                 ImagePathLen;
 
   DPRINT("LdrpMapDllImageFile() called\n");
 
   if (SearchPath == NULL)
     {
       /* get application running path */
+      ImagePathNameBufferPtr = NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer;
 
-      wcscpy (SearchPathBuffer, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
+      /* Length of ImagePathName */
+      ImagePathLen = wcslen(ImagePathNameBufferPtr);
 
-      len = wcslen (SearchPathBuffer);
+      /* Subtract application name leaveing only the directory length */
+      while (ImagePathLen && ImagePathNameBufferPtr[ImagePathLen - 1] != L'\\')
+          ImagePathLen--;
 
-      while (len && SearchPathBuffer[len - 1] != L'\\')
-           len--;
+      /* Length of directory + semicolon */
+      len = ImagePathLen + 1;
 
-      if (len) SearchPathBuffer[len-1] = L'\0';
+      /* Length of SystemRoot + "//system32"  + semicolon*/
+      len += wcslen(SharedUserData->NtSystemRoot) + 10;
+      /* Length of SystemRoot + semicolon */
+      len += wcslen(SharedUserData->NtSystemRoot) + 1;
 
-      wcscat (SearchPathBuffer, L";");
+      RtlInitUnicodeString (&PathName_U, L"PATH");
+      PathEnvironmentVar_U.Length = 0;
+      PathEnvironmentVar_U.MaximumLength = 0;
+      PathEnvironmentVar_U.Buffer = NULL;
+
+      /* Get the path environment variable */
+      Status = RtlQueryEnvironmentVariable_U(NULL, &PathName_U, &PathEnvironmentVar_U);
+
+      /* Check that valid information was returned */
+      if ((Status == STATUS_BUFFER_TOO_SMALL) && (PathEnvironmentVar_U.Length > 0))
+        {
+          /* Allocate memory for the path env var */
+          PathEnvironmentVar_U.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, PathEnvironmentVar_U.Length + sizeof(WCHAR));
+          if (!PathEnvironmentVar_U.Buffer)
+            {
+              DPRINT1("Fatal! Out of Memory!!\n");
+              return STATUS_NO_MEMORY;
+            }
+          PathEnvironmentVar_U.MaximumLength = PathEnvironmentVar_U.Length + sizeof(WCHAR);
+
+          /* Retry */
+          Status = RtlQueryEnvironmentVariable_U(NULL, &PathName_U, &PathEnvironmentVar_U);
+
+          if (!NT_SUCCESS(Status))
+            {
+              DPRINT1("Unable to get path environment string!\n");
+              ASSERT(FALSE);
+            }
+          /* Length of path evn var + semicolon */
+          len += (PathEnvironmentVar_U.Length / sizeof(WCHAR)) + 1;
+        }
+
+      /* Allocate the size needed to hold all the above paths + period */
+      SearchPathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, (len + 2) * sizeof(WCHAR));
+      if (!SearchPathBuffer)
+        {
+          DPRINT1("Fatal! Out of Memory!!\n");
+          return STATUS_NO_MEMORY;
+        }
 
+      wcsncpy(SearchPathBuffer, ImagePathNameBufferPtr, ImagePathLen);
+      wcscat (SearchPathBuffer, L";");
       wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
       wcscat (SearchPathBuffer, L"\\system32;");
       wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
-      wcscat (SearchPathBuffer, L";.");
+      wcscat (SearchPathBuffer, L";");
+
+      if (PathEnvironmentVar_U.Buffer)
+        {
+          wcscat (SearchPathBuffer, PathEnvironmentVar_U.Buffer);
+          wcscat (SearchPathBuffer, L";");
+          RtlFreeHeap(RtlGetProcessHeap(), 0, PathEnvironmentVar_U.Buffer);
+        }
+      wcscat (SearchPathBuffer, L".");
 
       SearchPath = SearchPathBuffer;
     }
@@ -699,13 +763,23 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
                           MAX_PATH,
                           DosName,
                           NULL) == 0)
-    return STATUS_DLL_NOT_FOUND;
+  {
+      /* try to find active context dll */
+    Status = find_actctx_dll(DllName->Buffer, DosName);
+    if(Status == STATUS_SUCCESS)
+        DPRINT("found %S for %S\n", DosName,DllName->Buffer);
+    else
+        return STATUS_DLL_NOT_FOUND;
+  }
 
   if (!RtlDosPathNameToNtPathName_U (DosName,
                                      &FullNtFileName,
                                      NULL,
                                      NULL))
+  {
+    DPRINT("Dll %wZ not found!\n", DllName);
     return STATUS_DLL_NOT_FOUND;
+  }
 
   DPRINT("FullNtFileName %wZ\n", &FullNtFileName);
 
@@ -825,25 +899,32 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
 {
   NTSTATUS              Status;
   PLDR_DATA_TABLE_ENTRY Module;
-
+  ULONG_PTR cookie;
   PPEB Peb = NtCurrentPeb();
 
-  TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n",
+  TRACE_LDR("LdrLoadDll loading %wZ%S%S with flags %d\n",
             Name,
             SearchPath ? L" from " : L"",
-            SearchPath ? SearchPath : L"");
+            SearchPath ? SearchPath : L"",
+            LoadFlags ? *LoadFlags : 0);
 
   Status = LdrpLoadModule(SearchPath, LoadFlags ? *LoadFlags : 0, Name, &Module, BaseAddress);
 
   if (NT_SUCCESS(Status) &&
       (!LoadFlags || 0 == (*LoadFlags & LOAD_LIBRARY_AS_DATAFILE)))
     {
+      if (!create_module_activation_context( Module ))
+         {
+        RtlActivateActivationContext(0, Module->EntryPointActivationContext, &cookie);
+      }
+
       if (!(Module->Flags & LDRP_PROCESS_ATTACH_CALLED))
         {
           RtlEnterCriticalSection(Peb->LoaderLock);
           Status = LdrpAttachProcess();
           RtlLeaveCriticalSection(Peb->LoaderLock);
         }
+       if (Module->EntryPointActivationContext) RtlDeactivateActivationContext(0, cookie);
     }
 
  if ((!Module) && (NT_SUCCESS(Status)))
@@ -1307,7 +1388,7 @@ LdrPerformRelocations(PIMAGE_NT_HEADERS NTHeaders,
   ULONG Count, ProtectSize, OldProtect, OldProtect2;
   PVOID Page, ProtectPage, ProtectPage2;
   PUSHORT TypeOffset;
-  ULONG_PTR Delta;
+  LONG_PTR Delta;
   NTSTATUS Status;
 
   if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
@@ -1426,10 +1507,10 @@ LdrpGetOrLoadModule(PWCHAR SearchPath,
    if (Load && !NT_SUCCESS(Status))
      {
        Status = LdrpLoadModule(SearchPath,
-                                                          0,
+                               0,
                                &DllName,
                                Module,
-                                                          NULL);
+                               NULL);
        if (NT_SUCCESS(Status))
          {
            Status = LdrFindEntryForName (&DllName, Module, FALSE);
@@ -1437,9 +1518,10 @@ LdrpGetOrLoadModule(PWCHAR SearchPath,
        if (!NT_SUCCESS(Status))
          {
            ULONG ErrorResponse;
-           ULONG_PTR ErrorParameter = (ULONG_PTR)&DllName;
+           ULONG_PTR ErrorParameter = (ULONG_PTR)&AnsiDllName;
 
            DPRINT1("failed to load %wZ\n", &DllName);
+
            NtRaiseHardError(STATUS_DLL_NOT_FOUND,
                             1,
                             1,
@@ -1518,6 +1600,9 @@ LdrpProcessImportDirectoryEntry(PLDR_DATA_TABLE_ENTRY Module,
        IATSize++;
      }
 
+   /* No need to fixup anything if IAT is empty */
+   if (IATSize == 0) return STATUS_SUCCESS;
+
    /* Unprotect the region we are about to write into. */
    IATBase = (PVOID)ImportAddressList;
    IATSize *= sizeof(PVOID*);
@@ -1756,11 +1841,12 @@ LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
    PIMAGE_TLS_DIRECTORY TlsDirectory;
    ULONG TlsSize = 0;
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
    PLDR_DATA_TABLE_ENTRY ImportedModule;
    PCHAR ImportedName;
    PWSTR ModulePath;
    ULONG Size;
+   ULONG_PTR cookie;
 
    DPRINT("LdrFixupImports(SearchPath %S, Module %p)\n", SearchPath, Module);
 
@@ -1784,6 +1870,16 @@ LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
          }
      }
 
+       if (!create_module_activation_context( Module ))
+         {
+           if (Module->EntryPointActivationContext == NULL)
+             {
+               DPRINT("EntryPointActivationContext has not be allocated\n");
+               DPRINT("Module->DllBaseName %wZ\n", Module->BaseDllName);
+             }
+           RtlActivateActivationContext( 0, Module->EntryPointActivationContext, &cookie );
+         }
+
    /*
     * Process each import module.
     */
@@ -1952,7 +2048,7 @@ LdrFixupImports(IN PWSTR SearchPath OPTIONAL,
            if (!NT_SUCCESS(Status))
              {
                DPRINT1("failed to load %s\n", ImportedName);
-               return Status;
+               break;
              }
 Success:
            if (Module == ImportedModule)
@@ -1966,10 +2062,29 @@ Success:
            if (!NT_SUCCESS(Status))
              {
                DPRINT1("failed to import %s\n", ImportedName);
-               return Status;
+               break;
              }
            ImportModuleDirectoryCurrent++;
          }
+
+         if (!NT_SUCCESS(Status))
+           {
+            NTSTATUS errorStatus = Status;
+
+            while (ImportModuleDirectoryCurrent >= ImportModuleDirectory)
+              {
+                ImportedName = (PCHAR)Module->DllBase + ImportModuleDirectoryCurrent->Name;
+
+                Status = LdrpGetOrLoadModule(NULL, ImportedName, &ImportedModule, FALSE);
+                if (NT_SUCCESS(Status) && Module != ImportedModule)
+                  {
+                    Status = LdrpUnloadModule(ImportedModule, FALSE);
+                    if (!NT_SUCCESS(Status)) DPRINT1("unable to unload %s\n", ImportedName);
+                  }
+                ImportModuleDirectoryCurrent--;
+              }
+            return errorStatus;
+           }
      }
 
    if (TlsDirectory && TlsSize > 0)
@@ -1977,6 +2092,8 @@ Success:
        LdrpAcquireTlsSlot(Module, TlsSize, FALSE);
      }
 
+    if (Module->EntryPointActivationContext) RtlDeactivateActivationContext( 0, cookie );
+
    return STATUS_SUCCESS;
 }
 
@@ -2019,6 +2136,7 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
    PIMAGE_DOS_HEADER    DosHeader;
    PIMAGE_NT_HEADERS    NTHeaders;
    PLDR_DATA_TABLE_ENTRY tmpModule;
+   PVOID ActivationContextStack;
 
    DPRINT("LdrPEStartup(ImageBase %p SectionHandle %p)\n",
            ImageBase, SectionHandle);
@@ -2066,6 +2184,19 @@ PEPFUNC LdrPEStartup (PVOID  ImageBase,
        (*Module)->Flags |= LDRP_IMAGE_NOT_AT_BASE;
      }
 
+   /* Allocate memory for the ActivationContextStack */
+   /* FIXME: Verify RtlAllocateActivationContextStack behavior */
+   Status = RtlAllocateActivationContextStack(&ActivationContextStack);
+   if (NT_SUCCESS(Status))
+   {
+      DPRINT("ActivationContextStack %x\n",ActivationContextStack);
+      DPRINT("ActiveFrame %x\n", ((PACTIVATION_CONTEXT_STACK)ActivationContextStack)->ActiveFrame);
+      NtCurrentTeb()->ActivationContextStackPointer = ActivationContextStack;
+      NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NULL;
+   }
+   else
+      DPRINT1("Warning: Unable to allocate ActivationContextStack\n");
+
    /*
     * If the DLL's imports symbols from other
     * modules, fixup the imported calls entry points.
@@ -2168,8 +2299,8 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
         /* Map the dll into the process */
         ViewSize = 0;
         ImageBase = 0;
-        ArbitraryUserPointer = NtCurrentTeb()->Tib.ArbitraryUserPointer;
-        NtCurrentTeb()->Tib.ArbitraryUserPointer = FullDosName.Buffer;
+        ArbitraryUserPointer = NtCurrentTeb()->NtTib.ArbitraryUserPointer;
+        NtCurrentTeb()->NtTib.ArbitraryUserPointer = FullDosName.Buffer;
         Status = NtMapViewOfSection(SectionHandle,
                                     NtCurrentProcess(),
                                     &ImageBase,
@@ -2180,7 +2311,7 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
                                     ViewShare,
                                     0,
                                     PAGE_READONLY);
-        NtCurrentTeb()->Tib.ArbitraryUserPointer = ArbitraryUserPointer;
+        NtCurrentTeb()->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
         if (!NT_SUCCESS(Status))
           {
             DPRINT1("map view of section failed (Status 0x%08lx)\n", Status);
@@ -2250,6 +2381,13 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
         if (!NT_SUCCESS(Status))
           {
             DPRINT1("LdrFixupImports failed for %wZ, status=%x\n", &(*Module)->BaseDllName, Status);
+            NtUnmapViewOfSection (NtCurrentProcess (), ImageBase);
+            NtClose (SectionHandle);
+            RtlFreeUnicodeString (&FullDosName);
+            RtlFreeUnicodeString (&(*Module)->FullDllName);
+            RtlFreeUnicodeString (&(*Module)->BaseDllName);
+            RemoveEntryList (&(*Module)->InLoadOrderLinks);
+            RtlFreeHeap (RtlGetProcessHeap (), 0, Module);
             return Status;
           }
 
@@ -2270,7 +2408,7 @@ LdrpUnloadModule(PLDR_DATA_TABLE_ENTRY Module,
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportDescriptorCurrent;
    PCHAR ImportedName;
    PLDR_DATA_TABLE_ENTRY ImportedModule;
-   NTSTATUS Status;
+   NTSTATUS Status = 0;
    LONG LoadCount;
    ULONG Size;
 
@@ -3199,6 +3337,7 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
                                    OUT PULONG ReturnedLength OPTIONAL)
 {
   PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+  CHAR KeyInfoBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 32];
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING ValueNameString;
   UNICODE_STRING KeyName;
@@ -3239,15 +3378,8 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
       return Status;
     }
 
-  KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 32;
-  KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
-                             HEAP_ZERO_MEMORY,
-                             KeyInfoSize);
-  if (KeyInfo == NULL)
-    {
-      NtClose (KeyHandle);
-      return STATUS_INSUFFICIENT_RESOURCES;
-    }
+  KeyInfoSize = sizeof(KeyInfoBuffer);
+  KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyInfoBuffer;
 
   RtlInitUnicodeString (&ValueNameString,
                         (PWSTR)ValueName);
@@ -3259,10 +3391,13 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
                             &ResultSize);
   if (Status == STATUS_BUFFER_OVERFLOW)
     {
+        /* We can allocate only if there is a process heap already */
+        if (!RtlGetProcessHeap())
+          {
+              NtClose (KeyHandle);
+              return STATUS_NO_MEMORY;
+          }
       KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + KeyInfo->DataLength;
-      RtlFreeHeap (RtlGetProcessHeap(),
-                   0,
-                   KeyInfo);
       KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
                                  KeyInfoSize);
@@ -3283,7 +3418,7 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
 
   if (!NT_SUCCESS(Status))
     {
-      if (KeyInfo != NULL)
+      if ((PCHAR)KeyInfo != KeyInfoBuffer)
         {
           RtlFreeHeap (RtlGetProcessHeap(),
                        0,
@@ -3294,9 +3429,12 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
 
   if (KeyInfo->Type != Type)
     {
-      RtlFreeHeap (RtlGetProcessHeap(),
-                   0,
-                   KeyInfo);
+      if ((PCHAR)KeyInfo != KeyInfoBuffer)
+        {
+          RtlFreeHeap (RtlGetProcessHeap(),
+                       0,
+                       KeyInfo);
+        }
       return STATUS_OBJECT_TYPE_MISMATCH;
     }
 
@@ -3313,9 +3451,12 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
                  &KeyInfo->Data,
                  ResultSize);
 
-  RtlFreeHeap (RtlGetProcessHeap(),
-               0,
-               KeyInfo);
+  if ((PCHAR)KeyInfo != KeyInfoBuffer)
+   {
+     RtlFreeHeap (RtlGetProcessHeap(),
+                  0,
+                  KeyInfo);
+  }
 
   if (ReturnedLength != NULL)
     {
@@ -3326,54 +3467,15 @@ LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING SubKey,
 }
 
 
-PIMAGE_BASE_RELOCATION NTAPI
-LdrProcessRelocationBlock(IN ULONG_PTR Address,
-                         IN ULONG Count,
-                         IN PUSHORT TypeOffset,
-                         IN LONG_PTR Delta)
+PIMAGE_BASE_RELOCATION
+NTAPI
+LdrProcessRelocationBlock(
+    IN ULONG_PTR Address,
+    IN ULONG Count,
+    IN PUSHORT TypeOffset,
+    IN LONG_PTR Delta)
 {
-  SHORT Offset;
-  USHORT Type;
-  USHORT i;
-  PUSHORT ShortPtr;
-  PULONG LongPtr;
-
-  for (i = 0; i < Count; i++)
-    {
-      Offset = *TypeOffset & 0xFFF;
-      Type = *TypeOffset >> 12;
-
-      switch (Type)
-        {
-          case IMAGE_REL_BASED_ABSOLUTE:
-            break;
-
-          case IMAGE_REL_BASED_HIGH:
-            ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
-            *ShortPtr += HIWORD(Delta);
-            break;
-
-          case IMAGE_REL_BASED_LOW:
-            ShortPtr = (PUSHORT)((ULONG_PTR)Address + Offset);
-            *ShortPtr += LOWORD(Delta);
-            break;
-
-          case IMAGE_REL_BASED_HIGHLOW:
-            LongPtr = (PULONG)((ULONG_PTR)Address + Offset);
-            *LongPtr += Delta;
-            break;
-
-          case IMAGE_REL_BASED_HIGHADJ:
-          case IMAGE_REL_BASED_MIPS_JMPADDR:
-          default:
-            DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
-            return NULL;
-        }
-
-      TypeOffset++;
-    }
-
-  return (PIMAGE_BASE_RELOCATION)TypeOffset;
+    return LdrProcessRelocationBlockLongLong(Address, Count, TypeOffset, Delta);
 }
 
 NTSTATUS