// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/win/process_info.h"

#include <dbghelp.h>
#include <intrin.h>
#include <wchar.h>

#include <memory>

#include "base/files/file_path.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/scoped_temp_dir.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/file/file_io.h"
#include "util/misc/from_pointer_cast.h"
#include "util/misc/random_string.h"
#include "util/misc/uuid.h"
#include "util/win/command_line.h"
#include "util/win/get_function.h"
#include "util/win/handle.h"
#include "util/win/scoped_handle.h"
#include "util/win/scoped_registry_key.h"

namespace crashpad {
namespace test {
namespace {

constexpr wchar_t kNtdllName[] = L"\\ntdll.dll";

#if !defined(ARCH_CPU_64_BITS)
bool IsProcessWow64(HANDLE process_handle) {
  static const auto is_wow64_process =
      GET_FUNCTION(L"kernel32.dll", ::IsWow64Process);
  if (!is_wow64_process)
    return false;
  BOOL is_wow64;
  if (!is_wow64_process(process_handle, &is_wow64)) {
    PLOG(ERROR) << "IsWow64Process";
    return false;
  }
  return !!is_wow64;
}
#endif

void VerifyAddressInInCodePage(const ProcessInfo& process_info,
                               WinVMAddress code_address) {
  // Make sure the child code address is an code page address with the right
  // information.
  const ProcessInfo::MemoryBasicInformation64Vector& memory_info =
      process_info.MemoryInfo();
  bool found_region = false;
  for (const auto& mi : memory_info) {
    if (mi.BaseAddress <= code_address &&
        mi.BaseAddress + mi.RegionSize > code_address) {
      EXPECT_EQ(mi.State, static_cast<DWORD>(MEM_COMMIT));
      EXPECT_EQ(mi.Protect, static_cast<DWORD>(PAGE_EXECUTE_READ));
      EXPECT_EQ(mi.Type, static_cast<DWORD>(MEM_IMAGE));
      EXPECT_FALSE(found_region);
      found_region = true;
    }
  }
  EXPECT_TRUE(found_region);
}

TEST(ProcessInfo, Self) {
  ProcessInfo process_info;
  ASSERT_TRUE(process_info.Initialize(GetCurrentProcess()));
  EXPECT_EQ(process_info.ProcessID(), GetCurrentProcessId());
  EXPECT_GT(process_info.ParentProcessID(), 0u);

#if defined(ARCH_CPU_64_BITS)
  EXPECT_TRUE(process_info.Is64Bit());
  EXPECT_FALSE(process_info.IsWow64());
#else
  EXPECT_FALSE(process_info.Is64Bit());
  if (IsProcessWow64(GetCurrentProcess()))
    EXPECT_TRUE(process_info.IsWow64());
  else
    EXPECT_FALSE(process_info.IsWow64());
#endif

  std::wstring command_line;
  EXPECT_TRUE(process_info.CommandLine(&command_line));
  EXPECT_EQ(command_line, std::wstring(GetCommandLine()));

  std::vector<ProcessInfo::Module> modules;
  EXPECT_TRUE(process_info.Modules(&modules));
  ASSERT_GE(modules.size(), 2u);
  std::wstring self_name =
      std::wstring(1, '\\') +
      TestPaths::ExpectedExecutableBasename(L"crashpad_util_test").value();
  ASSERT_GE(modules[0].name.size(), self_name.size());
  EXPECT_EQ(modules[0].name.substr(modules[0].name.size() - self_name.size()),
            self_name);
  ASSERT_GE(modules[1].name.size(), wcslen(kNtdllName));
  EXPECT_EQ(modules[1].name.substr(modules[1].name.size() - wcslen(kNtdllName)),
            kNtdllName);

  EXPECT_EQ(modules[0].dll_base,
            reinterpret_cast<uintptr_t>(GetModuleHandle(nullptr)));
  EXPECT_EQ(modules[1].dll_base,
            reinterpret_cast<uintptr_t>(GetModuleHandle(L"ntdll.dll")));

  EXPECT_GT(modules[0].size, 0u);
  EXPECT_GT(modules[1].size, 0u);

  EXPECT_EQ(modules[0].timestamp,
            GetTimestampForLoadedLibrary(GetModuleHandle(nullptr)));
  // System modules are forced to particular stamps and the file header values
  // don't match the on-disk times. Just make sure we got some data here.
  EXPECT_GT(modules[1].timestamp, 0);

  // Find something we know is a code address and confirm expected memory
  // information settings.
  VerifyAddressInInCodePage(process_info,
                            FromPointerCast<WinVMAddress>(_ReturnAddress()));
}

void TestOtherProcess(TestPaths::Architecture architecture) {
  ProcessInfo process_info;

  UUID done_uuid;
  done_uuid.InitializeWithNew();

  ScopedKernelHANDLE done(
      CreateEvent(nullptr, true, false, done_uuid.ToString16().c_str()));
  ASSERT_TRUE(done.get()) << ErrorMessage("CreateEvent");

  base::FilePath child_test_executable =
      TestPaths::BuildArtifact(L"util",
                               L"process_info_test_child",
                               TestPaths::FileType::kExecutable,
                               architecture);
  std::wstring args;
  AppendCommandLineArgument(done_uuid.ToString16(), &args);

  ChildLauncher child(child_test_executable, args);
  ASSERT_NO_FATAL_FAILURE(child.Start());

  // The child sends us a code address we can look up in the memory map.
  WinVMAddress code_address;
  CheckedReadFileExactly(
      child.stdout_read_handle(), &code_address, sizeof(code_address));

  ASSERT_TRUE(process_info.Initialize(child.process_handle()));

  // Tell the test it's OK to shut down now that we've read our data.
  EXPECT_TRUE(SetEvent(done.get())) << ErrorMessage("SetEvent");

  EXPECT_EQ(child.WaitForExit(), 0u);

  std::vector<ProcessInfo::Module> modules;
  EXPECT_TRUE(process_info.Modules(&modules));
  ASSERT_GE(modules.size(), 3u);
  std::wstring child_name = L"\\crashpad_util_test_process_info_test_child.exe";
  ASSERT_GE(modules[0].name.size(), child_name.size());
  EXPECT_EQ(modules[0].name.substr(modules[0].name.size() - child_name.size()),
            child_name);
  ASSERT_GE(modules[1].name.size(), wcslen(kNtdllName));
  EXPECT_EQ(modules[1].name.substr(modules[1].name.size() - wcslen(kNtdllName)),
            kNtdllName);
  // lz32.dll is an uncommonly-used-but-always-available module that the test
  // binary manually loads.
  static constexpr wchar_t kLz32dllName[] = L"\\lz32.dll";
  auto& lz32 = modules[modules.size() - 2];
  ASSERT_GE(lz32.name.size(), wcslen(kLz32dllName));
  EXPECT_EQ(lz32.name.substr(lz32.name.size() - wcslen(kLz32dllName)),
            kLz32dllName);

  // Note that the test code corrupts the PEB MemoryOrder list, whereas
  // ProcessInfo::Modules() retrieves the module names via the PEB LoadOrder
  // list. These are expected to point to the same strings, but theoretically
  // could be separate.
  auto& corrupted = modules.back();
  EXPECT_EQ(corrupted.name, L"???");

  VerifyAddressInInCodePage(process_info, code_address);
}

TEST(ProcessInfo, OtherProcess) {
  TestOtherProcess(TestPaths::Architecture::kDefault);
}

#if defined(ARCH_CPU_64_BITS)
TEST(ProcessInfo, OtherProcessWOW64) {
  if (!TestPaths::Has32BitBuildArtifacts()) {
    GTEST_SKIP();
  }

  TestOtherProcess(TestPaths::Architecture::k32Bit);
}
#endif  // ARCH_CPU_64_BITS

TEST(ProcessInfo, AccessibleRangesNone) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_FREE;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(2, 4),
                                   memory_info);

