diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index b773e08ff14..2f41fcb95aa 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -110,6 +110,7 @@ C_ASSERT(SYSTEM_PD_SIZE == PAGE_SIZE); #define MM_NOCACHE 8 #define MM_DECOMMIT 0x10 #define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE) +#define MM_INVALID_PROTECTION 0xFFFFFFFF // // Specific PTE Definitions that map to the Memory Manager's Protection Mask Bits diff --git a/reactos/ntoskrnl/mm/ARM3/section.c b/reactos/ntoskrnl/mm/ARM3/section.c new file mode 100644 index 00000000000..9a544c6d59b --- /dev/null +++ b/reactos/ntoskrnl/mm/ARM3/section.c @@ -0,0 +1,678 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/mm/ARM3/sectopm.c + * PURPOSE: ARM Memory Manager Section Support + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +#line 15 "ARM³::SECTION" +#define MODULE_INVOLVED_IN_ARM3 +#include "../ARM3/miarm.h" + +/* GLOBALS ********************************************************************/ + +ACCESS_MASK MmMakeSectionAccess[8] = +{ + SECTION_MAP_READ, + SECTION_MAP_READ, + SECTION_MAP_EXECUTE, + SECTION_MAP_EXECUTE | SECTION_MAP_READ, + SECTION_MAP_WRITE, + SECTION_MAP_READ, + SECTION_MAP_EXECUTE | SECTION_MAP_WRITE, + SECTION_MAP_EXECUTE | SECTION_MAP_READ +}; + +CHAR MmUserProtectionToMask1[16] = +{ + 0, + MM_NOACCESS, + MM_READONLY, + (CHAR)MM_INVALID_PROTECTION, + MM_READWRITE, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + MM_WRITECOPY, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION +}; + +CHAR MmUserProtectionToMask2[16] = +{ + 0, + MM_EXECUTE, + MM_EXECUTE_READ, + (CHAR)MM_INVALID_PROTECTION, + MM_EXECUTE_READWRITE, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + MM_EXECUTE_WRITECOPY, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION, + (CHAR)MM_INVALID_PROTECTION +}; + +/* PRIVATE FUNCTIONS **********************************************************/ + +ULONG +NTAPI +MiMakeProtectionMask(IN ULONG Protect) +{ + ULONG Mask1, Mask2, ProtectMask; + + /* PAGE_EXECUTE_WRITECOMBINE is theoretically the maximum */ + if (Protect >= (PAGE_WRITECOMBINE * 2)) return MM_INVALID_PROTECTION; + + /* + * Windows API protection mask can be understood as two bitfields, differing + * by whether or not execute rights are being requested + */ + Mask1 = Protect & 0xF; + Mask2 = (Protect >> 4) & 0xF; + + /* Check which field is there */ + if (!Mask1) + { + /* Mask2 must be there, use it to determine the PTE protection */ + if (!Mask2) return MM_INVALID_PROTECTION; + ProtectMask = MmUserProtectionToMask2[Mask2]; + } + else + { + /* Mask2 should not be there, use Mask1 to determine the PTE mask */ + if (Mask2) return MM_INVALID_PROTECTION; + ProtectMask = MmUserProtectionToMask1[Mask1]; + } + + /* Make sure the final mask is a valid one */ + if (ProtectMask == MM_INVALID_PROTECTION) return MM_INVALID_PROTECTION; + + /* Check for PAGE_GUARD option */ + if (Protect & PAGE_GUARD) + { + /* It's not valid on no-access, nocache, or writecombine pages */ + if ((ProtectMask == MM_NOACCESS) || + (Protect & (PAGE_NOCACHE | PAGE_WRITECOMBINE))) + { + /* Fail such requests */ + return MM_INVALID_PROTECTION; + } + + /* This actually turns on guard page in this scenario! */ + ProtectMask |= MM_DECOMMIT; + } + + /* Check for nocache option */ + if (Protect & PAGE_NOCACHE) + { + /* The earlier check should've eliminated this possibility */ + ASSERT((Protect & PAGE_GUARD) == 0); + + /* Check for no-access page or write combine page */ + if ((ProtectMask == MM_NOACCESS) || (Protect & PAGE_WRITECOMBINE)) + { + /* Such a request is invalid */ + return MM_INVALID_PROTECTION; + } + + /* Add the PTE flag */ + ProtectMask |= MM_NOCACHE; + } + + /* Check for write combine option */ + if (Protect & PAGE_WRITECOMBINE) + { + /* The two earlier scenarios should've caught this */ + ASSERT((Protect & (PAGE_GUARD | PAGE_NOACCESS)) == 0); + + /* Don't allow on no-access pages */ + if (ProtectMask == MM_NOACCESS) return MM_INVALID_PROTECTION; + + /* This actually turns on write-combine in this scenario! */ + ProtectMask |= MM_NOACCESS; + } + + /* Return the final MM PTE protection mask */ + return ProtectMask; +} +/* SYSTEM CALLS ***************************************************************/ + +NTSTATUS +NTAPI +NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, + IN PVOID File2MappedAsFile) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +NtCreateSection(OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER MaximumSize OPTIONAL, + IN ULONG SectionPageProtection OPTIONAL, + IN ULONG AllocationAttributes, + IN HANDLE FileHandle OPTIONAL) +{ + LARGE_INTEGER SafeMaximumSize; + PVOID SectionObject; + HANDLE Handle; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status; + PAGED_CODE(); + + /* Check for non-existing flags */ + if ((AllocationAttributes & ~(SEC_COMMIT | SEC_RESERVE | SEC_BASED | + SEC_LARGE_PAGES | SEC_IMAGE | SEC_NOCACHE | + SEC_NO_CHANGE))) + { + DPRINT1("Bogus allocation attribute: %lx\n", AllocationAttributes); + return STATUS_INVALID_PARAMETER_6; + } + + /* Check for no allocation type */ + if (!(AllocationAttributes & (SEC_COMMIT | SEC_RESERVE | SEC_IMAGE))) + { + DPRINT1("Missing allocation type in allocation attributes\n"); + return STATUS_INVALID_PARAMETER_6; + } + + /* Check for image allocation with invalid attributes */ + if ((AllocationAttributes & SEC_IMAGE) && + (AllocationAttributes & (SEC_COMMIT | SEC_RESERVE | SEC_LARGE_PAGES | + SEC_NOCACHE | SEC_NO_CHANGE))) + { + DPRINT1("Image allocation with invalid attributes\n"); + return STATUS_INVALID_PARAMETER_6; + } + + /* Check for allocation type is both commit and reserve */ + if ((AllocationAttributes & SEC_COMMIT) && (AllocationAttributes & SEC_RESERVE)) + { + DPRINT1("Commit and reserve in the same time\n"); + return STATUS_INVALID_PARAMETER_6; + } + + /* Now check for valid protection */ + if ((SectionPageProtection & PAGE_NOCACHE) || + (SectionPageProtection & PAGE_WRITECOMBINE) || + (SectionPageProtection & PAGE_GUARD) || + (SectionPageProtection & PAGE_NOACCESS)) + { + DPRINT1("Sections don't support these protections\n"); + return STATUS_INVALID_PAGE_PROTECTION; + } + + /* Use a maximum size of zero, if none was specified */ + SafeMaximumSize.QuadPart = 0; + + /* Check for user-mode caller */ + if (PreviousMode != KernelMode) + { + /* Enter SEH */ + _SEH2_TRY + { + /* Safely check user-mode parameters */ + if (MaximumSize) SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize); + MaximumSize = &SafeMaximumSize; + ProbeForWriteHandle(SectionHandle); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else if (!MaximumSize) MaximumSize = &SafeMaximumSize; + + /* Create the section */ + Status = MmCreateSection(&SectionObject, + DesiredAccess, + ObjectAttributes, + MaximumSize, + SectionPageProtection, + AllocationAttributes, + FileHandle, + NULL); + if (!NT_SUCCESS(Status)) return Status; + + /* FIXME: Should zero last page for a file mapping */ + + /* Now insert the object */ + Status = ObInsertObject(SectionObject, + NULL, + DesiredAccess, + 0, + NULL, + &Handle); + if (NT_SUCCESS(Status)) + { + /* Enter SEH */ + _SEH2_TRY + { + /* Return the handle safely */ + *SectionHandle = Handle; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Nothing here */ + } + _SEH2_END; + } + + /* Return the status */ + return Status; +} + +NTSTATUS +NTAPI +NtOpenSection(OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) +{ + HANDLE Handle; + NTSTATUS Status; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PAGED_CODE(); + + /* Check for user-mode caller */ + if (PreviousMode != KernelMode) + { + /* Enter SEH */ + _SEH2_TRY + { + /* Safely check user-mode parameters */ + ProbeForWriteHandle(SectionHandle); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + + /* Try opening the object */ + Status = ObOpenObjectByName(ObjectAttributes, + MmSectionObjectType, + PreviousMode, + NULL, + DesiredAccess, + NULL, + &Handle); + + /* Enter SEH */ + _SEH2_TRY + { + /* Return the handle safely */ + *SectionHandle = Handle; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Nothing here */ + } + _SEH2_END; + + /* Return the status */ + return Status; +} + +NTSTATUS +NTAPI +NtMapViewOfSection(IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN OUT PVOID* BaseAddress, + IN ULONG_PTR ZeroBits, + IN SIZE_T CommitSize, + IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, + IN OUT PSIZE_T ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG Protect) +{ + PVOID SafeBaseAddress; + LARGE_INTEGER SafeSectionOffset; + SIZE_T SafeViewSize; + PROS_SECTION_OBJECT Section; + PEPROCESS Process; + NTSTATUS Status; + ACCESS_MASK DesiredAccess; + ULONG ProtectionMask; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + + /* Check for invalid zero bits */ + if (ZeroBits > 21) // per-arch? + { + DPRINT1("Invalid zero bits\n"); + return STATUS_INVALID_PARAMETER_4; + } + + /* Check for invalid inherit disposition */ + if ((InheritDisposition > ViewUnmap) || (InheritDisposition < ViewShare)) + { + DPRINT1("Invalid inherit disposition\n"); + return STATUS_INVALID_PARAMETER_8; + } + + /* Allow only valid allocation types */ + if ((AllocationType & ~(MEM_TOP_DOWN | MEM_LARGE_PAGES | MEM_DOS_LIM | + SEC_NO_CHANGE | MEM_RESERVE))) + { + DPRINT1("Invalid allocation type\n"); + return STATUS_INVALID_PARAMETER_9; + } + + /* Convert the protection mask, and validate it */ + ProtectionMask = MiMakeProtectionMask(Protect); + if (ProtectionMask == MM_INVALID_PROTECTION) + { + DPRINT1("Invalid page protection\n"); + return STATUS_INVALID_PAGE_PROTECTION; + } + + /* Now convert the protection mask into desired section access mask */ + DesiredAccess = MmMakeSectionAccess[ProtectionMask & 0x7]; + + /* Assume no section offset */ + SafeSectionOffset.QuadPart = 0; + + /* Enter SEH */ + _SEH2_TRY + { + /* Check for unsafe parameters */ + if (PreviousMode != KernelMode) + { + /* Probe the parameters */ + ProbeForWritePointer(BaseAddress); + ProbeForWriteSize_t(ViewSize); + } + + /* Check if a section offset was given */ + if (SectionOffset) + { + /* Check for unsafe parameters and capture section offset */ + if (PreviousMode != KernelMode) ProbeForWriteLargeInteger(SectionOffset); + SafeSectionOffset = *SectionOffset; + } + + /* Capture the other parameters */ + SafeBaseAddress = *BaseAddress; + SafeViewSize = *ViewSize; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* Check for kernel-mode address */ + if (SafeBaseAddress > MM_HIGHEST_VAD_ADDRESS) + { + DPRINT1("Kernel base not allowed\n"); + return STATUS_INVALID_PARAMETER_3; + } + + /* Check for range entering kernel-mode */ + if (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)SafeBaseAddress) < SafeViewSize) + { + DPRINT1("Overflowing into kernel base not allowed\n"); + return STATUS_INVALID_PARAMETER_3; + } + + /* Check for invalid zero bits */ + if (((ULONG_PTR)SafeBaseAddress + SafeViewSize) > (0xFFFFFFFF >> ZeroBits)) // arch? + { + DPRINT1("Invalid zero bits\n"); + return STATUS_INVALID_PARAMETER_4; + } + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) return Status; + + /* Reference the section */ + Status = ObReferenceObjectByHandle(SectionHandle, + DesiredAccess, + MmSectionObjectType, + PreviousMode, + (PVOID*)&Section, + NULL); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Process); + return Status; + } + + /* Now do the actual mapping */ + Status = MmMapViewOfSection(Section, + Process, + &SafeBaseAddress, + ZeroBits, + CommitSize, + &SafeSectionOffset, + &SafeViewSize, + InheritDisposition, + AllocationType, + Protect); + + /* Check if this is an image for the current process */ + if ((Section->AllocationAttributes & SEC_IMAGE) && + (Process == PsGetCurrentProcess()) && + ((Status != STATUS_IMAGE_NOT_AT_BASE) || + (Status != STATUS_CONFLICTING_ADDRESSES))) + { + /* Notify the debugger */ + DbgkMapViewOfSection(Section, + SafeBaseAddress, + SafeSectionOffset.LowPart, + SafeViewSize); + } + + /* Return data only on success */ + if (NT_SUCCESS(Status)) + { + /* Enter SEH */ + _SEH2_TRY + { + /* Return parameters to user */ + *BaseAddress = SafeBaseAddress; + *ViewSize = SafeViewSize; + if (SectionOffset) *SectionOffset = SafeSectionOffset; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Nothing to do */ + } + _SEH2_END; + } + + /* Dereference all objects and return status */ + ObDereferenceObject(Section); + ObDereferenceObject(Process); + return Status; +} + +NTSTATUS +NTAPI +NtUnmapViewOfSection(IN HANDLE ProcessHandle, + IN PVOID BaseAddress) +{ + PEPROCESS Process; + NTSTATUS Status; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + + /* Don't allowing mapping kernel views */ + if ((PreviousMode == UserMode) && (BaseAddress > MM_HIGHEST_USER_ADDRESS)) + { + DPRINT1("Trying to unmap a kernel view\n"); + return STATUS_NOT_MAPPED_VIEW; + } + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_OPERATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) return Status; + + /* Unmap the view */ + Status = MmUnmapViewOfSection(Process, BaseAddress); + + /* Dereference the process and return status */ + ObDereferenceObject(Process); + return Status; +} + +NTSTATUS +NTAPI +NtExtendSection(IN HANDLE SectionHandle, + IN OUT PLARGE_INTEGER NewMaximumSize) +{ + LARGE_INTEGER SafeNewMaximumSize; + PROS_SECTION_OBJECT Section; + NTSTATUS Status; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + + /* Check for user-mode parameters */ + if (PreviousMode != KernelMode) + { + /* Enter SEH */ + _SEH2_TRY + { + /* Probe and capture the maximum size, it's both read and write */ + ProbeForWriteLargeInteger(NewMaximumSize); + SafeNewMaximumSize = *NewMaximumSize; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + /* Just read the size directly */ + SafeNewMaximumSize = *NewMaximumSize; + } + + /* Reference the section */ + Status = ObReferenceObjectByHandle(SectionHandle, + SECTION_EXTEND_SIZE, + MmSectionObjectType, + PreviousMode, + (PVOID*)&Section, + NULL); + if (!NT_SUCCESS(Status)) return Status; + + /* Really this should go in MmExtendSection */ + if (!(Section->AllocationAttributes & SEC_FILE)) + { + DPRINT1("Not extending a file\n"); + ObDereferenceObject(Section); + return STATUS_SECTION_NOT_EXTENDED; + } + + /* FIXME: Do the work */ + + /* Dereference the section */ + ObDereferenceObject(Section); + + /* Enter SEH */ + _SEH2_TRY + { + /* Write back the new size */ + *NewMaximumSize = SafeNewMaximumSize; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Nothing to do */ + } + _SEH2_END; + + /* Return the status */ + return STATUS_NOT_IMPLEMENTED; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +MmDisableModifiedWriteOfSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOLEAN +NTAPI +MmForceSectionClosed(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, + IN BOOLEAN DelayClose) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +MmMapViewInSessionSpace(IN PVOID Section, + OUT PVOID *MappedBase, + IN OUT PSIZE_T ViewSize) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +MmUnmapViewInSessionSpace(IN PVOID MappedBase) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index f15b18c0ac6..d1ef30377e5 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -3306,14 +3306,6 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject, ULONG i; ULONG FileAccess = 0; - /* - * Specifying a maximum size is meaningless for an image section - */ - if (UMaximumSize != NULL) - { - return(STATUS_INVALID_PARAMETER_4); - } - /* * Check file access required */ @@ -3470,132 +3462,7 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject, return(Status); } -/* - * @implemented - */ -NTSTATUS NTAPI -NtCreateSection (OUT PHANDLE SectionHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN PLARGE_INTEGER MaximumSize OPTIONAL, - IN ULONG SectionPageProtection OPTIONAL, - IN ULONG AllocationAttributes, - IN HANDLE FileHandle OPTIONAL) -{ - LARGE_INTEGER SafeMaximumSize; - PVOID SectionObject; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH2_TRY - { - if (MaximumSize != NULL) - { - /* make a copy on the stack */ - SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize); - MaximumSize = &SafeMaximumSize; - } - ProbeForWriteHandle(SectionHandle); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - - Status = MmCreateSection(&SectionObject, - DesiredAccess, - ObjectAttributes, - MaximumSize, - SectionPageProtection, - AllocationAttributes, - FileHandle, - NULL); - if (NT_SUCCESS(Status)) - { - Status = ObInsertObject ((PVOID)SectionObject, - NULL, - DesiredAccess, - 0, - NULL, - SectionHandle); - } - - return Status; -} - - -/********************************************************************** - * NAME - * NtOpenSection - * - * DESCRIPTION - * - * ARGUMENTS - * SectionHandle - * - * DesiredAccess - * - * ObjectAttributes - * - * RETURN VALUE - * - * REVISIONS - */ -NTSTATUS NTAPI -NtOpenSection(PHANDLE SectionHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) -{ - HANDLE hSection; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH2_TRY - { - ProbeForWriteHandle(SectionHandle); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - - Status = ObOpenObjectByName(ObjectAttributes, - MmSectionObjectType, - PreviousMode, - NULL, - DesiredAccess, - NULL, - &hSection); - - if(NT_SUCCESS(Status)) - { - _SEH2_TRY - { - *SectionHandle = hSection; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - - return(Status); -} static NTSTATUS MmMapViewOfSegment(PMMSUPPORT AddressSpace, @@ -3642,233 +3509,6 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace, } -/********************************************************************** - * NAME EXPORTED - * NtMapViewOfSection - * - * DESCRIPTION - * Maps a view of a section into the virtual address space of a - * process. - * - * ARGUMENTS - * SectionHandle - * Handle of the section. - * - * ProcessHandle - * Handle of the process. - * - * BaseAddress - * Desired base address (or NULL) on entry; - * Actual base address of the view on exit. - * - * ZeroBits - * Number of high order address bits that must be zero. - * - * CommitSize - * Size in bytes of the initially committed section of - * the view. - * - * SectionOffset - * Offset in bytes from the beginning of the section - * to the beginning of the view. - * - * ViewSize - * Desired length of map (or zero to map all) on entry - * Actual length mapped on exit. - * - * InheritDisposition - * Specified how the view is to be shared with - * child processes. - * - * AllocateType - * Type of allocation for the pages. - * - * Protect - * Protection for the committed region of the view. - * - * RETURN VALUE - * Status. - * - * @implemented - */ -NTSTATUS NTAPI -NtMapViewOfSection(IN HANDLE SectionHandle, - IN HANDLE ProcessHandle, - IN OUT PVOID* BaseAddress OPTIONAL, - IN ULONG_PTR ZeroBits OPTIONAL, - IN SIZE_T CommitSize, - IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, - IN OUT PSIZE_T ViewSize, - IN SECTION_INHERIT InheritDisposition, - IN ULONG AllocationType OPTIONAL, - IN ULONG Protect) -{ - PVOID SafeBaseAddress; - LARGE_INTEGER SafeSectionOffset; - SIZE_T SafeViewSize; - PROS_SECTION_OBJECT Section; - PEPROCESS Process; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; - ULONG tmpProtect; - ACCESS_MASK DesiredAccess; - - /* - * Check the protection - */ - if (Protect & ~PAGE_FLAGS_VALID_FROM_USER_MODE) - { - return STATUS_INVALID_PARAMETER_10; - } - - tmpProtect = Protect & ~(PAGE_GUARD|PAGE_NOCACHE); - if (tmpProtect != PAGE_NOACCESS && - tmpProtect != PAGE_READONLY && - tmpProtect != PAGE_READWRITE && - tmpProtect != PAGE_WRITECOPY && - tmpProtect != PAGE_EXECUTE && - tmpProtect != PAGE_EXECUTE_READ && - tmpProtect != PAGE_EXECUTE_READWRITE && - tmpProtect != PAGE_EXECUTE_WRITECOPY) - { - return STATUS_INVALID_PAGE_PROTECTION; - } - - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - SafeBaseAddress = NULL; - SafeSectionOffset.QuadPart = 0; - SafeViewSize = 0; - - _SEH2_TRY - { - if(BaseAddress != NULL) - { - ProbeForWritePointer(BaseAddress); - SafeBaseAddress = *BaseAddress; - } - if(SectionOffset != NULL) - { - ProbeForWriteLargeInteger(SectionOffset); - SafeSectionOffset = *SectionOffset; - } - ProbeForWriteSize_t(ViewSize); - SafeViewSize = *ViewSize; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - else - { - SafeBaseAddress = (BaseAddress != NULL ? *BaseAddress : NULL); - SafeSectionOffset.QuadPart = (SectionOffset != NULL ? SectionOffset->QuadPart : 0); - SafeViewSize = (ViewSize != NULL ? *ViewSize : 0); - } - - SafeSectionOffset.LowPart = PAGE_ROUND_DOWN(SafeSectionOffset.LowPart); - - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - PsProcessType, - PreviousMode, - (PVOID*)(PVOID)&Process, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - /* Convert NT Protection Attr to Access Mask */ - if (Protect == PAGE_READONLY) - { - DesiredAccess = SECTION_MAP_READ; - } - else if (Protect == PAGE_READWRITE) - { - DesiredAccess = SECTION_MAP_WRITE; - } - else if (Protect == PAGE_WRITECOPY) - { - DesiredAccess = SECTION_QUERY; - } - /* FIXME: Handle other Protection Attributes. For now keep previous behavior */ - else - { - DesiredAccess = SECTION_MAP_READ; - } - - Status = ObReferenceObjectByHandle(SectionHandle, - DesiredAccess, - MmSectionObjectType, - PreviousMode, - (PVOID*)(PVOID)&Section, - NULL); - if (!(NT_SUCCESS(Status))) - { - DPRINT("ObReference failed rc=%x\n",Status); - ObDereferenceObject(Process); - return(Status); - } - - Status = MmMapViewOfSection(Section, - (PEPROCESS)Process, - (BaseAddress != NULL ? &SafeBaseAddress : NULL), - ZeroBits, - CommitSize, - (SectionOffset != NULL ? &SafeSectionOffset : NULL), - (ViewSize != NULL ? &SafeViewSize : NULL), - InheritDisposition, - AllocationType, - Protect); - - /* Check if this is an image for the current process */ - if ((Section->AllocationAttributes & SEC_IMAGE) && - (Process == PsGetCurrentProcess()) && - (Status != STATUS_IMAGE_NOT_AT_BASE)) - { - /* Notify the debugger */ - DbgkMapViewOfSection(Section, - SafeBaseAddress, - SafeSectionOffset.LowPart, - SafeViewSize); - } - - ObDereferenceObject(Section); - ObDereferenceObject(Process); - - if(NT_SUCCESS(Status)) - { - /* copy parameters back to the caller */ - _SEH2_TRY - { - if(BaseAddress != NULL) - { - *BaseAddress = SafeBaseAddress; - } - if(SectionOffset != NULL) - { - *SectionOffset = SafeSectionOffset; - } - if(ViewSize != NULL) - { - *ViewSize = SafeViewSize; - } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } - - return(Status); -} static VOID MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, @@ -4156,54 +3796,7 @@ MmUnmapViewOfSection(PEPROCESS Process, return(STATUS_SUCCESS); } -/********************************************************************** - * NAME EXPORTED - * NtUnmapViewOfSection - * - * DESCRIPTION - * - * ARGUMENTS - * ProcessHandle - * - * BaseAddress - * - * RETURN VALUE - * Status. - * - * REVISIONS - */ -NTSTATUS NTAPI -NtUnmapViewOfSection (HANDLE ProcessHandle, - PVOID BaseAddress) -{ - PEPROCESS Process; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; - DPRINT("NtUnmapViewOfSection(ProcessHandle %x, BaseAddress %x)\n", - ProcessHandle, BaseAddress); - - PreviousMode = ExGetPreviousMode(); - - DPRINT("Referencing process\n"); - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - PsProcessType, - PreviousMode, - (PVOID*)(PVOID)&Process, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("ObReferenceObjectByHandle failed (Status %x)\n", Status); - return(Status); - } - - Status = MmUnmapViewOfSection(Process, BaseAddress); - - ObDereferenceObject(Process); - - return Status; -} /** @@ -4346,76 +3939,7 @@ NtQuerySection(IN HANDLE SectionHandle, } -/** - * Extends size of file backed section. - * - * @param SectionHandle - * Handle to the section object. It must be opened with - * SECTION_EXTEND_SIZE access. - * @param NewMaximumSize - * New maximum size of the section in bytes. - * - * @return Status. - * - * @todo Move the actual code to internal function MmExtendSection. - * @unimplemented - */ -NTSTATUS NTAPI -NtExtendSection(IN HANDLE SectionHandle, - IN PLARGE_INTEGER NewMaximumSize) -{ - LARGE_INTEGER SafeNewMaximumSize; - PROS_SECTION_OBJECT Section; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; - PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - _SEH2_TRY - { - /* make a copy on the stack */ - SafeNewMaximumSize = ProbeForReadLargeInteger(NewMaximumSize); - NewMaximumSize = &SafeNewMaximumSize; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - - Status = ObReferenceObjectByHandle(SectionHandle, - SECTION_EXTEND_SIZE, - MmSectionObjectType, - PreviousMode, - (PVOID*)&Section, - NULL); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - if (!(Section->AllocationAttributes & SEC_FILE)) - { - ObDereferenceObject(Section); - return STATUS_INVALID_PARAMETER; - } - - /* - * - Acquire file extneding resource. - * - Check if we're not resizing the section below it's actual size! - * - Extend segments if needed. - * - Set file information (FileAllocationInformation) to the new size. - * - Release file extending resource. - */ - - ObDereferenceObject(Section); - - return STATUS_NOT_IMPLEMENTED; -} /********************************************************************** * NAME EXPORTED @@ -4704,15 +4228,7 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, } -/* - * @unimplemented - */ -BOOLEAN NTAPI -MmDisableModifiedWriteOfSection (ULONG Unknown0) -{ - UNIMPLEMENTED; - return (FALSE); -} + /* * @implemented @@ -4737,19 +4253,6 @@ MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, return FALSE; } -/* - * @unimplemented - */ -BOOLEAN NTAPI -MmForceSectionClosed ( - IN PSECTION_OBJECT_POINTERS SectionObjectPointer, - IN BOOLEAN DelayClose) -{ - UNIMPLEMENTED; - return (FALSE); -} - - /* * @implemented */ @@ -4797,22 +4300,6 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, return Status; } -/* - * @unimplemented - */ -NTSTATUS -NTAPI -MmMapViewInSessionSpace ( - IN PVOID Section, - OUT PVOID *MappedBase, - IN OUT PSIZE_T ViewSize - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - /* * @implemented */ @@ -4831,18 +4318,6 @@ MmUnmapViewInSystemSpace (IN PVOID MappedBase) return Status; } -/* - * @unimplemented - */ -NTSTATUS -NTAPI -MmUnmapViewInSessionSpace ( - IN PVOID MappedBase - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} /********************************************************************** * NAME EXPORTED @@ -4957,14 +4432,6 @@ MmCreateSection (OUT PVOID * Section, AllocationAttributes)); } -NTSTATUS -NTAPI -NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, - IN PVOID File2MappedAsFile) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} /* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index ad096050155..abbcc9d0481 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -459,6 +459,7 @@ pfnlist.c pool.c procsup.c + section.c sysldr.c syspte.c vadnode.c