3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ldr/rtl.c
6 * PURPOSE: Loader utilities
8 * PROGRAMMERS: Jean Michault
9 * Rex Jolliff (rex@lvcablemodem.com)
12 /* INCLUDES *****************************************************************/
16 #include <internal/debug.h>
18 /* FUNCTIONS ****************************************************************/
21 LdrGetProcedureAddress (IN PVOID BaseAddress
,
24 OUT PVOID
*ProcedureAddress
)
26 PIMAGE_EXPORT_DIRECTORY ExportDir
;
27 ULONG ExportDirSize
= 0;
33 if (ProcedureAddress
== NULL
)
34 return STATUS_INVALID_PARAMETER
;
36 /* get the pointer to the export directory */
37 ExportDir
= RtlImageDirectoryEntryToData(BaseAddress
, TRUE
,
38 IMAGE_DIRECTORY_ENTRY_EXPORT
,
41 if (ExportDir
== NULL
|| ExportDirSize
== 0)
42 return STATUS_INVALID_PARAMETER
;
44 AddressPtr
= (PULONG
)RVA(BaseAddress
, ExportDir
->AddressOfFunctions
);
46 if (Name
&& Name
->Length
)
48 LONG minn
, maxn
, mid
, res
;
50 /* Search for export by name */
53 * NOTE: Exports are always sorted and so we can apply binary search.
54 * Also the function names are _case sensitive_, so respect that.
55 * -- Filip Navara, August 1st, 2005
58 OrdinalPtr
= (PUSHORT
)RVA(BaseAddress
, ExportDir
->AddressOfNameOrdinals
);
59 NamePtr
= (PULONG
)RVA(BaseAddress
, ExportDir
->AddressOfNames
);
61 minn
= 0; maxn
= ExportDir
->NumberOfNames
- 1;
64 mid
= (minn
+ maxn
) / 2;
65 CurrentNamePtr
= (PCHAR
)RVA(BaseAddress
, NamePtr
[mid
]);
66 res
= strncmp(CurrentNamePtr
, Name
->Buffer
, Name
->Length
);
70 * Check if the beginning of the name matched, but it's still
73 if (CurrentNamePtr
[Name
->Length
] != 0)
79 *ProcedureAddress
= (PVOID
)RVA(BaseAddress
, AddressPtr
[OrdinalPtr
[mid
]]);
80 return STATUS_SUCCESS
;
89 CPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name
);
93 /* Search for export by ordinal */
95 Ordinal
&= 0x0000FFFF;
96 if (Ordinal
- ExportDir
->Base
< ExportDir
->NumberOfFunctions
)
98 *ProcedureAddress
= (PVOID
)RVA(BaseAddress
, AddressPtr
[Ordinal
- ExportDir
->Base
]);
99 return STATUS_SUCCESS
;
102 CPRINT("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal
);
105 return STATUS_PROCEDURE_NOT_FOUND
;