// Copyright 2018 The Crashpad Authors
//
// 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/process/process_memory_win.h"

#include <windows.h>

#include <algorithm>
#include <limits>

#include "base/check_op.h"
#include "base/logging.h"
#include "base/memory/page_size.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/stringprintf.h"

namespace crashpad {

ProcessMemoryWin::ProcessMemoryWin()
    : ProcessMemory(), handle_(), process_info_(), initialized_() {}

ProcessMemoryWin::~ProcessMemoryWin() {}

bool ProcessMemoryWin::Initialize(HANDLE handle) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  handle_ = handle;
  if (!process_info_.Initialize(handle)) {
    LOG(ERROR) << "Failed to initialize ProcessInfo.";
    return false;
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

ssize_t ProcessMemoryWin::ReadUpTo(VMAddress address,
                                   size_t size,
                                   void* buffer) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  DCHECK_LE(size, (size_t)std::numeric_limits<ssize_t>::max());

  SIZE_T size_out = 0;
  BOOL success = ReadProcessMemory(
      handle_, reinterpret_cast<void*>(address), buffer, size, &size_out);
  if (success)
    return base::checked_cast<ssize_t>(size_out);

  if (GetLastError() == ERROR_PARTIAL_COPY) {
    // If we can not read the entire section, perform a short read of the first
    // page instead. This is necessary to support ReadCString().
    size_t short_read =
        base::GetPageSize() - (address & (base::GetPageSize() - 1));
    success = ReadProcessMemory(handle_,
                                reinterpret_cast<void*>(address),
                                buffer,
                                short_read,
                                &size_out);
    if (success)
      return base::checked_cast<ssize_t>(size_out);
  }

  PLOG(ERROR) << "ReadMemory at 0x" << std::hex << address << std::dec << " of "
              << size << " bytes failed";
  return -1;
}

size_t ProcessMemoryWin::ReadAvailableMemory(VMAddress address,
                                             size_t size,
                                             void* buffer) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  DCHECK_LE(size, (size_t)std::numeric_limits<ssize_t>::max());

  if (size == 0)
    return 0;

  auto ranges = process_info_.GetReadableRanges(
      CheckedRange<WinVMAddress, WinVMSize>(address, size));

  // We only read up until the first unavailable byte, so we only read from the
  // first range. If we have no ranges, then no bytes were accessible anywhere
  // in the range.
  if (ranges.empty()) {
    LOG(ERROR) << base::StringPrintf(
        "range at 0x%llx, size 0x%zx completely inaccessible", address, size);
    return 0;
  }

  // If the start address was adjusted, we couldn't read even the first
  // requested byte.
  if (ranges.front().base() != address) {
    LOG(ERROR) << base::StringPrintf(
        "start of range at 0x%llx, size 0x%zx inaccessible", address, size);
    return 0;
  }

  DCHECK_LE(ranges.front().size(), size);

  ssize_t result = ReadUpTo(ranges.front().base(),
                            base::checked_cast<size_t>(ranges.front().size()),
                            buffer);
  if (result < 0)
    return 0;

  return base::checked_cast<size_t>(result);
}

}  // namespace crashpad