  EXPECT_TRUE(result.empty());
}

TEST(ProcessInfo, AccessibleRangesOneInside) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(2, 4),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 2u);
  EXPECT_EQ(result[0].size(), 4u);
}

TEST(ProcessInfo, AccessibleRangesOneTruncatedSize) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 10;
  mbi.RegionSize = 20;
  mbi.State = MEM_FREE;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 5u);
  EXPECT_EQ(result[0].size(), 5u);
}

TEST(ProcessInfo, AccessibleRangesOneMovedStart) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_FREE;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 10;
  mbi.RegionSize = 20;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 10u);
  EXPECT_EQ(result[0].size(), 5u);
}

TEST(ProcessInfo, ReserveIsInaccessible) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_RESERVE;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 10;
  mbi.RegionSize = 20;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 10u);
  EXPECT_EQ(result[0].size(), 5u);
}

TEST(ProcessInfo, PageGuardIsInaccessible) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_COMMIT;
  mbi.Protect = PAGE_GUARD;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 10;
  mbi.RegionSize = 20;
  mbi.State = MEM_COMMIT;
  mbi.Protect = 0;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 10u);
  EXPECT_EQ(result[0].size(), 5u);
}

TEST(ProcessInfo, PageNoAccessIsInaccessible) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_COMMIT;
  mbi.Protect = PAGE_NOACCESS;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 10;
  mbi.RegionSize = 20;
  mbi.State = MEM_COMMIT;
  mbi.Protect = 0;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 10u);
  EXPECT_EQ(result[0].size(), 5u);
}

