some __stdcall fixes in ntoskrnl and ntdll
[reactos.git] / reactos / ntoskrnl / mm / section.c
1 /* $Id: section.c,v 1.14 1999/08/29 06:59:10 ea Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/mm/section.c
6 * PURPOSE: Implements section objects
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/mm.h>
16 #include <internal/ob.h>
17 #include <internal/io.h>
18 #include <internal/ps.h>
19 #include <wchar.h>
20
21 #define NDEBUG
22 #include <internal/debug.h>
23
24 /* GLOBALS *******************************************************************/
25
26 POBJECT_TYPE MmSectionType = NULL;
27
28 /* FUNCTIONS *****************************************************************/
29
30 VOID MmpDeleteSection(PVOID ObjectBody)
31 {
32 }
33
34 NTSTATUS MmpCreateSection(PVOID ObjectBody,
35 PVOID Parent,
36 PWSTR RemainingPath,
37 POBJECT_ATTRIBUTES ObjectAttributes)
38 {
39 NTSTATUS Status;
40
41 DPRINT("MmpCreateDevice(ObjectBody %x, Parent %x, RemainingPath %w)\n",
42 ObjectBody, Parent, RemainingPath);
43
44 if (RemainingPath == NULL)
45 {
46 return(STATUS_SUCCESS);
47 }
48
49 if (wcschr(RemainingPath+1, '\\') != NULL)
50 {
51 return(STATUS_UNSUCCESSFUL);
52 }
53
54 Status = ObReferenceObjectByPointer(Parent,
55 STANDARD_RIGHTS_REQUIRED,
56 ObDirectoryType,
57 UserMode);
58 if (!NT_SUCCESS(Status))
59 {
60 return(Status);
61 }
62
63 ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1);
64 ObDereferenceObject(Parent);
65
66 return(STATUS_SUCCESS);
67 }
68
69 NTSTATUS MmInitSectionImplementation(VOID)
70 {
71 ANSI_STRING AnsiString;
72
73 MmSectionType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
74
75 MmSectionType->TotalObjects = 0;
76 MmSectionType->TotalHandles = 0;
77 MmSectionType->MaxObjects = ULONG_MAX;
78 MmSectionType->MaxHandles = ULONG_MAX;
79 MmSectionType->PagedPoolCharge = 0;
80 MmSectionType->NonpagedPoolCharge = sizeof(SECTION_OBJECT);
81 MmSectionType->Dump = NULL;
82 MmSectionType->Open = NULL;
83 MmSectionType->Close = NULL;
84 MmSectionType->Delete = MmpDeleteSection;
85 MmSectionType->Parse = NULL;
86 MmSectionType->Security = NULL;
87 MmSectionType->QueryName = NULL;
88 MmSectionType->OkayToClose = NULL;
89 MmSectionType->Create = MmpCreateSection;
90
91 RtlInitAnsiString(&AnsiString,"Section");
92 RtlAnsiStringToUnicodeString(&MmSectionType->TypeName,
93 &AnsiString,TRUE);
94 return(STATUS_SUCCESS);
95 }
96
97
98 NTSTATUS
99 STDCALL
100 NtCreateSection (
101 OUT PHANDLE SectionHandle,
102 IN ACCESS_MASK DesiredAccess,
103 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
104 IN PLARGE_INTEGER MaximumSize OPTIONAL,
105 IN ULONG SectionPageProtection OPTIONAL,
106 IN ULONG AllocationAttributes,
107 IN HANDLE FileHandle OPTIONAL
108 )
109 /*
110 * FUNCTION: Creates a section object.
111 * ARGUMENTS:
112 * SectionHandle (OUT) = Caller supplied storage for the resulting
113 * handle
114 * DesiredAccess = Specifies the desired access to the section can be a
115 * combination of STANDARD_RIGHTS_REQUIRED |
116 * SECTION_QUERY | SECTION_MAP_WRITE |
117 * SECTION_MAP_READ | SECTION_MAP_EXECUTE.
118 * ObjectAttribute = Initialized attributes for the object can be used
119 * to create a named section
120 * MaxiumSize = Maximizes the size of the memory section. Must be
121 * non-NULL for a page-file backed section.
122 * If value specified for a mapped file and the file is
123 * not large enough, file will be extended.
124 * SectionPageProtection = Can be a combination of PAGE_READONLY |
125 * PAGE_READWRITE | PAGE_WRITEONLY |
126 * PAGE_WRITECOPY.
127 * AllocationAttributes = can be a combination of SEC_IMAGE |
128 * SEC_RESERVE
129 * FileHandle = Handle to a file to create a section mapped to a file
130 * instead of a memory backed section.
131 * RETURNS: Status
132 */
133 {
134 PSECTION_OBJECT Section;
135 NTSTATUS Status;
136
137 DPRINT("NtCreateSection()\n");
138
139 Section = ObCreateObject(SectionHandle,
140 DesiredAccess,
141 ObjectAttributes,
142 MmSectionType);
143 if (Section == NULL)
144 {
145 return(STATUS_UNSUCCESSFUL);
146 }
147
148 if (MaximumSize != NULL)
149 {
150 Section->MaximumSize = *MaximumSize;
151 }
152 else
153 {
154 Section->MaximumSize.QuadPart = 0xffffffff;
155 }
156 Section->SectionPageProtection = SectionPageProtection;
157 Section->AllocateAttributes = AllocationAttributes;
158
159 if (FileHandle != NULL)
160 {
161 Status = ObReferenceObjectByHandle(FileHandle,
162 FILE_READ_DATA,
163 IoFileType,
164 UserMode,
165 (PVOID*)&Section->FileObject,
166 NULL);
167 if (Status != STATUS_SUCCESS)
168 {
169 DPRINT("NtCreateSection() = %x\n",Status);
170 return(Status);
171 }
172 }
173 else
174 {
175 Section->FileObject = NULL;
176 }
177
178 DPRINT("NtCreateSection() = STATUS_SUCCESS\n");
179 return(STATUS_SUCCESS);
180 }
181
182
183 /**********************************************************************
184 * NAME
185 * NtOpenSection
186 *
187 * DESCRIPTION
188 *
189 * ARGUMENTS
190 * SectionHandle
191 *
192 * DesiredAccess
193 *
194 * ObjectAttributes
195 *
196 * RETURN VALUE
197 *
198 * REVISIONS
199 *
200 */
201 NTSTATUS
202 STDCALL
203 NtOpenSection (
204 PHANDLE SectionHandle,
205 ACCESS_MASK DesiredAccess,
206 POBJECT_ATTRIBUTES ObjectAttributes
207 )
208 {
209 PVOID Object;
210 NTSTATUS Status;
211
212 *SectionHandle = 0;
213
214 Status = ObReferenceObjectByName(
215 ObjectAttributes->ObjectName,
216 ObjectAttributes->Attributes,
217 NULL,
218 DesiredAccess,
219 MmSectionType,
220 UserMode,
221 NULL,
222 & Object
223 );
224 if (!NT_SUCCESS(Status))
225 {
226 return Status;
227 }
228
229 Status = ObCreateHandle(
230 PsGetCurrentProcess(),
231 Object,
232 DesiredAccess,
233 FALSE,
234 SectionHandle
235 );
236 return Status;
237 }
238
239
240 /**********************************************************************
241 * NAME EXPORTED
242 * NtMapViewOfSection
243 *
244 * DESCRIPTION
245 * Maps a view of a section into the virtual address space of a
246 * process.
247 *
248 * ARGUMENTS
249 * SectionHandle
250 * Handle of the section.
251 *
252 * ProcessHandle
253 * Handle of the process.
254 *
255 * BaseAddress
256 * Desired base address (or NULL) on entry;
257 * Actual base address of the view on exit.
258 *
259 * ZeroBits
260 * Number of high order address bits that must be zero.
261 *
262 * CommitSize
263 * Size in bytes of the initially committed section of
264 * the view.
265 *
266 * SectionOffset
267 * Offset in bytes from the beginning of the section
268 * to the beginning of the view.
269 *
270 * ViewSize
271 * Desired length of map (or zero to map all) on entry
272 * Actual length mapped on exit.
273 *
274 * InheritDisposition
275 * Specified how the view is to be shared with
276 * child processes.
277 *
278 * AllocateType
279 * Type of allocation for the pages.
280 *
281 * Protect
282 * Protection for the committed region of the view.
283 *
284 * RETURN VALUE
285 * Status.
286 */
287 NTSTATUS
288 STDCALL
289 NtMapViewOfSection (
290 HANDLE SectionHandle,
291 HANDLE ProcessHandle,
292 PVOID * BaseAddress,
293 ULONG ZeroBits,
294 ULONG CommitSize,
295 PLARGE_INTEGER SectionOffset,
296 PULONG ViewSize,
297 SECTION_INHERIT InheritDisposition,
298 ULONG AllocationType,
299 ULONG Protect
300 )
301 {
302 PSECTION_OBJECT Section;
303 PEPROCESS Process;
304 MEMORY_AREA * Result;
305 NTSTATUS Status;
306
307 DPRINT(
308 "NtMapViewOfSection(Section:%08lx, Process:%08lx,\n"
309 " Base:%08lx, ZeroBits:%08lx, CommitSize:%08lx,\n"
310 " SectionOffs:%08lx, *ViewSize:%08lx, InheritDisp:%08lx,\n"
311 " AllocType:%08lx, Protect:%08lx)\n",
312 SectionHandle,
313 ProcessHandle,
314 BaseAddress,
315 ZeroBits,
316 CommitSize,
317 SectionOffset,
318 *ViewSize,
319 InheritDisposition,
320 AllocationType,
321 Protect
322 );
323
324 DPRINT(" *Base:%08lx\n", *BaseAddress);
325
326 Status = ObReferenceObjectByHandle(
327 SectionHandle,
328 SECTION_MAP_READ,
329 MmSectionType,
330 UserMode,
331 (PVOID *) & Section,
332 NULL
333 );
334 if (Status != STATUS_SUCCESS)
335 {
336 DPRINT("ObReference failed rc=%x\n",Status);
337
338 return Status;
339 }
340
341 DPRINT("Section %x\n",Section);
342
343 Status = ObReferenceObjectByHandle(
344 ProcessHandle,
345 PROCESS_VM_OPERATION,
346 PsProcessType,
347 UserMode,
348 (PVOID *) & Process,
349 NULL
350 );
351 if (Status != STATUS_SUCCESS)
352 {
353 ObDereferenceObject(Section);
354
355 return Status;
356 }
357
358 DPRINT("ViewSize %x\n",ViewSize);
359
360 if ((*ViewSize) > Section->MaximumSize.u.LowPart)
361 {
362 (*ViewSize) = Section->MaximumSize.u.LowPart;
363 }
364
365 Status = MmCreateMemoryArea(
366 UserMode,
367 Process,
368 MEMORY_AREA_SECTION_VIEW_COMMIT,
369 BaseAddress,
370 * ViewSize,
371 Protect,
372 & Result
373 );
374 if (!NT_SUCCESS(Status))
375 {
376 DPRINT("NtMapViewOfSection() = %x\n",Status);
377
378 ObDereferenceObject(Process);
379 ObDereferenceObject(Section);
380
381 return Status;
382 }
383 Result->Data.SectionData.Section = Section;
384
385 DPRINT("SectionOffset %x\n",SectionOffset);
386
387 if (SectionOffset == NULL)
388 {
389 Result->Data.SectionData.ViewOffset = 0;
390 }
391 else
392 {
393 Result->Data.SectionData.ViewOffset =
394 SectionOffset->u.LowPart;
395 }
396
397 DPRINT("*BaseAddress %x\n",*BaseAddress);
398 ObDereferenceObject(Process);
399 ObDereferenceObject(Section);
400
401 return STATUS_SUCCESS;
402 }
403
404
405 /**********************************************************************
406 * NAME EXPORTED
407 * NtUnmapViewOfSection
408 *
409 * DESCRIPTION
410 *
411 * ARGUMENTS
412 * ProcessHandle
413 *
414 * BaseAddress
415 *
416 * RETURN VALUE
417 * Status.
418 *
419 * REVISIONS
420 *
421 */
422 NTSTATUS
423 STDCALL
424 NtUnmapViewOfSection (
425 HANDLE ProcessHandle,
426 PVOID BaseAddress
427 )
428 {
429 PEPROCESS Process;
430 NTSTATUS Status;
431
432 Status = ObReferenceObjectByHandle(
433 ProcessHandle,
434 PROCESS_VM_OPERATION,
435 PsProcessType,
436 UserMode,
437 (PVOID *) & Process,
438 NULL
439 );
440 if (Status != STATUS_SUCCESS)
441 {
442 return Status;
443 }
444 Status = MmFreeMemoryArea(
445 Process,
446 BaseAddress,
447 0,
448 TRUE
449 );
450 ObDereferenceObject(Process);
451
452 return Status;
453 }
454
455
456 NTSTATUS
457 STDCALL
458 NtQuerySection (
459 IN HANDLE SectionHandle,
460 IN CINT SectionInformationClass,
461 OUT PVOID SectionInformation,
462 IN ULONG Length,
463 OUT PULONG ResultLength
464 )
465 /*
466 * FUNCTION: Queries the information of a section object.
467 * ARGUMENTS:
468 * SectionHandle = Handle to the section link object
469 * SectionInformationClass = Index to a certain information structure
470 * SectionInformation (OUT)= Caller supplies storage for resulting
471 * information
472 * Length = Size of the supplied storage
473 * ResultLength = Data written
474 * RETURNS: Status
475 *
476 */
477 {
478 return(STATUS_UNSUCCESSFUL);
479 }
480
481
482 NTSTATUS
483 STDCALL
484 NtExtendSection (
485 IN HANDLE SectionHandle,
486 IN ULONG NewMaximumSize
487 )
488 {
489 UNIMPLEMENTED;
490 }
491
492
493 /* EOF */