mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Improved internal dll handling
Implemented or fixed dll and resource functions svn path=/trunk/; revision=1328
This commit is contained in:
parent
dd7e38a19d
commit
df314ce26e
11 changed files with 650 additions and 269 deletions
|
@ -1,18 +1,26 @@
|
|||
typedef NTSTATUS (*PEPFUNC)(PPEB);
|
||||
|
||||
typedef struct _DLL
|
||||
typedef struct _LDR_MODULE
|
||||
{
|
||||
PIMAGE_NT_HEADERS Headers;
|
||||
PVOID BaseAddress;
|
||||
HANDLE SectionHandle;
|
||||
struct _DLL* Prev;
|
||||
struct _DLL* Next;
|
||||
UINT ReferenceCount;
|
||||
} DLL, *PDLL;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList; // not used
|
||||
LIST_ENTRY InInitializationOrderModuleList; // not used
|
||||
PVOID BaseAddress;
|
||||
ULONG EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullDllName;
|
||||
UNICODE_STRING BaseDllName;
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
HANDLE SectionHandle;
|
||||
ULONG CheckSum;
|
||||
ULONG TimeDateStamp;
|
||||
} LDR_MODULE, *PLDR_MODULE;
|
||||
|
||||
|
||||
#define RVA(m, b) ((ULONG)b + m)
|
||||
|
||||
extern DLL LdrDllListHead;
|
||||
|
||||
PEPFUNC LdrPEStartup(PVOID ImageBase, HANDLE SectionHandle);
|
||||
NTSTATUS LdrMapSections(HANDLE ProcessHandle,
|
||||
|
@ -25,8 +33,7 @@ NTSTATUS LdrMapNTDllForProcess(HANDLE ProcessHandle,
|
|||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LdrDisableThreadCalloutsForDll (IN PVOID BaseAddress,
|
||||
IN BOOLEAN Disable);
|
||||
LdrDisableThreadCalloutsForDll (IN PVOID BaseAddress);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LdrGetDllHandle (IN ULONG Unknown1,
|
||||
|
@ -52,6 +59,12 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
IN PUNICODE_STRING Name,
|
||||
OUT PVOID *BaseAddress OPTIONAL);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LdrShutdownProcess (VOID);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LdrShutdownThread (VOID);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LdrUnloadDll (IN PVOID BaseAddress);
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
#define UNIMPLEMENTED DbgPrint("%s in %s:%d is unimplemented\n",__FUNCTION__,__FILE__,__LINE__);
|
||||
|
||||
#ifndef NASSERT
|
||||
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); for(;;);}
|
||||
#else
|
||||
#define assert(x)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DPRINT(args...)
|
||||
#define CHECKPOINT
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: ldr.c,v 1.8 2000/08/27 22:37:45 ekohl Exp $
|
||||
/* $Id: ldr.c,v 1.9 2000/09/01 17:09:19 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT : ReactOS user mode libraries
|
||||
|
@ -18,6 +18,24 @@
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
DisableThreadLibraryCalls (
|
||||
HMODULE hLibModule
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = LdrDisableThreadCalloutsForDll ((PVOID)hLibModule);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
SetLastErrorByStatus (Status);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
HINSTANCE
|
||||
STDCALL
|
||||
LoadLibraryA (
|
||||
|
@ -38,7 +56,8 @@ LoadLibraryExA (
|
|||
{
|
||||
UNICODE_STRING LibFileNameU;
|
||||
ANSI_STRING LibFileName;
|
||||
HINSTANCE hInstance;
|
||||
HINSTANCE hInst;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlInitAnsiString (&LibFileName,
|
||||
(LPSTR)lpLibFileName);
|
||||
|
@ -53,13 +72,20 @@ LoadLibraryExA (
|
|||
&LibFileName,
|
||||
TRUE);
|
||||
|
||||
hInstance = LoadLibraryExW (LibFileNameU.Buffer,
|
||||
hFile,
|
||||
dwFlags);
|
||||
Status = LdrLoadDll(NULL,
|
||||
dwFlags,
|
||||
&LibFileNameU,
|
||||
(PVOID*)&hInst);
|
||||
|
||||
RtlFreeUnicodeString (&LibFileNameU);
|
||||
|
||||
return hInstance;
|
||||
if ( !NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus (Status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hInst;
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,42 +107,15 @@ LoadLibraryExW (
|
|||
DWORD dwFlags
|
||||
)
|
||||
{
|
||||
HINSTANCE hInst;
|
||||
int i;
|
||||
LPWSTR lpDllName;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DllName;
|
||||
HINSTANCE hInst;
|
||||
NTSTATUS Status;
|
||||
|
||||
if ( lpLibFileName == NULL )
|
||||
return NULL;
|
||||
|
||||
i = wcslen (lpLibFileName);
|
||||
// full path specified
|
||||
if ( lpLibFileName[2] == L':' ) {
|
||||
lpDllName = HeapAlloc(GetProcessHeap(),0,(i+3)*sizeof(WCHAR));
|
||||
wcscpy (lpDllName,L"\\??\\");
|
||||
wcscat (lpDllName,lpLibFileName);
|
||||
}
|
||||
// point at the end means no extension
|
||||
else if ( lpLibFileName[i-1] == L'.' ) {
|
||||
lpDllName = HeapAlloc(GetProcessHeap(),0,(i+1)*sizeof(WCHAR));
|
||||
wcscpy (lpDllName,lpLibFileName);
|
||||
lpDllName[i-1] = 0;
|
||||
}
|
||||
// no extension
|
||||
else if (i > 3 && lpLibFileName[i-3] != L'.' ) {
|
||||
lpDllName = HeapAlloc(GetProcessHeap(),0,(i+4)*sizeof(WCHAR));
|
||||
wcscpy (lpDllName,lpLibFileName);
|
||||
wcscat (lpDllName,L".dll");
|
||||
}
|
||||
else {
|
||||
lpDllName = HeapAlloc(GetProcessHeap(),0,(i+1)*sizeof(WCHAR));
|
||||
wcscpy (lpDllName,lpLibFileName);
|
||||
}
|
||||
|
||||
RtlInitUnicodeString (&DllName, lpDllName);
|
||||
RtlInitUnicodeString (&DllName, (LPWSTR)lpLibFileName);
|
||||
Status = LdrLoadDll(NULL, dwFlags, &DllName, (PVOID*)&hInst);
|
||||
HeapFree(GetProcessHeap(), 0, lpDllName);
|
||||
if ( !NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus (Status);
|
||||
|
@ -171,30 +170,158 @@ FreeLibraryAndExitThread (
|
|||
DWORD dwExitCode
|
||||
)
|
||||
{
|
||||
|
||||
if ( FreeLibrary(hLibModule) )
|
||||
ExitThread(dwExitCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetModuleFileNameA (
|
||||
HINSTANCE hModule,
|
||||
LPSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
ANSI_STRING FileName;
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_MODULE Module;
|
||||
PPEB Peb;
|
||||
ULONG Length = 0;
|
||||
|
||||
Peb = NtCurrentPeb ();
|
||||
RtlEnterCriticalSection (Peb->LoaderLock);
|
||||
|
||||
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
if (Module->BaseAddress == (PVOID)hModule)
|
||||
{
|
||||
if (nSize * sizeof(WCHAR) < Module->FullDllName.Length)
|
||||
{
|
||||
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileName.Length = 0;
|
||||
FileName.MaximumLength = nSize * sizeof(WCHAR);
|
||||
FileName.Buffer = lpFilename;
|
||||
|
||||
/* convert unicode string to ansi (or oem) */
|
||||
if (bIsFileApiAnsi)
|
||||
RtlUnicodeStringToAnsiString (&FileName,
|
||||
&Module->FullDllName,
|
||||
FALSE);
|
||||
else
|
||||
RtlUnicodeStringToOemString (&FileName,
|
||||
&Module->FullDllName,
|
||||
FALSE);
|
||||
Length = Module->FullDllName.Length / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection (Peb->LoaderLock);
|
||||
return Length;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
SetLastErrorByStatus (STATUS_DLL_NOT_FOUND);
|
||||
RtlLeaveCriticalSection (Peb->LoaderLock);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetModuleFileNameW (
|
||||
HINSTANCE hModule,
|
||||
LPWSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
UNICODE_STRING FileName;
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_MODULE Module;
|
||||
PPEB Peb;
|
||||
ULONG Length = 0;
|
||||
|
||||
Peb = NtCurrentPeb ();
|
||||
RtlEnterCriticalSection (Peb->LoaderLock);
|
||||
|
||||
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
|
||||
if (Module->BaseAddress == (PVOID)hModule)
|
||||
{
|
||||
if (nSize * sizeof(WCHAR) < Module->FullDllName.Length)
|
||||
{
|
||||
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileName.Length = 0;
|
||||
FileName.MaximumLength = nSize * sizeof(WCHAR);
|
||||
FileName.Buffer = lpFilename;
|
||||
|
||||
RtlCopyUnicodeString (&FileName,
|
||||
&Module->FullDllName);
|
||||
Length = Module->FullDllName.Length / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
RtlLeaveCriticalSection (Peb->LoaderLock);
|
||||
return Length;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
SetLastErrorByStatus (STATUS_DLL_NOT_FOUND);
|
||||
RtlLeaveCriticalSection (Peb->LoaderLock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HMODULE
|
||||
STDCALL
|
||||
GetModuleHandleA ( LPCSTR lpModuleName )
|
||||
{
|
||||
UNICODE_STRING ModuleName;
|
||||
UNICODE_STRING UnicodeName;
|
||||
ANSI_STRING ModuleName;
|
||||
PVOID BaseAddress;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz (&ModuleName,
|
||||
(LPSTR)lpModuleName);
|
||||
RtlInitAnsiString (&ModuleName,
|
||||
(LPSTR)lpModuleName);
|
||||
|
||||
/* convert ansi (or oem) string to unicode */
|
||||
if (bIsFileApiAnsi)
|
||||
RtlAnsiStringToUnicodeString (&UnicodeName,
|
||||
&ModuleName,
|
||||
TRUE);
|
||||
else
|
||||
RtlOemStringToUnicodeString (&UnicodeName,
|
||||
&ModuleName,
|
||||
TRUE);
|
||||
|
||||
Status = LdrGetDllHandle (0,
|
||||
0,
|
||||
&ModuleName,
|
||||
&UnicodeName,
|
||||
&BaseAddress);
|
||||
|
||||
RtlFreeUnicodeString (&ModuleName);
|
||||
RtlFreeUnicodeString (&UnicodeName);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: stubs.c,v 1.20 2000/08/27 22:37:45 ekohl Exp $
|
||||
/* $Id: stubs.c,v 1.21 2000/09/01 17:09:19 ekohl Exp $
|
||||
*
|
||||
* KERNEL32.DLL stubs (unimplemented functions)
|
||||
* Remove from this file, if you implement them.
|
||||
|
@ -1485,32 +1485,6 @@ GetMailslotInfo (
|
|||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetModuleFileNameW (
|
||||
HINSTANCE hModule,
|
||||
LPWSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetModuleFileNameA (
|
||||
HINSTANCE hModule,
|
||||
LPSTR lpFilename,
|
||||
DWORD nSize
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetNamedPipeHandleStateW (
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.17 2000/07/01 17:07:02 ea Exp $
|
||||
/* $Id: thread.c,v 1.18 2000/09/01 17:09:50 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -364,28 +364,4 @@ int STDCALL GetThreadPriority(HANDLE hThread)
|
|||
return ThreadBasic.BasePriority;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME */
|
||||
WINBOOL
|
||||
STDCALL
|
||||
DisableThreadLibraryCalls (
|
||||
HMODULE hLibModule
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = LdrDisableThreadCalloutsForDll (
|
||||
(PVOID) hLibModule,
|
||||
TRUE
|
||||
);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
SetLastErrorByStatus (Status);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.def,v 1.63 2000/08/28 21:46:55 ekohl Exp $
|
||||
; $Id: ntdll.def,v 1.64 2000/09/01 17:04:47 ekohl Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -33,7 +33,7 @@ DbgUserBreakPoint@0
|
|||
;KiUserCallbackDispatcher
|
||||
;KiUserExceptionDispatcher
|
||||
LdrAccessResource@16
|
||||
LdrDisableThreadCalloutsForDll@8
|
||||
LdrDisableThreadCalloutsForDll@4
|
||||
;LdrEnumResources
|
||||
;LdrFindEntryForAddress
|
||||
;LdrFindResourceDirectory_U
|
||||
|
@ -45,10 +45,10 @@ LdrLoadDll@16
|
|||
;LdrProcessRelocationBlock
|
||||
;LdrQueryImageFileExecutionOptions
|
||||
;LdrQueryProcessModuleInformation
|
||||
;LdrShutdownProcess
|
||||
;LdrShutdownThread
|
||||
LdrShutdownProcess@0
|
||||
LdrShutdownThread@0
|
||||
LdrUnloadDll@4
|
||||
;LdrVerifyImageMatchesChecksum
|
||||
;LdrVerifyImageMatchesChecksum@16
|
||||
NlsAnsiCodePage DATA
|
||||
NlsMbCodePageTag DATA
|
||||
NlsMbOemCodePageTag DATA
|
||||
|
@ -395,7 +395,7 @@ RtlFindClearBits@12
|
|||
RtlFindClearBitsAndSet@12
|
||||
RtlFindLongestRunClear@8
|
||||
RtlFindLongestRunSet@8
|
||||
;RtlFindMessage
|
||||
;RtlFindMessage@20
|
||||
RtlFindSetBits@12
|
||||
RtlFindSetBitsAndClear@12
|
||||
RtlFirstFreeAce@8
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.edf,v 1.52 2000/08/28 21:46:55 ekohl Exp $
|
||||
; $Id: ntdll.edf,v 1.53 2000/09/01 17:04:47 ekohl Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -33,7 +33,7 @@ DbgUserBreakPoint=DbgUserBreakPoint@0
|
|||
;KiUserCallbackDispatcher
|
||||
;KiUserExceptionDispatcher
|
||||
LdrAccessResource=LdrAccessResource@16
|
||||
LdrDisableThreadCalloutsForDll=LdrDisableThreadCalloutsForDll@8
|
||||
LdrDisableThreadCalloutsForDll=LdrDisableThreadCalloutsForDll@4
|
||||
;LdrEnumResources
|
||||
;LdrFindEntryForAddress
|
||||
;LdrFindResourceDirectory_U
|
||||
|
@ -45,10 +45,10 @@ LdrLoadDll=LdrLoadDll@16
|
|||
;LdrProcessRelocationBlock
|
||||
;LdrQueryImageFileExecutionOptions
|
||||
;LdrQueryProcessModuleInformation
|
||||
;LdrShutdownProcess
|
||||
;LdrShutdownThread
|
||||
LdrShutdownProcess=LdrShutdownProcess@0
|
||||
LdrShutdownThread=LdrShutdownThread@0
|
||||
LdrUnloadDll=LdrUnloadDll@4
|
||||
;LdrVerifyImageMatchesChecksum
|
||||
;LdrVerifyImageMatchesChecksum@16
|
||||
NlsAnsiCodePage DATA
|
||||
NlsMbCodePageTag DATA
|
||||
NlsMbOemCodePageTag DATA
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: startup.c,v 1.29 2000/08/12 19:33:18 dwelch Exp $
|
||||
/* $Id: startup.c,v 1.30 2000/09/01 17:05:09 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -17,6 +17,7 @@
|
|||
#include <ntdll/rtl.h>
|
||||
#include <csrss/csrss.h>
|
||||
#include <ntdll/csr.h>
|
||||
#include <napi/shared_data.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <ntdll/ntdll.h>
|
||||
|
@ -26,10 +27,11 @@ VOID RtlInitializeHeapManager (VOID);
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
DLL LdrDllListHead;
|
||||
|
||||
extern unsigned int _image_base__;
|
||||
|
||||
static CRITICAL_SECTION PebLock;
|
||||
static CRITICAL_SECTION LoaderLock;
|
||||
|
||||
ULONG NtGlobalFlag = 0;
|
||||
|
||||
|
@ -42,23 +44,20 @@ LdrInitializeThunk (ULONG Unknown1,
|
|||
ULONG Unknown3,
|
||||
ULONG Unknown4)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NTHeaders;
|
||||
PEPFUNC EntryPoint;
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
NTSTATUS Status;
|
||||
PIMAGE_NT_HEADERS NTHeaders;
|
||||
PVOID ImageBase;
|
||||
PPEB Peb;
|
||||
PLDR_MODULE NtModule; // ntdll
|
||||
PLDR_MODULE ExeModule; // executable
|
||||
PKUSER_SHARED_DATA SharedUserData =
|
||||
(PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
|
||||
WCHAR FullNtDllPath[MAX_PATH];
|
||||
|
||||
DPRINT("LdrInitializeThunk()\n");
|
||||
|
||||
LdrDllListHead.BaseAddress = (PVOID)&_image_base__;
|
||||
LdrDllListHead.Prev = &LdrDllListHead;
|
||||
LdrDllListHead.Next = &LdrDllListHead;
|
||||
LdrDllListHead.SectionHandle = NULL;
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER)LdrDllListHead.BaseAddress;
|
||||
LdrDllListHead.Headers = (PIMAGE_NT_HEADERS)(LdrDllListHead.BaseAddress +
|
||||
PEDosHeader->e_lfanew);
|
||||
|
||||
Peb = (PPEB)(PEB_BASE);
|
||||
DPRINT("Peb %x\n", Peb);
|
||||
ImageBase = Peb->ImageBaseAddress;
|
||||
|
@ -116,7 +115,107 @@ LdrInitializeThunk (ULONG Unknown1,
|
|||
Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
|
||||
Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
|
||||
|
||||
/* initalize loader lock */
|
||||
RtlInitializeCriticalSection (&LoaderLock);
|
||||
Peb->LoaderLock = &LoaderLock;
|
||||
|
||||
/* create loader information */
|
||||
Peb->Ldr = (PPEB_LDR_DATA)RtlAllocateHeap (Peb->ProcessHeap,
|
||||
0,
|
||||
sizeof(PEB_LDR_DATA));
|
||||
if (Peb->Ldr == NULL)
|
||||
{
|
||||
DbgPrint("Failed to create loader data\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
|
||||
Peb->Ldr->Initialized = FALSE;
|
||||
Peb->Ldr->SsHandle = NULL;
|
||||
InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
|
||||
InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
|
||||
InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
|
||||
|
||||
/* build full ntdll path */
|
||||
wcscpy (FullNtDllPath, SharedUserData->NtSystemRoot);
|
||||
wcscat (FullNtDllPath, L"\\system32\\ntdll.dll");
|
||||
|
||||
/* add entry for ntdll */
|
||||
NtModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
|
||||
0,
|
||||
sizeof(LDR_MODULE));
|
||||
if (NtModule == NULL)
|
||||
{
|
||||
DbgPrint("Failed to create loader module entry (NTDLL)\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NtModule->BaseAddress = (PVOID)&_image_base__;
|
||||
NtModule->EntryPoint = 0; /* no entry point */
|
||||
RtlCreateUnicodeString (&NtModule->FullDllName,
|
||||
FullNtDllPath);
|
||||
RtlCreateUnicodeString (&NtModule->BaseDllName,
|
||||
L"ntdll.dll");
|
||||
NtModule->Flags = 0;
|
||||
NtModule->LoadCount = -1; /* don't unload */
|
||||
NtModule->TlsIndex = 0;
|
||||
NtModule->SectionHandle = NULL;
|
||||
NtModule->CheckSum = 0;
|
||||
|
||||
NTHeaders = RtlImageNtHeader (NtModule->BaseAddress);
|
||||
NtModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
|
||||
NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||
|
||||
InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
|
||||
&NtModule->InLoadOrderModuleList);
|
||||
|
||||
|
||||
/* add entry for executable (becomes first list entry) */
|
||||
ExeModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap,
|
||||
0,
|
||||
sizeof(LDR_MODULE));
|
||||
if (ExeModule == NULL)
|
||||
{
|
||||
DbgPrint("Failed to create loader module infomation\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
ExeModule->BaseAddress = Peb->ImageBaseAddress;
|
||||
|
||||
if ((Peb->ProcessParameters != NULL) &&
|
||||
(Peb->ProcessParameters->ImagePathName.Length != 0))
|
||||
{
|
||||
RtlCreateUnicodeString (&ExeModule->FullDllName,
|
||||
Peb->ProcessParameters->ImagePathName.Buffer);
|
||||
RtlCreateUnicodeString (&ExeModule->BaseDllName,
|
||||
wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME(???): smss.exe doesn't have a process parameter block */
|
||||
RtlCreateUnicodeString (&ExeModule->BaseDllName,
|
||||
L"smss.exe");
|
||||
RtlCreateUnicodeString (&ExeModule->FullDllName,
|
||||
L"C:\\reactos\\system32\\smss.exe");
|
||||
}
|
||||
|
||||
ExeModule->Flags = 0;
|
||||
ExeModule->LoadCount = -1; /* don't unload */
|
||||
ExeModule->TlsIndex = 0;
|
||||
ExeModule->SectionHandle = NULL;
|
||||
ExeModule->CheckSum = 0;
|
||||
|
||||
NTHeaders = RtlImageNtHeader (ExeModule->BaseAddress);
|
||||
ExeModule->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
|
||||
ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||
|
||||
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
|
||||
&ExeModule->InLoadOrderModuleList);
|
||||
|
||||
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL);
|
||||
ExeModule->EntryPoint = (ULONG)EntryPoint;
|
||||
|
||||
/* all required dlls are loaded now */
|
||||
Peb->Ldr->Initialized = TRUE;
|
||||
|
||||
if (EntryPoint == NULL)
|
||||
{
|
||||
DbgPrint("Failed to initialize image\n");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: utils.c,v 1.31 2000/08/28 21:47:34 ekohl Exp $
|
||||
/* $Id: utils.c,v 1.32 2000/09/01 17:05:09 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -8,6 +8,13 @@
|
|||
* Rex Jolliff (rex@lvcablemodem.com)
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - Fix calling of entry points
|
||||
* - Handle loading flags correctly
|
||||
* - any more ??
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <reactos/config.h>
|
||||
|
@ -17,13 +24,15 @@
|
|||
#include <wchar.h>
|
||||
#include <ntdll/ldr.h>
|
||||
#include <ntos/minmax.h>
|
||||
#include <napi/shared_data.h>
|
||||
|
||||
|
||||
#ifdef DBG_NTDLL_LDR_UTILS
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#include <ntdll/ntdll.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
/* PROTOTYPES ****************************************************************/
|
||||
|
||||
|
||||
/* Type for a DLL's entry point */
|
||||
|
@ -31,18 +40,101 @@ typedef
|
|||
WINBOOL
|
||||
STDCALL
|
||||
(* PDLLMAIN_FUNC) (
|
||||
HANDLE hInst,
|
||||
HANDLE hInst,
|
||||
ULONG ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
);
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
LdrFindDll (PDLL* Dll,PUNICODE_STRING Name);
|
||||
//LdrFindDll (PDLL* Dll,PCHAR Name);
|
||||
LdrFindDll (PLDR_MODULE *Dll,PUNICODE_STRING Name);
|
||||
|
||||
/**********************************************************************
|
||||
* NAME
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* NAME LOCAL
|
||||
* LdrAdjustDllName
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Adjusts the name of a dll to a fully qualified name.
|
||||
*
|
||||
* ARGUMENTS
|
||||
* FullDllName: Pointer to caller supplied storage for the fully
|
||||
* qualified dll name.
|
||||
* DllName: Pointer to the dll name.
|
||||
* BaseName: TRUE: Only the file name is passed to FullDllName
|
||||
* FALSE: The full path is preserved in FullDllName
|
||||
*
|
||||
* RETURN VALUE
|
||||
* None
|
||||
*
|
||||
* REVISIONS
|
||||
*
|
||||
* NOTE
|
||||
* A given path is not affected by the adjustment, but the file
|
||||
* name only:
|
||||
* ntdll --> ntdll.dll
|
||||
* ntdll. --> ntdll
|
||||
* ntdll.xyz --> ntdll.xyz
|
||||
*/
|
||||
|
||||
static VOID
|
||||
LdrAdjustDllName (PUNICODE_STRING FullDllName,
|
||||
PUNICODE_STRING DllName,
|
||||
BOOLEAN BaseName)
|
||||
{
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
ULONG Length;
|
||||
PWCHAR Extension;
|
||||
PWCHAR Pointer;
|
||||
|
||||
Length = DllName->Length / sizeof(WCHAR);
|
||||
|
||||
if (BaseName == TRUE)
|
||||
{
|
||||
/* get the base dll name */
|
||||
Pointer = DllName->Buffer + Length;
|
||||
Extension = Pointer;
|
||||
|
||||
do
|
||||
{
|
||||
--Pointer;
|
||||
}
|
||||
while (Pointer >= DllName->Buffer && *Pointer != L'\\' && *Pointer != L'/');
|
||||
|
||||
Pointer++;
|
||||
Length = Extension - Pointer;
|
||||
memmove (Buffer, Pointer, Length * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* get the full dll name */
|
||||
memmove (Buffer, DllName->Buffer, DllName->Length);
|
||||
}
|
||||
|
||||
/* Build the DLL's absolute name */
|
||||
Extension = wcsrchr (Buffer, L'.');
|
||||
if ((Extension != NULL) && (*Extension == L'.'))
|
||||
{
|
||||
/* with extension - remove dot if it's the last character */
|
||||
if (Buffer[Length - 1] == L'.')
|
||||
Length--;
|
||||
Buffer[Length] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* name without extension - assume that it is .dll */
|
||||
memmove (Buffer + Length, L".dll", 10);
|
||||
}
|
||||
|
||||
RtlCreateUnicodeString (FullDllName,
|
||||
Buffer);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* NAME EXPORTED
|
||||
* LdrLoadDll
|
||||
*
|
||||
* DESCRIPTION
|
||||
|
@ -63,8 +155,10 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
IN PUNICODE_STRING Name,
|
||||
OUT PVOID *BaseAddress OPTIONAL)
|
||||
{
|
||||
WCHAR fqname [255] = L"\\SystemRoot\\system32\\";
|
||||
UNICODE_STRING UnicodeString;
|
||||
WCHAR SearchPathBuffer[MAX_PATH];
|
||||
WCHAR FullDosName[MAX_PATH];
|
||||
UNICODE_STRING AdjustedName;
|
||||
UNICODE_STRING FullNtFileName;
|
||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||
char BlockBuffer [1024];
|
||||
PIMAGE_DOS_HEADER DosHeader;
|
||||
|
@ -76,11 +170,11 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
HANDLE FileHandle;
|
||||
HANDLE SectionHandle;
|
||||
PDLLMAIN_FUNC Entrypoint = NULL;
|
||||
PDLL Dll;
|
||||
PLDR_MODULE Module;
|
||||
|
||||
if ( Name == NULL )
|
||||
{
|
||||
*BaseAddress = LdrDllListHead.BaseAddress;
|
||||
*BaseAddress = NtCurrentPeb()->ImageBaseAddress;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -89,42 +183,67 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
DPRINT("LdrLoadDll(Name \"%wZ\" BaseAddress %x)\n",
|
||||
Name, BaseAddress);
|
||||
|
||||
/*
|
||||
* Build the DLL's absolute name
|
||||
*/
|
||||
|
||||
if (wcsncmp(Name->Buffer, L"\\??\\", 3) != 0)
|
||||
{
|
||||
wcscat(fqname, Name->Buffer);
|
||||
}
|
||||
else
|
||||
wcsncpy(fqname, Name->Buffer, 256);
|
||||
|
||||
DPRINT("fqname \"%S\"\n", fqname);
|
||||
/* adjust the full dll name */
|
||||
LdrAdjustDllName (&AdjustedName,
|
||||
Name,
|
||||
FALSE);
|
||||
DPRINT("AdjustedName: %wZ\n", &AdjustedName);
|
||||
|
||||
/*
|
||||
* Open the DLL's image file.
|
||||
* Test if dll is already loaded.
|
||||
*/
|
||||
if (LdrFindDll(&Dll, Name) == STATUS_SUCCESS)
|
||||
if (LdrFindDll(&Module, &AdjustedName) == STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT ("DLL %wZ already loaded.\n", Name);
|
||||
*BaseAddress = Dll->BaseAddress;
|
||||
DPRINT("DLL %wZ already loaded.\n", &AdjustedName);
|
||||
if (Module->LoadCount != -1)
|
||||
Module->LoadCount++;
|
||||
*BaseAddress = Module->BaseAddress;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&UnicodeString,
|
||||
fqname);
|
||||
if (SearchPath == NULL)
|
||||
{
|
||||
PKUSER_SHARED_DATA SharedUserData =
|
||||
(PKUSER_SHARED_DATA)USER_SHARED_DATA_BASE;
|
||||
|
||||
SearchPath = SearchPathBuffer;
|
||||
wcscpy (SearchPathBuffer, SharedUserData->NtSystemRoot);
|
||||
wcscat (SearchPathBuffer, L"\\system32;");
|
||||
wcscat (SearchPathBuffer, SharedUserData->NtSystemRoot);
|
||||
}
|
||||
|
||||
DPRINT("SearchPath %S\n", SearchPath);
|
||||
|
||||
if (RtlDosSearchPath_U (SearchPath,
|
||||
AdjustedName.Buffer,
|
||||
NULL,
|
||||
MAX_PATH,
|
||||
FullDosName,
|
||||
NULL) == 0)
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
|
||||
DPRINT("FullDosName %S\n", FullDosName);
|
||||
|
||||
RtlFreeUnicodeString (&AdjustedName);
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U (FullDosName,
|
||||
&FullNtFileName,
|
||||
NULL,
|
||||
NULL))
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
|
||||
DPRINT("FullNtFileName %wZ\n", &FullNtFileName);
|
||||
|
||||
InitializeObjectAttributes(
|
||||
& FileObjectAttributes,
|
||||
& UnicodeString,
|
||||
& FullNtFileName,
|
||||
0,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
DPRINT("Opening dll \"%wZ\"\n", &UnicodeString);
|
||||
|
||||
DPRINT("Opening dll \"%wZ\"\n", &FullNtFileName);
|
||||
|
||||
Status = ZwOpenFile(
|
||||
& FileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
|
@ -136,9 +255,12 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("Dll open of %wZ failed: Status = 0x%08x\n",
|
||||
&UnicodeString, Status);
|
||||
&FullNtFileName, Status);
|
||||
RtlFreeUnicodeString (&FullNtFileName);
|
||||
return Status;
|
||||
}
|
||||
RtlFreeUnicodeString (&FullNtFileName);
|
||||
|
||||
Status = ZwReadFile(
|
||||
FileHandle,
|
||||
0,
|
||||
|
@ -198,6 +320,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
ZwClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the dll into the process.
|
||||
*/
|
||||
|
@ -226,34 +349,55 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
}
|
||||
ZwClose(FileHandle);
|
||||
|
||||
Dll = RtlAllocateHeap(
|
||||
Module = RtlAllocateHeap(
|
||||
RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof (DLL)
|
||||
sizeof (LDR_MODULE)
|
||||
);
|
||||
Dll->Headers = NTHeaders;
|
||||
Dll->BaseAddress = (PVOID)ImageBase;
|
||||
Dll->Next = LdrDllListHead.Next;
|
||||
Dll->Prev = & LdrDllListHead;
|
||||
Dll->ReferenceCount = 1;
|
||||
LdrDllListHead.Next->Prev = Dll;
|
||||
LdrDllListHead.Next = Dll;
|
||||
Module->BaseAddress = (PVOID)ImageBase;
|
||||
Module->SizeOfImage = ImageSize;
|
||||
if (NtCurrentPeb()->Ldr->Initialized == TRUE)
|
||||
{
|
||||
/* loading while app is running */
|
||||
Module->LoadCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* loading while app is initializing
|
||||
* dll must not be unloaded
|
||||
*/
|
||||
Module->LoadCount = -1;
|
||||
}
|
||||
|
||||
Module->TlsIndex = 0; // ???
|
||||
Module->CheckSum = 0; // ???
|
||||
Module->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
|
||||
|
||||
if ((Dll->Headers->FileHeader.Characteristics & IMAGE_FILE_DLL) ==
|
||||
IMAGE_FILE_DLL)
|
||||
{
|
||||
RtlCreateUnicodeString (&Module->FullDllName,
|
||||
FullDosName);
|
||||
RtlCreateUnicodeString (&Module->BaseDllName,
|
||||
wcsrchr(FullDosName, L'\\') + 1);
|
||||
|
||||
InsertTailList(&NtCurrentPeb()->Ldr->InLoadOrderModuleList,
|
||||
&Module->InLoadOrderModuleList);
|
||||
|
||||
DPRINT ("BaseDllName %wZ\n", &Module->BaseDllName);
|
||||
|
||||
if ((NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) ==
|
||||
IMAGE_FILE_DLL)
|
||||
{
|
||||
Entrypoint =
|
||||
(PDLLMAIN_FUNC) LdrPEStartup(
|
||||
ImageBase,
|
||||
SectionHandle
|
||||
);
|
||||
|
||||
if (Entrypoint != NULL)
|
||||
{
|
||||
DPRINT("Calling entry point at 0x%08x\n", Entrypoint);
|
||||
if (FALSE == Entrypoint(
|
||||
Dll->BaseAddress,
|
||||
Module->BaseAddress,
|
||||
DLL_PROCESS_ATTACH,
|
||||
NULL
|
||||
))
|
||||
|
@ -272,12 +416,14 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
}
|
||||
}
|
||||
|
||||
*BaseAddress = Dll->BaseAddress;
|
||||
Module->EntryPoint = (ULONG)Entrypoint;
|
||||
|
||||
*BaseAddress = Module->BaseAddress;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
/***************************************************************************
|
||||
* NAME LOCAL
|
||||
* LdrFindDll
|
||||
*
|
||||
|
@ -292,56 +438,38 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
|||
* NOTE
|
||||
*
|
||||
*/
|
||||
static NTSTATUS LdrFindDll(PDLL* Dll, PUNICODE_STRING Name)
|
||||
static NTSTATUS LdrFindDll(PLDR_MODULE *Dll, PUNICODE_STRING Name)
|
||||
{
|
||||
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
||||
PIMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||
DLL * current;
|
||||
UNICODE_STRING DllName;
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_MODULE Module;
|
||||
|
||||
DPRINT("NTDLL.LdrFindDll(Name %wZ)\n", Name);
|
||||
|
||||
current = & LdrDllListHead;
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
|
||||
// NULL is the current process
|
||||
|
||||
if ( Name == NULL )
|
||||
{
|
||||
*Dll = current;
|
||||
*Dll = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
do
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
OptionalHeader = & current->Headers->OptionalHeader;
|
||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
||||
OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
||||
.VirtualAddress;
|
||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
||||
((ULONG)ExportDir + (ULONG)current->BaseAddress);
|
||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
|
||||
DPRINT("Scanning %x %x %x\n",ExportDir->Name,
|
||||
current->BaseAddress,
|
||||
(ExportDir->Name + current->BaseAddress));
|
||||
DPRINT("Scanning %wZ %wZ\n", &Module->BaseDllName, Name);
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz (&DllName,
|
||||
ExportDir->Name + current->BaseAddress);
|
||||
|
||||
DPRINT("Scanning %wZ %wZ\n", &DllName, Name);
|
||||
|
||||
if (RtlCompareUnicodeString(&DllName, Name, TRUE) == 0)
|
||||
if (RtlCompareUnicodeString(&Module->BaseDllName, Name, TRUE) == 0)
|
||||
{
|
||||
*Dll = current;
|
||||
current->ReferenceCount++;
|
||||
RtlFreeUnicodeString (&DllName);
|
||||
*Dll = Module;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
current = current->Next;
|
||||
|
||||
} while (current != & LdrDllListHead);
|
||||
|
||||
RtlFreeUnicodeString (&DllName);
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
DPRINT("Failed to find dll %wZ\n", Name);
|
||||
|
||||
|
@ -811,14 +939,13 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
|
|||
* NOTE
|
||||
*
|
||||
*/
|
||||
PEPFUNC LdrPEStartup (PVOID ImageBase,
|
||||
PEPFUNC LdrPEStartup (PVOID ImageBase,
|
||||
HANDLE SectionHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PEPFUNC EntryPoint = NULL;
|
||||
PIMAGE_DOS_HEADER DosHeader;
|
||||
PIMAGE_NT_HEADERS NTHeaders;
|
||||
|
||||
|
||||
/*
|
||||
* Overlay DOS and WNT headers structures
|
||||
|
@ -885,35 +1012,44 @@ PEPFUNC LdrPEStartup (PVOID ImageBase,
|
|||
NTSTATUS STDCALL
|
||||
LdrUnloadDll (IN PVOID BaseAddress)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeaders;
|
||||
PDLLMAIN_FUNC Entrypoint;
|
||||
PDLL Dll;
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_MODULE Module;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (BaseAddress == NULL)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Dll = &LdrDllListHead;
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
|
||||
do
|
||||
while (Entry != ModuleListHead);
|
||||
{
|
||||
if (Dll->BaseAddress == BaseAddress)
|
||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
if (Module->BaseAddress == BaseAddress)
|
||||
{
|
||||
|
||||
if ( Dll->ReferenceCount > 1 )
|
||||
if (Module->LoadCount == -1)
|
||||
{
|
||||
Dll->ReferenceCount--;
|
||||
/* never unload this dll */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (Module->LoadCount > 1)
|
||||
{
|
||||
Module->LoadCount--;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
if ((Dll->Headers->FileHeader.Characteristics & IMAGE_FILE_DLL ) == IMAGE_FILE_DLL)
|
||||
NtHeaders = RtlImageNtHeader (Module->BaseAddress);
|
||||
if ((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL)
|
||||
{
|
||||
Entrypoint = (PDLLMAIN_FUNC) LdrPEStartup(Dll->BaseAddress,
|
||||
Dll->SectionHandle);
|
||||
Entrypoint = (PDLLMAIN_FUNC) LdrPEStartup(Module->BaseAddress,
|
||||
Module->SectionHandle);
|
||||
if (Entrypoint != NULL)
|
||||
{
|
||||
DPRINT("Calling entry point at 0x%08x\n", Entrypoint);
|
||||
Entrypoint(Dll->BaseAddress,
|
||||
Entrypoint(Module->BaseAddress,
|
||||
DLL_PROCESS_DETACH,
|
||||
NULL);
|
||||
}
|
||||
|
@ -923,14 +1059,20 @@ LdrUnloadDll (IN PVOID BaseAddress)
|
|||
}
|
||||
}
|
||||
Status = ZwUnmapViewOfSection (NtCurrentProcess (),
|
||||
Dll->BaseAddress);
|
||||
Module->BaseAddress);
|
||||
ZwClose (Module->SectionHandle);
|
||||
|
||||
/* remove the module entry from the list */
|
||||
RtlFreeUnicodeString (&Module->FullDllName);
|
||||
RtlFreeUnicodeString (&Module->BaseDllName);
|
||||
RemoveEntryList (Entry);
|
||||
RtlFreeHeap (RtlGetProcessHeap (), 0, Module);
|
||||
|
||||
ZwClose (Dll->SectionHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Dll = Dll->Next;
|
||||
} while (Dll != & LdrDllListHead);
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
DPRINT("NTDLL.LDR: Dll not found\n")
|
||||
|
||||
|
@ -1104,16 +1246,36 @@ LdrAccessResource(IN PVOID BaseAddress,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
LdrDisableThreadCalloutsForDll (
|
||||
IN PVOID BaseAddress,
|
||||
IN BOOLEAN Disable
|
||||
)
|
||||
NTSTATUS STDCALL
|
||||
LdrDisableThreadCalloutsForDll (IN PVOID BaseAddress)
|
||||
{
|
||||
/* FIXME: implement it! */
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_MODULE Module;
|
||||
NTSTATUS Status;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
Status = STATUS_DLL_NOT_FOUND;
|
||||
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
|
||||
while (Entry != ModuleListHead);
|
||||
{
|
||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
if (Module->BaseAddress == BaseAddress)
|
||||
{
|
||||
if (Module->TlsIndex == 0)
|
||||
{
|
||||
Module->Flags |= 0x00040000;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1218,58 +1380,52 @@ LdrGetDllHandle (IN ULONG Unknown1,
|
|||
IN PUNICODE_STRING DllName,
|
||||
OUT PVOID *BaseAddress)
|
||||
{
|
||||
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
||||
PIMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||
ANSI_STRING AnsiName;
|
||||
DLL *current;
|
||||
UNICODE_STRING FullDllName;
|
||||
PLIST_ENTRY ModuleListHead;
|
||||
PLIST_ENTRY Entry;
|
||||
PLDR_MODULE Module;
|
||||
|
||||
DPRINT("LdrGetDllHandle (Unknown1 %x Unknown2 %x DllName %wZ BaseAddress %p)\n",
|
||||
Unknown1, Unknown2, DllName, BaseAddress);
|
||||
|
||||
current = &LdrDllListHead;
|
||||
|
||||
// NULL is the current process
|
||||
/* NULL is the current executable */
|
||||
if ( DllName == NULL )
|
||||
{
|
||||
*BaseAddress = current->BaseAddress;
|
||||
*BaseAddress = NtCurrentPeb()->ImageBaseAddress;
|
||||
DPRINT1("BaseAddress %x\n", *BaseAddress);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
RtlUnicodeStringToAnsiString (&AnsiName, DllName, TRUE);
|
||||
LdrAdjustDllName (&FullDllName,
|
||||
DllName,
|
||||
TRUE);
|
||||
|
||||
do
|
||||
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
Entry = ModuleListHead->Flink;
|
||||
|
||||
while (Entry != ModuleListHead)
|
||||
{
|
||||
OptionalHeader = & current->Headers->OptionalHeader;
|
||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
||||
OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
||||
.VirtualAddress;
|
||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
||||
((ULONG)ExportDir + (ULONG)current->BaseAddress);
|
||||
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
|
||||
|
||||
DPRINT("Scanning %x %x %x\n",ExportDir->Name,
|
||||
current->BaseAddress,
|
||||
(ExportDir->Name + current->BaseAddress));
|
||||
DPRINT("Scanning %s %s\n",
|
||||
ExportDir->Name + current->BaseAddress, AnsiName.Buffer);
|
||||
DPRINT("Scanning %wZ %wZ\n",
|
||||
&Module->BaseDllName,
|
||||
FullDllName);
|
||||
|
||||
if (!_stricmp(ExportDir->Name + current->BaseAddress, AnsiName.Buffer))
|
||||
if (!RtlCompareUnicodeString(&Module->BaseDllName, &FullDllName, TRUE))
|
||||
{
|
||||
RtlFreeAnsiString (&AnsiName);
|
||||
*BaseAddress = current->BaseAddress;
|
||||
DPRINT1("BaseAddress %x\n", *BaseAddress);
|
||||
RtlFreeUnicodeString (&FullDllName);
|
||||
*BaseAddress = Module->BaseAddress;
|
||||
DPRINT("BaseAddress %x\n", *BaseAddress);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
current = current->Next;
|
||||
|
||||
} while (current != & LdrDllListHead);
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
DbgPrint("Failed to find dll %s\n", AnsiName.Buffer);
|
||||
RtlFreeAnsiString (&AnsiName);
|
||||
DbgPrint("Failed to find dll %wZ\n", &FullDllName);
|
||||
RtlFreeUnicodeString (&FullDllName);
|
||||
*BaseAddress = NULL;
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1333,4 +1489,20 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
|
|||
return STATUS_PROCEDURE_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LdrShutdownProcess (VOID)
|
||||
{
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LdrShutdownThread (VOID)
|
||||
{
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: path.c,v 1.5 2000/07/05 18:05:21 ekohl Exp $
|
||||
/* $Id: path.c,v 1.6 2000/09/01 17:05:46 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -811,6 +811,10 @@ RtlDoesFileExists_U (
|
|||
CURDIR CurDir;
|
||||
PWSTR Buffer;
|
||||
|
||||
/* only used by replacement code */
|
||||
HANDLE FileHandle;
|
||||
IO_STATUS_BLOCK StatusBlock;
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U (FileName,
|
||||
&NtFileName,
|
||||
NULL,
|
||||
|
@ -831,7 +835,19 @@ RtlDoesFileExists_U (
|
|||
CurDir.Handle,
|
||||
NULL);
|
||||
|
||||
Status = NtQueryAttributesFile (&Attr, NULL);
|
||||
/* FIXME: not implemented yet */
|
||||
// Status = NtQueryAttributesFile (&Attr, NULL);
|
||||
|
||||
/* REPLACEMENT start */
|
||||
Status = NtOpenFile (&FileHandle,
|
||||
0x10001,
|
||||
&Attr,
|
||||
&StatusBlock,
|
||||
1,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
if (NT_SUCCESS(Status))
|
||||
NtClose (FileHandle);
|
||||
/* REPLACEMENT end */
|
||||
|
||||
RtlFreeHeap (RtlGetProcessHeap (),
|
||||
0,
|
||||
|
|
|
@ -34,8 +34,6 @@ STUB(LdrFindResourceDirectory_U)
|
|||
STUB(LdrProcessRelocationBlock)
|
||||
STUB(LdrQueryImageFileExecutionOptions)
|
||||
STUB(LdrQueryProcessModuleInformation)
|
||||
STUB(LdrShutdownProcess)
|
||||
STUB(LdrShutdownThread)
|
||||
STUB(LdrVerifyImageMatchesChecksum)
|
||||
STUB(NPXEMULATORTABLE)
|
||||
STUB(PfxFindPrefix)
|
||||
|
|
Loading…
Reference in a new issue