TEST(ProcessInfo, AccessibleRangesCoalesced) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_FREE;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 10;
  mbi.RegionSize = 2;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 12;
  mbi.RegionSize = 5;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(11, 4),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 11u);
  EXPECT_EQ(result[0].size(), 4u);
}

TEST(ProcessInfo, AccessibleRangesMiddleUnavailable) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 0;
  mbi.RegionSize = 10;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 10;
  mbi.RegionSize = 5;
  mbi.State = MEM_FREE;
  memory_info.push_back(mbi);

  mbi.BaseAddress = 15;
  mbi.RegionSize = 100;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 45),
                                   memory_info);

  ASSERT_EQ(result.size(), 2u);
  EXPECT_EQ(result[0].base(), 5u);
  EXPECT_EQ(result[0].size(), 5u);
  EXPECT_EQ(result[1].base(), 15u);
  EXPECT_EQ(result[1].size(), 35u);
}

TEST(ProcessInfo, RequestedBeforeMap) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 10;
  mbi.RegionSize = 10;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(CheckedRange<WinVMAddress, WinVMSize>(5, 10),
                                   memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 10u);
  EXPECT_EQ(result[0].size(), 5u);
}

TEST(ProcessInfo, RequestedAfterMap) {
  ProcessInfo::MemoryBasicInformation64Vector memory_info;
  MEMORY_BASIC_INFORMATION64 mbi = {0};

  mbi.BaseAddress = 10;
  mbi.RegionSize = 10;
  mbi.State = MEM_COMMIT;
  memory_info.push_back(mbi);

  std::vector<CheckedRange<WinVMAddress, WinVMSize>> result =
      GetReadableRangesOfMemoryMap(
          CheckedRange<WinVMAddress, WinVMSize>(15, 100), memory_info);

  ASSERT_EQ(result.size(), 1u);
  EXPECT_EQ(result[0].base(), 15u);
  EXPECT_EQ(result[0].size(), 5u);
}

