tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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