// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Tools.CrashReporter.CrashReportCommon
{
///
/// A class to return the result of the CheckReport web request.
///
public class CrashReporterResult
{
/// A bool representing success or failure of the CheckReport web request.
[XmlAttribute]
public bool bSuccess = false;
/// An optional integer value typically representing a unique ID.
[XmlAttribute]
public int ID = 0;
/// A optional message to explain any return values.
[XmlAttribute]
public string Message = "";
/// A bool representing if a failure was caused by a database timeout.
[XmlAttribute]
public bool bTimeout = false;
}
///
/// A class to send to the web service to check to see if the report has already been uploaded.
///
public class CheckReportRequest
{
/// A unique ID, actually the directory name of the WER.
[XmlAttribute]
public string ReportId = "";
/// LEGACY SUPPORT for crashes reported from clients before CrashReportUploader had been rebuilt
[XmlAttribute]
public string DirectoryName = "";
/// A simple default constructor to allow Xml serialisation.
public CheckReportRequest()
{
}
}
///
/// A class to send to the CrashReport website to add a new crash to the database.
///
public class CrashDescription
{
/// The type of the crash e.g. crash, assert or ensure.
[XmlElement]
public string CrashType = "";
/// The name of the branch this game was built out of.
[XmlElement]
public string BranchName = "";
/// The name of the game that crashed.
[XmlElement]
public string GameName = "";
/// The platform that crashed e.g. Win64.
[XmlElement]
public string Platform = "";
/// The mode the game was in e.g. editor.
[XmlElement]
public string EngineMode = "";
/// Extended mode info (Vanilla, Dirty, Unset).
[XmlElement]
public string EngineModeEx = "";
/// The four component version of the app e.g. 4.4.1.0
[XmlElement]
public string EngineVersion = "";
/// The four component version of the app e.g. 4.4.1.0
[XmlElement]
public string BuildVersion = "";
/// Changelist number.
[XmlElement]
public int BuiltFromCL = 0;
/// The command line of the application that crashed.
[XmlElement]
public string CommandLine = "";
/// The base directory where the app was running.
[XmlElement]
public string BaseDir = "";
/// The language code the app was running in e.g. 1033.
[XmlElement]
public string Language = "";
/// The language code of the system.
[XmlElement]
public string SystemLanguage = "";
///
/// The name of the user that caused this crash.
/// @UserName varchar(64)
///
[XmlElement]
public string UserName = "";
///
/// The GUID of the machine the crash occurred on.
/// @ComputerName varchar(64)
///
[XmlElement]
public string MachineGuid = "";
///
/// The Epic account ID for the user who last used the Launcher.
/// @EpicAccountId varchar(64)
///
[XmlElement]
public string EpicAccountId = "";
/// An array of strings representing the callstack of the crash.
[XmlElement]
public string[] CallStack = null;
/// An array of strings showing the source code around the crash.
[XmlElement]
public string[] SourceContext = null;
/// An array of strings representing the user description of the crash.
[XmlElement]
public string[] UserDescription = null;
/// A string representing the user activity hint text from the application.
[XmlElement]
public string UserActivityHint = "";
/// The error message, can be assertion message, ensure message or message from the fatal error.
[XmlElement]
public string[] ErrorMessage = null;
/// Crash GUID from the crash context.
[XmlElement]
public string CrashGUID = "";
/// The UTC time the crash occurred.
[XmlElement]
public DateTime TimeofCrash;
/// Whether this crash has a minidump.
[XmlElement]
public bool bHasMiniDump = false;
/// Whether this crash has a log file.
[XmlElement]
public bool bHasLog = false;
/// Obsolete.
[XmlElement]
public bool bHasDiags = false;
/// Obsolete.
[XmlElement]
public bool bHasWERData = false;
/// Whether this crash has a video.
[XmlElement]
public bool bHasVideo = false;
/// Whether the user allowed us to be contacted.
[XmlElement]
public bool bAllowToBeContacted = false;
/// Whether the processor generated an error while generating this crash report
[XmlElement]
public bool bProcessorFailed = false;
/// A simple default constructor to allow Xml serialization.
public CrashDescription()
{
}
}
/// Details about received compressed crash.
public class FCompressedCrashInformation
{
/// Size of the compressed data.
public string CompressedSize = "";
/// Size of the data after decompression.
public string UncompressedSize = "";
/// Number of files stored in the compressed data.
public string NumberOfFiles = "";
/// A simple default constructor to allow Xml serialization.
public FCompressedCrashInformation()
{}
/// Initialization constructor.
public FCompressedCrashInformation( string InCompressedSize, string InUncompressedSize, string InNumberOfFiles )
{
CompressedSize = InCompressedSize;
UncompressedSize = InUncompressedSize;
NumberOfFiles = InNumberOfFiles;
}
/// CompressedSize as int.
public int GetCompressedSize()
{
int Result = 0;
int.TryParse( CompressedSize, out Result );
return Result;
}
/// UncompressedSize as int.
public int GetUncompressedSize()
{
int Result = 0;
int.TryParse( UncompressedSize, out Result );
return Result;
}
/// NumberOfFiles as int.
public int GetNumberOfFiles()
{
int Result = 0;
int.TryParse( NumberOfFiles, out Result );
return Result;
}
}
/// Helper class for reading binary data.
public class FBinaryReaderHelper
{
/// Reads FString serialized with SerializeAsANSICharArray.
public static string ReadFixedSizeString( BinaryReader BinaryStream )
{
uint Length = BinaryStream.ReadUInt32();
string Result = new string( BinaryStream.ReadChars( (int)Length ) );
Result = FixFixedSizeString( Result );
return Result;
}
static String FixFixedSizeString( string String )
{
int RealLength = 0;
while( String[RealLength++] != '\0' )
{
}
string Result = String.Remove( RealLength - 1 );
return Result;
}
}
///
/// Base class for Crash Reporter system exceptions
///
[Serializable]
public class CrashReporterException : Exception
{
///
/// Default constructor
///
public CrashReporterException() {}
///
/// Construct from an error message
///
/// The error message
public CrashReporterException(string message)
: base(message) {}
///
/// Construct from an error message and inner exception
///
/// The error message
/// Inner exception
public CrashReporterException(string message, Exception inner)
: base(message, inner) {}
///
/// Protected constructor for serialization
///
/// Serialization info
/// Streaming context
protected CrashReporterException(SerializationInfo info, StreamingContext context)
: base(info, context) {}
}
///
/// Helper class for checking the available space on a storage medium
///
public static class StorageSpaceHelper
{
///
/// Attempts to extract the drive letter including colon and first slash from a file or folder path. Will not throw exceptions on
/// malformed or illegal paths. Does not currently support UNC paths.
///
/// A folder or file path that starts with a regular drive letter
/// (out) If the path starts with a valid drive letter, contains the drive letter, colon and first slash.
/// True if the drive letter was return successfully, false if the method fails for any reason.
public static bool TryGetDriveLetter(string InPath, out string OutDriveLetter)
{
try
{
OutDriveLetter = Path.GetPathRoot(InPath);
return !string.IsNullOrWhiteSpace(OutDriveLetter);
}
catch (Exception)
{
OutDriveLetter = String.Empty;
return false;
}
}
///
/// This will work for regular drives with letters. Network shares require Win32 calls
///
/// Filepath (must be in a regular drive with a letter in this version)
/// (out) The number of bytes free
/// (out) The percentage of free space
/// True if the number of free bytes is retrieved successfully, otherwise false if an error occurs.
public static bool TryGetSpaceAvailable(string InPath, out Int64 OutSpaceAvailable, out float OutPercentAvailable)
{
string PathRoot;
if (TryGetDriveLetter(InPath, out PathRoot))
{
try
{
DriveInfo Info = new DriveInfo(PathRoot);
OutSpaceAvailable = Info.AvailableFreeSpace;
OutPercentAvailable = 100.0f*OutSpaceAvailable/Info.TotalSize;
return true;
}
catch (Exception)
{
// eat exceptions
}
}
// TODO: fallback on p/invoking platform-specific disk space APIs?
OutSpaceAvailable = 0;
OutPercentAvailable = 0.0f;
return false;
}
}
}