// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// ms_symbol_server_converter.cc: Obtain symbol files from a Microsoft
// symbol server, and convert them to Breakpad's dumped format.
//
// See ms_symbol_server_converter.h for documentation.
//
// Author: Mark Mentovai

#include <windows.h>
#include <dbghelp.h>
#include <pathcch.h>

#include <cassert>
#include <cstdio>

#include "tools/windows/converter/ms_symbol_server_converter.h"
#include "common/windows/pdb_source_line_writer.h"
#include "common/windows/pe_source_line_writer.h"
#include "common/windows/string_utils-inl.h"

// SYMOPT_NO_PROMPTS is not defined in earlier platform SDKs.  Define it
// in that case, in the event that this code is used with a newer version
// of DbgHelp at runtime that recognizes the option.  The presence of this
// bit in the symbol options should not harm earlier versions of DbgHelp.
#ifndef SYMOPT_NO_PROMPTS
#define SYMOPT_NO_PROMPTS 0x00080000
#endif  // SYMOPT_NO_PROMPTS

namespace {

std::wstring GetExeDirectory() {
  wchar_t directory[MAX_PATH];

  // Get path to this process exe.
  DWORD result = GetModuleFileName(/*hModule=*/nullptr, directory, MAX_PATH);
  if (result <= 0 || result == MAX_PATH) {
    fprintf(stderr,
        "GetExeDirectory: failed to get path to process exe.\n");
    return L"";
  }
  HRESULT hr = PathCchRemoveFileSpec(directory, result + 1);
  if (hr != S_OK) {
    fprintf(stderr,
        "GetExeDirectory: failed to remove basename from path '%ls'.\n",
        directory);
    return L"";
  }

  return std::wstring(directory);
}

}  // namespace

namespace google_breakpad {

// Use sscanf_s if it is available, to quench the warning about scanf being
// deprecated.  Use scanf where sscanf_is not available.  Note that the
// parameters passed to sscanf and sscanf_s are only compatible as long as
// fields of type c, C, s, S, and [ are not used.
#if _MSC_VER >= 1400  // MSVC 2005/8
#define SSCANF sscanf_s
#else  // _MSC_VER >= 1400
#define SSCANF sscanf
#endif  // _MSC_VER >= 1400

bool GUIDOrSignatureIdentifier::InitializeFromString(
    const string& identifier) {
  type_ = TYPE_NONE;

  size_t length = identifier.length();

  if (length > 32 && length <= 40) {
    // GUID
    if (SSCANF(identifier.c_str(),
               "%08X%04hX%04hX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%X",
               &guid_.Data1, &guid_.Data2, &guid_.Data3,
               &guid_.Data4[0], &guid_.Data4[1],
               &guid_.Data4[2], &guid_.Data4[3],
               &guid_.Data4[4], &guid_.Data4[5],
               &guid_.Data4[6], &guid_.Data4[7],
               &age_) != 12) {
      return false;
    }

    type_ = TYPE_GUID;
  } else if (length > 8 && length <= 15) {
    // Signature
    if (SSCANF(identifier.c_str(), "%08X%x", &signature_, &age_) != 2) {
      return false;
    }

    type_ = TYPE_SIGNATURE;
  } else {
    return false;
  }

  return true;
}

#undef SSCANF

MSSymbolServerConverter::MSSymbolServerConverter(
    const string& local_cache, const vector<string>& symbol_servers)
    : symbol_path_(),
      fail_dns_(false),
      fail_timeout_(false),
      fail_not_found_(false) {
  // Setting local_cache can be done without verifying that it exists because
  // SymSrv will create it if it is missing - any creation failures will occur
  // at that time, so there's nothing to check here, making it safe to
  // assign this in the constructor.

  assert(symbol_servers.size() > 0);

#if !defined(NDEBUG)
  // These are characters that are interpreted as having special meanings in
  // symbol_path_.
  const char kInvalidCharacters[] = "*;";
  assert(local_cache.find_first_of(kInvalidCharacters) == string::npos);
#endif  // !defined(NDEBUG)

  for (vector<string>::const_iterator symbol_server = symbol_servers.begin();
       symbol_server != symbol_servers.end();
       ++symbol_server) {
    // The symbol path format is explained by
    // http://msdn.microsoft.com/library/en-us/debug/base/using_symsrv.asp .
    // "srv*" is the same as "symsrv*symsrv.dll*", which means that
    // symsrv.dll is to be responsible for locating symbols.  symsrv.dll
    // interprets the rest of the string as a series of symbol stores separated
    // by '*'.  "srv*local_cache*symbol_server" means to check local_cache
    // first for the symbol file, and if it is not found there, to check
    // symbol_server.  Symbol files found on the symbol server will be placed
    // in the local cache, decompressed.
    //
    // Multiple specifications in this format may be presented, separated by
    // semicolons.

    assert((*symbol_server).find_first_of(kInvalidCharacters) == string::npos);
    symbol_path_ += "srv*" + local_cache + "*" + *symbol_server + ";";
  }

  // Strip the trailing semicolon.
  symbol_path_.erase(symbol_path_.length() - 1);
}

// A stack-based class that manages SymInitialize and SymCleanup calls.
class AutoSymSrv {
 public:
  AutoSymSrv() : initialized_(false) {}

