mirror of
https://github.com/reactos/reactos.git
synced 2025-06-25 23:49:43 +00:00
[LDR] Introduce a private heap for the loader.
This ensures we can still do stuff when the process heap is corrupted.
This commit is contained in:
parent
34b0516ec4
commit
04ff7481b1
3 changed files with 33 additions and 24 deletions
|
@ -32,6 +32,7 @@ typedef struct _LDRP_TLS_DATA
|
||||||
/* Global data */
|
/* Global data */
|
||||||
extern RTL_CRITICAL_SECTION LdrpLoaderLock;
|
extern RTL_CRITICAL_SECTION LdrpLoaderLock;
|
||||||
extern BOOLEAN LdrpInLdrInit;
|
extern BOOLEAN LdrpInLdrInit;
|
||||||
|
extern PVOID LdrpHeap;
|
||||||
extern LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
|
extern LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
|
||||||
extern BOOLEAN ShowSnaps;
|
extern BOOLEAN ShowSnaps;
|
||||||
extern UNICODE_STRING LdrpDefaultPath;
|
extern UNICODE_STRING LdrpDefaultPath;
|
||||||
|
|
|
@ -55,6 +55,7 @@ ULONG LdrpNumberOfProcessors;
|
||||||
PVOID NtDllBase;
|
PVOID NtDllBase;
|
||||||
extern LARGE_INTEGER RtlpTimeout;
|
extern LARGE_INTEGER RtlpTimeout;
|
||||||
BOOLEAN RtlpTimeoutDisable;
|
BOOLEAN RtlpTimeoutDisable;
|
||||||
|
PVOID LdrpHeap;
|
||||||
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
|
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
|
||||||
LIST_ENTRY LdrpDllNotificationList;
|
LIST_ENTRY LdrpDllNotificationList;
|
||||||
HANDLE LdrpKnownDllObjectDirectory;
|
HANDLE LdrpKnownDllObjectDirectory;
|
||||||
|
@ -663,7 +664,7 @@ LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL)
|
||||||
if (Count > 16)
|
if (Count > 16)
|
||||||
{
|
{
|
||||||
/* Allocate space for all the entries */
|
/* Allocate space for all the entries */
|
||||||
LdrRootEntry = RtlAllocateHeap(RtlGetProcessHeap(),
|
LdrRootEntry = RtlAllocateHeap(LdrpHeap,
|
||||||
0,
|
0,
|
||||||
Count * sizeof(*LdrRootEntry));
|
Count * sizeof(*LdrRootEntry));
|
||||||
if (!LdrRootEntry) return STATUS_NO_MEMORY;
|
if (!LdrRootEntry) return STATUS_NO_MEMORY;
|
||||||
|
@ -921,7 +922,7 @@ Quickie:
|
||||||
if (LdrRootEntry != LocalArray)
|
if (LdrRootEntry != LocalArray)
|
||||||
{
|
{
|
||||||
/* Free the array */
|
/* Free the array */
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, LdrRootEntry);
|
RtlFreeHeap(LdrpHeap, 0, LdrRootEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return to caller */
|
/* Return to caller */
|
||||||
|
@ -1752,9 +1753,9 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||||
&ConfigSize);
|
&ConfigSize);
|
||||||
|
|
||||||
/* Setup the Heap Parameters */
|
/* Setup the Heap Parameters */
|
||||||
RtlZeroMemory(&HeapParameters, sizeof(RTL_HEAP_PARAMETERS));
|
RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
|
||||||
HeapFlags = HEAP_GROWABLE;
|
HeapFlags = HEAP_GROWABLE;
|
||||||
HeapParameters.Length = sizeof(RTL_HEAP_PARAMETERS);
|
HeapParameters.Length = sizeof(HeapParameters);
|
||||||
|
|
||||||
/* Check if we have Configuration Data */
|
/* Check if we have Configuration Data */
|
||||||
if ((LoadConfig) && (ConfigSize == sizeof(IMAGE_LOAD_CONFIG_DIRECTORY)))
|
if ((LoadConfig) && (ConfigSize == sizeof(IMAGE_LOAD_CONFIG_DIRECTORY)))
|
||||||
|
@ -1875,8 +1876,15 @@ LdrpInitializeProcess(IN PCONTEXT Context,
|
||||||
Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
|
Status = RtlAllocateActivationContextStack(&Teb->ActivationContextStackPointer);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
// FIXME: Loader private heap is missing
|
RtlZeroMemory(&HeapParameters, sizeof(HeapParameters));
|
||||||
//DPRINT1("Loader private heap is missing\n");
|
HeapFlags = HEAP_GROWABLE | HEAP_CLASS_1;
|
||||||
|
HeapParameters.Length = sizeof(HeapParameters);
|
||||||
|
LdrpHeap = RtlCreateHeap(HeapFlags, 0, 0x10000, 0x6000, 0, &HeapParameters);
|
||||||
|
if (!LdrpHeap)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create loader private heap\n");
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for Debug Heap */
|
/* Check for Debug Heap */
|
||||||
if (OptionsKey)
|
if (OptionsKey)
|
||||||
|
|
|
@ -50,7 +50,7 @@ LdrpAllocateUnicodeString(IN OUT PUNICODE_STRING StringOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the string*/
|
/* Allocate the string*/
|
||||||
StringOut->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
StringOut->Buffer = RtlAllocateHeap(LdrpHeap,
|
||||||
0,
|
0,
|
||||||
StringOut->Length + sizeof(WCHAR));
|
StringOut->Length + sizeof(WCHAR));
|
||||||
if (!StringOut->Buffer)
|
if (!StringOut->Buffer)
|
||||||
|
@ -88,7 +88,7 @@ LdrpFreeUnicodeString(IN PUNICODE_STRING StringIn)
|
||||||
/* If Buffer is not NULL - free it */
|
/* If Buffer is not NULL - free it */
|
||||||
if (StringIn->Buffer)
|
if (StringIn->Buffer)
|
||||||
{
|
{
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StringIn->Buffer);
|
RtlFreeHeap(LdrpHeap, 0, StringIn->Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero it out */
|
/* Zero it out */
|
||||||
|
@ -703,7 +703,7 @@ LdrpResolveDllName(PWSTR DllPath,
|
||||||
ULONG BufSize = 500;
|
ULONG BufSize = 500;
|
||||||
|
|
||||||
/* Allocate space for full DLL name */
|
/* Allocate space for full DLL name */
|
||||||
FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufSize + sizeof(UNICODE_NULL));
|
FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BufSize + sizeof(UNICODE_NULL));
|
||||||
if (!FullDllName->Buffer) return FALSE;
|
if (!FullDllName->Buffer) return FALSE;
|
||||||
|
|
||||||
Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer,
|
Length = RtlDosSearchPath_U(DllPath ? DllPath : LdrpDefaultPath.Buffer,
|
||||||
|
@ -721,7 +721,7 @@ LdrpResolveDllName(PWSTR DllPath,
|
||||||
DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
|
DPRINT1("%ws from %ws\n", DllName, DllPath ? DllPath : LdrpDefaultPath.Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(FullDllName);
|
LdrpFreeUnicodeString(FullDllName);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,16 +730,16 @@ LdrpResolveDllName(PWSTR DllPath,
|
||||||
FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
|
FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
|
||||||
|
|
||||||
/* Allocate a new buffer */
|
/* Allocate a new buffer */
|
||||||
NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
|
NameBuffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
|
||||||
if (!NameBuffer)
|
if (!NameBuffer)
|
||||||
{
|
{
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
|
RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy over the contents from the previous one and free it */
|
/* Copy over the contents from the previous one and free it */
|
||||||
RtlCopyMemory(NameBuffer, FullDllName->Buffer, FullDllName->MaximumLength);
|
RtlCopyMemory(NameBuffer, FullDllName->Buffer, FullDllName->MaximumLength);
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
|
RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
|
||||||
FullDllName->Buffer = NameBuffer;
|
FullDllName->Buffer = NameBuffer;
|
||||||
|
|
||||||
/* Find last backslash */
|
/* Find last backslash */
|
||||||
|
@ -766,11 +766,11 @@ LdrpResolveDllName(PWSTR DllPath,
|
||||||
/* Construct base DLL name */
|
/* Construct base DLL name */
|
||||||
BaseDllName->Length = (ULONG_PTR)p1 - (ULONG_PTR)p2;
|
BaseDllName->Length = (ULONG_PTR)p1 - (ULONG_PTR)p2;
|
||||||
BaseDllName->MaximumLength = BaseDllName->Length + sizeof(UNICODE_NULL);
|
BaseDllName->MaximumLength = BaseDllName->Length + sizeof(UNICODE_NULL);
|
||||||
BaseDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BaseDllName->MaximumLength);
|
BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, BaseDllName->MaximumLength);
|
||||||
|
|
||||||
if (!BaseDllName->Buffer)
|
if (!BaseDllName->Buffer)
|
||||||
{
|
{
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
|
RtlFreeHeap(LdrpHeap, 0, NameBuffer);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,7 +867,7 @@ LdrpCheckForKnownDll(PWSTR DllName,
|
||||||
/* Set up BaseDllName */
|
/* Set up BaseDllName */
|
||||||
BaseDllName->Length = DllNameUnic.Length;
|
BaseDllName->Length = DllNameUnic.Length;
|
||||||
BaseDllName->MaximumLength = DllNameUnic.MaximumLength;
|
BaseDllName->MaximumLength = DllNameUnic.MaximumLength;
|
||||||
BaseDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
BaseDllName->Buffer = RtlAllocateHeap(LdrpHeap,
|
||||||
0,
|
0,
|
||||||
DllNameUnic.MaximumLength);
|
DllNameUnic.MaximumLength);
|
||||||
if (!BaseDllName->Buffer)
|
if (!BaseDllName->Buffer)
|
||||||
|
@ -882,7 +882,7 @@ LdrpCheckForKnownDll(PWSTR DllName,
|
||||||
/* Set up FullDllName */
|
/* Set up FullDllName */
|
||||||
FullDllName->Length = LdrpKnownDllPath.Length + BaseDllName->Length + sizeof(WCHAR);
|
FullDllName->Length = LdrpKnownDllPath.Length + BaseDllName->Length + sizeof(WCHAR);
|
||||||
FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
|
FullDllName->MaximumLength = FullDllName->Length + sizeof(UNICODE_NULL);
|
||||||
FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
|
FullDllName->Buffer = RtlAllocateHeap(LdrpHeap, 0, FullDllName->MaximumLength);
|
||||||
if (!FullDllName->Buffer)
|
if (!FullDllName->Buffer)
|
||||||
{
|
{
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
|
@ -932,8 +932,8 @@ Failure:
|
||||||
if (Section) NtClose(Section);
|
if (Section) NtClose(Section);
|
||||||
|
|
||||||
/* Free string resources */
|
/* Free string resources */
|
||||||
if (BaseDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, BaseDllName->Buffer);
|
if (BaseDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, BaseDllName->Buffer);
|
||||||
if (FullDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
|
if (FullDllName->Buffer) RtlFreeHeap(LdrpHeap, 0, FullDllName->Buffer);
|
||||||
|
|
||||||
/* Return status */
|
/* Return status */
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1137,8 +1137,8 @@ SkipCheck:
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Free the name strings and return */
|
/* Free the name strings and return */
|
||||||
RtlFreeUnicodeString(&FullDllName);
|
LdrpFreeUnicodeString(&FullDllName);
|
||||||
RtlFreeUnicodeString(&BaseDllName);
|
LdrpFreeUnicodeString(&BaseDllName);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1286,7 +1286,7 @@ SkipCheck:
|
||||||
RemoveEntryList(&LdrEntry->HashLinks);
|
RemoveEntryList(&LdrEntry->HashLinks);
|
||||||
|
|
||||||
/* Remove the LDR Entry */
|
/* Remove the LDR Entry */
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, LdrEntry );
|
RtlFreeHeap(LdrpHeap, 0, LdrEntry );
|
||||||
|
|
||||||
/* Unmap and close section */
|
/* Unmap and close section */
|
||||||
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
NtUnmapViewOfSection(NtCurrentProcess(), ViewBase);
|
||||||
|
@ -1553,7 +1553,7 @@ LdrpAllocateDataTableEntry(IN PVOID BaseAddress)
|
||||||
if (NtHeader)
|
if (NtHeader)
|
||||||
{
|
{
|
||||||
/* Allocate an entry */
|
/* Allocate an entry */
|
||||||
LdrEntry = RtlAllocateHeap(RtlGetProcessHeap(),
|
LdrEntry = RtlAllocateHeap(LdrpHeap,
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
sizeof(LDR_DATA_TABLE_ENTRY));
|
sizeof(LDR_DATA_TABLE_ENTRY));
|
||||||
|
|
||||||
|
@ -1608,7 +1608,7 @@ LdrpFinalizeAndDeallocateDataTableEntry(IN PLDR_DATA_TABLE_ENTRY Entry)
|
||||||
if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
|
if (Entry->FullDllName.Buffer) LdrpFreeUnicodeString(&Entry->FullDllName);
|
||||||
|
|
||||||
/* Finally free the entry's memory */
|
/* Finally free the entry's memory */
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Entry);
|
RtlFreeHeap(LdrpHeap, 0, Entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue