WindowsMapRemoteView.cpp (4492B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/WindowsMapRemoteView.h" 8 9 #include "mozilla/Assertions.h" 10 #include "mozilla/DynamicallyLinkedFunctionPtr.h" 11 12 #include <winternl.h> 13 14 #if (NTDDI_VERSION < NTDDI_WIN10_RS2) 15 16 // MapViewOfFile2 is just an inline function that calls MapViewOfFileNuma2 with 17 // its preferred node set to NUMA_NO_PREFERRED_NODE 18 WINBASEAPI PVOID WINAPI MapViewOfFileNuma2(HANDLE aFileMapping, HANDLE aProcess, 19 ULONG64 aOffset, PVOID aBaseAddress, 20 SIZE_T aViewSize, 21 ULONG aAllocationType, 22 ULONG aPageProtection, 23 ULONG aPreferredNode); 24 25 WINBASEAPI BOOL WINAPI UnmapViewOfFile2(HANDLE aProcess, PVOID aBaseAddress, 26 ULONG aUnmapFlags); 27 28 #endif // (NTDDI_VERSION < NTDDI_WIN10_RS2) 29 30 enum SECTION_INHERIT { ViewShare = 1, ViewUnmap = 2 }; 31 32 NTSTATUS NTAPI NtMapViewOfSection( 33 HANDLE aSection, HANDLE aProcess, PVOID* aBaseAddress, ULONG_PTR aZeroBits, 34 SIZE_T aCommitSize, PLARGE_INTEGER aSectionOffset, PSIZE_T aViewSize, 35 SECTION_INHERIT aInheritDisposition, ULONG aAllocationType, 36 ULONG aProtectionFlags); 37 38 NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE aProcess, PVOID aBaseAddress); 39 40 static DWORD GetWin32ErrorCode(NTSTATUS aNtStatus) { 41 static const mozilla::StaticDynamicallyLinkedFunctionPtr< 42 decltype(&RtlNtStatusToDosError)> 43 pRtlNtStatusToDosError(L"ntdll.dll", "RtlNtStatusToDosError"); 44 45 MOZ_ASSERT(!!pRtlNtStatusToDosError); 46 if (!pRtlNtStatusToDosError) { 47 return ERROR_GEN_FAILURE; 48 } 49 50 return pRtlNtStatusToDosError(aNtStatus); 51 } 52 53 namespace mozilla { 54 55 MFBT_API void* MapRemoteViewOfFile(HANDLE aFileMapping, HANDLE aProcess, 56 ULONG64 aOffset, PVOID aBaseAddress, 57 SIZE_T aViewSize, ULONG aAllocationType, 58 ULONG aProtectionFlags) { 59 static const StaticDynamicallyLinkedFunctionPtr<decltype(&MapViewOfFileNuma2)> 60 pMapViewOfFileNuma2(L"Api-ms-win-core-memory-l1-1-5.dll", 61 "MapViewOfFileNuma2"); 62 63 if (!!pMapViewOfFileNuma2) { 64 return pMapViewOfFileNuma2(aFileMapping, aProcess, aOffset, aBaseAddress, 65 aViewSize, aAllocationType, aProtectionFlags, 66 NUMA_NO_PREFERRED_NODE); 67 } 68 69 static const StaticDynamicallyLinkedFunctionPtr<decltype(&NtMapViewOfSection)> 70 pNtMapViewOfSection(L"ntdll.dll", "NtMapViewOfSection"); 71 72 MOZ_ASSERT(!!pNtMapViewOfSection); 73 if (!pNtMapViewOfSection) { 74 return nullptr; 75 } 76 77 // For the sake of consistency, we only permit the same flags that 78 // MapViewOfFileNuma2 allows 79 if (aAllocationType != 0 && aAllocationType != MEM_RESERVE && 80 aAllocationType != MEM_LARGE_PAGES) { 81 ::SetLastError(ERROR_INVALID_PARAMETER); 82 return nullptr; 83 } 84 85 NTSTATUS ntStatus; 86 87 LARGE_INTEGER offset; 88 offset.QuadPart = aOffset; 89 90 ntStatus = pNtMapViewOfSection(aFileMapping, aProcess, &aBaseAddress, 0, 0, 91 &offset, &aViewSize, ViewUnmap, 92 aAllocationType, aProtectionFlags); 93 if (NT_SUCCESS(ntStatus)) { 94 ::SetLastError(ERROR_SUCCESS); 95 return aBaseAddress; 96 } 97 98 ::SetLastError(GetWin32ErrorCode(ntStatus)); 99 return nullptr; 100 } 101 102 MFBT_API bool UnmapRemoteViewOfFile(HANDLE aProcess, PVOID aBaseAddress) { 103 static const StaticDynamicallyLinkedFunctionPtr<decltype(&UnmapViewOfFile2)> 104 pUnmapViewOfFile2(L"kernel32.dll", "UnmapViewOfFile2"); 105 106 if (!!pUnmapViewOfFile2) { 107 return !!pUnmapViewOfFile2(aProcess, aBaseAddress, 0); 108 } 109 110 static const StaticDynamicallyLinkedFunctionPtr< 111 decltype(&NtUnmapViewOfSection)> 112 pNtUnmapViewOfSection(L"ntdll.dll", "NtUnmapViewOfSection"); 113 114 MOZ_ASSERT(!!pNtUnmapViewOfSection); 115 if (!pNtUnmapViewOfSection) { 116 return false; 117 } 118 119 NTSTATUS ntStatus = pNtUnmapViewOfSection(aProcess, aBaseAddress); 120 ::SetLastError(GetWin32ErrorCode(ntStatus)); 121 return NT_SUCCESS(ntStatus); 122 } 123 124 } // namespace mozilla