From 1ea8fff57a43d42edad98b1e95c96139e98c03e0 Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Thu, 15 Oct 2009 05:56:41 +0000 Subject: [PATCH] - Multiple PEB/TEB creation fixes: - Set up PEB and TEB under SEH to handle possible paging errors (which are legitimate). - Also touch the image under SEH to handle image paging errors (also legitimate). - Should avoid kernel panics in cases where the executable is damaged, invalid, or impossible to page in. - Initialize more PEB fields. - Add new INITIAL_PEB structure to support fork() in the future. Also fixes the fact we don't create a PEB for the system process anymore. - Create PEB while attached to the process. - Handle UP-only images, and set correct affinity mask in the PEB. - Set session ID instead of session structure (currently zero). - Set correct TIB version in the TEB. Due to a historical oddity, the NT TIB identifies itself as '0x1e00', which is 30 shifted 8 bits. 30 is the version identifier of OS/2 3.0, the original 32-bit target of the Windows NT effort. - Handle initial TEB correctly for fork(). - Move AWE APIs to procsup.c instea of section.c since they are unrelated. - Move the rewritten PEB/TEB functions to ARM3's procsup.c. svn path=/trunk/; revision=43476 --- reactos/include/ndk/pstypes.h | 46 ++- reactos/ntoskrnl/include/internal/mm.h | 15 +- reactos/ntoskrnl/mm/ARM3/miarm.h | 4 + reactos/ntoskrnl/mm/ARM3/procsup.c | 457 +++++++++++++++++++++++++ reactos/ntoskrnl/mm/procsup.c | 264 -------------- reactos/ntoskrnl/mm/section.c | 40 --- reactos/ntoskrnl/ps/process.c | 45 ++- reactos/ntoskrnl/ps/thread.c | 6 +- 8 files changed, 552 insertions(+), 325 deletions(-) diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index a2006a29f78..45e27f2d741 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -586,24 +586,54 @@ typedef struct _PEB_FREE_BLOCK ULONG Size; } PEB_FREE_BLOCK, *PPEB_FREE_BLOCK; +// +// Initial PEB +// +typedef struct _INITIAL_PEB +{ + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + union + { + BOOLEAN BitField; +#if (NTDDI_VERSION >= NTDDI_WS03) + struct + { + BOOLEAN ImageUsesLargePages:1; +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + BOOLEAN IsProtectedProcess:1; + BOOLEAN IsLegacyProcess:1; + BOOLEAN SpareBits:5; +#else + BOOLEAN SpareBits:7; +#endif + }; +#else + BOOLEAN SpareBool; +#endif + }; + HANDLE Mutant; +} INITIAL_PEB, *PINITIAL_PEB; + // // Process Environment Block (PEB) // typedef struct _PEB { - UCHAR InheritedAddressSpace; - UCHAR ReadImageFileExecOptions; - UCHAR BeingDebugged; + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; #if (NTDDI_VERSION >= NTDDI_WS03) struct { - UCHAR ImageUsesLargePages:1; + BOOLEAN ImageUsesLargePages:1; #if (NTDDI_VERSION >= NTDDI_LONGHORN) - UCHAR IsProtectedProcess:1; - UCHAR IsLegacyProcess:1; - UCHAR SpareBits:5; + BOOLEAN IsProtectedProcess:1; + BOOLEAN IsLegacyProcess:1; + BOOLEAN SpareBits:5; #else - UCHAR SpareBits:7; + BOOLEAN SpareBits:7; #endif }; #else diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 4237c75bd11..ef3ddc12a6e 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -776,14 +776,19 @@ MmInitializeProcessAddressSpace( NTSTATUS NTAPI -MmCreatePeb(struct _EPROCESS *Process); +MmCreatePeb( + IN PEPROCESS Process, + IN PINITIAL_PEB InitialPeb, + OUT PPEB *BasePeb +); -PTEB +NTSTATUS NTAPI MmCreateTeb( - struct _EPROCESS *Process, - PCLIENT_ID ClientId, - PINITIAL_TEB InitialTeb + IN PEPROCESS Process, + IN PCLIENT_ID ClientId, + IN PINITIAL_TEB InitialTeb, + OUT PTEB* BaseTeb ); VOID diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index a3d7c3a5bfd..9e27fa210e3 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -29,6 +29,10 @@ #define MI_PAGED_POOL_START (PVOID)0xE1000000 #define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000 +#define MM_HIGHEST_VAD_ADDRESS \ + (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) + + // // FIXFIX: These should go in ex.h after the pool merge // diff --git a/reactos/ntoskrnl/mm/ARM3/procsup.c b/reactos/ntoskrnl/mm/ARM3/procsup.c index 919b3e43de4..d64678b6847 100644 --- a/reactos/ntoskrnl/mm/ARM3/procsup.c +++ b/reactos/ntoskrnl/mm/ARM3/procsup.c @@ -16,6 +16,13 @@ #define MODULE_INVOLVED_IN_ARM3 #include "../ARM3/miarm.h" +extern MM_SYSTEMSIZE MmSystemSize; + +PVOID +NTAPI +MiCreatePebOrTeb(PEPROCESS Process, + PVOID BaseAddress); + /* PRIVATE FUNCTIONS **********************************************************/ VOID @@ -278,4 +285,454 @@ MmGrowKernelStack(IN PVOID StackPointer) return MmGrowKernelStackEx(StackPointer, KERNEL_LARGE_STACK_COMMIT); } +NTSTATUS +NTAPI +MmSetMemoryPriorityProcess(IN PEPROCESS Process, + IN UCHAR MemoryPriority) +{ + UCHAR OldPriority; + + // + // Check if we have less then 16MB of Physical Memory + // + if ((MmSystemSize == MmSmallSystem) && + (MmStats.NrTotalPages < ((15 * 1024 * 1024) / PAGE_SIZE))) + { + // + // Always use background priority + // + MemoryPriority = MEMORY_PRIORITY_BACKGROUND; + } + + // + // Save the old priority and update it + // + OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority; + Process->Vm.Flags.MemoryPriority = MemoryPriority; + + // + // Return the old priority + // + return OldPriority; +} + +LCID +NTAPI +MmGetSessionLocaleId(VOID) +{ + PEPROCESS Process; + PAGED_CODE(); + + // + // Get the current process + // + Process = PsGetCurrentProcess(); + + // + // Check if it's the Session Leader + // + if (Process->Vm.Flags.SessionLeader) + { + // + // Make sure it has a valid Session + // + if (Process->Session) + { + // + // Get the Locale ID + // +#if ROS_HAS_SESSIONS + return ((PMM_SESSION_SPACE)Process->Session)->LocaleId; +#endif + } + } + + // + // Not a session leader, return the default + // + return PsDefaultThreadLocaleId; +} + +NTSTATUS +NTAPI +MmCreatePeb(IN PEPROCESS Process, + IN PINITIAL_PEB InitialPeb, + OUT PPEB *BasePeb) +{ + PPEB Peb = NULL; + LARGE_INTEGER SectionOffset; + SIZE_T ViewSize = 0; + PVOID TableBase = NULL; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData; + NTSTATUS Status; + USHORT Characteristics; + KAFFINITY ProcessAffinityMask = 0; + SectionOffset.QuadPart = (ULONGLONG)0; + *BasePeb = NULL; + + // + // Attach to Process + // + KeAttachProcess(&Process->Pcb); + + // + // Allocate the PEB + // + Peb = MiCreatePebOrTeb(Process, + (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); + ASSERT(Peb == (PVOID)0x7FFDF000); + + // + // Map NLS Tables + // + Status = MmMapViewOfSection(ExpNlsSectionPointer, + (PEPROCESS)Process, + &TableBase, + 0, + 0, + &SectionOffset, + &ViewSize, + ViewShare, + MEM_TOP_DOWN, + PAGE_READONLY); + if (!NT_SUCCESS(Status)) return Status; + + // + // Use SEH in case we can't load the PEB + // + _SEH2_TRY + { + // + // Initialize the PEB + // + RtlZeroMemory(Peb, sizeof(PEB)); + + // + // Set up data + // + Peb->ImageBaseAddress = Process->SectionBaseAddress; + Peb->InheritedAddressSpace = InitialPeb->InheritedAddressSpace; + Peb->Mutant = InitialPeb->Mutant; + Peb->ImageUsesLargePages = InitialPeb->ImageUsesLargePages; + + // + // NLS + // + Peb->AnsiCodePageData = (PCHAR)TableBase + ExpAnsiCodePageDataOffset; + Peb->OemCodePageData = (PCHAR)TableBase + ExpOemCodePageDataOffset; + Peb->UnicodeCaseTableData = (PCHAR)TableBase + ExpUnicodeCaseTableDataOffset; + + // + // Default Version Data (could get changed below) + // + Peb->OSMajorVersion = NtMajorVersion; + Peb->OSMinorVersion = NtMinorVersion; + Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF); + Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */ + Peb->OSCSDVersion = (USHORT)CmNtCSDVersion; + + // + // Heap and Debug Data + // + Peb->NumberOfProcessors = KeNumberProcessors; + Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE); + Peb->NtGlobalFlag = NtGlobalFlag; + /*Peb->HeapSegmentReserve = MmHeapSegmentReserve; + Peb->HeapSegmentCommit = MmHeapSegmentCommit; + Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold; + Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold; + Peb->CriticalSectionTimeout = MmCriticalSectionTimeout; + Peb->MinimumStackCommit = MmMinimumStackCommitInBytes; + */ + Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID); + Peb->ProcessHeaps = (PVOID*)(Peb + 1); + + // + // Session ID + // + if (Process->Session) Peb->SessionId = 0; // MmGetSessionId(Process); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Fail + // + KeDetachProcess(); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + // + // Use SEH in case we can't load the image + // + _SEH2_TRY + { + // + // Get NT Headers + // + NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress); + Characteristics = NtHeaders->FileHeader.Characteristics; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Fail + // + KeDetachProcess(); + _SEH2_YIELD(return STATUS_INVALID_IMAGE_PROTECT); + } + _SEH2_END; + + // + // Parse the headers + // + if (NtHeaders) + { + // + // Use SEH in case we can't load the headers + // + _SEH2_TRY + { + // + // Get the Image Config Data too + // + ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, + TRUE, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, + &ViewSize); + if (ImageConfigData) + { + // + // Probe it + // + ProbeForRead(ImageConfigData, + sizeof(IMAGE_LOAD_CONFIG_DIRECTORY), + sizeof(ULONG)); + } + + // + // Write subsystem data + // + Peb->ImageSubSystem = NtHeaders->OptionalHeader.Subsystem; + Peb->ImageSubSystemMajorVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion; + Peb->ImageSubSystemMinorVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion; + + // + // Check for version data + // + if (NtHeaders->OptionalHeader.Win32VersionValue) + { + // + // Extract values and write them + // + Peb->OSMajorVersion = NtHeaders->OptionalHeader.Win32VersionValue & 0xFF; + Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF; + Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF; + Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2; + } + + // + // Process the image config data overrides if specfied + // + if (ImageConfigData != NULL) + { + // + // Process CSD version override + // + if (ImageConfigData->CSDVersion) + { + // + // Set new data + // + Peb->OSCSDVersion = ImageConfigData->CSDVersion; + } + + // + // Process affinity mask ovverride + // + if (ImageConfigData->ProcessAffinityMask) + { + // + // Set new data + // + ProcessAffinityMask = ImageConfigData->ProcessAffinityMask; + } + } + + // + // Check if this is a UP image + if (Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) + { + // + // Force it to use CPU 0 + // + Peb->ImageProcessAffinityMask = 0; + } + else + { + // + // Whatever was configured + // + Peb->ImageProcessAffinityMask = ProcessAffinityMask; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Fail + // + KeDetachProcess(); + _SEH2_YIELD(return STATUS_INVALID_IMAGE_PROTECT); + } + _SEH2_END; + } + + // + // Detach from the Process + // + KeDetachProcess(); + *BasePeb = Peb; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +MmCreateTeb(IN PEPROCESS Process, + IN PCLIENT_ID ClientId, + IN PINITIAL_TEB InitialTeb, + OUT PTEB *BaseTeb) +{ + PTEB Teb; + NTSTATUS Status = STATUS_SUCCESS; + *BaseTeb = NULL; + + // + // Attach to Target + // + KeAttachProcess(&Process->Pcb); + + // + // Allocate the TEB + // + Teb = MiCreatePebOrTeb(Process, + (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); + if (!Teb) return STATUS_INSUFFICIENT_RESOURCES; + + // + // Use SEH in case we can't load the TEB + // + _SEH2_TRY + { + // + // Initialize the PEB + // + RtlZeroMemory(Teb, sizeof(TEB)); + + // + // Set TIB Data + // + Teb->Tib.ExceptionList = EXCEPTION_CHAIN_END; + Teb->Tib.Self = (PNT_TIB)Teb; + + // + // Identify this as an OS/2 V3.0 ("Cruiser") TIB + // + Teb->Tib.Version = 30 << 8; + + // + // Set TEB Data + // + Teb->ClientId = *ClientId; + Teb->RealClientId = *ClientId; + Teb->ProcessEnvironmentBlock = Process->Peb; + Teb->CurrentLocale = PsDefaultThreadLocaleId; + + // + // Check if we have a grandparent TEB + // + if ((InitialTeb->PreviousStackBase == NULL) && + (InitialTeb->PreviousStackLimit == NULL)) + { + // + // Use grandparent TEB values + // + Teb->Tib.StackBase = InitialTeb->PreviousStackBase; + Teb->Tib.StackLimit = InitialTeb->PreviousStackLimit; + } + else + { + // + // Use initial TEB values + // + Teb->Tib.StackBase = InitialTeb->StackBase; + Teb->Tib.StackLimit = InitialTeb->StackLimit; + Teb->DeallocationStack = InitialTeb->AllocatedStackBase; + } + + // + // Initialize the static unicode string + // + Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer); + Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + // + // Get error code + // + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + // + // Return + // + KeDetachProcess(); + *BaseTeb = Teb; + return Status; +} + +/* SYSTEM CALLS ***************************************************************/ + +NTSTATUS +NTAPI +NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle, + IN OUT PULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtMapUserPhysicalPages(IN PVOID VirtualAddresses, + IN ULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, + IN ULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtFreeUserPhysicalPages(IN HANDLE ProcessHandle, + IN OUT PULONG_PTR NumberOfPages, + IN OUT PULONG_PTR UserPfnArray) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + /* EOF */ diff --git a/reactos/ntoskrnl/mm/procsup.c b/reactos/ntoskrnl/mm/procsup.c index 4d367f6fac1..ededba8ff46 100644 --- a/reactos/ntoskrnl/mm/procsup.c +++ b/reactos/ntoskrnl/mm/procsup.c @@ -13,67 +13,8 @@ #define NDEBUG #include -extern ULONG NtMajorVersion; -extern ULONG NtMinorVersion; -extern ULONG CmNtCSDVersion; -extern ULONG NtBuildNumber; -extern MM_SYSTEMSIZE MmSystemSize; - -#define MM_HIGHEST_VAD_ADDRESS \ - (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE)) - /* FUNCTIONS *****************************************************************/ -NTSTATUS -NTAPI -MmSetMemoryPriorityProcess(IN PEPROCESS Process, - IN UCHAR MemoryPriority) -{ - UCHAR OldPriority; - - /* Check if we have less then 16MB of Physical Memory */ - if ((MmSystemSize == MmSmallSystem) && - (MmStats.NrTotalPages < ((15 * 1024 * 1024) / PAGE_SIZE))) - { - /* Always use background priority */ - MemoryPriority = 0; - } - - /* Save the old priority and update it */ - OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority; - Process->Vm.Flags.MemoryPriority = MemoryPriority; - - /* Return the old priority */ - return OldPriority; -} - -LCID -NTAPI -MmGetSessionLocaleId(VOID) -{ - PEPROCESS Process; - PAGED_CODE(); - - /* Get the current process */ - Process = PsGetCurrentProcess(); - - /* Check if it's the Session Leader */ - if (Process->Vm.Flags.SessionLeader) - { - /* Make sure it has a valid Session */ - if (Process->Session) - { - /* Get the Locale ID */ -#if ROS_HAS_SESSIONS - return ((PMM_SESSION_SPACE)Process->Session)->LocaleId; -#endif - } - } - - /* Not a session leader, return the default */ - return PsDefaultThreadLocaleId; -} - PVOID NTAPI MiCreatePebOrTeb(PEPROCESS Process, @@ -148,211 +89,6 @@ MmDeleteTeb(PEPROCESS Process, MmUnlockAddressSpace(ProcessAddressSpace); } -NTSTATUS -NTAPI -MmCreatePeb(PEPROCESS Process) -{ - PPEB Peb = NULL; - LARGE_INTEGER SectionOffset; - SIZE_T ViewSize = 0; - PVOID TableBase = NULL; - PIMAGE_NT_HEADERS NtHeaders; - PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData; - NTSTATUS Status; - KAFFINITY ProcessAffinityMask = 0; - SectionOffset.QuadPart = (ULONGLONG)0; - DPRINT("MmCreatePeb\n"); - - /* Allocate the PEB */ - Peb = MiCreatePebOrTeb(Process, - (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); - ASSERT(Peb == (PVOID)0x7FFDF000); - - /* Map NLS Tables */ - DPRINT("Mapping NLS\n"); - Status = MmMapViewOfSection(ExpNlsSectionPointer, - (PEPROCESS)Process, - &TableBase, - 0, - 0, - &SectionOffset, - &ViewSize, - ViewShare, - MEM_TOP_DOWN, - PAGE_READONLY); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status); - return(Status); - } - DPRINT("TableBase %p ViewSize %lx\n", TableBase, ViewSize); - - /* Attach to Process */ - KeAttachProcess(&Process->Pcb); - - /* Initialize the PEB */ - DPRINT("Allocated: %x\n", Peb); - RtlZeroMemory(Peb, sizeof(PEB)); - - /* Set up data */ - DPRINT("Setting up PEB\n"); - Peb->ImageBaseAddress = Process->SectionBaseAddress; - Peb->InheritedAddressSpace = 0; - Peb->Mutant = NULL; - - /* NLS */ - Peb->AnsiCodePageData = (PCHAR)TableBase + ExpAnsiCodePageDataOffset; - Peb->OemCodePageData = (PCHAR)TableBase + ExpOemCodePageDataOffset; - Peb->UnicodeCaseTableData = (PCHAR)TableBase + ExpUnicodeCaseTableDataOffset; - - /* Default Version Data (could get changed below) */ - Peb->OSMajorVersion = NtMajorVersion; - Peb->OSMinorVersion = NtMinorVersion; - Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF); - Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */ - Peb->OSCSDVersion = (USHORT)CmNtCSDVersion; - - /* Heap and Debug Data */ - Peb->NumberOfProcessors = KeNumberProcessors; - Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL ? TRUE : FALSE); - Peb->NtGlobalFlag = NtGlobalFlag; - /*Peb->HeapSegmentReserve = MmHeapSegmentReserve; - Peb->HeapSegmentCommit = MmHeapSegmentCommit; - Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold; - Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;*/ - Peb->NumberOfHeaps = 0; - Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID); - Peb->ProcessHeaps = (PVOID*)(Peb + 1); - - /* Image Data */ - if ((NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress))) - { - /* Write subsystem data */ - Peb->ImageSubSystem = NtHeaders->OptionalHeader.Subsystem; - Peb->ImageSubSystemMajorVersion = NtHeaders->OptionalHeader.MajorSubsystemVersion; - Peb->ImageSubSystemMinorVersion = NtHeaders->OptionalHeader.MinorSubsystemVersion; - - /* Write Version Data */ - if (NtHeaders->OptionalHeader.Win32VersionValue) - { - Peb->OSMajorVersion = NtHeaders->OptionalHeader.Win32VersionValue & 0xFF; - Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF; - Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF; - - /* Set the Platform ID */ - Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2; - } - - /* Check if the image is not safe for SMP */ - if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) - { - /* FIXME: Choose one randomly */ - Peb->ImageProcessAffinityMask = 1; - } - else - { - /* Use affinity from Image Header */ - Peb->ImageProcessAffinityMask = ProcessAffinityMask; - } - - _SEH2_TRY - { - /* Get the Image Config Data too */ - ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, - &ViewSize); - - ProbeForRead(ImageConfigData, - sizeof(IMAGE_LOAD_CONFIG_DIRECTORY), - sizeof(ULONG)); - - /* Process the image config data overrides if specfied. */ - if (ImageConfigData != NULL) - { - if (ImageConfigData->CSDVersion) - { - Peb->OSCSDVersion = ImageConfigData->CSDVersion; - } - if (ImageConfigData->ProcessAffinityMask) - { - ProcessAffinityMask = ImageConfigData->ProcessAffinityMask; - } - } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - - /* Misc data */ - Peb->SessionId = Process->Session; - Process->Peb = Peb; - - /* Detach from the Process */ - KeDetachProcess(); - - DPRINT("MmCreatePeb: Peb created at %p\n", Peb); - return Status; -} - -PTEB -NTAPI -MmCreateTeb(PEPROCESS Process, - PCLIENT_ID ClientId, - PINITIAL_TEB InitialTeb) -{ - PTEB Teb; - BOOLEAN Attached = FALSE; - - /* Attach to the process */ - DPRINT("MmCreateTeb\n"); - if (Process != PsGetCurrentProcess()) - { - /* Attach to Target */ - KeAttachProcess(&Process->Pcb); - Attached = TRUE; - } - - /* Allocate the TEB */ - Teb = MiCreatePebOrTeb(Process, - (PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)); - - /* Initialize the PEB */ - RtlZeroMemory(Teb, sizeof(TEB)); - - /* Set TIB Data */ - Teb->Tib.ExceptionList = (PVOID)0xFFFFFFFF; - Teb->Tib.Version = 1; - Teb->Tib.Self = (PNT_TIB)Teb; - - /* Set TEB Data */ - Teb->ClientId = *ClientId; - Teb->RealClientId = *ClientId; - Teb->ProcessEnvironmentBlock = Process->Peb; - Teb->CurrentLocale = PsDefaultThreadLocaleId; - - /* Store stack information from InitialTeb */ - if(InitialTeb != NULL) - { - Teb->Tib.StackBase = InitialTeb->StackBase; - Teb->Tib.StackLimit = InitialTeb->StackLimit; - Teb->DeallocationStack = InitialTeb->AllocatedStackBase; - } - - /* Initialize the static unicode string */ - Teb->StaticUnicodeString.Length = 0; - Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer); - Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer; - - /* Return TEB Address */ - DPRINT("Allocated: %x\n", Teb); - if (Attached) KeDetachProcess(); - return Teb; -} - NTSTATUS NTAPI MmInitializeHandBuiltProcess2(IN PEPROCESS Process) diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 22a50c8bac6..7613d0065e3 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -5070,46 +5070,6 @@ MmCreateSection (OUT PVOID * Section, AllocationAttributes)); } -NTSTATUS -NTAPI -NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle, - IN OUT PULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -NtMapUserPhysicalPages(IN PVOID VirtualAddresses, - IN ULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, - IN ULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -NtFreeUserPhysicalPages(IN HANDLE ProcessHandle, - IN OUT PULONG_PTR NumberOfPages, - IN OUT PULONG_PTR UserPfnArray) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS NTAPI NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 745389b50ce..31c01628822 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -379,6 +379,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, BOOLEAN Result, SdAllocated; PSECURITY_DESCRIPTOR SecurityDescriptor; SECURITY_SUBJECT_CONTEXT SubjectContext; + BOOLEAN NeedsPeb = FALSE; + INITIAL_PEB InitialPeb; PAGED_CODE(); PSTRACE(PS_PROCESS_DEBUG, "ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess); @@ -635,17 +637,27 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, SeAuditProcessCreationInfo. ImageFileName); if (!NT_SUCCESS(Status)) goto CleanupWithRef; + + // + // We need a PEB + // + NeedsPeb = TRUE; } else if (Parent) { /* Check if this is a child of the system process */ if (Parent != PsInitialSystemProcess) { + // + // We need a PEB + // + NeedsPeb = TRUE; + /* This is a clone! */ ASSERTMSG("No support for cloning yet\n", FALSE); } else - { + { /* This is the initial system process */ Flags &= ~PS_LARGE_PAGES; Status = MmInitializeProcessAddressSpace(Process, @@ -702,11 +714,34 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, } /* Create PEB only for User-Mode Processes */ - if (Parent) + if ((Parent) && (NeedsPeb)) { - /* Create it */ - Status = MmCreatePeb(Process); - if (!NT_SUCCESS(Status)) goto CleanupWithRef; + // + // Set up the initial PEB + // + RtlZeroMemory(&InitialPeb, sizeof(INITIAL_PEB)); + InitialPeb.Mutant = (HANDLE)-1; + InitialPeb.ImageUsesLargePages = 0; // FIXME: Not yet supported + + // + // Create it only if we have an image section + // + if (SectionHandle) + { + // + // Create it + // + Status = MmCreatePeb(Process, &InitialPeb, &Process->Peb); + if (!NT_SUCCESS(Status)) goto CleanupWithRef; + } + else + { + // + // We have to clone it + // + ASSERTMSG("No support for cloning yet\n", FALSE); + } + } /* The process can now be activated */ diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index d5e3be4b048..e0ea695bb35 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -310,13 +310,13 @@ PspCreateThread(OUT PHANDLE ThreadHandle, if (ThreadContext) { /* User-mode Thread, create Teb */ - TebBase = MmCreateTeb(Process, &Thread->Cid, InitialTeb); - if (!TebBase) + Status = MmCreateTeb(Process, &Thread->Cid, InitialTeb, &TebBase); + if (!NT_SUCCESS(Status)) { /* Failed to create the TEB. Release rundown and dereference */ ExReleaseRundownProtection(&Process->RundownProtect); ObDereferenceObject(Thread); - return STATUS_INSUFFICIENT_RESOURCES; + return Status; } /* Set the Start Addresses */