  ~AutoSymSrv() {
    if (!Cleanup()) {
      // Print the error message here, because destructors have no return
      // value.
      fprintf(stderr, "~AutoSymSrv: SymCleanup: error %lu\n", GetLastError());
    }
  }

  bool Initialize(HANDLE process, char* path, bool invade_process) {
    process_ = process;

    // TODO(nbilling): Figure out why dbghelp.dll is being loaded from
    // system32/SysWOW64 before exe folder.

    // Attempt to locate and load dbghelp.dll beside the process exe. This is
    // somewhat of a workaround to loader delay load behavior that is occurring
    // when we call into symsrv APIs. dbghelp.dll must be loaded from beside
    // the process exe so that we are guaranteed to find symsrv.dll alongside
    // dbghelp.dll (a security requirement of dbghelp.dll) and so that the
    // symsrv.dll file that is loaded has a symsrv.yes file alongside it (a
    // requirement of symsrv.dll when accessing Microsoft-owned symbol
    // servers).
    // 'static local' because we don't care about the value but we need the
    // initialization to happen exactly once.
    static HMODULE dbghelp_module = [] () -> HMODULE {
      std::wstring exe_directory = GetExeDirectory();
      if (exe_directory.empty()) {
        return nullptr;
      }
      std::wstring dbghelp_path = exe_directory + L"\\dbghelp.dll";
      return LoadLibrary(dbghelp_path.c_str());
    }();
    if (dbghelp_module == nullptr) {
      fprintf(stderr,
          "AutoSymSrv::Initialize: failed to load dbghelp.dll beside exe.");
      return false;
    }

    initialized_ = SymInitialize(process, path, invade_process) == TRUE;
    return initialized_;
  }

  bool Cleanup() {
    if (initialized_) {
      if (SymCleanup(process_)) {
        initialized_ = false;
        return true;
      }
      return false;
    }

    return true;
  }

 private:
  HANDLE process_;
  bool initialized_;
};

// A stack-based class that "owns" a pathname and deletes it when destroyed,
// unless told not to by having its Release() method called.  Early deletions
// are supported by calling Delete().
class AutoDeleter {
 public:
  explicit AutoDeleter(const string& path) : path_(path) {}

  ~AutoDeleter() {
    int error;
    if ((error = Delete()) != 0) {
      // Print the error message here, because destructors have no return
      // value.
      fprintf(stderr, "~AutoDeleter: Delete: error %d for %s\n",
              error, path_.c_str());
    }
  }

  int Delete() {
    if (path_.empty())
      return 0;

    int error = remove(path_.c_str());
    Release();
    return error;
  }

  void Release() {
    path_.clear();
  }

