// 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
