fce21f5bd6f63adff8627f4af1ade95a7d5d0118
[reactos.git] / reactos / ntoskrnl / mm / procsup.c
1 /*
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
6 *
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 VOID NTAPI MiRosTakeOverPebTebRanges(IN PEPROCESS Process);
17
18 /* FUNCTIONS *****************************************************************/
19
20 NTSTATUS
21 NTAPI
22 MmInitializeHandBuiltProcess2(IN PEPROCESS Process)
23 {
24 PVOID BaseAddress;
25 PMEMORY_AREA MemoryArea;
26 PHYSICAL_ADDRESS BoundaryAddressMultiple;
27 NTSTATUS Status;
28 PMMSUPPORT ProcessAddressSpace = &Process->Vm;
29 BoundaryAddressMultiple.QuadPart = 0;
30
31 /* Create the shared data page */
32 BaseAddress = (PVOID)USER_SHARED_DATA;
33 Status = MmCreateMemoryArea(ProcessAddressSpace,
34 MEMORY_AREA_SHARED_DATA,
35 &BaseAddress,
36 PAGE_SIZE,
37 PAGE_EXECUTE_READ,
38 &MemoryArea,
39 FALSE,
40 0,
41 BoundaryAddressMultiple);
42
43 /* Lock the VAD, ARM3-owned ranges away */
44 MiRosTakeOverPebTebRanges(Process);
45 return Status;
46 }
47
48 NTSTATUS
49 NTAPI
50 MmInitializeProcessAddressSpace(IN PEPROCESS Process,
51 IN PEPROCESS ProcessClone OPTIONAL,
52 IN PVOID Section OPTIONAL,
53 IN OUT PULONG Flags,
54 IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL)
55 {
56 NTSTATUS Status;
57 PMMSUPPORT ProcessAddressSpace = &Process->Vm;
58 PVOID BaseAddress;
59 PMEMORY_AREA MemoryArea;
60 PHYSICAL_ADDRESS BoundaryAddressMultiple;
61 SIZE_T ViewSize = 0;
62 PVOID ImageBase = 0;
63 PROS_SECTION_OBJECT SectionObject = Section;
64 BoundaryAddressMultiple.QuadPart = 0;
65
66 /* Initialize the Addresss Space lock */
67 KeInitializeGuardedMutex(&Process->AddressCreationLock);
68 Process->Vm.WorkingSetExpansionLinks.Flink = NULL;
69
70 /* Initialize AVL tree */
71 ASSERT(Process->VadRoot.NumberGenericTableElements == 0);
72 Process->VadRoot.BalancedRoot.u1.Parent = &Process->VadRoot.BalancedRoot;
73
74 /* Acquire the Lock */
75 MmLockAddressSpace(ProcessAddressSpace);
76
77 /* Protect the highest 64KB of the process address space */
78 BaseAddress = (PVOID)MmUserProbeAddress;
79 Status = MmCreateMemoryArea(ProcessAddressSpace,
80 MEMORY_AREA_NO_ACCESS,
81 &BaseAddress,
82 0x10000,
83 PAGE_NOACCESS,
84 &MemoryArea,
85 FALSE,
86 0,
87 BoundaryAddressMultiple);
88 if (!NT_SUCCESS(Status))
89 {
90 DPRINT1("Failed to protect last 64KB\n");
91 goto exit;
92 }
93
94 /* Protect the 60KB above the shared user page */
95 BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
96 Status = MmCreateMemoryArea(ProcessAddressSpace,
97 MEMORY_AREA_NO_ACCESS,
98 &BaseAddress,
99 0x10000 - PAGE_SIZE,
100 PAGE_NOACCESS,
101 &MemoryArea,
102 FALSE,
103 0,
104 BoundaryAddressMultiple);
105 if (!NT_SUCCESS(Status))
106 {
107 DPRINT1("Failed to protect the memory above the shared user page\n");
108 goto exit;
109 }
110
111 /* Create the shared data page */
112 BaseAddress = (PVOID)USER_SHARED_DATA;
113 Status = MmCreateMemoryArea(ProcessAddressSpace,
114 MEMORY_AREA_SHARED_DATA,
115 &BaseAddress,
116 PAGE_SIZE,
117 PAGE_EXECUTE_READ,
118 &MemoryArea,
119 FALSE,
120 0,
121 BoundaryAddressMultiple);
122 if (!NT_SUCCESS(Status))
123 {
124 DPRINT1("Failed to create Shared User Data\n");
125 goto exit;
126 }
127
128 /* Lock the VAD, ARM3-owned ranges away */
129 MiRosTakeOverPebTebRanges(Process);
130
131 /* The process now has an address space */
132 Process->HasAddressSpace = TRUE;
133
134 /* Check if there's a Section Object */
135 if (SectionObject)
136 {
137 UNICODE_STRING FileName;
138 PWCHAR szSrc;
139 PCHAR szDest;
140 USHORT lnFName = 0;
141
142 /* Unlock the Address Space */
143 DPRINT("Unlocking\n");
144 MmUnlockAddressSpace(ProcessAddressSpace);
145
146 DPRINT("Mapping process image. Section: %p, Process: %p, ImageBase: %p\n",
147 SectionObject, Process, &ImageBase);
148 Status = MmMapViewOfSection(Section,
149 (PEPROCESS)Process,
150 (PVOID*)&ImageBase,
151 0,
152 0,
153 NULL,
154 &ViewSize,
155 0,
156 MEM_COMMIT,
157 PAGE_READWRITE);
158 if (!NT_SUCCESS(Status))
159 {
160 DPRINT1("Failed to map process Image\n");
161 return Status;
162 }
163
164 /* Save the pointer */
165 Process->SectionBaseAddress = ImageBase;
166
167 /* Determine the image file name and save it to EPROCESS */
168 DPRINT("Getting Image name\n");
169 FileName = SectionObject->FileObject->FileName;
170 szSrc = (PWCHAR)((PCHAR)FileName.Buffer + FileName.Length);
171 if (FileName.Buffer)
172 {
173 /* Loop the file name*/
174 while (szSrc > FileName.Buffer)
175 {
176 /* Make sure this isn't a backslash */
177 if (*--szSrc == OBJ_NAME_PATH_SEPARATOR)
178 {
179 /* If so, stop it here */
180 szSrc++;
181 break;
182 }
183 else
184 {
185 /* Otherwise, keep going */
186 lnFName++;
187 }
188 }
189 }
190
191 /* Copy the to the process and truncate it to 15 characters if necessary */
192 szDest = Process->ImageFileName;
193 lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1);
194 while (lnFName--) *szDest++ = (UCHAR)*szSrc++;
195 *szDest = ANSI_NULL;
196
197 /* Check if caller wants an audit name */
198 if (AuditName)
199 {
200 /* Setup the audit name */
201 SeInitializeProcessAuditName(SectionObject->FileObject,
202 FALSE,
203 AuditName);
204 }
205
206 /* Return status to caller */
207 return Status;
208 }
209
210 exit:
211 /* Unlock the Address Space */
212 DPRINT("Unlocking\n");
213 MmUnlockAddressSpace(ProcessAddressSpace);
214
215 /* Return status to caller */
216 return Status;
217 }
218
219 VOID
220 NTAPI
221 MmCleanProcessAddressSpace(IN PEPROCESS Process)
222 {
223 /* FIXME: Add part of MmDeleteProcessAddressSpace here */
224 }
225
226 NTSTATUS
227 NTAPI
228 MmDeleteProcessAddressSpace(PEPROCESS Process)
229 {
230 PVOID Address;
231 PMEMORY_AREA MemoryArea;
232
233 DPRINT("MmDeleteProcessAddressSpace(Process %x (%s))\n", Process,
234 Process->ImageFileName);
235
236 MmLockAddressSpace(&Process->Vm);
237
238 while ((MemoryArea = (PMEMORY_AREA)Process->Vm.WorkingSetExpansionLinks.Flink) != NULL)
239 {
240 switch (MemoryArea->Type)
241 {
242 case MEMORY_AREA_SECTION_VIEW:
243 Address = (PVOID)MemoryArea->StartingAddress;
244 MmUnlockAddressSpace(&Process->Vm);
245 MmUnmapViewOfSection(Process, Address);
246 MmLockAddressSpace(&Process->Vm);
247 break;
248
249 case MEMORY_AREA_VIRTUAL_MEMORY:
250 case MEMORY_AREA_PEB_OR_TEB:
251 MmFreeVirtualMemory(Process, MemoryArea);
252 break;
253
254 case MEMORY_AREA_SHARED_DATA:
255 case MEMORY_AREA_NO_ACCESS:
256 case MEMORY_AREA_OWNED_BY_ARM3:
257 MmFreeMemoryArea(&Process->Vm,
258 MemoryArea,
259 NULL,
260 NULL);
261 break;
262
263 case MEMORY_AREA_MDL_MAPPING:
264 KeBugCheck(PROCESS_HAS_LOCKED_PAGES);
265 break;
266
267 default:
268 KeBugCheck(MEMORY_MANAGEMENT);
269 }
270 }
271
272 Mmi386ReleaseMmInfo(Process);
273
274 MmUnlockAddressSpace(&Process->Vm);
275
276 DPRINT("Finished MmReleaseMmInfo()\n");
277 return(STATUS_SUCCESS);
278 }
279