diff --git a/reactos/dll/ntdll/include/ntdllp.h b/reactos/dll/ntdll/include/ntdllp.h index c882ef0e263..fcb04a98a6e 100644 --- a/reactos/dll/ntdll/include/ntdllp.h +++ b/reactos/dll/ntdll/include/ntdllp.h @@ -27,11 +27,14 @@ extern BOOLEAN LdrpInLdrInit; /* ldrinit.c */ NTSTATUS NTAPI LdrpRunInitializeRoutines(IN PCONTEXT Context OPTIONAL); +NTSTATUS NTAPI LdrpInitializeThread(IN PCONTEXT Context); NTSTATUS NTAPI LdrpInitializeTls(VOID); NTSTATUS NTAPI LdrpAllocateTls(VOID); VOID NTAPI LdrpFreeTls(VOID); VOID NTAPI LdrpTlsCallback(PVOID BaseAddress, ULONG Reason); BOOLEAN NTAPI LdrpCallDllEntry(PDLLMAIN_FUNC EntryPoint, PVOID BaseAddress, ULONG Reason, PVOID Context); +NTSTATUS NTAPI LdrpInitializeProcess(PCONTEXT Context, PVOID SystemArgument1); + /* ldrpe.c */ NTSTATUS diff --git a/reactos/dll/ntdll/ldr/ldrinit.c b/reactos/dll/ntdll/ldr/ldrinit.c index 2440d4c6d5d..535bce90b8c 100644 --- a/reactos/dll/ntdll/ldr/ldrinit.c +++ b/reactos/dll/ntdll/ldr/ldrinit.c @@ -21,6 +21,7 @@ UNICODE_STRING ImageExecOptionsString = RTL_CONSTANT_STRING(L"\\Registry\\Machin UNICODE_STRING Wow64OptionsString = RTL_CONSTANT_STRING(L""); BOOLEAN LdrpInLdrInit; +LONG LdrpProcessInitialized; PLDR_DATA_TABLE_ENTRY LdrpImageEntry; PUNICODE_STRING LdrpTopLevelDllBeingLoaded; @@ -39,6 +40,11 @@ RTL_CRITICAL_SECTION LdrpLoaderLock; BOOLEAN ShowSnaps; +ULONG LdrpFatalHardErrorCount; + +VOID RtlpInitializeVectoredExceptionHandling(VOID); +VOID NTAPI RtlpInitDeferedCriticalSection(VOID); + /* FUNCTIONS *****************************************************************/ /* @@ -832,5 +838,148 @@ LdrpFreeTls(VOID) TlsVector); } +VOID +NTAPI +LdrpInitFailure(NTSTATUS Status) +{ + ULONG Response; + + /* Print a debug message */ + DPRINT1("LDR: Process initialization failure; NTSTATUS = %08lx\n", Status); + + /* Raise a hard error */ + if (!LdrpFatalHardErrorCount) + { + ZwRaiseHardError(STATUS_APP_INIT_FAILURE, 1, 0, (PULONG_PTR)&Status, OptionOk, &Response); + } +} + +VOID +NTAPI +LdrpInit(PCONTEXT Context, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + LARGE_INTEGER Timeout; + PTEB Teb = NtCurrentTeb(); + NTSTATUS Status, LoaderStatus = STATUS_SUCCESS; + MEMORY_BASIC_INFORMATION MemoryBasicInfo; + PPEB Peb = NtCurrentPeb(); + + DPRINT("LdrpInit()\n"); + + /* Check if we have a deallocation stack */ + if (!Teb->DeallocationStack) + { + /* We don't, set one */ + Status = NtQueryVirtualMemory(NtCurrentProcess(), + Teb->NtTib.StackLimit, + MemoryBasicInformation, + &MemoryBasicInfo, + sizeof(MEMORY_BASIC_INFORMATION), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + LdrpInitFailure(Status); + RtlRaiseStatus(Status); + return; + } + + /* Set the stack */ + Teb->DeallocationStack = MemoryBasicInfo.AllocationBase; + } + + /* Now check if the process is already being initialized */ + while (_InterlockedCompareExchange(&LdrpProcessInitialized, + 1, + 0) == 1) + { + /* Set the timeout to 30 seconds */ + Timeout.QuadPart = Int32x32To64(30, -10000); + + /* Make sure the status hasn't changed */ + while (!LdrpProcessInitialized) + { + /* Do the wait */ + ZwDelayExecution(FALSE, &Timeout); + } + } + + /* Check if we have already setup LDR data */ + if (!Peb->Ldr) + { + /* Setup the Loader Lock */ + Peb->LoaderLock = &LdrpLoaderLock; + + /* Let other code know we're initializing */ + LdrpInLdrInit = TRUE; + + /* Initialize Critical Section Data */ + RtlpInitDeferedCriticalSection(); + + /* Initialize VEH Call lists */ + RtlpInitializeVectoredExceptionHandling(); + + /* Protect with SEH */ + _SEH2_TRY + { + /* Initialize the Process */ + LoaderStatus = LdrpInitializeProcess(Context, + SystemArgument1); + + /* Check for success and if MinimumStackCommit was requested */ + if (NT_SUCCESS(LoaderStatus) && Peb->MinimumStackCommit) + { + /* Enforce the limit */ + //LdrpTouchThreadStack(Peb->MinimumStackCommit); + UNIMPLEMENTED; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with the SEH error */ + LoaderStatus = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* We're not initializing anymore */ + LdrpInLdrInit = FALSE; + + /* Check if init worked */ + if (NT_SUCCESS(LoaderStatus)) + { + /* Set the process as Initialized */ + _InterlockedIncrement(&LdrpProcessInitialized); + } + } + else + { + /* Loader data is there... is this a fork() ? */ + if(Peb->InheritedAddressSpace) + { + /* Handle the fork() */ + //LoaderStatus = LdrpForkProcess(); + LoaderStatus = STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + } + else + { + /* This is a new thread initializing */ + LdrpInitializeThread(Context); + } + } + + /* All done, test alert the thread */ + NtTestAlert(); + + /* Return */ + if (!NT_SUCCESS(LoaderStatus)) + { + /* Fail */ + LdrpInitFailure(LoaderStatus); + RtlRaiseStatus(LoaderStatus); + } +} /* EOF */ diff --git a/reactos/dll/ntdll/ldr/startup.c b/reactos/dll/ntdll/ldr/startup.c index 774f4495d50..731842ac26e 100644 --- a/reactos/dll/ntdll/ldr/startup.c +++ b/reactos/dll/ntdll/ldr/startup.c @@ -16,9 +16,6 @@ VOID RtlInitializeHeapManager(VOID); VOID LdrpInitLoader(VOID); -VOID NTAPI RtlpInitDeferedCriticalSection(VOID); -NTSTATUS LdrpAttachThread(VOID); -VOID RtlpInitializeVectoredExceptionHandling(VOID); extern PTEB LdrpTopLevelDllBeingLoadedTeb; /* GLOBALS *******************************************************************/ @@ -27,8 +24,6 @@ extern PLDR_DATA_TABLE_ENTRY LdrpImageEntry; static RTL_CRITICAL_SECTION PebLock; static RTL_BITMAP TlsBitMap; static RTL_BITMAP TlsExpansionBitMap; -static volatile BOOLEAN LdrpInitialized = FALSE; -static LONG LdrpInitLock = 0; #define VALUE_BUFFER_SIZE 256 @@ -312,11 +307,10 @@ finish: return FALSE; } -static -VOID -LdrpInit2(PCONTEXT Context, - PVOID SystemArgument1, - PVOID SystemArgument2) +NTSTATUS +NTAPI +LdrpInitializeProcess(PCONTEXT Context, + PVOID SystemArgument1) { PIMAGE_NT_HEADERS NTHeaders; PEPFUNC EntryPoint; @@ -378,9 +372,6 @@ LdrpInit2(PCONTEXT Context, Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors; - /* Initialize Critical Section Data */ - RtlpInitDeferedCriticalSection(); - /* Load execution options */ LoadImageFileExecutionOptions(Peb); @@ -439,9 +430,6 @@ LdrpInit2(PCONTEXT Context, ZwTerminateProcess(NtCurrentProcess(), STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE); } - /* initialized vectored exception handling */ - RtlpInitializeVectoredExceptionHandling(); - /* initalize peb lock support */ RtlInitializeCriticalSection(&PebLock); Peb->FastPebLock = &PebLock; @@ -585,37 +573,8 @@ LdrpInit2(PCONTEXT Context, /* Break into debugger */ if (Peb->BeingDebugged) DbgBreakPoint(); -} -VOID -NTAPI -LdrpInit(PCONTEXT Context, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - if (!LdrpInitialized) - { - if (!_InterlockedExchange(&LdrpInitLock, 1)) - { - LdrpInit2(Context, SystemArgument1, SystemArgument2); - LdrpInitialized = TRUE; - } - else - { - LARGE_INTEGER Interval = {{-200000, -1}}; - - do - { - NtDelayExecution(FALSE, &Interval); - } - while (!LdrpInitialized); - } - } - - /* attach the thread */ - RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); - LdrpAttachThread(); - RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); + return STATUS_SUCCESS; } /* EOF */ diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 77a18cc17cd..2f660dacdbe 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -2664,9 +2664,9 @@ LdrShutdownProcess (VOID) /* * @implemented */ - NTSTATUS -LdrpAttachThread (VOID) +NTAPI +LdrpInitializeThread(IN PCONTEXT Context) { PLIST_ENTRY ModuleListHead; PLIST_ENTRY Entry;