TEST(ProcessInfo, ReadableRanges) {
  SYSTEM_INFO system_info;
  GetSystemInfo(&system_info);

  const size_t kBlockSize = system_info.dwPageSize;

  // Allocate 6 pages, and then commit the second, fourth, and fifth, and mark
  // two as committed, but PAGE_NOACCESS, so we have a setup like this:
  // 0       1       2       3       4       5
  // +-----------------------------------------------+
  // | ????? |       | xxxxx |       |       | ????? |
  // +-----------------------------------------------+
  void* reserve_region =
      VirtualAlloc(nullptr, kBlockSize * 6, MEM_RESERVE, PAGE_READWRITE);
  ASSERT_TRUE(reserve_region);
  uintptr_t reserved_as_int = reinterpret_cast<uintptr_t>(reserve_region);
  void* readable1 =
      VirtualAlloc(reinterpret_cast<void*>(reserved_as_int + kBlockSize),
                   kBlockSize,
                   MEM_COMMIT,
                   PAGE_READWRITE);
  ASSERT_TRUE(readable1);
  void* readable2 =
      VirtualAlloc(reinterpret_cast<void*>(reserved_as_int + (kBlockSize * 3)),
                   kBlockSize * 2,
                   MEM_COMMIT,
                   PAGE_READWRITE);
  ASSERT_TRUE(readable2);

  void* no_access =
      VirtualAlloc(reinterpret_cast<void*>(reserved_as_int + (kBlockSize * 2)),
                   kBlockSize,
                   MEM_COMMIT,
                   PAGE_NOACCESS);
  ASSERT_TRUE(no_access);

  HANDLE current_process = GetCurrentProcess();
  ProcessInfo info;
  info.Initialize(current_process);
  auto ranges = info.GetReadableRanges(
      CheckedRange<WinVMAddress, WinVMSize>(reserved_as_int, kBlockSize * 6));

  ASSERT_EQ(ranges.size(), 2u);
  EXPECT_EQ(ranges[0].base(), reserved_as_int + kBlockSize);
  EXPECT_EQ(ranges[0].size(), kBlockSize);
  EXPECT_EQ(ranges[1].base(), reserved_as_int + (kBlockSize * 3));
  EXPECT_EQ(ranges[1].size(), kBlockSize * 2);

  // Also make sure what we think we can read corresponds with what we can
  // actually read.
  std::unique_ptr<unsigned char[]> into(new unsigned char[kBlockSize * 6]);
  SIZE_T bytes_read;

  EXPECT_TRUE(ReadProcessMemory(
      current_process, readable1, into.get(), kBlockSize, &bytes_read));
  EXPECT_EQ(bytes_read, kBlockSize);

  EXPECT_TRUE(ReadProcessMemory(
      current_process, readable2, into.get(), kBlockSize * 2, &bytes_read));
  EXPECT_EQ(bytes_read, kBlockSize * 2);

  EXPECT_FALSE(ReadProcessMemory(
      current_process, no_access, into.get(), kBlockSize, &bytes_read));
  EXPECT_FALSE(ReadProcessMemory(
      current_process, reserve_region, into.get(), kBlockSize, &bytes_read));
  EXPECT_FALSE(ReadProcessMemory(current_process,
                                 reserve_region,
                                 into.get(),
                                 kBlockSize * 6,
                                 &bytes_read));
}