 private:
  string path_;
};

MSSymbolServerConverter::LocateResult
MSSymbolServerConverter::LocateFile(const string& debug_or_code_file,
                                    const string& debug_or_code_id,
                                    const string& version,
                                    string* file_name) {
  assert(file_name);
  file_name->clear();

  GUIDOrSignatureIdentifier identifier;
  if (!identifier.InitializeFromString(debug_or_code_id)) {
    fprintf(stderr,
            "LocateFile: Unparseable identifier for %s %s %s\n",
            debug_or_code_file.c_str(),
            debug_or_code_id.c_str(),
            version.c_str());
    return LOCATE_FAILURE;
  }

  HANDLE process = GetCurrentProcess();  // CloseHandle is not needed.
  AutoSymSrv symsrv;
  if (!symsrv.Initialize(process,
                         const_cast<char*>(symbol_path_.c_str()),
                         false)) {
    fprintf(stderr, "LocateFile: SymInitialize: error %lu for %s %s %s\n",
            GetLastError(),
            debug_or_code_file.c_str(),
            debug_or_code_id.c_str(),
            version.c_str());
    return LOCATE_FAILURE;
  }

  if (!SymRegisterCallback64(process, SymCallback,
                             reinterpret_cast<ULONG64>(this))) {
    fprintf(stderr,
            "LocateFile: SymRegisterCallback64: error %lu for %s %s %s\n",
            GetLastError(),
            debug_or_code_file.c_str(),
            debug_or_code_id.c_str(),
            version.c_str());
    return LOCATE_FAILURE;
  }

  // SYMOPT_DEBUG arranges for SymCallback to be called with additional
  // debugging information.  This is used to determine the nature of failures.
  DWORD options = SymGetOptions() | SYMOPT_DEBUG | SYMOPT_NO_PROMPTS |
                  SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_SECURE;
  SymSetOptions(options);

  // SymCallback will set these as needed inisde the SymFindFileInPath call.
  fail_dns_ = false;
  fail_timeout_ = false;
  fail_not_found_ = false;

  // Do the lookup.
  char path[MAX_PATH];
  if (!SymFindFileInPath(
          process, NULL,
          const_cast<char*>(debug_or_code_file.c_str()),
          const_cast<void*>(identifier.guid_or_signature_pointer()),
          identifier.age(), 0,
          identifier.type() == GUIDOrSignatureIdentifier::TYPE_GUID ?
              SSRVOPT_GUIDPTR : SSRVOPT_DWORDPTR,
          path, SymFindFileInPathCallback, this)) {
    DWORD error = GetLastError();
    if (error == ERROR_FILE_NOT_FOUND) {
      // This can be returned for a number of reasons.  Use the crumbs
      // collected by SymCallback to determine which one is relevant.

      // These errors are possibly transient.
      if (fail_dns_ || fail_timeout_) {
        return LOCATE_RETRY;
      }

      // This is an authoritiative file-not-found message.
      if (fail_not_found_) {
        fprintf(stderr,
                "LocateFile: SymFindFileInPath: LOCATE_NOT_FOUND error "
                "for %s %s %s\n",
                debug_or_code_file.c_str(),
                debug_or_code_id.c_str(),
                version.c_str());
        return LOCATE_NOT_FOUND;
      }

      // If the error is FILE_NOT_FOUND but none of the known error
      // conditions are matched, fall through to LOCATE_FAILURE.
    }

    fprintf(stderr,
            "LocateFile: SymFindFileInPath: error %lu for %s %s %s\n",
            error,
            debug_or_code_file.c_str(),
            debug_or_code_id.c_str(),
            version.c_str());
    return LOCATE_FAILURE;
  }

  // Making sure path is null-terminated.
  path[MAX_PATH - 1] = '\0';

  // The AutoDeleter ensures that the file is only kept when returning
  // LOCATE_SUCCESS.
  AutoDeleter deleter(path);

  // Do the cleanup here even though it will happen when symsrv goes out of
  // scope, to allow it to influence the return value.
  if (!symsrv.Cleanup()) {
    fprintf(stderr, "LocateFile: SymCleanup: error %lu for %s %s %s\n",
            GetLastError(),
            debug_or_code_file.c_str(),
            debug_or_code_id.c_str(),
            version.c_str());
    return LOCATE_FAILURE;
  }

  deleter.Release();

  printf("Downloaded: %s\n", path);
  *file_name = path;
  return LOCATE_SUCCESS;
}


MSSymbolServerConverter::LocateResult
MSSymbolServerConverter::LocatePEFile(const MissingSymbolInfo& missing,
                                      string* pe_file) {
  return LocateFile(missing.code_file, missing.code_identifier,
                    missing.version, pe_file);
}

MSSymbolServerConverter::LocateResult
MSSymbolServerConverter::LocateSymbolFile(const MissingSymbolInfo& missing,
                                          string* symbol_file) {
  return LocateFile(missing.debug_file, missing.debug_identifier,
                    missing.version, symbol_file);
}


// static
BOOL CALLBACK MSSymbolServerConverter::SymCallback(HANDLE process,
                                                   ULONG action,
                                                   ULONG64 data,
                                                   ULONG64 context) {
  MSSymbolServerConverter* self =
      reinterpret_cast<MSSymbolServerConverter*>(context);

  switch (action) {
    case CBA_EVENT: {
      IMAGEHLP_CBA_EVENT* cba_event =
          reinterpret_cast<IMAGEHLP_CBA_EVENT*>(data);

      // Put the string into a string object to be able to use string::find
      // for substring matching.  This is important because the not-found
      // message does not use the entire string but is appended to the URL
      // that SymSrv attempted to retrieve.
      string desc(cba_event->desc);

      // desc_action maps strings (in desc) to boolean pointers that are to
      // be set to true if the string matches.
      struct desc_action {
        const char* desc;  // The substring to match.
        bool* action;      // On match, this pointer will be set to true.
      };

      static const desc_action desc_actions[] = {
        // When a DNS error occurs, it could be indiciative of network
        // problems.
        { "SYMSRV:  The server name or address could not be resolved\n",
          &self->fail_dns_ },

        // This message is produced if no connection is opened.
        { "SYMSRV:  A connection with the server could not be established\n",
          &self->fail_timeout_ },

        // This message is produced if a connection is established but the
        // server fails to respond to the HTTP request.
        { "SYMSRV:  The operation timed out\n",
          &self->fail_timeout_ },

        // This message is produced when the requested file is not found,
        // even if one or more of the above messages are also produced.
        // It's trapped to distinguish between not-found and unknown-failure
        // conditions.  Note that this message will not be produced if a
        // connection is established and the server begins to respond to the
        // HTTP request but does not finish transmitting the file.
        { " not found\n",
          &self->fail_not_found_ }
      };

      for (int desc_action_index = 0;
           desc_action_index <
           static_cast<int>(sizeof(desc_actions) / sizeof(desc_action));
           ++desc_action_index) {
        if (desc.find(desc_actions[desc_action_index].desc) != string::npos) {
          *(desc_actions[desc_action_index].action) = true;
          break;
        }
      }

      break;
    }
  }

  // This function is a mere fly on the wall.  Treat everything as unhandled.
  return FALSE;
}

// static
BOOL CALLBACK MSSymbolServerConverter::SymFindFileInPathCallback(
    const char* filename, void* context) {
  // FALSE ends the search, indicating that the located symbol file is
  // satisfactory.
  return FALSE;
}

MSSymbolServerConverter::LocateResult
MSSymbolServerConverter::LocateAndConvertSymbolFile(
    const MissingSymbolInfo& missing,
    bool keep_symbol_file,
    bool keep_pe_file,
    string* converted_symbol_file,
    string* symbol_file,
    string* out_pe_file) {
  assert(converted_symbol_file);
  converted_symbol_file->clear();
  if (symbol_file) {
    symbol_file->clear();
  }

  string pdb_file;
  LocateResult result = LocateSymbolFile(missing, &pdb_file);
  if (result != LOCATE_SUCCESS) {
    fprintf(stderr, "Fallback to PE-only symbol generation for: %s\n",
        missing.debug_file.c_str());
    return LocateAndConvertPEFile(missing, keep_pe_file, converted_symbol_file,
        out_pe_file);
  }

  if (symbol_file && keep_symbol_file) {
    *symbol_file = pdb_file;
  }

  // The conversion of a symbol file for a Windows 64-bit module requires
  // loading of the executable file.  If there is no executable file, convert
  // using only the PDB file.  Without an executable file, the conversion will
  // fail for 64-bit modules but it should succeed for 32-bit modules.
  string pe_file;
  result = LocatePEFile(missing, &pe_file);
  if (result != LOCATE_SUCCESS) {
    fprintf(stderr, "WARNING: Could not download: %s\n", pe_file.c_str());
  }

  if (out_pe_file && keep_pe_file) {
    *out_pe_file = pe_file;
  }

  // Conversion may fail because the file is corrupt.  If a broken file is
  // kept in the local cache, LocateSymbolFile will not hit the network again
  // to attempt to locate it.  To guard against problems like this, the
  // symbol file in the local cache will be removed if conversion fails.
  AutoDeleter pdb_deleter(pdb_file);
  AutoDeleter pe_deleter(pe_file);

  // Be sure that it's a .pdb file, since we'll be replacing .pdb with .sym
  // for the converted file's name.
  string pdb_extension = pdb_file.substr(pdb_file.length() - 4);
  // strcasecmp is called _stricmp here.
  if (_stricmp(pdb_extension.c_str(), ".pdb") != 0) {
    fprintf(stderr, "LocateAndConvertSymbolFile: "
            "no .pdb extension for %s %s %s %s\n",
            missing.debug_file.c_str(),
            missing.debug_identifier.c_str(),
            missing.version.c_str(),
            pdb_file.c_str());
    return LOCATE_FAILURE;
  }

  PDBSourceLineWriter writer;
  wstring pe_file_w;
  if (!WindowsStringUtils::safe_mbstowcs(pe_file, &pe_file_w)) {
    fprintf(stderr,
            "LocateAndConvertSymbolFile: "
                "WindowsStringUtils::safe_mbstowcs failed for %s\n",
            pe_file.c_str());
    return LOCATE_FAILURE;
  }
  wstring pdb_file_w;
  if (!WindowsStringUtils::safe_mbstowcs(pdb_file, &pdb_file_w)) {
    fprintf(stderr,
            "LocateAndConvertSymbolFile: "
                "WindowsStringUtils::safe_mbstowcs failed for %ws\n",
            pdb_file_w.c_str());
    return LOCATE_FAILURE;
  }
  if (!writer.Open(pdb_file_w, PDBSourceLineWriter::PDB_FILE)) {
    fprintf(stderr,
            "ERROR: PDBSourceLineWriter::Open failed for %s %s %s %ws\n",
            missing.debug_file.c_str(), missing.debug_identifier.c_str(),
            missing.version.c_str(), pdb_file_w.c_str());
    return LOCATE_FAILURE;
  }
  if (!writer.SetCodeFile(pe_file_w)) {
    fprintf(stderr,
            "ERROR: PDBSourceLineWriter::SetCodeFile failed for %s %s %s %ws\n",
            missing.debug_file.c_str(), missing.debug_identifier.c_str(),
            missing.version.c_str(), pe_file_w.c_str());
    return LOCATE_FAILURE;
  }

  *converted_symbol_file = pdb_file.substr(0, pdb_file.length() - 4) + ".sym";

  FILE* converted_output = NULL;
#if _MSC_VER >= 1400  // MSVC 2005/8
  errno_t err;
  if ((err = fopen_s(&converted_output, converted_symbol_file->c_str(), "w"))
    != 0) {
#else  // _MSC_VER >= 1400
  // fopen_s and errno_t were introduced in MSVC8.  Use fopen for earlier
  // environments.  Don't use fopen with MSVC8 and later, because it's
  // deprecated.  fopen does not provide reliable error codes, so just use
  // -1 in the event of a failure.
  int err;
  if (!(converted_output = fopen(converted_symbol_file->c_str(), "w"))) {
    err = -1;
#endif  // _MSC_VER >= 1400
    fprintf(stderr, "LocateAndConvertSymbolFile: "
        "fopen_s: error %d for %s %s %s %s\n",
        err,
        missing.debug_file.c_str(),
        missing.debug_identifier.c_str(),
        missing.version.c_str(),
        converted_symbol_file->c_str());
    return LOCATE_FAILURE;
  }

  AutoDeleter sym_deleter(*converted_symbol_file);

  bool success = writer.WriteSymbols(converted_output);
  fclose(converted_output);

  if (!success) {
    fprintf(stderr, "LocateAndConvertSymbolFile: "
            "PDBSourceLineWriter::WriteMap failed for %s %s %s %s\n",
            missing.debug_file.c_str(),
            missing.debug_identifier.c_str(),
            missing.version.c_str(),
            pdb_file.c_str());
    return LOCATE_FAILURE;
  }

  if (keep_symbol_file) {
    pdb_deleter.Release();
  }

  if (keep_pe_file) {
    pe_deleter.Release();
  }

  sym_deleter.Release();

  return LOCATE_SUCCESS;
}

MSSymbolServerConverter::LocateResult
MSSymbolServerConverter::LocateAndConvertPEFile(
    const MissingSymbolInfo& missing,
    bool keep_pe_file,
    string* converted_symbol_file,
    string* out_pe_file) {
  assert(converted_symbol_file);
  converted_symbol_file->clear();

  string pe_file;
  MSSymbolServerConverter::LocateResult result = LocatePEFile(missing,
      &pe_file);
  if (result != LOCATE_SUCCESS) {
    fprintf(stderr, "WARNING: Could not download: %s\n", pe_file.c_str());
    return result;
  }

  if (out_pe_file && keep_pe_file) {
    *out_pe_file = pe_file;
  }

  // Conversion may fail because the file is corrupt.  If a broken file is
  // kept in the local cache, LocatePEFile will not hit the network again
  // to attempt to locate it.  To guard against problems like this, the
  // PE file in the local cache will be removed if conversion fails.
  AutoDeleter pe_deleter(pe_file);

  // Be sure that it's a .exe or .dll file, since we'll be replacing extension
  // with .sym for the converted file's name.
  string pe_extension = pe_file.substr(pe_file.length() - 4);
  // strcasecmp is called _stricmp here.
  if (_stricmp(pe_extension.c_str(), ".exe") != 0 &&
    _stricmp(pe_extension.c_str(), ".dll") != 0) {
    fprintf(stderr, "LocateAndConvertPEFile: "
        "no .dll/.exe extension for %s %s %s %s\n",
        missing.debug_file.c_str(),
        missing.debug_identifier.c_str(),
        missing.version.c_str(),
        pe_file.c_str());
    return LOCATE_FAILURE;
  }

  *converted_symbol_file = pe_file.substr(0, pe_file.length() - 4) + ".sym";

  FILE* converted_output = NULL;
#if _MSC_VER >= 1400  // MSVC 2005/8
  errno_t err;
  if ((err = fopen_s(&converted_output, converted_symbol_file->c_str(), "w"))
      != 0) {
#else  // _MSC_VER >= 1400
  // fopen_s and errno_t were introduced in MSVC8.  Use fopen for earlier
  // environments.  Don't use fopen with MSVC8 and later, because it's
  // deprecated.  fopen does not provide reliable error codes, so just use
  // -1 in the event of a failure.
  int err;
  if (!(converted_output = fopen(converted_symbol_file->c_str(), "w"))) {
    err = -1;
#endif  // _MSC_VER >= 1400
    fprintf(stderr, "LocateAndConvertPEFile: "
        "fopen_s: error %d for %s %s %s %s\n",
        err,
        missing.debug_file.c_str(),
        missing.debug_identifier.c_str(),
        missing.version.c_str(),
        converted_symbol_file->c_str());
    return LOCATE_FAILURE;
  }
  AutoDeleter sym_deleter(*converted_symbol_file);

  wstring pe_file_w;
  if (!WindowsStringUtils::safe_mbstowcs(pe_file, &pe_file_w)) {
    fprintf(stderr,
        "LocateAndConvertPEFile: "
        "WindowsStringUtils::safe_mbstowcs failed for %s\n",
        pe_file.c_str());
    return LOCATE_FAILURE;
  }
  PESourceLineWriter writer(pe_file_w);
  PDBModuleInfo module_info;
  if (!writer.GetModuleInfo(&module_info)) {
    fprintf(stderr, "LocateAndConvertPEFile: "
        "PESourceLineWriter::GetModuleInfo failed for %s %s %s %s\n",
        missing.debug_file.c_str(),
        missing.debug_identifier.c_str(),
        missing.version.c_str(),
        pe_file.c_str());
    return LOCATE_FAILURE;
  }
  if (module_info.cpu.compare(L"x86_64") != 0) {
    // This module is not x64 so we cannot generate Breakpad symbols from the
    // PE alone. Don't delete PE-- no need to retry download.
    pe_deleter.Release();
    return LOCATE_FAILURE;
  }

  bool success = writer.WriteSymbols(converted_output);
  fclose(converted_output);

  if (!success) {
    fprintf(stderr, "LocateAndConvertPEFile: "
        "PESourceLineWriter::WriteMap failed for %s %s %s %s\n",
        missing.debug_file.c_str(),
        missing.debug_identifier.c_str(),
        missing.version.c_str(),
        pe_file.c_str());
    return LOCATE_FAILURE;
  }

  if (keep_pe_file) {
    pe_deleter.Release();
  }

  sym_deleter.Release();

  return LOCATE_SUCCESS;
}

}  // namespace google_breakpad
