- Implement (although non-optimally) MmGrowKernelStack for future use.
[reactos.git] / reactos / ntoskrnl / mm / process.c
index f5ddc7a..0ac708d 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/mm/process.c
 extern ULONG NtMajorVersion;
 extern ULONG NtMinorVersion;
 extern ULONG NtOSCSDVersion;
+extern ULONG NtGlobalFlag;
+
+#define MM_HIGHEST_VAD_ADDRESS \
+    (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
 
 /* FUNCTIONS *****************************************************************/
-  
+
 PVOID
 STDCALL
 MiCreatePebOrTeb(PEPROCESS Process,
@@ -28,14 +32,14 @@ MiCreatePebOrTeb(PEPROCESS Process,
     PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace;
     PMEMORY_AREA MemoryArea;
     PHYSICAL_ADDRESS BoundaryAddressMultiple;
-    BoundaryAddressMultiple.QuadPart = 0;
     PVOID AllocatedBase = BaseAddress;
-    
+    BoundaryAddressMultiple.QuadPart = 0;
+
     /* Acquire the Lock */
     MmLockAddressSpace(ProcessAddressSpace);
 
-    /* 
-     * Create a Peb or Teb. 
+    /*
+     * Create a Peb or Teb.
      * Loop until it works, decreasing by PAGE_SIZE each time. The logic here
      * is that a PEB allocation should never fail since the address is free,
      * while TEB allocation can fail, and we should simply try the address
@@ -44,40 +48,39 @@ MiCreatePebOrTeb(PEPROCESS Process,
      */
     do {
         DPRINT("Trying to allocate: %x\n", AllocatedBase);
-        Status = MmCreateMemoryArea(Process,
-                                    ProcessAddressSpace,
+        Status = MmCreateMemoryArea(ProcessAddressSpace,
                                     MEMORY_AREA_PEB_OR_TEB,
                                     &AllocatedBase,
                                     PAGE_SIZE,
                                     PAGE_READWRITE,
                                     &MemoryArea,
                                     TRUE,
-                                    FALSE,
+                                    0,
                                     BoundaryAddressMultiple);
-        AllocatedBase = AllocatedBase - PAGE_SIZE;
+        AllocatedBase = RVA(AllocatedBase, -PAGE_SIZE);
     } while (Status != STATUS_SUCCESS);
-       
+
     /* Initialize the Region */
-    MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
-                       PAGE_SIZE, 
-                       MEM_COMMIT, 
+    MmInitializeRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
+                       PAGE_SIZE,
+                       MEM_COMMIT,
                        PAGE_READWRITE);
-    
+
     /* Reserve the pages */
     MmReserveSwapPages(PAGE_SIZE);
-    
+
     /* Unlock Address Space */
     DPRINT("Returning\n");
     MmUnlockAddressSpace(ProcessAddressSpace);
-    return AllocatedBase + PAGE_SIZE;
+    return RVA(AllocatedBase, PAGE_SIZE);
 }
 
 VOID
-MiFreeStackPage(PVOID Context, 
-                MEMORY_AREA* MemoryArea, 
-                PVOID Address, 
-                PFN_TYPE Page, 
-                SWAPENTRY SwapEntry, 
+MiFreeStackPage(PVOID Context,
+                MEMORY_AREA* MemoryArea,
+                PVOID Address,
+                PFN_TYPE Page,
+                SWAPENTRY SwapEntry,
                 BOOLEAN Dirty)
 {
     ASSERT(SwapEntry == 0);
@@ -88,64 +91,38 @@ VOID
 STDCALL
 MmDeleteKernelStack(PVOID Stack,
                     BOOLEAN GuiStack)
-{       
+{
     /* Lock the Address Space */
     MmLockAddressSpace(MmGetKernelAddressSpace());
-    
+
     /* Delete the Stack */
     MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
                           Stack,
                           MiFreeStackPage,
                           NULL);
-                          
+
     /* Unlock the Address Space */
     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);
 }
@@ -157,74 +134,113 @@ MmCreateKernelStack(BOOLEAN GuiStack)
     PMEMORY_AREA StackArea;
     ULONG i;
     PHYSICAL_ADDRESS BoundaryAddressMultiple;
-    PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE];
+    ULONG StackSize = GuiStack ? KERNEL_LARGE_STACK_SIZE : KERNEL_STACK_SIZE;
+    PFN_TYPE Page[KERNEL_LARGE_STACK_SIZE / PAGE_SIZE];
     PVOID KernelStack = NULL;
     NTSTATUS Status;
-    
+
     /* Initialize the Boundary Address */
     BoundaryAddressMultiple.QuadPart = 0;
-          
+
     /* Lock the Kernel Address Space */
     MmLockAddressSpace(MmGetKernelAddressSpace());
-    
+
     /* Create a MAREA for the Kernel Stack */
-    Status = MmCreateMemoryArea(NULL,
-                                MmGetKernelAddressSpace(),
+    Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
                                 MEMORY_AREA_KERNEL_STACK,
                                 &KernelStack,
-                                MM_STACK_SIZE,
-                                0,
+                                StackSize,
+                                PAGE_READWRITE,
                                 &StackArea,
                                 FALSE,
-                                FALSE,
+                                0,
                                 BoundaryAddressMultiple);
-        
+
     /* Unlock the Address Space */
     MmUnlockAddressSpace(MmGetKernelAddressSpace());
-      
+
     /* Check for Success */
-    if (!NT_SUCCESS(Status)) 
-    {    
+    if (!NT_SUCCESS(Status))
+    {
         DPRINT1("Failed to create thread stack\n");
         KEBUGCHECK(0);
     }
-        
-    /* Mark the Stack in use */
-    for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++) 
+
+    /*
+     * Mark the Stack in use.
+     * Note: Currently we mark all 60KB in use for a GUI Thread.
+     * We should only do this inside MmGrowKernelStack. TODO!
+     */
+    for (i = 0; i < (StackSize / PAGE_SIZE); i++)
     {
         Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
     }
-        
+
     /* Create a Virtual Mapping for it */
     Status = MmCreateVirtualMapping(NULL,
                                     KernelStack,
                                     PAGE_READWRITE,
                                     Page,
-                                    MM_STACK_SIZE / PAGE_SIZE);
-        
+                                    StackSize / PAGE_SIZE);
+
     /* Check for success */
-    if (!NT_SUCCESS(Status)) 
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("Could not create Virtual Mapping for Kernel Stack\n");
         KEBUGCHECK(0);
     }
