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 /* FUNCTIONS *****************************************************************/
20 MiCreatePebOrTeb(PEPROCESS Process
,
24 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
25 PMEMORY_AREA MemoryArea
;
26 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
27 PVOID AllocatedBase
= BaseAddress
;
28 BoundaryAddressMultiple
.QuadPart
= 0;
30 /* Acquire the Lock */
31 MmLockAddressSpace(ProcessAddressSpace
);
34 * Create a Peb or Teb.
35 * Loop until it works, decreasing by PAGE_SIZE each time. The logic here
36 * is that a PEB allocation should never fail since the address is free,
37 * while TEB allocation can fail, and we should simply try the address
38 * below. Is there a nicer way of doing this automagically? (ie: findning)
39 * a gap region? -- Alex
42 DPRINT("Trying to allocate: %x\n", AllocatedBase
);
43 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
44 MEMORY_AREA_PEB_OR_TEB
,
51 BoundaryAddressMultiple
);
52 AllocatedBase
= RVA(AllocatedBase
, -PAGE_SIZE
);
53 } while (Status
!= STATUS_SUCCESS
);
55 /* Initialize the Region */
56 MmInitializeRegion(&MemoryArea
->Data
.VirtualMemoryData
.RegionListHead
,
61 /* Reserve the pages */
62 MmReserveSwapPages(PAGE_SIZE
);
64 /* Unlock Address Space */
65 DPRINT("Returning\n");
66 MmUnlockAddressSpace(ProcessAddressSpace
);
67 return RVA(AllocatedBase
, PAGE_SIZE
);
72 MmDeleteTeb(PEPROCESS Process
,
75 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
76 PMEMORY_AREA MemoryArea
;
78 /* Lock the Address Space */
79 MmLockAddressSpace(ProcessAddressSpace
);
81 MemoryArea
= MmLocateMemoryAreaByAddress(ProcessAddressSpace
, (PVOID
)Teb
);
85 MmFreeVirtualMemory(Process
, MemoryArea
);
88 /* Unlock the Address Space */
89 MmUnlockAddressSpace(ProcessAddressSpace
);
94 MmInitializeHandBuiltProcess2(IN PEPROCESS Process
)
97 PMEMORY_AREA MemoryArea
;
98 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
100 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
101 BoundaryAddressMultiple
.QuadPart
= 0;
103 /* Create the shared data page */
104 BaseAddress
= (PVOID
)USER_SHARED_DATA
;
105 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
106 MEMORY_AREA_SHARED_DATA
,
113 BoundaryAddressMultiple
);
119 MmInitializeProcessAddressSpace(IN PEPROCESS Process
,
120 IN PEPROCESS ProcessClone OPTIONAL
,
121 IN PVOID Section OPTIONAL
,
123 IN POBJECT_NAME_INFORMATION
*AuditName OPTIONAL
)
126 PMMSUPPORT ProcessAddressSpace
= &Process
->Vm
;
128 PMEMORY_AREA MemoryArea
;
129 PHYSICAL_ADDRESS BoundaryAddressMultiple
;
132 PROS_SECTION_OBJECT SectionObject
= Section
;
133 BoundaryAddressMultiple
.QuadPart
= 0;
135 /* Initialize the Addresss Space lock */
136 KeInitializeGuardedMutex(&Process
->AddressCreationLock
);
137 Process
->Vm
.WorkingSetExpansionLinks
.Flink
= NULL
;
139 /* Initialize AVL tree */
140 ASSERT(Process
->VadRoot
.NumberGenericTableElements
== 0);
141 Process
->VadRoot
.BalancedRoot
.u1
.Parent
= &Process
->VadRoot
.BalancedRoot
;
143 /* Acquire the Lock */
144 MmLockAddressSpace(ProcessAddressSpace
);
146 /* Protect the highest 64KB of the process address space */
147 BaseAddress
= (PVOID
)MmUserProbeAddress
;
148 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
149 MEMORY_AREA_NO_ACCESS
,
156 BoundaryAddressMultiple
);
157 if (!NT_SUCCESS(Status
))
159 DPRINT1("Failed to protect last 64KB\n");
163 /* Protect the 60KB above the shared user page */
164 BaseAddress
= (char*)USER_SHARED_DATA
+ PAGE_SIZE
;
165 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
166 MEMORY_AREA_NO_ACCESS
,
173 BoundaryAddressMultiple
);
174 if (!NT_SUCCESS(Status
))
176 DPRINT1("Failed to protect the memory above the shared user page\n");
180 /* Create the shared data page */
181 BaseAddress
= (PVOID
)USER_SHARED_DATA
;
182 Status
= MmCreateMemoryArea(ProcessAddressSpace
,
183 MEMORY_AREA_SHARED_DATA
,
190 BoundaryAddressMultiple
);
191 if (!NT_SUCCESS(Status
))
193 DPRINT1("Failed to create Shared User Data\n");
197 /* The process now has an address space */
198 Process
->HasAddressSpace
= TRUE
;
200 /* Check if there's a Section Object */
203 UNICODE_STRING FileName
;
208 /* Unlock the Address Space */
209 DPRINT("Unlocking\n");
210 MmUnlockAddressSpace(ProcessAddressSpace
);
212 DPRINT("Mapping process image. Section: %p, Process: %p, ImageBase: %p\n",
213 SectionObject
, Process
, &ImageBase
);
214 Status
= MmMapViewOfSection(Section
,
224 if (!NT_SUCCESS(Status
))
226 DPRINT1("Failed to map process Image\n");
230 /* Save the pointer */
231 Process
->SectionBaseAddress
= ImageBase
;
233 /* Determine the image file name and save it to EPROCESS */
234 DPRINT("Getting Image name\n");
235 FileName
= SectionObject
->FileObject
->FileName
;
236 szSrc
= (PWCHAR
)((PCHAR
)FileName
.Buffer
+ FileName
.Length
);
239 /* Loop the file name*/
240 while (szSrc
> FileName
.Buffer
)
242 /* Make sure this isn't a backslash */
243 if (*--szSrc
== OBJ_NAME_PATH_SEPARATOR
)
245 /* If so, stop it here */
251 /* Otherwise, keep going */
257 /* Copy the to the process and truncate it to 15 characters if necessary */
258 szDest
= Process
->ImageFileName
;
259 lnFName
= min(lnFName
, sizeof(Process
->ImageFileName
) - 1);
260 while (lnFName
--) *szDest
++ = (UCHAR
)*szSrc
++;
263 /* Check if caller wants an audit name */
266 /* Setup the audit name */
267 SeInitializeProcessAuditName(SectionObject
->FileObject
,
272 /* Return status to caller */
277 /* Unlock the Address Space */
278 DPRINT("Unlocking\n");
279 MmUnlockAddressSpace(ProcessAddressSpace
);
281 /* Return status to caller */
287 MmCleanProcessAddressSpace(IN PEPROCESS Process
)
289 /* FIXME: Add part of MmDeleteProcessAddressSpace here */
294 MmDeleteProcessAddressSpace(PEPROCESS Process
)
297 PMEMORY_AREA MemoryArea
;
299 DPRINT("MmDeleteProcessAddressSpace(Process %x (%s))\n", Process
,
300 Process
->ImageFileName
);
302 MmLockAddressSpace(&Process
->Vm
);
304 while ((MemoryArea
= (PMEMORY_AREA
)Process
->Vm
.WorkingSetExpansionLinks
.Flink
) != NULL
)
306 switch (MemoryArea
->Type
)
308 case MEMORY_AREA_SECTION_VIEW
:
309 Address
= (PVOID
)MemoryArea
->StartingAddress
;
310 MmUnlockAddressSpace(&Process
->Vm
);
311 MmUnmapViewOfSection(Process
, Address
);
312 MmLockAddressSpace(&Process
->Vm
);
315 case MEMORY_AREA_VIRTUAL_MEMORY
:
316 case MEMORY_AREA_PEB_OR_TEB
:
317 MmFreeVirtualMemory(Process
, MemoryArea
);
320 case MEMORY_AREA_SHARED_DATA
:
321 case MEMORY_AREA_NO_ACCESS
:
322 MmFreeMemoryArea(&Process
->Vm
,
328 case MEMORY_AREA_MDL_MAPPING
:
329 KeBugCheck(PROCESS_HAS_LOCKED_PAGES
);
333 KeBugCheck(MEMORY_MANAGEMENT
);
337 Mmi386ReleaseMmInfo(Process
);
339 MmUnlockAddressSpace(&Process
->Vm
);
341 DPRINT("Finished MmReleaseMmInfo()\n");
342 return(STATUS_SUCCESS
);