mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:42:57 +00:00
[NTDLL/LDR]
- Improve LdrpCheckForKnownDll by adding parameters validation, return status value, better failure paths handling. svn path=/trunk/; revision=54606
This commit is contained in:
parent
eb919ba888
commit
9a63c24e07
2 changed files with 76 additions and 20 deletions
|
@ -59,6 +59,7 @@ BOOLEAN NTAPI LdrpCallInitRoutine(PDLL_INIT_ROUTINE EntryPoint, PVOID BaseAddres
|
||||||
NTSTATUS NTAPI LdrpInitializeProcess(PCONTEXT Context, PVOID SystemArgument1);
|
NTSTATUS NTAPI LdrpInitializeProcess(PCONTEXT Context, PVOID SystemArgument1);
|
||||||
VOID NTAPI LdrpInitFailure(NTSTATUS Status);
|
VOID NTAPI LdrpInitFailure(NTSTATUS Status);
|
||||||
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry);
|
VOID NTAPI LdrpValidateImageForMp(IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry);
|
||||||
|
VOID NTAPI LdrpEnsureLoaderLockIsHeld();
|
||||||
|
|
||||||
/* ldrpe.c */
|
/* ldrpe.c */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -663,12 +663,13 @@ LdrpFetchAddressOfEntryPoint(IN PVOID ImageBase)
|
||||||
return (PVOID)EntryPoint;
|
return (PVOID)EntryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: This function is broken, wrong number of parameters, no SxS, etc */
|
/* NOTE: This function is partially missing SxS */
|
||||||
HANDLE
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
LdrpCheckForKnownDll(PWSTR DllName,
|
LdrpCheckForKnownDll(PWSTR DllName,
|
||||||
PUNICODE_STRING FullDllName,
|
PUNICODE_STRING FullDllName,
|
||||||
PUNICODE_STRING BaseDllName)
|
PUNICODE_STRING BaseDllName,
|
||||||
|
HANDLE *SectionHandle)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
HANDLE Section = NULL;
|
HANDLE Section = NULL;
|
||||||
|
@ -677,9 +678,35 @@ LdrpCheckForKnownDll(PWSTR DllName,
|
||||||
PCHAR p1;
|
PCHAR p1;
|
||||||
PWCHAR p2;
|
PWCHAR p2;
|
||||||
|
|
||||||
|
/* Zero initialize provided parameters */
|
||||||
|
if (SectionHandle) *SectionHandle = 0;
|
||||||
|
|
||||||
|
if (FullDllName)
|
||||||
|
{
|
||||||
|
FullDllName->Length = 0;
|
||||||
|
FullDllName->MaximumLength = 0;
|
||||||
|
FullDllName->Buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BaseDllName)
|
||||||
|
{
|
||||||
|
BaseDllName->Length = 0;
|
||||||
|
BaseDllName->MaximumLength = 0;
|
||||||
|
BaseDllName->Buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If any of these three params are missing then fail */
|
||||||
|
if (!SectionHandle || !FullDllName || !BaseDllName)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* Check the Loader Lock */
|
||||||
|
LdrpEnsureLoaderLockIsHeld();
|
||||||
|
|
||||||
/* Upgrade DllName to a unicode string */
|
/* Upgrade DllName to a unicode string */
|
||||||
RtlInitUnicodeString(&DllNameUnic, DllName);
|
RtlInitUnicodeString(&DllNameUnic, DllName);
|
||||||
|
|
||||||
|
/* FIXME: Missing RtlComputePrivatizedDllName_U related functionality */
|
||||||
|
|
||||||
/* Get the activation context */
|
/* Get the activation context */
|
||||||
Status = RtlFindActivationContextSectionString(0,
|
Status = RtlFindActivationContextSectionString(0,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -691,13 +718,21 @@ LdrpCheckForKnownDll(PWSTR DllName,
|
||||||
if (Status == STATUS_SXS_SECTION_NOT_FOUND ||
|
if (Status == STATUS_SXS_SECTION_NOT_FOUND ||
|
||||||
Status == STATUS_SXS_KEY_NOT_FOUND)
|
Status == STATUS_SXS_KEY_NOT_FOUND)
|
||||||
{
|
{
|
||||||
|
/* NOTE: Here it's beneficial to allocate one big unicode string
|
||||||
|
using LdrpAllocateUnicodeString instead of fragmenting the heap
|
||||||
|
with two allocations as it's done now. */
|
||||||
|
|
||||||
/* 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(RtlGetProcessHeap(),
|
||||||
0,
|
0,
|
||||||
DllNameUnic.MaximumLength);
|
DllNameUnic.MaximumLength);
|
||||||
if (!BaseDllName->Buffer) return NULL;
|
if (!BaseDllName->Buffer)
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto Failure;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the contents there */
|
/* Copy the contents there */
|
||||||
RtlMoveMemory(BaseDllName->Buffer, DllNameUnic.Buffer, DllNameUnic.MaximumLength);
|
RtlMoveMemory(BaseDllName->Buffer, DllNameUnic.Buffer, DllNameUnic.MaximumLength);
|
||||||
|
@ -708,9 +743,8 @@ LdrpCheckForKnownDll(PWSTR DllName,
|
||||||
FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
|
FullDllName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullDllName->MaximumLength);
|
||||||
if (!FullDllName->Buffer)
|
if (!FullDllName->Buffer)
|
||||||
{
|
{
|
||||||
/* Free base name and fail */
|
Status = STATUS_NO_MEMORY;
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, BaseDllName->Buffer);
|
goto Failure;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlMoveMemory(FullDllName->Buffer, LdrpKnownDllPath.Buffer, LdrpKnownDllPath.Length);
|
RtlMoveMemory(FullDllName->Buffer, LdrpKnownDllPath.Buffer, LdrpKnownDllPath.Length);
|
||||||
|
@ -741,19 +775,26 @@ LdrpCheckForKnownDll(PWSTR DllName,
|
||||||
&ObjectAttributes);
|
&ObjectAttributes);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Opening failed, free resources */
|
/* Clear status in case it was just not found */
|
||||||
Section = NULL;
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND) Status = STATUS_SUCCESS;
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, BaseDllName->Buffer);
|
goto Failure;
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!NT_SUCCESS(Status)) Section = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return section handle */
|
/* Pass section handle to the caller and return success */
|
||||||
return Section;
|
*SectionHandle = Section;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
Failure:
|
||||||
|
/* Close section object if it was opened */
|
||||||
|
if (Section) NtClose(Section);
|
||||||
|
|
||||||
|
/* Free string resources */
|
||||||
|
if (BaseDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, BaseDllName->Buffer);
|
||||||
|
if (FullDllName->Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, FullDllName->Buffer);
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -893,9 +934,23 @@ LdrpMapDll(IN PWSTR SearchPath OPTIONAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to find a Known DLL */
|
/* Try to find a Known DLL */
|
||||||
SectionHandle = LdrpCheckForKnownDll(DllName,
|
Status = LdrpCheckForKnownDll(DllName,
|
||||||
&FullDllName,
|
&FullDllName,
|
||||||
&BaseDllName);
|
&BaseDllName,
|
||||||
|
&SectionHandle);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status) && (Status != STATUS_DLL_NOT_FOUND))
|
||||||
|
{
|
||||||
|
/* Failure */
|
||||||
|
DbgPrintEx(81, //DPFLTR_LDR_ID,
|
||||||
|
0,
|
||||||
|
"LDR: %s - call to LdrpCheckForKnownDll(\"%ws\", ...) failed with status %x\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
DllName,
|
||||||
|
Status);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipCheck:
|
SkipCheck:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue