Map the NLS tables after creating the PEB.
[reactos.git] / reactos / ntoskrnl / mm / process.c
index 48b6156..3577dd2 100644 (file)
@@ -16,6 +16,7 @@
 extern ULONG NtMajorVersion;
 extern ULONG NtMinorVersion;
 extern ULONG NtOSCSDVersion;
+extern ULONG NtGlobalFlag;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -102,49 +103,23 @@ MmDeleteKernelStack(PVOID Stack,
     MmUnlockAddressSpace(MmGetKernelAddressSpace());
 }
 
-VOID
-MiFreePebPage(PVOID Context,
-              MEMORY_AREA* MemoryArea,
-              PVOID Address,
-              PFN_TYPE Page,
-              SWAPENTRY SwapEntry,
-              BOOLEAN Dirty)
-{
-    PEPROCESS Process = (PEPROCESS)Context;
-
-    if (Page != 0)
-    {
-        SWAPENTRY SavedSwapEntry;
-        SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
-        if (SavedSwapEntry != 0)
-        {
-            MmFreeSwapPage(SavedSwapEntry);
-            MmSetSavedSwapEntryPage(Page, 0);
-        }
-        MmDeleteRmap(Page, Process, Address);
-        MmReleasePageMemoryConsumer(MC_USER, Page);
-    }
-    else if (SwapEntry != 0)
-    {
-        MmFreeSwapPage(SwapEntry);
-    }
-}
-
 VOID
 STDCALL
 MmDeleteTeb(PEPROCESS Process,
             PTEB Teb)
 {
     PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace;
+    PMEMORY_AREA MemoryArea;
 
     /* Lock the Address Space */
     MmLockAddressSpace(ProcessAddressSpace);
-
-    /* Delete the Stack */
-    MmFreeMemoryAreaByPtr(ProcessAddressSpace,
-                          Teb,
-                          MiFreePebPage,
-                          Process);
+    
+    MemoryArea = MmLocateMemoryAreaByAddress(ProcessAddressSpace, (PVOID)Teb);
+    if (MemoryArea)
+    {
+       /* Delete the Teb */
+       MmFreeVirtualMemory(Process, MemoryArea);
+    }
 
     /* Unlock the Address Space */
     MmUnlockAddressSpace(ProcessAddressSpace);
@@ -220,11 +195,22 @@ MmCreatePeb(PEPROCESS Process)
     LARGE_INTEGER SectionOffset;
     ULONG 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)PEB_BASE);
+    if (Peb != (PVOID)PEB_BASE)
+    {
+        DPRINT1("MiCreatePebOrTeb() returned %x\n", Peb);
+        return STATUS_UNSUCCESSFUL;
+    }
+
     /* Map NLS Tables */
     DPRINT("Mapping NLS\n");
     Status = MmMapViewOfSection(NlsSectionObject,
@@ -247,9 +233,6 @@ MmCreatePeb(PEPROCESS Process)
     /* Attach to Process */
     KeAttachProcess(&Process->Pcb);
 
-    /* Allocate the PEB */
-    Peb = MiCreatePebOrTeb(Process, (PVOID)PEB_BASE);
-
     /* Initialize the PEB */
     DPRINT("Allocated: %x\n", Peb);
     RtlZeroMemory(Peb, sizeof(PEB));
@@ -257,18 +240,88 @@ MmCreatePeb(PEPROCESS Process)
     /* Set up data */
     DPRINT("Setting up PEB\n");
     Peb->ImageBaseAddress = Process->SectionBaseAddress;
+    Peb->InheritedAddressSpace = 0;
+    Peb->Mutant = NULL;
+
+    /* NLS */
+    Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset;
+    Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset;
+    Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset;
+
+    /* Default Version Data (could get changed below) */
     Peb->OSMajorVersion = NtMajorVersion;
     Peb->OSMinorVersion = NtMinorVersion;
     Peb->OSBuildNumber = 2195;
-    Peb->OSPlatformId = 2; //VER_PLATFORM_WIN32_NT;
+    Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */
     Peb->OSCSDVersion = NtOSCSDVersion;
-    Peb->AnsiCodePageData = (char*)TableBase + NlsAnsiTableOffset;
-    Peb->OemCodePageData = (char*)TableBase + NlsOemTableOffset;
-    Peb->UnicodeCaseTableData = (char*)TableBase + NlsUnicodeTableOffset;
+
+    /* 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)))
+    {
+        /* Get the Image Config Data too */
+        ImageConfigData = RtlImageDirectoryEntryToData(Peb->ImageBaseAddress,
+                                                       TRUE,
+                                                       IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
+                                                       &ViewSize);
+
+        /* 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;
+
+            /* Lie about the version if requested */
+            if (ImageConfigData && ImageConfigData->CSDVersion)
+            {
+                Peb->OSCSDVersion = ImageConfigData->CSDVersion;
+            }
+
+            /* Set the Platform ID */
+            Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2;
+        }
+
+        /* Check for affinity override */
+        if (ImageConfigData && ImageConfigData->ProcessAffinityMask)
+        {
+            ProcessAffinityMask = ImageConfigData->ProcessAffinityMask;
+        }
+
+        /* 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;
+        }
+    }
 
+    /* Misc data */
+    Peb->SessionId = Process->Session;
     Process->Peb = Peb;
+
+    /* Detach from the Process */
     KeDetachProcess();
 
     DPRINT("MmCreatePeb: Peb created at %p\n", Peb);
@@ -313,20 +366,9 @@ MmCreateTeb(PEPROCESS Process,
     /* Store stack information from InitialTeb */
     if(InitialTeb != NULL)
     {
-        /* fixed-size stack */
-        if(InitialTeb->PreviousStackBase && InitialTeb->PreviousStackLimit)
-        {
-            Teb->Tib.StackBase = InitialTeb->PreviousStackBase;
-            Teb->Tib.StackLimit = InitialTeb->PreviousStackLimit;
-            Teb->DeallocationStack = InitialTeb->PreviousStackLimit;
-        }
-        /* expandable stack */
-        else
-        {
-            Teb->Tib.StackBase = InitialTeb->StackBase;
-            Teb->Tib.StackLimit = InitialTeb->StackLimit;
-            Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
-        }
+        Teb->Tib.StackBase = InitialTeb->StackBase;
+        Teb->Tib.StackLimit = InitialTeb->StackLimit;
+        Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
     }
 
     /* Return TEB Address */
@@ -436,10 +478,8 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to map process Image\n");
-            ObDereferenceObject(Section);
             goto exit;
         }
-        ObDereferenceObject(Section);
 
         /* Save the pointer */
         Process->SectionBaseAddress = ImageBase;