- Fix inverted if condition in TEB initialization, spotted by Stefan.
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / procsup.c
index 5349106..ae711fd 100644 (file)
 #define MODULE_INVOLVED_IN_ARM3
 #include "../ARM3/miarm.h"
 
+extern MM_SYSTEMSIZE MmSystemSize;
+
+PVOID
+NTAPI
+MiCreatePebOrTeb(PEPROCESS Process,
+                 PVOID BaseAddress);
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 VOID
@@ -128,9 +135,9 @@ MmCreateKernelStack(IN BOOLEAN GuiStack,
     // Setup the template stack PTE
     //
     TempPte = HyperTemplatePte;
-    TempPte.u.Hard.Global = FALSE;
+    MI_MAKE_LOCAL_PAGE(&TempPte);
+    MI_MAKE_DIRTY_PAGE(&TempPte);
     TempPte.u.Hard.PageFrameNumber = 0;
-    TempPte.u.Hard.Dirty = TRUE;
     
     //
     // Acquire the PFN DB lock
@@ -225,9 +232,9 @@ MmGrowKernelStackEx(IN PVOID StackPointer,
     // Setup the template stack PTE
     //
     TempPte = HyperTemplatePte;
-    TempPte.u.Hard.Global = FALSE;
+    MI_MAKE_LOCAL_PAGE(&TempPte);
+    MI_MAKE_DIRTY_PAGE(&TempPte);
     TempPte.u.Hard.PageFrameNumber = 0;
-    TempPte.u.Hard.Dirty = TRUE;
     
     //
     // Acquire the PFN DB lock
@@ -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 initial TEB values
+            //
+            Teb->Tib.StackBase = InitialTeb->StackBase;
+            Teb->Tib.StackLimit = InitialTeb->StackLimit;
+            Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
+        }
+        else
+        {
+            //
+            // Use grandparent TEB values
+            //
+            Teb->Tib.StackBase = InitialTeb->PreviousStackBase;
+            Teb->Tib.StackLimit = InitialTeb->PreviousStackLimit;
+        }
+
+        //
+        // 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 */