782be787ee748202e941fb49641c9ea56fc073dd
[reactos.git] / reactos / ntoskrnl / mm / section.c
1 /* $Id: section.c,v 1.31 2000/05/24 22:29:38 dwelch 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 EXPORTED MmSectionObjectType = NULL;
27
28 /* FUNCTIONS *****************************************************************/
29
30 VOID MmLockSection(PSECTION_OBJECT Section)
31 {
32 KeWaitForSingleObject(&Section->Lock,
33 UserRequest,
34 KernelMode,
35 FALSE,
36 NULL);
37 }
38
39 VOID MmUnlockSection(PSECTION_OBJECT Section)
40 {
41 KeReleaseMutex(&Section->Lock, FALSE);
42 }
43
44 VOID MmSetPageEntrySection(PSECTION_OBJECT Section,
45 ULONG Offset,
46 PVOID Entry)
47 {
48 PSECTION_PAGE_TABLE Table;
49 ULONG DirectoryOffset;
50 ULONG TableOffset;
51
52 DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset);
53 Table = Section->PageDirectory.PageTables[DirectoryOffset];
54 if (Table == NULL)
55 {
56 Table =
57 Section->PageDirectory.PageTables[DirectoryOffset] =
58 ExAllocatePool(NonPagedPool, sizeof(SECTION_PAGE_TABLE));
59 memset(Table, 0, sizeof(SECTION_PAGE_TABLE));
60 DPRINT("Table %x\n", Table);
61 }
62 TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
63 Table->Pages[TableOffset] = Entry;
64 }
65
66 PVOID MmGetPageEntrySection(PSECTION_OBJECT Section,
67 ULONG Offset)
68 {
69 PSECTION_PAGE_TABLE Table;
70 PVOID Entry;
71 ULONG DirectoryOffset;
72 ULONG TableOffset;
73
74 DPRINT("MmGetPageEntrySection(Offset %x)\n", Offset);
75
76 DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset);
77 Table = Section->PageDirectory.PageTables[DirectoryOffset];
78 DPRINT("Table %x\n", Table);
79 if (Table == NULL)
80 {
81 return(NULL);
82 }
83 TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
84 Entry = Table->Pages[TableOffset];
85 return(Entry);
86 }
87
88 NTSTATUS MmOldLoadPageForSection(PMADDRESS_SPACE AddressSpace,
89 MEMORY_AREA* MemoryArea,
90 PVOID Address)
91 {
92 LARGE_INTEGER Offset;
93 IO_STATUS_BLOCK IoStatus;
94 PMDL Mdl;
95 PVOID Page;
96 NTSTATUS Status;
97 ULONG PAddress;
98 PSECTION_OBJECT Section;
99
100 DPRINT("MmOldLoadPageForSection(MemoryArea %x, Address %x)\n",
101 MemoryArea,Address);
102
103 if (MmIsPagePresent(NULL, Address))
104 {
105 DPRINT("Page is already present\n");
106 return(STATUS_SUCCESS);
107 }
108
109 PAddress = (ULONG)PAGE_ROUND_DOWN(((ULONG)Address));
110 Offset.QuadPart = (PAddress - (ULONG)MemoryArea->BaseAddress) +
111 MemoryArea->Data.SectionData.ViewOffset;
112
113 DPRINT("MemoryArea->BaseAddress %x\n", MemoryArea->BaseAddress);
114 DPRINT("MemoryArea->Data.SectionData.ViewOffset %x\n",
115 MemoryArea->Data.SectionData.ViewOffset);
116 DPRINT("Got offset %x\n", Offset.QuadPart);
117
118 Section = MemoryArea->Data.SectionData.Section;
119
120 DPRINT("Section %x\n", Section);
121
122 MmLockSection(Section);
123
124 Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
125 MmBuildMdlFromPages(Mdl);
126 Page = MmGetMdlPageAddress(Mdl, 0);
127 MmUnlockSection(Section);
128 MmUnlockAddressSpace(AddressSpace);
129 DPRINT("Reading file offset %x\n", Offset.QuadPart);
130 Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
131 Mdl,
132 &Offset,
133 &IoStatus);
134 if (!NT_SUCCESS(Status))
135 {
136 return(Status);
137 }
138
139 MmLockAddressSpace(AddressSpace);
140 MmLockSection(Section);
141
142 MmSetPage(NULL,
143 Address,
144 MemoryArea->Attributes,
145 (ULONG)Page);
146 MmUnlockSection(Section);
147
148 return(STATUS_SUCCESS);
149
150 }
151
152 NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
153 MEMORY_AREA* MemoryArea,
154 PVOID Address)
155 {
156 LARGE_INTEGER Offset;
157 IO_STATUS_BLOCK IoStatus;
158 PMDL Mdl;
159 PVOID Page;
160 NTSTATUS Status;
161 ULONG PAddress;
162 PSECTION_OBJECT Section;
163 PVOID Entry;
164
165 DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
166 MemoryArea,Address);
167
168 if (MmIsPagePresent(NULL, Address))
169 {
170 DPRINT("Page is already present\n");
171 return(STATUS_SUCCESS);
172 }
173
174 PAddress = (ULONG)PAGE_ROUND_DOWN(((ULONG)Address));
175 Offset.QuadPart = (PAddress - (ULONG)MemoryArea->BaseAddress) +
176 MemoryArea->Data.SectionData.ViewOffset;
177
178 if ((MemoryArea->Data.SectionData.ViewOffset % PAGESIZE) != 0)
179 {
180 return(MmOldLoadPageForSection(AddressSpace, MemoryArea, Address));
181 }
182
183 DPRINT("MemoryArea->BaseAddress %x\n", MemoryArea->BaseAddress);
184 DPRINT("MemoryArea->Data.SectionData.ViewOffset %x\n",
185 MemoryArea->Data.SectionData.ViewOffset);
186 DPRINT("Got offset %x\n", Offset.QuadPart);
187
188 Section = MemoryArea->Data.SectionData.Section;
189
190 DPRINT("Section %x\n", Section);
191
192 MmLockSection(Section);
193
194 Entry = MmGetPageEntrySection(Section, Offset.u.LowPart);
195
196 DPRINT("Entry %x\n", Entry);
197
198 if (Entry == NULL)
199 {
200 Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
201 MmBuildMdlFromPages(Mdl);
202 Page = MmGetMdlPageAddress(Mdl, 0);
203 MmUnlockSection(Section);
204 MmUnlockAddressSpace(AddressSpace);
205 DPRINT("Reading file offset %x\n", Offset.QuadPart);
206 Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
207 Mdl,
208 &Offset,
209 &IoStatus);
210 if (!NT_SUCCESS(Status))
211 {
212 return(Status);
213 }
214
215 MmLockAddressSpace(AddressSpace);
216 MmLockSection(Section);
217
218 Entry = MmGetPageEntrySection(Section, Offset.QuadPart);
219
220 if (Entry == NULL)
221 {
222 MmSetPageEntrySection(Section,
223 Offset.QuadPart,
224 Page);
225 }
226 else
227 {
228 MmDereferencePage(Page);
229 Page = Entry;
230 MmReferencePage(Page);
231 }
232 }
233 else
234 {
235 Page = Entry;
236 MmReferencePage(Page);
237 }
238
239 MmSetPage(NULL,
240 Address,
241 MemoryArea->Attributes,
242 (ULONG)Page);
243 MmUnlockSection(Section);
244
245 return(STATUS_SUCCESS);
246 }
247
248 VOID MmpDeleteSection(PVOID ObjectBody)
249 {
250 DPRINT("MmpDeleteSection(ObjectBody %x)\n", ObjectBody);
251 }
252
253 VOID MmpCloseSection(PVOID ObjectBody,
254 ULONG HandleCount)
255 {
256 DPRINT("MmpCloseSection(OB %x, HC %d) RC %d\n",
257 ObjectBody, HandleCount, ObGetReferenceCount(ObjectBody));
258 }
259
260 NTSTATUS MmpCreateSection(PVOID ObjectBody,
261 PVOID Parent,
262 PWSTR RemainingPath,
263 POBJECT_ATTRIBUTES ObjectAttributes)
264 {
265 NTSTATUS Status;
266
267 DPRINT("MmpCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n",
268 ObjectBody, Parent, RemainingPath);
269
270 if (RemainingPath == NULL)
271 {
272 return(STATUS_SUCCESS);
273 }
274
275 if (wcschr(RemainingPath+1, L'\\') != NULL)
276 {
277 return(STATUS_UNSUCCESSFUL);
278 }
279
280 Status = ObReferenceObjectByPointer(Parent,
281 STANDARD_RIGHTS_REQUIRED,
282 ObDirectoryType,
283 UserMode);
284 if (!NT_SUCCESS(Status))
285 {
286 return(Status);
287 }
288
289 ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1);
290 ObDereferenceObject(Parent);
291
292 return(STATUS_SUCCESS);
293 }
294
295 NTSTATUS MmInitSectionImplementation(VOID)
296 {
297 MmSectionObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
298
299 RtlInitUnicodeString(&MmSectionObjectType->TypeName, L"Section");
300
301 MmSectionObjectType->TotalObjects = 0;
302 MmSectionObjectType->TotalHandles = 0;
303 MmSectionObjectType->MaxObjects = ULONG_MAX;
304 MmSectionObjectType->MaxHandles = ULONG_MAX;
305 MmSectionObjectType->PagedPoolCharge = 0;
306 MmSectionObjectType->NonpagedPoolCharge = sizeof(SECTION_OBJECT);
307 MmSectionObjectType->Dump = NULL;
308 MmSectionObjectType->Open = NULL;
309 MmSectionObjectType->Close = MmpCloseSection;
310 MmSectionObjectType->Delete = MmpDeleteSection;
311 MmSectionObjectType->Parse = NULL;
312 MmSectionObjectType->Security = NULL;
313 MmSectionObjectType->QueryName = NULL;
314 MmSectionObjectType->OkayToClose = NULL;
315 MmSectionObjectType->Create = MmpCreateSection;
316
317 return(STATUS_SUCCESS);
318 }
319
320
321 /* FIXME: NtCS should call MmCS */
322 NTSTATUS STDCALL NtCreateSection (OUT PHANDLE SectionHandle,
323 IN ACCESS_MASK DesiredAccess,
324 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
325 IN PLARGE_INTEGER MaximumSize OPTIONAL,
326 IN ULONG SectionPageProtection OPTIONAL,
327 IN ULONG AllocationAttributes,
328 IN HANDLE FileHandle OPTIONAL)
329 /*
330 * FUNCTION: Creates a section object.
331 * ARGUMENTS:
332 * SectionHandle (OUT) = Caller supplied storage for the resulting
333 * handle
334 * DesiredAccess = Specifies the desired access to the section can be a
335 * combination of STANDARD_RIGHTS_REQUIRED |
336 * SECTION_QUERY | SECTION_MAP_WRITE |
337 * SECTION_MAP_READ | SECTION_MAP_EXECUTE.
338 * ObjectAttribute = Initialized attributes for the object can be used
339 * to create a named section
340 * MaxiumSize = Maximizes the size of the memory section. Must be
341 * non-NULL for a page-file backed section.
342 * If value specified for a mapped file and the file is
343 * not large enough, file will be extended.
344 * SectionPageProtection = Can be a combination of PAGE_READONLY |
345 * PAGE_READWRITE | PAGE_WRITEONLY |
346 * PAGE_WRITECOPY.
347 * AllocationAttributes = can be a combination of SEC_IMAGE |
348 * SEC_RESERVE
349 * FileHandle = Handle to a file to create a section mapped to a file
350 * instead of a memory backed section.
351 * RETURNS: Status
352 */
353 {
354 PSECTION_OBJECT Section;
355 NTSTATUS Status;
356
357 DPRINT("NtCreateSection()\n");
358
359 Section = ObCreateObject(SectionHandle,
360 DesiredAccess,
361 ObjectAttributes,
362 MmSectionObjectType);
363 DPRINT("SectionHandle %x\n", SectionHandle);
364 if (Section == NULL)
365 {
366 return(STATUS_UNSUCCESSFUL);
367 }
368
369 if (MaximumSize != NULL)
370 {
371 Section->MaximumSize = *MaximumSize;
372 }
373 else
374 {
375 Section->MaximumSize.QuadPart = 0xffffffff;
376 }
377 Section->SectionPageProtection = SectionPageProtection;
378 Section->AllocateAttributes = AllocationAttributes;
379 InitializeListHead(&Section->ViewListHead);
380 KeInitializeSpinLock(&Section->ViewListLock);
381 KeInitializeMutex(&Section->Lock, 0);
382 memset(&Section->PageDirectory, 0, sizeof(Section->PageDirectory));
383
384 if (FileHandle != (HANDLE)0xffffffff)
385 {
386 Status = ObReferenceObjectByHandle(FileHandle,
387 FILE_READ_DATA,
388 IoFileObjectType,
389 UserMode,
390 (PVOID*)&Section->FileObject,
391 NULL);
392 if (!NT_SUCCESS(Status))
393 {
394 DPRINT("NtCreateSection() = %x\n",Status);
395 ZwClose(SectionHandle);
396 ObDereferenceObject(Section);
397 return(Status);
398 }
399 }
400 else
401 {
402 Section->FileObject = NULL;
403 }
404
405 DPRINT("NtCreateSection() = STATUS_SUCCESS\n");
406 ObDereferenceObject(Section);
407 return(STATUS_SUCCESS);
408 }
409
410
411 /**********************************************************************
412 * NAME
413 * NtOpenSection
414 *
415 * DESCRIPTION
416 *
417 * ARGUMENTS
418 * SectionHandle
419 *
420 * DesiredAccess
421 *
422 * ObjectAttributes
423 *
424 * RETURN VALUE
425 *
426 * REVISIONS
427 *
428 */
429 NTSTATUS STDCALL NtOpenSection(PHANDLE SectionHandle,
430 ACCESS_MASK DesiredAccess,
431 POBJECT_ATTRIBUTES ObjectAttributes)
432 {
433 PVOID Object;
434 NTSTATUS Status;
435
436 *SectionHandle = 0;
437
438 Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
439 ObjectAttributes->Attributes,
440 NULL,
441 DesiredAccess,
442 MmSectionObjectType,
443 UserMode,
444 NULL,
445 &Object);
446 if (!NT_SUCCESS(Status))
447 {
448 return Status;
449 }
450
451 Status = ObCreateHandle(PsGetCurrentProcess(),
452 Object,
453 DesiredAccess,
454 FALSE,
455 SectionHandle);
456 ObDereferenceObject(Object);
457 return(Status);
458 }
459
460
461 /**********************************************************************
462 * NAME EXPORTED
463 * NtMapViewOfSection
464 *
465 * DESCRIPTION
466 * Maps a view of a section into the virtual address space of a
467 * process.
468 *
469 * ARGUMENTS
470 * SectionHandle
471 * Handle of the section.
472 *
473 * ProcessHandle
474 * Handle of the process.
475 *
476 * BaseAddress
477 * Desired base address (or NULL) on entry;
478 * Actual base address of the view on exit.
479 *
480 * ZeroBits
481 * Number of high order address bits that must be zero.
482 *
483 * CommitSize
484 * Size in bytes of the initially committed section of
485 * the view.
486 *
487 * SectionOffset
488 * Offset in bytes from the beginning of the section
489 * to the beginning of the view.
490 *
491 * ViewSize
492 * Desired length of map (or zero to map all) on entry
493 * Actual length mapped on exit.
494 *
495 * InheritDisposition
496 * Specified how the view is to be shared with
497 * child processes.
498 *
499 * AllocateType
500 * Type of allocation for the pages.
501 *
502 * Protect
503 * Protection for the committed region of the view.
504 *
505 * RETURN VALUE
506 * Status.
507 */
508 NTSTATUS STDCALL NtMapViewOfSection(HANDLE SectionHandle,
509 HANDLE ProcessHandle,
510 PVOID* BaseAddress,
511 ULONG ZeroBits,
512 ULONG CommitSize,
513 PLARGE_INTEGER SectionOffset,
514 PULONG ViewSize,
515 SECTION_INHERIT InheritDisposition,
516 ULONG AllocationType,
517 ULONG Protect)
518 {
519 PSECTION_OBJECT Section;
520 PEPROCESS Process;
521 MEMORY_AREA* Result;
522 NTSTATUS Status;
523 KIRQL oldIrql;
524 ULONG ViewOffset;
525 PMADDRESS_SPACE AddressSpace;
526
527 DPRINT("NtMapViewOfSection(Section:%08lx, Process:%08lx,\n"
528 " Base:%08lx, ZeroBits:%08lx, CommitSize:%08lx,\n"
529 " SectionOffs:%08lx, *ViewSize:%08lx, InheritDisp:%08lx,\n"
530 " AllocType:%08lx, Protect:%08lx)\n",
531 SectionHandle, ProcessHandle, BaseAddress, ZeroBits,
532 CommitSize, SectionOffset, *ViewSize, InheritDisposition,
533 AllocationType, Protect);
534
535 DPRINT(" *Base:%08lx\n", *BaseAddress);
536
537 Status = ObReferenceObjectByHandle(SectionHandle,
538 SECTION_MAP_READ,
539 MmSectionObjectType,
540 UserMode,
541 (PVOID*)&Section,
542 NULL);
543 if (!(NT_SUCCESS(Status)))
544 {
545 DPRINT("ObReference failed rc=%x\n",Status);
546 return Status;
547 }
548
549 DPRINT("Section %x\n",Section);
550 MmLockSection(Section);
551
552 Status = ObReferenceObjectByHandle(ProcessHandle,
553 PROCESS_VM_OPERATION,
554 PsProcessType,
555 UserMode,
556 (PVOID*)&Process,
557 NULL);
558 if (!NT_SUCCESS(Status))
559 {
560 DPRINT("ObReferenceObjectByHandle(ProcessHandle, ...) failed (%x)\n",
561 Status);
562 MmUnlockSection(Section);
563 ObDereferenceObject(Section);
564 return Status;
565 }
566
567 AddressSpace = &Process->Pcb.AddressSpace;
568
569 DPRINT("Process %x\n", Process);
570 DPRINT("ViewSize %x\n",ViewSize);
571
572 if (SectionOffset == NULL)
573 {
574 ViewOffset = 0;
575 }
576 else
577 {
578 ViewOffset = SectionOffset->u.LowPart;
579 }
580
581 if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart)
582 {
583 (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset;
584 }
585
586 DPRINT("Creating memory area\n");
587 MmLockAddressSpace(AddressSpace);
588 Status = MmCreateMemoryArea(Process,
589 &Process->Pcb.AddressSpace,
590 MEMORY_AREA_SECTION_VIEW_COMMIT,
591 BaseAddress,
592 *ViewSize,
593 Protect,
594 &Result);
595 if (!NT_SUCCESS(Status))
596 {
597 DPRINT("NtMapViewOfSection() = %x\n",Status);
598
599 MmUnlockAddressSpace(AddressSpace);
600 ObDereferenceObject(Process);
601 MmUnlockSection(Section);
602 ObDereferenceObject(Section);
603
604 return Status;
605 }
606
607 KeAcquireSpinLock(&Section->ViewListLock, &oldIrql);
608 InsertTailList(&Section->ViewListHead,
609 &Result->Data.SectionData.ViewListEntry);
610 KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
611
612 Result->Data.SectionData.Section = Section;
613 Result->Data.SectionData.ViewOffset = ViewOffset;
614
615 DPRINT("SectionOffset %x\n",SectionOffset);
616
617
618 DPRINT("*BaseAddress %x\n",*BaseAddress);
619 MmUnlockAddressSpace(AddressSpace);
620 ObDereferenceObject(Process);
621 MmUnlockSection(Section);
622
623 DPRINT("NtMapViewOfSection() returning (Status %x)\n", STATUS_SUCCESS);
624 return(STATUS_SUCCESS);
625 }
626
627 NTSTATUS STDCALL MmUnmapViewOfSection(PEPROCESS Process,
628 PMEMORY_AREA MemoryArea)
629 {
630 PSECTION_OBJECT Section;
631 KIRQL oldIrql;
632
633 Section = MemoryArea->Data.SectionData.Section;
634
635 DPRINT("MmUnmapViewOfSection(Section %x) SectionRC %d\n",
636 Section, ObGetReferenceCount(Section));
637
638 MmLockSection(Section);
639 KeAcquireSpinLock(&Section->ViewListLock, &oldIrql);
640 RemoveEntryList(&MemoryArea->Data.SectionData.ViewListEntry);
641 KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
642 MmUnlockSection(Section);
643 ObDereferenceObject(Section);
644
645 return(STATUS_SUCCESS);
646 }
647
648 /**********************************************************************
649 * NAME EXPORTED
650 * NtUnmapViewOfSection
651 *
652 * DESCRIPTION
653 *
654 * ARGUMENTS
655 * ProcessHandle
656 *
657 * BaseAddress
658 *
659 * RETURN VALUE
660 * Status.
661 *
662 * REVISIONS
663 *
664 */
665 NTSTATUS STDCALL NtUnmapViewOfSection (HANDLE ProcessHandle,
666 PVOID BaseAddress)
667 {
668 PEPROCESS Process;
669 NTSTATUS Status;
670 PMEMORY_AREA MemoryArea;
671 PMADDRESS_SPACE AddressSpace;
672
673 DPRINT("NtUnmapViewOfSection(ProcessHandle %x, BaseAddress %x)\n",
674 ProcessHandle, BaseAddress);
675
676 DPRINT("Referencing process\n");
677 Status = ObReferenceObjectByHandle(ProcessHandle,
678 PROCESS_VM_OPERATION,
679 PsProcessType,
680 UserMode,
681 (PVOID*)&Process,
682 NULL);
683 if (!NT_SUCCESS(Status))
684 {
685 DPRINT("ObReferenceObjectByHandle failed (Status %x)\n", Status);
686 return(Status);
687 }
688
689 AddressSpace = &Process->Pcb.AddressSpace;
690
691 DPRINT("Opening memory area Process %x BaseAddress %x\n",
692 Process, BaseAddress);
693 MmLockAddressSpace(AddressSpace);
694 MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
695 BaseAddress);
696 if (MemoryArea == NULL)
697 {
698 MmUnlockAddressSpace(AddressSpace);
699 ObDereferenceObject(Process);
700 return(STATUS_UNSUCCESSFUL);
701 }
702
703 Status = MmUnmapViewOfSection(Process,
704 MemoryArea);
705
706 DPRINT("MmFreeMemoryArea()\n");
707 Status = MmFreeMemoryArea(&Process->Pcb.AddressSpace,
708 BaseAddress,
709 0,
710 TRUE);
711 MmUnlockAddressSpace(AddressSpace);
712 ObDereferenceObject(Process);
713
714 return Status;
715 }
716
717
718 NTSTATUS STDCALL NtQuerySection (IN HANDLE SectionHandle,
719 IN CINT SectionInformationClass,
720 OUT PVOID SectionInformation,
721 IN ULONG Length,
722 OUT PULONG ResultLength)
723 /*
724 * FUNCTION: Queries the information of a section object.
725 * ARGUMENTS:
726 * SectionHandle = Handle to the section link object
727 * SectionInformationClass = Index to a certain information structure
728 * SectionInformation (OUT)= Caller supplies storage for resulting
729 * information
730 * Length = Size of the supplied storage
731 * ResultLength = Data written
732 * RETURNS: Status
733 *
734 */
735 {
736 return(STATUS_UNSUCCESSFUL);
737 }
738
739
740 NTSTATUS STDCALL NtExtendSection(IN HANDLE SectionHandle,
741 IN ULONG NewMaximumSize)
742 {
743 UNIMPLEMENTED;
744 }
745
746
747 /**********************************************************************
748 * NAME INTERNAL
749 * MmAllocateSection@4
750 *
751 * DESCRIPTION
752 *
753 * ARGUMENTS
754 * Length
755 *
756 * RETURN VALUE
757 *
758 * NOTE
759 * Code taken from ntoskrnl/mm/special.c.
760 *
761 * REVISIONS
762 *
763 */
764 PVOID STDCALL MmAllocateSection (IN ULONG Length)
765 {
766 PVOID Result;
767 MEMORY_AREA* marea;
768 NTSTATUS Status;
769 ULONG i;
770 PMADDRESS_SPACE AddressSpace;
771
772 DPRINT("MmAllocateSection(Length %x)\n",Length);
773
774 AddressSpace = MmGetKernelAddressSpace();
775 Result = NULL;
776 MmLockAddressSpace(AddressSpace);
777 Status = MmCreateMemoryArea (NULL,
778 AddressSpace,
779 MEMORY_AREA_SYSTEM,
780 &Result,
781 Length,
782 0,
783 &marea);
784 if (STATUS_SUCCESS != Status)
785 {
786 return (NULL);
787 }
788 DPRINT("Result %p\n",Result);
789 for (i = 0; (i <= (Length / PAGESIZE)); i++)
790 {
791 MmSetPage (NULL,
792 (Result + (i * PAGESIZE)),
793 PAGE_READWRITE,
794 (ULONG) MmAllocPage ());
795 }
796 MmUnlockAddressSpace(AddressSpace);
797 return ((PVOID)Result);
798 }
799
800
801 /**********************************************************************
802 * NAME EXPORTED
803 * MmMapViewOfSection@40
804 *
805 * DESCRIPTION
806 *
807 * ARGUMENTS
808 * FIXME: stack space allocated is 40 bytes, but nothing
809 * is known about what they are filled with.
810 *
811 * RETURN VALUE
812 * Status.
813 *
814 */
815 PVOID
816 STDCALL
817 MmMapViewOfSection (
818 DWORD Unknown0,
819 DWORD Unknown1,
820 DWORD Unknown2,
821 DWORD Unknown3,
822 DWORD Unknown4,
823 DWORD Unknown5,
824 DWORD Unknown6,
825 DWORD Unknown7,
826 DWORD Unknown8,
827 DWORD Unknown9
828 )
829 {
830 UNIMPLEMENTED;
831 return (NULL);
832 }
833
834
835 BOOLEAN
836 STDCALL
837 MmCanFileBeTruncated (
838 IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
839 IN PLARGE_INTEGER NewFileSize
840 )
841 {
842 UNIMPLEMENTED;
843 return (FALSE);
844 }
845
846
847 BOOLEAN
848 STDCALL
849 MmDisableModifiedWriteOfSection (
850 DWORD Unknown0
851 )
852 {
853 UNIMPLEMENTED;
854 return (FALSE);
855 }
856
857 BOOLEAN
858 STDCALL
859 MmFlushImageSection (
860 IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
861 IN MMFLUSH_TYPE FlushType
862 )
863 {
864 UNIMPLEMENTED;
865 return (FALSE);
866 }
867
868 BOOLEAN
869 STDCALL
870 MmForceSectionClosed (
871 DWORD Unknown0,
872 DWORD Unknown1
873 )
874 {
875 UNIMPLEMENTED;
876 return (FALSE);
877 }
878
879
880 NTSTATUS
881 STDCALL
882 MmMapViewInSystemSpace (
883 IN PVOID Section,
884 OUT PVOID * MappedBase,
885 IN PULONG ViewSize
886 )
887 {
888 UNIMPLEMENTED;
889 return (STATUS_NOT_IMPLEMENTED);
890 }
891
892 NTSTATUS
893 STDCALL
894 MmUnmapViewInSystemSpace (
895 DWORD Unknown0
896 )
897 {
898 UNIMPLEMENTED;
899 return (STATUS_NOT_IMPLEMENTED);
900 }
901
902
903 NTSTATUS
904 STDCALL
905 MmSetBankedSection (
906 DWORD Unknown0,
907 DWORD Unknown1,
908 DWORD Unknown2,
909 DWORD Unknown3,
910 DWORD Unknown4,
911 DWORD Unknown5
912 )
913 {
914 UNIMPLEMENTED;
915 return (STATUS_NOT_IMPLEMENTED);
916 }
917
918
919 /**********************************************************************
920 * NAME EXPORTED
921 * MmCreateSection@
922 *
923 * DESCRIPTION
924 * Creates a section object.
925 *
926 * ARGUMENTS
927 * SectionObjiect (OUT)
928 * Caller supplied storage for the resulting pointer
929 * to a SECTION_BOJECT instance;
930 *
931 * DesiredAccess
932 * Specifies the desired access to the section can be a
933 * combination of:
934 * STANDARD_RIGHTS_REQUIRED |
935 * SECTION_QUERY |
936 * SECTION_MAP_WRITE |
937 * SECTION_MAP_READ |
938 * SECTION_MAP_EXECUTE
939 *
940 * ObjectAttributes [OPTIONAL]
941 * Initialized attributes for the object can be used
942 * to create a named section;
943 *
944 * MaximumSize
945 * Maximizes the size of the memory section. Must be
946 * non-NULL for a page-file backed section.
947 * If value specified for a mapped file and the file is
948 * not large enough, file will be extended.
949 *
950 * SectionPageProtection
951 * Can be a combination of:
952 * PAGE_READONLY |
953 * PAGE_READWRITE |
954 * PAGE_WRITEONLY |
955 * PAGE_WRITECOPY
956 *
957 * AllocationAttributes
958 * Can be a combination of:
959 * SEC_IMAGE |
960 * SEC_RESERVE
961 *
962 * FileHandle
963 * Handle to a file to create a section mapped to a file
964 * instead of a memory backed section;
965 *
966 * File
967 * Unknown.
968 *
969 * RETURN VALUE
970 * Status.
971 */
972 NTSTATUS
973 STDCALL
974 MmCreateSection (
975 OUT PSECTION_OBJECT * SectionObject,
976 IN ACCESS_MASK DesiredAccess,
977 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
978 IN PLARGE_INTEGER MaximumSize,
979 IN ULONG SectionPageProtection,
980 IN ULONG AllocationAttributes,
981 IN HANDLE FileHandle OPTIONAL,
982 IN PFILE_OBJECT File OPTIONAL
983 )
984 {
985 return (STATUS_NOT_IMPLEMENTED);
986 }
987
988 /* EOF */