// 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.h: Obtain symbol files from a Microsoft
// symbol server, and convert them to Breakpad's dumped format.
//
// At runtime, MSSymbolServerConverter and code that it calls depend on being
// able to locate suitable versions of dbghelp.dll and symsrv.dll.  For best
// results, place these files in the same directory as the executable.
// dbghelp.dll and symsrv.dll as supplied with Debugging Tools for Windows are
// both redistributable, as indicated by the package's redist.txt file.
//
// When connecting to Microsoft's symbol server at
// http://msdl.microsoft.com/download/symbols/, which provides access to
// symbols for the operating system itself, symsrv.dll requires agreement to
// Microsoft's "Terms of Use for Microsoft Symbols and Binaries."  Because this
// library places the symbol engine into a promptless mode, the dialog with the
// terms will not appear, and use of Microsoft's symbol server will not be
// possible.  To indicate agreement to the terms, create a file called
// symsrv.yes in the same directory as symsrv.dll.  (Note that symsrv.dll will
// also recognize a symsrv.no file as indicating that you do not accept the
// terms; the .yes file takes priority over the .no file.)  The terms of use
// are contained within symsrv.dll; they were formerly available online at
// http://www.microsoft.com/whdc/devtools/debugging/symsrvTOU2.mspx , but
// do not appear to be available online any longer as of January, 2007.  It is
// possible to view the terms from within WinDbg (Debugging Tools for Windows)
// by removing any symsrv.yes and symsrv.no files from WinDbg's directory,
// setting the symbol path to include Microsoft's symbol server (.sympath), and
// attempting to load symbols from their server (.reload).
//
// This code has been tested with dbghelp.dll 6.5.3.7 and symsrv.dll 6.5.3.8,
// included with Microsoft Visual Studio 8 in Common7/IDE.  This has also been
// tested with dbghelp.dll and symsrv.dll versions 6.6.7.5 and 6.12.2.633,
// included with the same versions of Debugging Tools for Windows, available at
// http://www.microsoft.com/whdc/devtools/debugging/ .
//
// Author: Mark Mentovai

#ifndef TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
#define TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_

#include <windows.h>

#include <string>
#include <vector>

namespace google_breakpad {

using std::string;
using std::vector;

// MissingSymbolInfo contains the subset of the information in the processor's
// CodeModule structure relevant to obtaining a missing symbol file.  Only
// debug_file and debug_identifier are relevant in actually obtaining the
// missing file; the other fields are for convenience.
struct MissingSymbolInfo {
  string code_file;
  string code_identifier;
  string debug_file;
  string debug_identifier;
  string version;
};

class GUIDOrSignatureIdentifier {
 public:
  enum GUIDOrSignatureType {
    TYPE_NONE = 0,
    TYPE_GUID,
    TYPE_SIGNATURE
  };

  GUIDOrSignatureIdentifier() : type_(TYPE_NONE) {}

  // Converts |identifier|, a debug_identifier-formatted string, into its
  // component fields: either a GUID and age, or signature and age.  If
  // successful, sets the relevant fields in the object, including the type
  // field, and returns true.  On error, returns false.
  bool InitializeFromString(const string& identifier);

  GUIDOrSignatureType type() const { return type_; }
  GUID guid() const { return guid_; }
  DWORD signature() const { return signature_; }
  int age() const { return age_; }
  const void* guid_or_signature_pointer() const { return &guid_; }

 private:
  GUIDOrSignatureType type_;

  // An identifier contains either a 128-bit uuid or a 32-bit signature.
  union {
    GUID guid_;
    DWORD signature_;
  };

  // All identifiers used here have age fields, which indicate a specific
  // revision given a uuid or signature.
  int age_;
};

class MSSymbolServerConverter {
 public:
  enum LocateResult {
    LOCATE_FAILURE = 0,
    LOCATE_NOT_FOUND,    // Authoritative: the file is not present.
    LOCATE_RETRY,        // Transient (network?) error, try again later.
    LOCATE_SUCCESS
  };

  // Create a new object.  local_cache is the location (pathname) of a local
  // symbol store used to hold downloaded and converted symbol files.  This
  // directory will be created by LocateSymbolFile when it successfully
  // retrieves a symbol file. symbol_servers contains a list of locations (URLs
  // or pathnames) of the upstream symbol server stores, given in order of
  // preference, with the first string in the vector identifying the first
  // store to try.  The vector must contain at least one string.  None of the
  // strings passed to this constructor may contain asterisk ('*') or semicolon
  // (';') characters, as the symbol engine uses these characters as separators.
  MSSymbolServerConverter(const string& local_cache,
                          const vector<string>& symbol_servers);