TEST(ProcessInfo, Handles) {
  ScopedTempDir temp_dir;

  ScopedFileHandle file(LoggingOpenFileForWrite(
      temp_dir.path().Append(FILE_PATH_LITERAL("test_file")),
      FileWriteMode::kTruncateOrCreate,
      FilePermissions::kWorldReadable));
  ASSERT_TRUE(file.is_valid());

  SECURITY_ATTRIBUTES security_attributes = {0};
  security_attributes.nLength = sizeof(security_attributes);
  security_attributes.bInheritHandle = true;
  ScopedFileHandle inherited_file(CreateFile(
      temp_dir.path().Append(FILE_PATH_LITERAL("inheritable")).value().c_str(),
      GENERIC_WRITE,
      0,
      &security_attributes,
      CREATE_NEW,
      FILE_ATTRIBUTE_NORMAL,
      nullptr));
  ASSERT_TRUE(inherited_file.is_valid());

  HKEY key;
  ASSERT_EQ(RegOpenKeyEx(
                HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft", 0, KEY_READ, &key),
            ERROR_SUCCESS);
  ScopedRegistryKey scoped_key(key);
  ASSERT_TRUE(scoped_key.is_valid());

  std::wstring mapping_name =
      base::UTF8ToUTF16(base::StringPrintf("Local\\test_mapping_%lu_%s",
                                           GetCurrentProcessId(),
                                           RandomString().c_str()));
  ScopedKernelHANDLE mapping(CreateFileMapping(INVALID_HANDLE_VALUE,
                                               nullptr,
                                               PAGE_READWRITE,
                                               0,
                                               1024,
                                               mapping_name.c_str()));
  ASSERT_TRUE(mapping.is_valid()) << ErrorMessage("CreateFileMapping");

  ProcessInfo info;
  info.Initialize(GetCurrentProcess());
  bool found_file_handle = false;
  bool found_inherited_file_handle = false;
  bool found_key_handle = false;
  bool found_mapping_handle = false;
  for (auto handle : info.Handles()) {
    if (handle.handle == HandleToInt(file.get())) {
      EXPECT_FALSE(found_file_handle);
      found_file_handle = true;
      EXPECT_EQ(handle.type_name, L"File");
      EXPECT_EQ(handle.handle_count, 1u);
      EXPECT_NE(handle.pointer_count, 0u);
      EXPECT_EQ(handle.granted_access & STANDARD_RIGHTS_ALL,
                static_cast<uint32_t>(STANDARD_RIGHTS_READ |
                                      STANDARD_RIGHTS_WRITE | SYNCHRONIZE));
      EXPECT_EQ(handle.attributes, 0u);
    }
    if (handle.handle == HandleToInt(inherited_file.get())) {
      EXPECT_FALSE(found_inherited_file_handle);
      found_inherited_file_handle = true;
      EXPECT_EQ(handle.type_name, L"File");
      EXPECT_EQ(handle.handle_count, 1u);
      EXPECT_NE(handle.pointer_count, 0u);
      EXPECT_EQ(handle.granted_access & STANDARD_RIGHTS_ALL,
                static_cast<uint32_t>(STANDARD_RIGHTS_READ |
                                      STANDARD_RIGHTS_WRITE | SYNCHRONIZE));

      // OBJ_INHERIT from ntdef.h, but including that conflicts with other
      // headers.
      constexpr uint32_t kObjInherit = 0x2;
      EXPECT_EQ(handle.attributes, kObjInherit);
    }
    if (handle.handle == HandleToInt(scoped_key.get())) {
      EXPECT_FALSE(found_key_handle);
      found_key_handle = true;
      EXPECT_EQ(handle.type_name, L"Key");
      EXPECT_EQ(handle.handle_count, 1u);
      EXPECT_NE(handle.pointer_count, 0u);
      EXPECT_EQ(handle.granted_access & STANDARD_RIGHTS_ALL,
                static_cast<uint32_t>(STANDARD_RIGHTS_READ));
      EXPECT_EQ(handle.attributes, 0u);
    }
    if (handle.handle == HandleToInt(mapping.get())) {
      EXPECT_FALSE(found_mapping_handle);
      found_mapping_handle = true;
      EXPECT_EQ(handle.type_name, L"Section");
      EXPECT_EQ(handle.handle_count, 1u);
      EXPECT_NE(handle.pointer_count, 0u);
      EXPECT_EQ(handle.granted_access & STANDARD_RIGHTS_ALL,
                static_cast<uint32_t>(DELETE | READ_CONTROL | WRITE_DAC |
                                      WRITE_OWNER | STANDARD_RIGHTS_READ |
                                      STANDARD_RIGHTS_WRITE));
      EXPECT_EQ(handle.attributes, 0u);
    }
  }
  EXPECT_TRUE(found_file_handle);
  EXPECT_TRUE(found_inherited_file_handle);
  EXPECT_TRUE(found_key_handle);
  EXPECT_TRUE(found_mapping_handle);
}

TEST(ProcessInfo, OutOfRangeCheck) {
  constexpr size_t kAllocationSize = 12345;
  std::unique_ptr<char[]> safe_memory(new char[kAllocationSize]);

  ProcessInfo info;
  info.Initialize(GetCurrentProcess());

  EXPECT_TRUE(
      info.LoggingRangeIsFullyReadable(CheckedRange<WinVMAddress, WinVMSize>(
          FromPointerCast<WinVMAddress>(safe_memory.get()), kAllocationSize)));
  EXPECT_FALSE(info.LoggingRangeIsFullyReadable(
      CheckedRange<WinVMAddress, WinVMSize>(0, 1024)));
}

}  // namespace
}  // namespace test
}  // namespace crashpad
