mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[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.
This commit is contained in:
parent
e8b048a282
commit
4e55236662
2 changed files with 80 additions and 130 deletions
|
@ -213,6 +213,60 @@ MiLoadImageSection(_Inout_ PSECTION *SectionPtr,
|
|||
return Status;
|
||||
}
|
||||
|
||||
#ifndef RVA
|
||||
#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
|
||||
#endif
|
||||
|
||||
USHORT
|
||||
NTAPI
|
||||
NameToOrdinal(
|
||||
_In_ PCSTR ExportName,
|
||||
_In_ PVOID ImageBase,
|
||||
_In_ ULONG NumberOfNames,
|
||||
_In_ PULONG NameTable,
|
||||
_In_ PUSHORT OrdinalTable)
|
||||
{
|
||||
LONG Low, Mid, High, Ret;
|
||||
|
||||
/* Fail if no names */
|
||||
if (!NumberOfNames)
|
||||
return -1;
|
||||
|
||||
/* Do a binary search */
|
||||
Low = Mid = 0;
|
||||
High = NumberOfNames - 1;
|
||||
while (High >= Low)
|
||||
{
|
||||
/* Get new middle value */
|
||||
Mid = (Low + High) >> 1;
|
||||
|
||||
/* Compare name */
|
||||
Ret = strcmp(ExportName, (PCHAR)RVA(ImageBase, NameTable[Mid]));
|
||||
if (Ret < 0)
|
||||
{
|
||||
/* Update high */
|
||||
High = Mid - 1;
|
||||
}
|
||||
else if (Ret > 0)
|
||||
{
|
||||
/* Update low */
|
||||
Low = Mid + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We got it */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we couldn't find it */
|
||||
if (High < Low)
|
||||
return -1;
|
||||
|
||||
/* Otherwise, this is the ordinal */
|
||||
return OrdinalTable[Mid];
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
MiLocateExportName(IN PVOID DllBase,
|
||||
|
@ -221,7 +275,6 @@ MiLocateExportName(IN PVOID DllBase,
|
|||
PULONG NameTable;
|
||||
PUSHORT OrdinalTable;
|
||||
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
|
||||
LONG Low = 0, Mid = 0, High, Ret;
|
||||
USHORT Ordinal;
|
||||
PVOID Function;
|
||||
ULONG ExportSize;
|
||||
|
@ -241,37 +294,15 @@ MiLocateExportName(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, (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,
|
||||
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;
|
||||
|
||||
/* 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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue