Improved internal dll handling

Implemented or fixed dll and resource functions

svn path=/trunk/; revision=1328
This commit is contained in:
Eric Kohl 2000-09-01 17:09:50 +00:00
parent dd7e38a19d
commit df314ce26e
11 changed files with 650 additions and 269 deletions

View file

@ -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);

View file

@ -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

View file

@ -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))
{

View file

@ -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 (

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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");

View file

@ -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 */

View file

@ -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,

View file

@ -34,8 +34,6 @@ STUB(LdrFindResourceDirectory_U)
STUB(LdrProcessRelocationBlock)
STUB(LdrQueryImageFileExecutionOptions)
STUB(LdrQueryProcessModuleInformation)
STUB(LdrShutdownProcess)
STUB(LdrShutdownThread)
STUB(LdrVerifyImageMatchesChecksum)
STUB(NPXEMULATORTABLE)
STUB(PfxFindPrefix)