https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4e55236662c75dff342d0…
commit 4e55236662c75dff342d04d47227fc686bd8f2a5
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Aug 22 19:06:34 2023 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Aug 29 17:26:56 2023 +0200
[NTOS:MM/PS] De-duplicate export name-to-ordinal functionality (#4918)
It was implemented in psmgr.c but in a recursive way. That implementation
is replaced, in the NameToOrdinal() helper, by the better non-recursive one
found in the MiLocateExportName() and MiFindExportedRoutineByName() functions.
This NameToOrdinal() helper is then called in lieu of the duplicated code
in MiLocateExportName() and MiFindExportedRoutineByName(). In addition,
one block of code in MiSnapThunk() is simplified in a similar manner.
---
ntoskrnl/mm/ARM3/sysldr.c | 160 +++++++++++++++++++++-------------------------
ntoskrnl/ps/psmgr.c | 46 ++-----------
2 files changed, 78 insertions(+), 128 deletions(-)
diff --git a/ntoskrnl/mm/ARM3/sysldr.c b/ntoskrnl/mm/ARM3/sysldr.c
index b17a53b82eb..89f394bddb5 100644
--- a/ntoskrnl/mm/ARM3/sysldr.c
+++ b/ntoskrnl/mm/ARM3/sysldr.c
@@ -213,43 +213,35 @@ MiLoadImageSection(_Inout_ PSECTION *SectionPtr,
return Status;
}
-PVOID
+#ifndef RVA
+#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
+#endif
+
+USHORT
NTAPI
-MiLocateExportName(IN PVOID DllBase,
- IN PCHAR ExportName)
+NameToOrdinal(
+ _In_ PCSTR ExportName,
+ _In_ PVOID ImageBase,
+ _In_ ULONG NumberOfNames,
+ _In_ PULONG NameTable,
+ _In_ PUSHORT OrdinalTable)
{
- PULONG NameTable;
- PUSHORT OrdinalTable;
- PIMAGE_EXPORT_DIRECTORY ExportDirectory;
- LONG Low = 0, Mid = 0, High, Ret;
- USHORT Ordinal;
- PVOID Function;
- ULONG ExportSize;
- PULONG ExportTable;
- PAGED_CODE();
+ LONG Low, Mid, High, Ret;
- /* Get the export directory */
- ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &ExportSize);
- if (!ExportDirectory) return NULL;
-
- /* Setup name tables */
- NameTable = (PULONG)((ULONG_PTR)DllBase +
- ExportDirectory->AddressOfNames);
- OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
- ExportDirectory->AddressOfNameOrdinals);
+ /* Fail if no names */
+ if (!NumberOfNames)
+ return -1;
/* Do a binary search */
- High = ExportDirectory->NumberOfNames - 1;
+ Low = Mid = 0;
+ High = NumberOfNames - 1;
while (High >= Low)
{
/* Get new middle value */
Mid = (Low + High) >> 1;
/* Compare name */
- Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);
+ Ret = strcmp(ExportName, (PCHAR)RVA(ImageBase, NameTable[Mid]));
if (Ret < 0)
{
/* Update high */
@@ -268,10 +260,49 @@ MiLocateExportName(IN PVOID DllBase,
}
/* Check if we couldn't find it */
- if (High < Low) return NULL;
+ if (High < Low)
+ return -1;
/* Otherwise, this is the ordinal */
- Ordinal = OrdinalTable[Mid];
+ return OrdinalTable[Mid];
+}
+
+PVOID
+NTAPI
+MiLocateExportName(IN PVOID DllBase,
+ IN PCHAR ExportName)
+{
+ PULONG NameTable;
+ PUSHORT OrdinalTable;
+ PIMAGE_EXPORT_DIRECTORY ExportDirectory;
+ USHORT Ordinal;
+ PVOID Function;
+ ULONG ExportSize;
+ PULONG ExportTable;
+ PAGED_CODE();
+
+ /* Get the export directory */
+ ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize);
+ if (!ExportDirectory) return NULL;
+
+ /* Setup name tables */
+ NameTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNames);
+ OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNameOrdinals);
+
+ /* Get the ordinal */
+ Ordinal = NameToOrdinal(ExportName,
+ DllBase,
+ ExportDirectory->NumberOfNames,
+ NameTable,
+ OrdinalTable);
+
+ /* Check if we couldn't find it */
+ if (Ordinal == -1) return NULL;
/* Resolve the address and write it */
ExportTable = (PULONG)((ULONG_PTR)DllBase +
@@ -486,7 +517,6 @@ MiFindExportedRoutineByName(IN PVOID DllBase,
PULONG NameTable;
PUSHORT OrdinalTable;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
- LONG Low = 0, Mid = 0, High, Ret;
USHORT Ordinal;
PVOID Function;
ULONG ExportSize;
@@ -506,37 +536,15 @@ MiFindExportedRoutineByName(IN PVOID DllBase,
OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
ExportDirectory->AddressOfNameOrdinals);
- /* Do a binary search */
- High = ExportDirectory->NumberOfNames - 1;
- while (High >= Low)
- {
- /* Get new middle value */
- Mid = (Low + High) >> 1;
-
- /* Compare name */
- Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
- if (Ret < 0)
- {
- /* Update high */
- High = Mid - 1;
- }
- else if (Ret > 0)
- {
- /* Update low */
- Low = Mid + 1;
- }
- else
- {
- /* We got it */
- break;
- }
- }
+ /* Get the ordinal */
+ Ordinal = NameToOrdinal(ExportName->Buffer,
+ DllBase,
+ ExportDirectory->NumberOfNames,
+ NameTable,
+ OrdinalTable);
/* Check if we couldn't find it */
- if (High < Low) return NULL;
-
- /* Otherwise, this is the ordinal */
- Ordinal = OrdinalTable[Mid];
+ if (Ordinal == -1) return NULL;
/* Validate the ordinal */
if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
@@ -696,8 +704,6 @@ MiSnapThunk(IN PVOID DllBase,
PUSHORT OrdinalTable;
PIMAGE_IMPORT_BY_NAME NameImport;
USHORT Hint;
- ULONG Low = 0, Mid = 0, High;
- LONG Ret;
NTSTATUS Status;
PCHAR MissingForwarder;
CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
@@ -751,40 +757,18 @@ MiSnapThunk(IN PVOID DllBase,
else
{
/* Do a binary search */
- High = ExportDirectory->NumberOfNames - 1;
- while (High >= Low)
- {
- /* Get new middle value */
- Mid = (Low + High) >> 1;
-
- /* Compare name */
- Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase +
NameTable[Mid]);
- if (Ret < 0)
- {
- /* Update high */
- High = Mid - 1;
- }
- else if (Ret > 0)
- {
- /* Update low */
- Low = Mid + 1;
- }
- else
- {
- /* We got it */
- break;
- }
- }
+ Ordinal = NameToOrdinal((PCHAR)NameImport->Name,
+ DllBase,
+ ExportDirectory->NumberOfNames,
+ NameTable,
+ OrdinalTable);
/* Check if we couldn't find it */
- if (High < Low)
+ if (Ordinal == -1)
{
DPRINT1("Warning: Driver failed to load, %s not found\n",
NameImport->Name);
return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
}
-
- /* Otherwise, this is the ordinal */
- Ordinal = OrdinalTable[Mid];
}
}
diff --git a/ntoskrnl/ps/psmgr.c b/ntoskrnl/ps/psmgr.c
index 80d9a964b3f..ad02cdfd82a 100644
--- a/ntoskrnl/ps/psmgr.c
+++ b/ntoskrnl/ps/psmgr.c
@@ -62,48 +62,14 @@ BOOLEAN PspDoingGiveBacks;
/* PRIVATE FUNCTIONS *********************************************************/
-CODE_SEG("INIT")
USHORT
NTAPI
-NameToOrdinal(IN PCHAR Name,
- IN PVOID DllBase,
- IN ULONG NumberOfNames,
- IN PULONG NameTable,
- IN PUSHORT OrdinalTable)
-{
- ULONG Mid;
- LONG Ret;
-
- /* Fail if no names */
- if (!NumberOfNames) return -1;
-
- /* Do binary search */
- Mid = NumberOfNames >> 1;
- Ret = strcmp(Name, (PCHAR)((ULONG_PTR)DllBase + NameTable[Mid]));
-
- /* Check if we found it */
- if (!Ret) return OrdinalTable[Mid];
-
- /* We didn't. Check if we only had one name to check */
- if (NumberOfNames == 1) return -1;
-
- /* Check if we should look up or down */
- if (Ret < 0)
- {
- /* Loop down */
- NumberOfNames = Mid;
- }
- else
- {
- /* Look up, update tables */
- NameTable = &NameTable[Mid + 1];
- OrdinalTable = &OrdinalTable[Mid + 1];
- NumberOfNames -= (Mid - 1);
- }
-
- /* Call us recursively */
- return NameToOrdinal(Name, DllBase, NumberOfNames, NameTable, OrdinalTable);
-}
+NameToOrdinal(
+ _In_ PCSTR ExportName,
+ _In_ PVOID ImageBase,
+ _In_ ULONG NumberOfNames,
+ _In_ PULONG NameTable,
+ _In_ PUSHORT OrdinalTable);
CODE_SEG("INIT")
NTSTATUS