  // Locates the PE file (DLL or EXE) specified by the identifying information
  // in |missing|, by checking the symbol stores identified when the object
  // was created.  When returning LOCATE_SUCCESS, pe_file is set to
  // the pathname of the decompressed PE file as it is stored in the
  // local cache.
  LocateResult LocatePEFile(const MissingSymbolInfo& missing, string* pe_file);

  // Locates the symbol file specified by the identifying information in
  // |missing|, by checking the symbol stores identified when the object
  // was created.  When returning LOCATE_SUCCESS, symbol_file is set to
  // the pathname of the decompressed symbol file as it is stored in the
  // local cache.
  LocateResult LocateSymbolFile(const MissingSymbolInfo& missing,
                                string* symbol_file);

  // Calls LocateSymbolFile and converts the returned symbol file to the
  // dumped-symbol format, storing it adjacent to the symbol file.  The
  // only conversion supported is from pdb files.  Returns the return
  // value of LocateSymbolFile, or if LocateSymbolFile succeeds but
  // conversion fails, returns LOCATE_FAILURE.  The pathname to the
  // pdb file and to the converted symbol file are returned in
  // |converted_symbol_file|, |symbol_file|, and |pe_file|.  |symbol_file| and
  // |pe_file| are optional and may be NULL.  If only the converted symbol file
  // is desired, set |keep_symbol_file| and |keep_pe_file| to false to indicate
  // that the original symbol file (pdb) and executable file (exe, dll) should
  // be deleted after conversion.
  LocateResult LocateAndConvertSymbolFile(const MissingSymbolInfo& missing,
                                          bool keep_symbol_file,
                                          bool keep_pe_file,
                                          string* converted_symbol_file,
                                          string* symbol_file,
                                          string* pe_file);

  // Calls LocatePEFile and converts the returned PE file to the
  // dumped-symbol format, storing it adjacent to the PE file. The
  // only conversion supported is from PE files. Returns the return
  // value of LocatePEFile, or if LocatePEFile succeeds but
  // conversion fails, returns LOCATE_FAILURE. The pathname to the
  // PE file and to the converted symbol file are returned in
  // |converted_symbol_file| and |pe_file|. |pe_file| is optional and may be
  // NULL.  If only the converted symbol file is desired, set |keep_pe_file|
  // to false to indicate that the executable file (exe, dll) should be deleted
  // after conversion.
  // NOTE: Currrently only supports x64 PEs.
  LocateResult LocateAndConvertPEFile(const MissingSymbolInfo& missing,
                                      bool keep_pe_file,
                                      string* converted_symbol_file,
                                      string* pe_file);

 private:
  // Locates the PDB or PE file (DLL or EXE) specified by the identifying
  // information in |debug_or_code_file| and |debug_or_code_id|, by checking
  // the symbol stores identified when the object was created.  When
  // returning LOCATE_SUCCESS, file_name is set to the pathname of the
  // decompressed PDB or PE file file as it is stored in the local cache.
  LocateResult LocateFile(const string& debug_or_code_file,
                          const string& debug_or_code_id,
                          const string& version, string* file_name);

  // Called by various SymSrv functions to report status as progress is made
  // and to allow the callback to influence processing.  Messages sent to this
  // callback can be used to distinguish between the various failure modes
  // that SymFindFileInPath might encounter.
  static BOOL CALLBACK SymCallback(HANDLE process, ULONG action, ULONG64 data,
                                   ULONG64 context);

  // Called by SymFindFileInPath (in LocateSymbolFile) after a candidate
  // symbol file is located, when it's present in the local cache.
  // SymFindFileInPath actually seems to accept NULL for a callback function
  // and behave properly for our needs in that case, but the documentation
  // doesn't mention it, so this little callback is provided.
  static BOOL CALLBACK SymFindFileInPathCallback(const char* filename,
                                                 void* context);

  // The search path used by SymSrv, built based on the arguments to the
  // constructor.
  string symbol_path_;

  // SymCallback will set at least one of these failure variables if
  // SymFindFileInPath fails for an expected reason.
  bool fail_dns_;        // DNS failures (fail_not_found_ will also be set).
  bool fail_timeout_;    // Timeouts (fail_not_found_ will also be set).
  bool fail_not_found_;  // The file could not be found.  If this is the only
                         // fail_* member set, then it is authoritative.
};

}  // namespace google_breakpad

#endif  // TOOLS_WINDOWS_MS_SYMBOL_SERVER_CONVERTER_H_
