2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/procsup.c
5 * PURPOSE: Memory functions related to Processes
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
10 /* INCLUDES *****************************************************************/
16 VOID NTAPI
MiRosTakeOverPebTebRanges(IN PEPROCESS Process
);
18 /* FUNCTIONS *****************************************************************/
22 MiCreatePebOrTeb(PEPROCESS Process
,
26 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
27 PMEMORY_AREA MemoryArea
;
28 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
29 PVOID AllocatedBase
= BaseAddress
;
30 BoundaryAddressMultiple
.QuadPart
= 0;
32 /* Acquire the Lock */
33 MmLockAddressSpace(ProcessAddressSpace
);
36 * Create a Peb or Teb.
37 * Loop until it works, decreasing by PAGE_SIZE each time. The logic here
38 * is that a PEB allocation should never fail since the address is free,
39 * while TEB allocation can fail, and we should simply try the address
40 * below. Is there a nicer way of doing this automagically? (ie: findning)
41 * a gap region? -- Alex
44 DPRINT("Trying to allocate: %x\n", AllocatedBase
);
45 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
46 MEMORY_AREA_PEB_OR_TEB
,
53 BoundaryAddressMultiple
);
54 AllocatedBase
= RVA(AllocatedBase
, -PAGE_SIZE
);
55 } while (Status
!= STATUS_SUCCESS
);
57 /* Initialize the Region */
58 MmInitializeRegion(&MemoryArea
->Data
.VirtualMemoryData
.RegionListHead
,
63 /* Reserve the pages */
64 MmReserveSwapPages(PAGE_SIZE
);
66 /* Unlock Address Space */
67 DPRINT("Returning\n");
68 MmUnlockAddressSpace(ProcessAddressSpace
);
69 return RVA(AllocatedBase
, PAGE_SIZE
);
74 MmDeleteTeb(PEPROCESS Process
,
77 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
78 PMEMORY_AREA MemoryArea
;
80 /* Lock the Address Space */
81 MmLockAddressSpace(ProcessAddressSpace
);
83 MemoryArea
= MmLocateMemoryAreaByAddress(ProcessAddressSpace
, (PVOID
)Teb
);
87 MmFreeVirtualMemory(Process
, MemoryArea
);
90 /* Unlock the Address Space */
91 MmUnlockAddressSpace(ProcessAddressSpace
);
96 MmInitializeHandBuiltProcess2(IN PEPROCESS Process
)
99 PMEMORY_AREA MemoryArea
;
100 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
102 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
103 BoundaryAddressMultiple
.QuadPart
= 0;
105 /* Create the shared data page */
106 BaseAddress
= (PVOID
)USER_SHARED_DATA
;
107 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
108 MEMORY_AREA_SHARED_DATA
,
115 BoundaryAddressMultiple
);
117 /* Lock the VAD, ARM3-owned ranges away */
118 MiRosTakeOverPebTebRanges(Process
);
124 MmInitializeProcessAddressSpace(IN PEPROCESS Process
,
125 IN PEPROCESS ProcessClone OPTIONAL
,
126 IN PVOID Section OPTIONAL
,
128 IN POBJECT_NAME_INFORMATION
*AuditName OPTIONAL
)
131 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
133 PMEMORY_AREA MemoryArea
;
134 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
137 PROS_SECTION_OBJECT SectionObject
= Section
;
138 BoundaryAddressMultiple
.QuadPart
= 0;
140 /* Initialize the Addresss Space lock */
141 KeInitializeGuardedMutex(&Process
->AddressCreationLock
);
142 Process
->Vm
.WorkingSetExpansionLinks
.Flink
= NULL
;
144 /* Initialize AVL tree */
145 ASSERT(Process
->VadRoot
.NumberGenericTableElements
== 0);
146 Process
->VadRoot
.BalancedRoot
.u1
.Parent
= &Process
->VadRoot
.BalancedRoot
;
148 /* Acquire the Lock */
149 MmLockAddressSpace(ProcessAddressSpace
);
151 /* Protect the highest 64KB of the process address space */
152 BaseAddress
= (PVOID
)MmUserProbeAddress
;
153 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
154 MEMORY_AREA_NO_ACCESS
,
161 BoundaryAddressMultiple
);
162 if (!NT_SUCCESS(Status
))
164 DPRINT1("Failed to protect last 64KB\n");
168 /* Protect the 60KB above the shared user page */
169 BaseAddress
= (char*)USER_SHARED_DATA
+ PAGE_SIZE
;
170 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
171 MEMORY_AREA_NO_ACCESS
,
178 BoundaryAddressMultiple
);
179 if (!NT_SUCCESS(Status
))
181 DPRINT1("Failed to protect the memory above the shared user page\n");
185 /* Create the shared data page */
186 BaseAddress
= (PVOID
)USER_SHARED_DATA
;
187 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
188 MEMORY_AREA_SHARED_DATA
,
195 BoundaryAddressMultiple
);
196 if (!NT_SUCCESS(Status
))
198 DPRINT1("Failed to create Shared User Data\n");
202 /* Lock the VAD, ARM3-owned ranges away */
203 MiRosTakeOverPebTebRanges(Process
);
205 /* The process now has an address space */
206 Process
->HasAddressSpace
= TRUE
;
208 /* Check if there's a Section Object */
211 UNICODE_STRING FileName
;
216 /* Unlock the Address Space */
217 DPRINT("Unlocking\n");
218 MmUnlockAddressSpace(ProcessAddressSpace
);
220 DPRINT("Mapping process image. Section: %p, Process: %p, ImageBase: %p\n",
221 SectionObject
, Process
, &ImageBase
);
222 Status
= MmMapViewOfSection(Section
,
232 if (!NT_SUCCESS(Status
))
234 DPRINT1("Failed to map process Image\n");
238 /* Save the pointer */
239 Process
->SectionBaseAddress
= ImageBase
;
241 /* Determine the image file name and save it to EPROCESS */
242 DPRINT("Getting Image name\n");
243 FileName
= SectionObject
->FileObject
->FileName
;
244 szSrc
= (PWCHAR
)((PCHAR
)FileName
.Buffer
+ FileName
.Length
);
247 /* Loop the file name*/
248 while (szSrc
> FileName
.Buffer
)
250 /* Make sure this isn't a backslash */
251 if (*--szSrc
== OBJ_NAME_PATH_SEPARATOR
)
253 /* If so, stop it here */
259 /* Otherwise, keep going */
265 /* Copy the to the process and truncate it to 15 characters if necessary */
266 szDest
= Process
->ImageFileName
;
267 lnFName
= min(lnFName
, sizeof(Process
->ImageFileName
) - 1);
268 while (lnFName
--) *szDest
++ = (UCHAR
)*szSrc
++;
271 /* Check if caller wants an audit name */
274 /* Setup the audit name */
275 SeInitializeProcessAuditName(SectionObject
->FileObject
,
280 /* Return status to caller */
285 /* Unlock the Address Space */
286 DPRINT("Unlocking\n");
287 MmUnlockAddressSpace(ProcessAddressSpace
);
289 /* Return status to caller */
295 MmCleanProcessAddressSpace(IN PEPROCESS Process
)
297 /* FIXME: Add part of MmDeleteProcessAddressSpace here */
302 MmDeleteProcessAddressSpace(PEPROCESS Process
)
305 PMEMORY_AREA MemoryArea
;
307 DPRINT("MmDeleteProcessAddressSpace(Process %x (%s))\n", Process
,
308 Process
->ImageFileName
);
310 MmLockAddressSpace(&Process
->Vm
);
312 while ((MemoryArea
= (PMEMORY_AREA
)Process
->Vm
.WorkingSetExpansionLinks
.Flink
) != NULL
)
314 switch (MemoryArea
->Type
)
316 case MEMORY_AREA_SECTION_VIEW
:
317 Address
= (PVOID
)MemoryArea
->StartingAddress
;
318 MmUnlockAddressSpace(&Process
->Vm
);
319 MmUnmapViewOfSection(Process
, Address
);
320 MmLockAddressSpace(&Process
->Vm
);
323 case MEMORY_AREA_VIRTUAL_MEMORY
:
324 case MEMORY_AREA_PEB_OR_TEB
:
325 MmFreeVirtualMemory(Process
, MemoryArea
);
328 case MEMORY_AREA_SHARED_DATA
:
329 case MEMORY_AREA_NO_ACCESS
:
330 case MEMORY_AREA_OWNED_BY_ARM3
:
331 MmFreeMemoryArea(&Process
->Vm
,
337 case MEMORY_AREA_MDL_MAPPING
:
338 KeBugCheck(PROCESS_HAS_LOCKED_PAGES
);
342 KeBugCheck(MEMORY_MANAGEMENT
);
346 Mmi386ReleaseMmInfo(Process
);
348 MmUnlockAddressSpace(&Process
->Vm
);
350 DPRINT("Finished MmReleaseMmInfo()\n");
351 return(STATUS_SUCCESS
);