-    
+
+    /* Return the stack */
     return KernelStack;
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+MmGrowKernelStack(PVOID StackPointer)
+{
+    PETHREAD Thread = PsGetCurrentThread();
+
+    /* Make sure we have reserved space for our grow */
+    ASSERT(((PCHAR)Thread->Tcb.StackBase - (PCHAR)Thread->Tcb.StackLimit) <=
+           (KERNEL_LARGE_STACK_SIZE + PAGE_SIZE));
+
+    /* 
+     * We'll give you three more pages.
+     * NOTE: See note in MmCreateKernelStack. These pages are already being reserved.
+     * It would be more efficient to only grow them (commit them) here.
+     */
+    Thread->Tcb.StackLimit -= KERNEL_STACK_SIZE;
+
+    /* Return success */
+    DPRINT1("Thread, Thread Limit, Stack %p %p %p\n", KeGetCurrentThread(),
+                                                      KeGetCurrentThread()->StackLimit,
+                                                      StackPointer);
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 STDCALL
 MmCreatePeb(PEPROCESS Process)
-{    
+{
     PPEB Peb = NULL;
     LARGE_INTEGER SectionOffset;
-    ULONG ViewSize = 0;
+    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(NlsSectionObject,
@@ -237,7 +253,7 @@ MmCreatePeb(PEPROCESS Process)
                                 ViewShare,
                                 MEM_TOP_DOWN,
                                 PAGE_READONLY);
-    if (!NT_SUCCESS(Status)) 
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
         return(Status);
@@ -246,10 +262,7 @@ 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 +270,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);
@@ -283,7 +366,7 @@ MmCreateTeb(PEPROCESS Process,
 {
     PTEB Teb;
     BOOLEAN Attached = FALSE;
-    
+
     /* Attach to the process */
     DPRINT("MmCreateTeb\n");
     if (Process != PsGetCurrentProcess())
@@ -292,43 +375,33 @@ MmCreateTeb(PEPROCESS Process,
         KeAttachProcess(&Process->Pcb);
         Attached = TRUE;
     }
-    
+
     /* Allocate the TEB */
-    Teb = MiCreatePebOrTeb(Process, (PVOID)TEB_BASE);
-    
+    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->Cid = *ClientId;
     Teb->RealClientId = *ClientId;
-    Teb->Peb = Process->Peb;
+    Teb->ProcessEnvironmentBlock = Process->Peb;
     Teb->CurrentLocale = PsDefaultThreadLocaleId;
-    
+
     /* Store stack information from InitialTeb */
     if(InitialTeb != NULL)
     {
-        /* fixed-size stack */
-        if(InitialTeb->StackBase && InitialTeb->StackLimit)
-        {
-            Teb->Tib.StackBase = InitialTeb->StackBase;
-            Teb->Tib.StackLimit = InitialTeb->StackLimit;
-            Teb->DeallocationStack = InitialTeb->StackLimit;
-        }
-        /* expandable stack */
-        else
-        {
-            Teb->Tib.StackBase = InitialTeb->StackCommit;
-            Teb->Tib.StackLimit = InitialTeb->StackCommitMax;
-            Teb->DeallocationStack = InitialTeb->StackReserved;
-        }
+        Teb->Tib.StackBase = InitialTeb->StackBase;
+        Teb->Tib.StackLimit = InitialTeb->StackLimit;
+        Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
     }
-    
+
     /* Return TEB Address */
     DPRINT("Allocated: %x\n", Teb);
     if (Attached) KeDetachProcess();
@@ -345,47 +418,45 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
     PVOID BaseAddress;
     PMEMORY_AREA MemoryArea;
     PHYSICAL_ADDRESS BoundaryAddressMultiple;
-    BoundaryAddressMultiple.QuadPart = 0;
-    ULONG ViewSize = 0;
+    SIZE_T ViewSize = 0;
     PVOID ImageBase = 0;
-                    
+    BoundaryAddressMultiple.QuadPart = 0;
+
     /* Initialize the Addresss Space */
-    MmInitializeAddressSpace(Process, ProcessAddressSpace);    
-    
+    MmInitializeAddressSpace(Process, ProcessAddressSpace);
+
     /* Acquire the Lock */
     MmLockAddressSpace(ProcessAddressSpace);
 
     /* Protect the highest 64KB of the process address space */
     BaseAddress = (PVOID)MmUserProbeAddress;
-    Status = MmCreateMemoryArea(Process,
-                                ProcessAddressSpace,
+    Status = MmCreateMemoryArea(ProcessAddressSpace,
                                 MEMORY_AREA_NO_ACCESS,
                                 &BaseAddress,
                                 0x10000,
                                 PAGE_NOACCESS,
                                 &MemoryArea,
                                 FALSE,
-                                FALSE,
+                                0,
                                 BoundaryAddressMultiple);
-    if (!NT_SUCCESS(Status)) 
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to protect last 64KB\n");
         goto exit;
      }
-    
+
     /* Protect the 60KB above the shared user page */
     BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
-    Status = MmCreateMemoryArea(Process,
-                                ProcessAddressSpace,
+    Status = MmCreateMemoryArea(ProcessAddressSpace,
                                 MEMORY_AREA_NO_ACCESS,
                                 &BaseAddress,
                                 0x10000 - PAGE_SIZE,
                                 PAGE_NOACCESS,
                                 &MemoryArea,
                                 FALSE,
-                                FALSE,
+                                0,
                                 BoundaryAddressMultiple);
-    if (!NT_SUCCESS(Status)) 
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to protect the memory above the shared user page\n");
         goto exit;
@@ -393,34 +464,33 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
 
     /* Create the shared data page */
     BaseAddress = (PVOID)USER_SHARED_DATA;
-    Status = MmCreateMemoryArea(Process,
-                                ProcessAddressSpace,
+    Status = MmCreateMemoryArea(ProcessAddressSpace,
                                 MEMORY_AREA_SHARED_DATA,
                                 &BaseAddress,
                                 PAGE_SIZE,
-                                PAGE_READONLY,
+                                PAGE_EXECUTE_READ,
                                 &MemoryArea,
                                 FALSE,
-                                FALSE,
+                                0,
                                 BoundaryAddressMultiple);
-    if (!NT_SUCCESS(Status)) 
+    if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to create Shared User Data\n");
         goto exit;
      }
-                
+
     /* Check if there's a Section Object */
-    if (Section) 
+    if (Section)
     {
         UNICODE_STRING FileName;
         PWCHAR szSrc;
         PCHAR szDest;
         USHORT lnFName = 0;
-        
+
         /* Unlock the Address Space */
         DPRINT("Unlocking\n");
         MmUnlockAddressSpace(ProcessAddressSpace);
-    
+
         DPRINT("Mapping process image. Section: %p, Process: %p, ImageBase: %p\n",
                  Section, Process, &ImageBase);
         Status = MmMapViewOfSection(Section,
@@ -433,30 +503,28 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
                                     0,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
-        if (!NT_SUCCESS(Status)) 
+        if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to map process Image\n");
-            ObDereferenceObject(Section); 
-            goto exit;
+            return Status;
         }
-        ObDereferenceObject(Section);
-        
+
         /* Save the pointer */
         Process->SectionBaseAddress = ImageBase;
-        
+
         /* Determine the image file name and save it to EPROCESS */
         DPRINT("Getting Image name\n");
         FileName = Section->FileObject->FileName;
         szSrc = (PWCHAR)(FileName.Buffer + (FileName.Length / sizeof(WCHAR)) - 1);
 
-        while(szSrc >= FileName.Buffer) 
+        while(szSrc >= FileName.Buffer)
         {
-            if(*szSrc == L'\\') 
+            if(*szSrc == L'\\')
             {
                 szSrc++;
                 break;
-            }  
-            else 
+            }
+            else
             {
                 szSrc--;
                 lnFName++;
@@ -468,16 +536,16 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
         szDest = Process->ImageFileName;
         lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1);
         while(lnFName-- > 0) *(szDest++) = (UCHAR)*(szSrc++);
-        
+
         /* Return status to caller */
         return Status;
     }
-    
+
 exit:
     /* Unlock the Address Space */
     DPRINT("Unlocking\n");
     MmUnlockAddressSpace(ProcessAddressSpace);
-        
+
     /* Return status to caller */
     return Status;
 }