summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/client
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/client')
-rw-r--r--toolkit/crashreporter/client/Makefile.in20
-rw-r--r--toolkit/crashreporter/client/Throbber-small.avibin3584 -> 0 bytes
-rw-r--r--toolkit/crashreporter/client/crashreporter.cpp759
-rw-r--r--toolkit/crashreporter/client/crashreporter.exe.manifest37
-rw-r--r--toolkit/crashreporter/client/crashreporter.h158
-rw-r--r--toolkit/crashreporter/client/crashreporter.icobin25214 -> 0 bytes
-rwxr-xr-xtoolkit/crashreporter/client/crashreporter.rc148
-rw-r--r--toolkit/crashreporter/client/crashreporter_gtk_common.cpp453
-rw-r--r--toolkit/crashreporter/client/crashreporter_gtk_common.h50
-rw-r--r--toolkit/crashreporter/client/crashreporter_linux.cpp576
-rw-r--r--toolkit/crashreporter/client/crashreporter_osx.h107
-rw-r--r--toolkit/crashreporter/client/crashreporter_osx.mm922
-rw-r--r--toolkit/crashreporter/client/crashreporter_unix_common.cpp85
-rw-r--r--toolkit/crashreporter/client/crashreporter_win.cpp1568
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Info.plist32
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/PkgInfo2
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in8
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib102
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib18
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nibbin25518 -> 0 bytes
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/classes.nib102
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/info.nib18
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/keyedobjects.nibbin27032 -> 0 bytes
-rw-r--r--toolkit/crashreporter/client/macbuild/Contents/Resources/crashreporter.icnsbin61743 -> 0 bytes
-rw-r--r--toolkit/crashreporter/client/moz.build78
-rw-r--r--toolkit/crashreporter/client/resource.h37
26 files changed, 0 insertions, 5280 deletions
diff --git a/toolkit/crashreporter/client/Makefile.in b/toolkit/crashreporter/client/Makefile.in
deleted file mode 100644
index 88be52dff..000000000
--- a/toolkit/crashreporter/client/Makefile.in
+++ /dev/null
@@ -1,20 +0,0 @@
-# vim:set ts=8 sw=8 sts=8 noet:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-ifeq ($(OS_ARCH),WINNT)
-MOZ_WINCONSOLE = 0
-endif
-
-include $(topsrcdir)/config/rules.mk
-
-ifeq ($(OS_ARCH),Darwin)
-libs::
- $(NSINSTALL) -D $(DIST)/bin/crashreporter.app
- rsync -a -C --exclude '*.in' $(srcdir)/macbuild/Contents $(DIST)/bin/crashreporter.app
- sed -e 's/%APP_NAME%/$(MOZ_APP_DISPLAYNAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | \
- iconv -f UTF-8 -t UTF-16 > $(DIST)/bin/crashreporter.app/Contents/Resources/English.lproj/InfoPlist.strings
- $(NSINSTALL) -D $(DIST)/bin/crashreporter.app/Contents/MacOS
- $(NSINSTALL) $(DIST)/bin/crashreporter $(DIST)/bin/crashreporter.app/Contents/MacOS
-endif
diff --git a/toolkit/crashreporter/client/Throbber-small.avi b/toolkit/crashreporter/client/Throbber-small.avi
deleted file mode 100644
index 640ea62c0..000000000
--- a/toolkit/crashreporter/client/Throbber-small.avi
+++ /dev/null
Binary files differ
diff --git a/toolkit/crashreporter/client/crashreporter.cpp b/toolkit/crashreporter/client/crashreporter.cpp
deleted file mode 100644
index 10aa65dd2..000000000
--- a/toolkit/crashreporter/client/crashreporter.cpp
+++ /dev/null
@@ -1,759 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "crashreporter.h"
-
-#ifdef _MSC_VER
-// Disable exception handler warnings.
-# pragma warning( disable : 4530 )
-#endif
-
-#include <fstream>
-#include <sstream>
-#include <memory>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-
-using std::string;
-using std::istream;
-using std::ifstream;
-using std::istringstream;
-using std::ostringstream;
-using std::ostream;
-using std::ofstream;
-using std::vector;
-using std::auto_ptr;
-
-namespace CrashReporter {
-
-StringTable gStrings;
-string gSettingsPath;
-string gEventsPath;
-int gArgc;
-char** gArgv;
-
-enum SubmissionResult {Succeeded, Failed};
-
-static auto_ptr<ofstream> gLogStream(nullptr);
-static string gReporterDumpFile;
-static string gExtraFile;
-static string gMemoryFile;
-
-static const char kExtraDataExtension[] = ".extra";
-static const char kMemoryReportExtension[] = ".memory.json.gz";
-
-void UIError(const string& message)
-{
- string errorMessage;
- if (!gStrings[ST_CRASHREPORTERERROR].empty()) {
- char buf[2048];
- UI_SNPRINTF(buf, 2048,
- gStrings[ST_CRASHREPORTERERROR].c_str(),
- message.c_str());
- errorMessage = buf;
- } else {
- errorMessage = message;
- }
-
- UIError_impl(errorMessage);
-}
-
-static string Unescape(const string& str)
-{
- string ret;
- for (string::const_iterator iter = str.begin();
- iter != str.end();
- iter++) {
- if (*iter == '\\') {
- iter++;
- if (*iter == '\\'){
- ret.push_back('\\');
- } else if (*iter == 'n') {
- ret.push_back('\n');
- } else if (*iter == 't') {
- ret.push_back('\t');
- }
- } else {
- ret.push_back(*iter);
- }
- }
-
- return ret;
-}
-
-static string Escape(const string& str)
-{
- string ret;
- for (string::const_iterator iter = str.begin();
- iter != str.end();
- iter++) {
- if (*iter == '\\') {
- ret += "\\\\";
- } else if (*iter == '\n') {
- ret += "\\n";
- } else if (*iter == '\t') {
- ret += "\\t";
- } else {
- ret.push_back(*iter);
- }
- }
-
- return ret;
-}
-
-bool ReadStrings(istream& in, StringTable& strings, bool unescape)
-{
- string currentSection;
- while (!in.eof()) {
- string line;
- std::getline(in, line);
- int sep = line.find('=');
- if (sep >= 0) {
- string key, value;
- key = line.substr(0, sep);
- value = line.substr(sep + 1);
- if (unescape)
- value = Unescape(value);
- strings[key] = value;
- }
- }
-
- return true;
-}
-
-bool ReadStringsFromFile(const string& path,
- StringTable& strings,
- bool unescape)
-{
- ifstream* f = UIOpenRead(path);
- bool success = false;
- if (f->is_open()) {
- success = ReadStrings(*f, strings, unescape);
- f->close();
- }
-
- delete f;
- return success;
-}
-
-bool WriteStrings(ostream& out,
- const string& header,
- StringTable& strings,
- bool escape)
-{
- out << "[" << header << "]" << std::endl;
- for (StringTable::iterator iter = strings.begin();
- iter != strings.end();
- iter++) {
- out << iter->first << "=";
- if (escape)
- out << Escape(iter->second);
- else
- out << iter->second;
-
- out << std::endl;
- }
-
- return true;
-}
-
-bool WriteStringsToFile(const string& path,
- const string& header,
- StringTable& strings,
- bool escape)
-{
- ofstream* f = UIOpenWrite(path.c_str());
- bool success = false;
- if (f->is_open()) {
- success = WriteStrings(*f, header, strings, escape);
- f->close();
- }
-
- delete f;
- return success;
-}
-
-static string Basename(const string& file)
-{
- string::size_type slashIndex = file.rfind(UI_DIR_SEPARATOR);
- if (slashIndex != string::npos)
- return file.substr(slashIndex + 1);
- else
- return file;
-}
-
-static string GetDumpLocalID()
-{
- string localId = Basename(gReporterDumpFile);
- string::size_type dot = localId.rfind('.');
-
- if (dot == string::npos)
- return "";
-
- return localId.substr(0, dot);
-}
-
-// This appends the StackTraces entry generated by the minidump analyzer to the
-// main crash event so that it can be picked up by Firefox once it restarts
-static void AppendStackTracesToEventFile(const string& aStackTraces)
-{
- if (gEventsPath.empty()) {
- // If there is no path for finding the crash event, skip this step.
- return;
- }
-
- string localId = GetDumpLocalID();
- string path = gEventsPath + UI_DIR_SEPARATOR + localId;
- ofstream* f = UIOpenWrite(path.c_str(), true);
-
- if (f->is_open()) {
- *f << "StackTraces=" << aStackTraces;
- f->close();
- }
-
- delete f;
-}
-
-static void WriteSubmissionEvent(SubmissionResult result,
- const string& remoteId)
-{
- if (gEventsPath.empty()) {
- // If there is no path for writing the submission event, skip it.
- return;
- }
-
- string localId = GetDumpLocalID();
- string fpath = gEventsPath + UI_DIR_SEPARATOR + localId + "-submission";
- ofstream* f = UIOpenWrite(fpath.c_str(), false, true);
- time_t tm;
- time(&tm);
-
- if (f->is_open()) {
- *f << "crash.submission.1\n";
- *f << tm << "\n";
- *f << localId << "\n";
- *f << (result == Succeeded ? "true" : "false") << "\n";
- *f << remoteId;
-
- f->close();
- }
-
- delete f;
-}
-
-void LogMessage(const std::string& message)
-{
- if (gLogStream.get()) {
- char date[64];
- time_t tm;
- time(&tm);
- if (strftime(date, sizeof(date) - 1, "%c", localtime(&tm)) == 0)
- date[0] = '\0';
- (*gLogStream) << "[" << date << "] " << message << std::endl;
- }
-}
-
-static void OpenLogFile()
-{
- string logPath = gSettingsPath + UI_DIR_SEPARATOR + "submit.log";
- gLogStream.reset(UIOpenWrite(logPath.c_str(), true));
-}
-
-static bool ReadConfig()
-{
- string iniPath;
- if (!UIGetIniPath(iniPath))
- return false;
-
- if (!ReadStringsFromFile(iniPath, gStrings, true))
- return false;
-
- // See if we have a string override file, if so process it
- char* overrideEnv = getenv("MOZ_CRASHREPORTER_STRINGS_OVERRIDE");
- if (overrideEnv && *overrideEnv && UIFileExists(overrideEnv))
- ReadStringsFromFile(overrideEnv, gStrings, true);
-
- return true;
-}
-
-static string
-GetAdditionalFilename(const string& dumpfile, const char* extension)
-{
- string filename(dumpfile);
- int dot = filename.rfind('.');
- if (dot < 0)
- return "";
-
- filename.replace(dot, filename.length() - dot, extension);
- return filename;
-}
-
-static bool MoveCrashData(const string& toDir,
- string& dumpfile,
- string& extrafile,
- string& memoryfile)
-{
- if (!UIEnsurePathExists(toDir)) {
- UIError(gStrings[ST_ERROR_CREATEDUMPDIR]);
- return false;
- }
-
- string newDump = toDir + UI_DIR_SEPARATOR + Basename(dumpfile);
- string newExtra = toDir + UI_DIR_SEPARATOR + Basename(extrafile);
- string newMemory = toDir + UI_DIR_SEPARATOR + Basename(memoryfile);
-
- if (!UIMoveFile(dumpfile, newDump)) {
- UIError(gStrings[ST_ERROR_DUMPFILEMOVE]);
- return false;
- }
-
- if (!UIMoveFile(extrafile, newExtra)) {
- UIError(gStrings[ST_ERROR_EXTRAFILEMOVE]);
- return false;
- }
-
- if (!memoryfile.empty()) {
- // Ignore errors from moving the memory file
- if (!UIMoveFile(memoryfile, newMemory)) {
- UIDeleteFile(memoryfile);
- newMemory.erase();
- }
- memoryfile = newMemory;
- }
-
- dumpfile = newDump;
- extrafile = newExtra;
-
- return true;
-}
-
-static bool AddSubmittedReport(const string& serverResponse)
-{
- StringTable responseItems;
- istringstream in(serverResponse);
- ReadStrings(in, responseItems, false);
-
- if (responseItems.find("StopSendingReportsFor") != responseItems.end()) {
- // server wants to tell us to stop sending reports for a certain version
- string reportPath =
- gSettingsPath + UI_DIR_SEPARATOR + "EndOfLife" +
- responseItems["StopSendingReportsFor"];
-
- ofstream* reportFile = UIOpenWrite(reportPath);
- if (reportFile->is_open()) {
- // don't really care about the contents
- *reportFile << 1 << "\n";
- reportFile->close();
- }
- delete reportFile;
- }
-
- if (responseItems.find("Discarded") != responseItems.end()) {
- // server discarded this report... save it so the user can resubmit it
- // manually
- return false;
- }
-
- if (responseItems.find("CrashID") == responseItems.end())
- return false;
-
- string submittedDir =
- gSettingsPath + UI_DIR_SEPARATOR + "submitted";
- if (!UIEnsurePathExists(submittedDir)) {
- return false;
- }
-
- string path = submittedDir + UI_DIR_SEPARATOR +
- responseItems["CrashID"] + ".txt";
-
- ofstream* file = UIOpenWrite(path);
- if (!file->is_open()) {
- delete file;
- return false;
- }
-
- char buf[1024];
- UI_SNPRINTF(buf, 1024,
- gStrings["CrashID"].c_str(),
- responseItems["CrashID"].c_str());
- *file << buf << "\n";
-
- if (responseItems.find("ViewURL") != responseItems.end()) {
- UI_SNPRINTF(buf, 1024,
- gStrings["CrashDetailsURL"].c_str(),
- responseItems["ViewURL"].c_str());
- *file << buf << "\n";
- }
-
- file->close();
- delete file;
-
- WriteSubmissionEvent(Succeeded, responseItems["CrashID"]);
- return true;
-}
-
-void DeleteDump()
-{
- const char* noDelete = getenv("MOZ_CRASHREPORTER_NO_DELETE_DUMP");
- if (!noDelete || *noDelete == '\0') {
- if (!gReporterDumpFile.empty())
- UIDeleteFile(gReporterDumpFile);
- if (!gExtraFile.empty())
- UIDeleteFile(gExtraFile);
- if (!gMemoryFile.empty())
- UIDeleteFile(gMemoryFile);
- }
-}
-
-void SendCompleted(bool success, const string& serverResponse)
-{
- if (success) {
- if (AddSubmittedReport(serverResponse)) {
- DeleteDump();
- }
- else {
- string directory = gReporterDumpFile;
- int slashpos = directory.find_last_of("/\\");
- if (slashpos < 2)
- return;
- directory.resize(slashpos);
- UIPruneSavedDumps(directory);
- WriteSubmissionEvent(Failed, "");
- }
- } else {
- WriteSubmissionEvent(Failed, "");
- }
-}
-
-bool ShouldEnableSending()
-{
- srand(time(0));
- return ((rand() % 100) < MOZ_CRASHREPORTER_ENABLE_PERCENT);
-}
-
-} // namespace CrashReporter
-
-using namespace CrashReporter;
-
-void RewriteStrings(StringTable& queryParameters)
-{
- // rewrite some UI strings with the values from the query parameters
- string product = queryParameters["ProductName"];
- string vendor = queryParameters["Vendor"];
- if (vendor.empty()) {
- // Assume Mozilla if no vendor is specified
- vendor = "Mozilla";
- }
-
- char buf[4096];
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_CRASHREPORTERVENDORTITLE].c_str(),
- vendor.c_str());
- gStrings[ST_CRASHREPORTERTITLE] = buf;
-
-
- string str = gStrings[ST_CRASHREPORTERPRODUCTERROR];
- // Only do the replacement here if the string has two
- // format specifiers to start. Otherwise
- // we assume it has the product name hardcoded.
- string::size_type pos = str.find("%s");
- if (pos != string::npos)
- pos = str.find("%s", pos+2);
- if (pos != string::npos) {
- // Leave a format specifier for UIError to fill in
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_CRASHREPORTERPRODUCTERROR].c_str(),
- product.c_str(),
- "%s");
- gStrings[ST_CRASHREPORTERERROR] = buf;
- }
- else {
- // product name is hardcoded
- gStrings[ST_CRASHREPORTERERROR] = str;
- }
-
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_CRASHREPORTERDESCRIPTION].c_str(),
- product.c_str());
- gStrings[ST_CRASHREPORTERDESCRIPTION] = buf;
-
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_CHECKSUBMIT].c_str(),
- vendor.c_str());
- gStrings[ST_CHECKSUBMIT] = buf;
-
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_CHECKEMAIL].c_str(),
- vendor.c_str());
- gStrings[ST_CHECKEMAIL] = buf;
-
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_RESTART].c_str(),
- product.c_str());
- gStrings[ST_RESTART] = buf;
-
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_QUIT].c_str(),
- product.c_str());
- gStrings[ST_QUIT] = buf;
-
- UI_SNPRINTF(buf, sizeof(buf),
- gStrings[ST_ERROR_ENDOFLIFE].c_str(),
- product.c_str());
- gStrings[ST_ERROR_ENDOFLIFE] = buf;
-}
-
-bool CheckEndOfLifed(string version)
-{
- string reportPath =
- gSettingsPath + UI_DIR_SEPARATOR + "EndOfLife" + version;
- return UIFileExists(reportPath);
-}
-
-#ifndef RELEASE_OR_BETA
-
-static string
-GetMinidumpAnalyzerPath()
-{
- string path = gArgv[0];
- size_t pos = path.rfind(UI_CRASH_REPORTER_FILENAME BIN_SUFFIX);
- path.erase(pos);
- path.append(UI_MINIDUMP_ANALYZER_FILENAME BIN_SUFFIX);
-
- return path;
-}
-
-#endif
-
-int main(int argc, char** argv)
-{
- gArgc = argc;
- gArgv = argv;
-
- if (!ReadConfig()) {
- UIError("Couldn't read configuration.");
- return 0;
- }
-
- if (!UIInit())
- return 0;
-
- if (argc > 1) {
- gReporterDumpFile = argv[1];
- }
-
- if (gReporterDumpFile.empty()) {
- // no dump file specified, run the default UI
- UIShowDefaultUI();
- } else {
-#ifndef RELEASE_OR_BETA
- // start by running minidump analyzer, this is currently enabled only in
- // nightly and aurora
- UIRunMinidumpAnalyzer(GetMinidumpAnalyzerPath(), gReporterDumpFile);
-#endif
-
- // go ahead with the crash reporter
- gExtraFile = GetAdditionalFilename(gReporterDumpFile, kExtraDataExtension);
- if (gExtraFile.empty()) {
- UIError(gStrings[ST_ERROR_BADARGUMENTS]);
- return 0;
- }
-
- if (!UIFileExists(gExtraFile)) {
- UIError(gStrings[ST_ERROR_EXTRAFILEEXISTS]);
- return 0;
- }
-
- gMemoryFile = GetAdditionalFilename(gReporterDumpFile,
- kMemoryReportExtension);
- if (!UIFileExists(gMemoryFile)) {
- gMemoryFile.erase();
- }
-
- StringTable queryParameters;
- if (!ReadStringsFromFile(gExtraFile, queryParameters, true)) {
- UIError(gStrings[ST_ERROR_EXTRAFILEREAD]);
- return 0;
- }
-
- if (queryParameters.find("ProductName") == queryParameters.end()) {
- UIError(gStrings[ST_ERROR_NOPRODUCTNAME]);
- return 0;
- }
-
- // There is enough information in the extra file to rewrite strings
- // to be product specific
- RewriteStrings(queryParameters);
-
- if (queryParameters.find("ServerURL") == queryParameters.end()) {
- UIError(gStrings[ST_ERROR_NOSERVERURL]);
- return 0;
- }
-
- // Hopefully the settings path exists in the environment. Try that before
- // asking the platform-specific code to guess.
-#ifdef XP_WIN32
- static const wchar_t kDataDirKey[] = L"MOZ_CRASHREPORTER_DATA_DIRECTORY";
- const wchar_t *settingsPath = _wgetenv(kDataDirKey);
- if (settingsPath && *settingsPath) {
- gSettingsPath = WideToUTF8(settingsPath);
- }
-#else
- static const char kDataDirKey[] = "MOZ_CRASHREPORTER_DATA_DIRECTORY";
- const char *settingsPath = getenv(kDataDirKey);
- if (settingsPath && *settingsPath) {
- gSettingsPath = settingsPath;
- }
-#endif
- else {
- string product = queryParameters["ProductName"];
- string vendor = queryParameters["Vendor"];
- if (!UIGetSettingsPath(vendor, product, gSettingsPath)) {
- gSettingsPath.clear();
- }
- }
-
- if (gSettingsPath.empty() || !UIEnsurePathExists(gSettingsPath)) {
- UIError(gStrings[ST_ERROR_NOSETTINGSPATH]);
- return 0;
- }
-
- OpenLogFile();
-
-#ifdef XP_WIN32
- static const wchar_t kEventsDirKey[] = L"MOZ_CRASHREPORTER_EVENTS_DIRECTORY";
- const wchar_t *eventsPath = _wgetenv(kEventsDirKey);
- if (eventsPath && *eventsPath) {
- gEventsPath = WideToUTF8(eventsPath);
- }
-#else
- static const char kEventsDirKey[] = "MOZ_CRASHREPORTER_EVENTS_DIRECTORY";
- const char *eventsPath = getenv(kEventsDirKey);
- if (eventsPath && *eventsPath) {
- gEventsPath = eventsPath;
- }
-#endif
- else {
- gEventsPath.clear();
- }
-
- // Update the crash event with stacks if they are present
- auto stackTracesItr = queryParameters.find("StackTraces");
- if (stackTracesItr != queryParameters.end()) {
- AppendStackTracesToEventFile(stackTracesItr->second);
- }
-
- if (!UIFileExists(gReporterDumpFile)) {
- UIError(gStrings[ST_ERROR_DUMPFILEEXISTS]);
- return 0;
- }
-
- string pendingDir = gSettingsPath + UI_DIR_SEPARATOR + "pending";
- if (!MoveCrashData(pendingDir, gReporterDumpFile, gExtraFile,
- gMemoryFile)) {
- return 0;
- }
-
- string sendURL = queryParameters["ServerURL"];
- // we don't need to actually send this
- queryParameters.erase("ServerURL");
-
- queryParameters["Throttleable"] = "1";
-
- // re-set XUL_APP_FILE for xulrunner wrapped apps
- const char *appfile = getenv("MOZ_CRASHREPORTER_RESTART_XUL_APP_FILE");
- if (appfile && *appfile) {
- const char prefix[] = "XUL_APP_FILE=";
- char *env = (char*) malloc(strlen(appfile) + strlen(prefix) + 1);
- if (!env) {
- UIError("Out of memory");
- return 0;
- }
- strcpy(env, prefix);
- strcat(env, appfile);
- putenv(env);
- free(env);
- }
-
- vector<string> restartArgs;
-
- ostringstream paramName;
- int i = 0;
- paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++;
- const char *param = getenv(paramName.str().c_str());
- while (param && *param) {
- restartArgs.push_back(param);
-
- paramName.str("");
- paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++;
- param = getenv(paramName.str().c_str());
- }
-
- // allow override of the server url via environment variable
- //XXX: remove this in the far future when our robot
- // masters force everyone to use XULRunner
- char* urlEnv = getenv("MOZ_CRASHREPORTER_URL");
- if (urlEnv && *urlEnv) {
- sendURL = urlEnv;
- }
-
- // see if this version has been end-of-lifed
- if (queryParameters.find("Version") != queryParameters.end() &&
- CheckEndOfLifed(queryParameters["Version"])) {
- UIError(gStrings[ST_ERROR_ENDOFLIFE]);
- DeleteDump();
- return 0;
- }
-
- StringTable files;
- files["upload_file_minidump"] = gReporterDumpFile;
- if (!gMemoryFile.empty()) {
- files["memory_report"] = gMemoryFile;
- }
-
- if (!UIShowCrashUI(files, queryParameters, sendURL, restartArgs))
- DeleteDump();
- }
-
- UIShutdown();
-
- return 0;
-}
-
-#if defined(XP_WIN) && !defined(__GNUC__)
-#include <windows.h>
-
-// We need WinMain in order to not be a console app. This function is unused
-// if we are a console application.
-int WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR args, int )
-{
- // Remove everything except close window from the context menu
- {
- HKEY hkApp;
- RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Classes\\Applications", 0,
- nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, nullptr,
- &hkApp, nullptr);
- RegCloseKey(hkApp);
- if (RegCreateKeyExW(HKEY_CURRENT_USER,
- L"Software\\Classes\\Applications\\crashreporter.exe",
- 0, nullptr, REG_OPTION_VOLATILE, KEY_SET_VALUE,
- nullptr, &hkApp, nullptr) == ERROR_SUCCESS) {
- RegSetValueExW(hkApp, L"IsHostApp", 0, REG_NONE, 0, 0);
- RegSetValueExW(hkApp, L"NoOpenWith", 0, REG_NONE, 0, 0);
- RegSetValueExW(hkApp, L"NoStartPage", 0, REG_NONE, 0, 0);
- RegCloseKey(hkApp);
- }
- }
-
- char** argv = static_cast<char**>(malloc(__argc * sizeof(char*)));
- for (int i = 0; i < __argc; i++) {
- argv[i] = strdup(WideToUTF8(__wargv[i]).c_str());
- }
-
- // Do the real work.
- return main(__argc, argv);
-}
-#endif
diff --git a/toolkit/crashreporter/client/crashreporter.exe.manifest b/toolkit/crashreporter/client/crashreporter.exe.manifest
deleted file mode 100644
index e6b2ceefb..000000000
--- a/toolkit/crashreporter/client/crashreporter.exe.manifest
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
-<assemblyIdentity
- version="1.0.0.0"
- processorArchitecture="*"
- name="CrashReporter"
- type="win32"
-/>
-<description>Crash Reporter</description>
-<dependency>
- <dependentAssembly>
- <assemblyIdentity
- type="win32"
- name="Microsoft.Windows.Common-Controls"
- version="6.0.0.0"
- processorArchitecture="*"
- publicKeyToken="6595b64144ccf1df"
- language="*"
- />
- </dependentAssembly>
-</dependency>
-<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
- <ms_asmv3:security>
- <ms_asmv3:requestedPrivileges>
- <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
- </ms_asmv3:requestedPrivileges>
- </ms_asmv3:security>
-</ms_asmv3:trustInfo>
- <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
- <application>
- <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
- <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
- <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
- <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
- </application>
- </compatibility>
-</assembly>
diff --git a/toolkit/crashreporter/client/crashreporter.h b/toolkit/crashreporter/client/crashreporter.h
deleted file mode 100644
index 8c5ca3613..000000000
--- a/toolkit/crashreporter/client/crashreporter.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CRASHREPORTER_H__
-#define CRASHREPORTER_H__
-
-#ifdef _MSC_VER
-# pragma warning( push )
-// Disable exception handler warnings.
-# pragma warning( disable : 4530 )
-#endif
-
-#include <string>
-#include <map>
-#include <vector>
-#include <stdlib.h>
-#include <stdio.h>
-#include <iostream>
-#include <fstream>
-
-#define MAX_COMMENT_LENGTH 500
-
-#if defined(XP_WIN32)
-
-#include <windows.h>
-
-#define UI_SNPRINTF _snprintf
-#define UI_DIR_SEPARATOR "\\"
-
-std::string WideToUTF8(const std::wstring& wide, bool* success = 0);
-
-#else
-
-#define UI_SNPRINTF snprintf
-#define UI_DIR_SEPARATOR "/"
-
-#endif
-
-#define UI_CRASH_REPORTER_FILENAME "crashreporter"
-#define UI_MINIDUMP_ANALYZER_FILENAME "minidump-analyzer"
-
-typedef std::map<std::string, std::string> StringTable;
-
-#define ST_CRASHREPORTERTITLE "CrashReporterTitle"
-#define ST_CRASHREPORTERVENDORTITLE "CrashReporterVendorTitle"
-#define ST_CRASHREPORTERERROR "CrashReporterErrorText"
-#define ST_CRASHREPORTERPRODUCTERROR "CrashReporterProductErrorText2"
-#define ST_CRASHREPORTERHEADER "CrashReporterSorry"
-#define ST_CRASHREPORTERDESCRIPTION "CrashReporterDescriptionText2"
-#define ST_CRASHREPORTERDEFAULT "CrashReporterDefault"
-#define ST_VIEWREPORT "Details"
-#define ST_VIEWREPORTTITLE "ViewReportTitle"
-#define ST_COMMENTGRAYTEXT "CommentGrayText"
-#define ST_EXTRAREPORTINFO "ExtraReportInfo"
-#define ST_CHECKSUBMIT "CheckSendReport"
-#define ST_CHECKURL "CheckIncludeURL"
-#define ST_CHECKEMAIL "CheckAllowEmail"
-#define ST_EMAILGRAYTEXT "EmailGrayText"
-#define ST_REPORTPRESUBMIT "ReportPreSubmit2"
-#define ST_REPORTDURINGSUBMIT "ReportDuringSubmit2"
-#define ST_REPORTSUBMITSUCCESS "ReportSubmitSuccess"
-#define ST_SUBMITFAILED "ReportSubmitFailed"
-#define ST_QUIT "Quit2"
-#define ST_RESTART "Restart"
-#define ST_OK "Ok"
-#define ST_CLOSE "Close"
-
-#define ST_ERROR_BADARGUMENTS "ErrorBadArguments"
-#define ST_ERROR_EXTRAFILEEXISTS "ErrorExtraFileExists"
-#define ST_ERROR_EXTRAFILEREAD "ErrorExtraFileRead"
-#define ST_ERROR_EXTRAFILEMOVE "ErrorExtraFileMove"
-#define ST_ERROR_DUMPFILEEXISTS "ErrorDumpFileExists"
-#define ST_ERROR_DUMPFILEMOVE "ErrorDumpFileMove"
-#define ST_ERROR_NOPRODUCTNAME "ErrorNoProductName"
-#define ST_ERROR_NOSERVERURL "ErrorNoServerURL"
-#define ST_ERROR_NOSETTINGSPATH "ErrorNoSettingsPath"
-#define ST_ERROR_CREATEDUMPDIR "ErrorCreateDumpDir"
-#define ST_ERROR_ENDOFLIFE "ErrorEndOfLife"
-
-//=============================================================================
-// implemented in crashreporter.cpp
-//=============================================================================
-
-namespace CrashReporter {
- extern StringTable gStrings;
- extern std::string gSettingsPath;
- extern std::string gEventsPath;
- extern int gArgc;
- extern char** gArgv;
-
- void UIError(const std::string& message);
-
- // The UI finished sending the report
- void SendCompleted(bool success, const std::string& serverResponse);
-
- bool ReadStrings(std::istream& in,
- StringTable& strings,
- bool unescape);
- bool ReadStringsFromFile(const std::string& path,
- StringTable& strings,
- bool unescape);
- bool WriteStrings(std::ostream& out,
- const std::string& header,
- StringTable& strings,
- bool escape);
- bool WriteStringsToFile(const std::string& path,
- const std::string& header,
- StringTable& strings,
- bool escape);
- void LogMessage(const std::string& message);
- void DeleteDump();
- bool ShouldEnableSending();
-
- static const unsigned int kSaveCount = 10;
-}
-
-//=============================================================================
-// implemented in the platform-specific files
-//=============================================================================
-
-bool UIInit();
-void UIShutdown();
-
-// Run the UI for when the app was launched without a dump file
-void UIShowDefaultUI();
-
-// Run the UI for when the app was launched with a dump file
-// Return true if the user sent (or tried to send) the crash report,
-// false if they chose not to, and it should be deleted.
-bool UIShowCrashUI(const StringTable& files,
- const StringTable& queryParameters,
- const std::string& sendURL,
- const std::vector<std::string>& restartArgs);
-
-void UIError_impl(const std::string& message);
-
-bool UIGetIniPath(std::string& path);
-bool UIGetSettingsPath(const std::string& vendor,
- const std::string& product,
- std::string& settingsPath);
-bool UIEnsurePathExists(const std::string& path);
-bool UIFileExists(const std::string& path);
-bool UIMoveFile(const std::string& oldfile, const std::string& newfile);
-bool UIDeleteFile(const std::string& oldfile);
-std::ifstream* UIOpenRead(const std::string& filename);
-std::ofstream* UIOpenWrite(const std::string& filename,
- bool append=false,
- bool binary=false);
-void UIPruneSavedDumps(const std::string& directory);
-void UIRunMinidumpAnalyzer(const std::string& exename,
- const std::string& filename);
-
-#ifdef _MSC_VER
-# pragma warning( pop )
-#endif
-
-#endif
diff --git a/toolkit/crashreporter/client/crashreporter.ico b/toolkit/crashreporter/client/crashreporter.ico
deleted file mode 100644
index 29ac3c618..000000000
--- a/toolkit/crashreporter/client/crashreporter.ico
+++ /dev/null
Binary files differ
diff --git a/toolkit/crashreporter/client/crashreporter.rc b/toolkit/crashreporter/client/crashreporter.rc
deleted file mode 100755
index 0ccd0757f..000000000
--- a/toolkit/crashreporter/client/crashreporter.rc
+++ /dev/null
@@ -1,148 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "winresrc.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""winresrc.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-1 24 "crashreporter.exe.manifest"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_MAINICON ICON "crashreporter.ico"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// AVI
-//
-
-IDR_THROBBER AVI "Throbber-small.avi"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_SENDDIALOG DIALOGEX 0, 0, 241, 187
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
-EXSTYLE WS_EX_APPWINDOW
-CAPTION "Sending Crash Report..."
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- CONTROL "",IDC_DESCRIPTIONTEXT,"RICHEDIT50W",ES_MULTILINE | ES_READONLY,8,7,226,12,WS_EX_TRANSPARENT
- CONTROL "tell mozilla about this crash so they can fix it",IDC_SUBMITREPORTCHECK,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,25,222,10
- CHECKBOX "details...",IDC_VIEWREPORTBUTTON,24,40,54,14,BS_PUSHLIKE
- EDITTEXT IDC_COMMENTTEXT,24,59,210,43,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL
- CONTROL "include the address of the page i was on",IDC_INCLUDEURLCHECK,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,107,210,10
- CONTROL "tell mozilla to email me with more information",IDC_EMAILMECHECK,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,120,210,10
- EDITTEXT IDC_EMAILTEXT,36,133,198,14,ES_AUTOHSCROLL
- CONTROL "",IDC_THROBBER,"SysAnimate32",ACS_TRANSPARENT | NOT WS_VISIBLE | WS_TABSTOP,4,152,16,16
- LTEXT "your crash report will be submitted when you restart",IDC_PROGRESSTEXT,24,152,210,10,SS_NOPREFIX
- DEFPUSHBUTTON "restart firefox",IDC_RESTARTBUTTON,84,166,68,14
- PUSHBUTTON "quit without sending",IDC_CLOSEBUTTON,157,166,77,14
-END
-
-IDD_VIEWREPORTDIALOG DIALOGEX 0, 0, 208, 126
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
-CAPTION "view report"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- CONTROL "",IDC_VIEWREPORTTEXT,"RICHEDIT50W",ES_MULTILINE | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,194,92
- DEFPUSHBUTTON "OK",IDOK,151,105,50,14
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
-BEGIN
- IDD_SENDDIALOG, DIALOG
- BEGIN
- LEFTMARGIN, 8
- RIGHTMARGIN, 234
- TOPMARGIN, 7
- BOTTOMMARGIN, 180
- END
-
- IDD_VIEWREPORTDIALOG, DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 201
- TOPMARGIN, 7
- BOTTOMMARGIN, 119
- END
-END
-#endif // APSTUDIO_INVOKED
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/toolkit/crashreporter/client/crashreporter_gtk_common.cpp b/toolkit/crashreporter/client/crashreporter_gtk_common.cpp
deleted file mode 100644
index 395a339bf..000000000
--- a/toolkit/crashreporter/client/crashreporter_gtk_common.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "crashreporter.h"
-
-#include <unistd.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "common/linux/http_upload.h"
-#include "crashreporter.h"
-#include "crashreporter_gtk_common.h"
-
-#ifndef GDK_KEY_Escape
-#define GDK_KEY_Escape GDK_Escape
-#endif
-
-using std::string;
-using std::vector;
-
-using namespace CrashReporter;
-
-GtkWidget* gWindow = 0;
-GtkWidget* gSubmitReportCheck = 0;
-GtkWidget* gIncludeURLCheck = 0;
-GtkWidget* gThrobber = 0;
-GtkWidget* gProgressLabel = 0;
-GtkWidget* gCloseButton = 0;
-GtkWidget* gRestartButton = 0;
-
-bool gInitialized = false;
-bool gDidTrySend = false;
-StringTable gFiles;
-StringTable gQueryParameters;
-string gHttpProxy;
-string gAuth;
-string gCACertificateFile;
-string gSendURL;
-string gURLParameter;
-vector<string> gRestartArgs;
-GThread* gSendThreadID;
-
-// From crashreporter_linux.cpp
-void SaveSettings();
-void SendReport();
-void TryInitGnome();
-void UpdateSubmit();
-
-static bool RestartApplication()
-{
- char** argv = reinterpret_cast<char**>(
- malloc(sizeof(char*) * (gRestartArgs.size() + 1)));
-
- if (!argv) return false;
-
- unsigned int i;
- for (i = 0; i < gRestartArgs.size(); i++) {
- argv[i] = (char*)gRestartArgs[i].c_str();
- }
- argv[i] = 0;
-
- pid_t pid = fork();
- if (pid == -1)
- return false;
- else if (pid == 0) {
- (void)execv(argv[0], argv);
- _exit(1);
- }
-
- free(argv);
-
- return true;
-}
-
-// Quit the app, used as a timeout callback
-static gboolean CloseApp(gpointer data)
-{
- gtk_main_quit();
- g_thread_join(gSendThreadID);
- return FALSE;
-}
-
-static gboolean ReportCompleted(gpointer success)
-{
- gtk_widget_hide(gThrobber);
- string str = success ? gStrings[ST_REPORTSUBMITSUCCESS]
- : gStrings[ST_SUBMITFAILED];
- gtk_label_set_text(GTK_LABEL(gProgressLabel), str.c_str());
- g_timeout_add(5000, CloseApp, 0);
- return FALSE;
-}
-
-#ifdef MOZ_ENABLE_GCONF
-#define HTTP_PROXY_DIR "/system/http_proxy"
-
-void LoadProxyinfo()
-{
- class GConfClient;
- typedef GConfClient * (*_gconf_default_fn)();
- typedef gboolean (*_gconf_bool_fn)(GConfClient *, const gchar *, GError **);
- typedef gint (*_gconf_int_fn)(GConfClient *, const gchar *, GError **);
- typedef gchar * (*_gconf_string_fn)(GConfClient *, const gchar *, GError **);
-
- if (getenv ("http_proxy"))
- return; // libcurl can use the value from the environment
-
- static void* gconfLib = dlopen("libgconf-2.so.4", RTLD_LAZY);
- if (!gconfLib)
- return;
-
- _gconf_default_fn gconf_client_get_default =
- (_gconf_default_fn)dlsym(gconfLib, "gconf_client_get_default");
- _gconf_bool_fn gconf_client_get_bool =
- (_gconf_bool_fn)dlsym(gconfLib, "gconf_client_get_bool");
- _gconf_int_fn gconf_client_get_int =
- (_gconf_int_fn)dlsym(gconfLib, "gconf_client_get_int");
- _gconf_string_fn gconf_client_get_string =
- (_gconf_string_fn)dlsym(gconfLib, "gconf_client_get_string");
-
- if(!(gconf_client_get_default &&
- gconf_client_get_bool &&
- gconf_client_get_int &&
- gconf_client_get_string)) {
- dlclose(gconfLib);
- return;
- }
-
- GConfClient *conf = gconf_client_get_default();
-
- if (gconf_client_get_bool(conf, HTTP_PROXY_DIR "/use_http_proxy", nullptr)) {
- gint port;
- gchar *host = nullptr, *httpproxy = nullptr;
-
- host = gconf_client_get_string(conf, HTTP_PROXY_DIR "/host", nullptr);
- port = gconf_client_get_int(conf, HTTP_PROXY_DIR "/port", nullptr);
-
- if (port && host && *host != '\0') {
- httpproxy = g_strdup_printf("http://%s:%d/", host, port);
- gHttpProxy = httpproxy;
- }
-
- g_free(host);
- g_free(httpproxy);
-
- if (gconf_client_get_bool(conf, HTTP_PROXY_DIR "/use_authentication",
- nullptr)) {
- gchar *user, *password, *auth = nullptr;
-
- user = gconf_client_get_string(conf,
- HTTP_PROXY_DIR "/authentication_user",
- nullptr);
- password = gconf_client_get_string(conf,
- HTTP_PROXY_DIR
- "/authentication_password",
- nullptr);
-
- if (user && password) {
- auth = g_strdup_printf("%s:%s", user, password);
- gAuth = auth;
- }
-
- g_free(user);
- g_free(password);
- g_free(auth);
- }
- }
-
- g_object_unref(conf);
-
- // Don't dlclose gconfLib as libORBit-2 uses atexit().
-}
-#endif
-
-gpointer SendThread(gpointer args)
-{
- string response, error;
- long response_code;
-
- bool success = google_breakpad::HTTPUpload::SendRequest
- (gSendURL,
- gQueryParameters,
- gFiles,
- gHttpProxy, gAuth,
- gCACertificateFile,
- &response,
- &response_code,
- &error);
- if (success) {
- LogMessage("Crash report submitted successfully");
- }
- else {
- LogMessage("Crash report submission failed: " + error);
- }
-
- SendCompleted(success, response);
- // Apparently glib is threadsafe, and will schedule this
- // on the main thread, see:
- // http://library.gnome.org/devel/gtk-faq/stable/x499.html
- g_idle_add(ReportCompleted, (gpointer)success);
-
- return nullptr;
-}
-
-gboolean WindowDeleted(GtkWidget* window,
- GdkEvent* event,
- gpointer userData)
-{
- SaveSettings();
- gtk_main_quit();
- return TRUE;
-}
-
-gboolean check_escape(GtkWidget* window,
- GdkEventKey* event,
- gpointer userData)
-{
- if (event->keyval == GDK_KEY_Escape) {
- gtk_main_quit();
- return TRUE;
- }
- return FALSE;
-}
-
-static void MaybeSubmitReport()
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck))) {
- gDidTrySend = true;
- SendReport();
- } else {
- gtk_main_quit();
- }
-}
-
-void CloseClicked(GtkButton* button,
- gpointer userData)
-{
- SaveSettings();
- MaybeSubmitReport();
-}
-
-void RestartClicked(GtkButton* button,
- gpointer userData)
-{
- SaveSettings();
- RestartApplication();
- MaybeSubmitReport();
-}
-
-static void UpdateURL()
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck))) {
- gQueryParameters["URL"] = gURLParameter;
- } else {
- gQueryParameters.erase("URL");
- }
-}
-
-void SubmitReportChecked(GtkButton* sender, gpointer userData)
-{
- UpdateSubmit();
-}
-
-void IncludeURLClicked(GtkButton* sender, gpointer userData)
-{
- UpdateURL();
-}
-
-/* === Crashreporter UI Functions === */
-
-bool UIInit()
-{
- // breakpad probably left us with blocked signals, unblock them here
- sigset_t signals, old;
- sigfillset(&signals);
- sigprocmask(SIG_UNBLOCK, &signals, &old);
-
- // tell glib we're going to use threads
- g_thread_init(nullptr);
-
- if (gtk_init_check(&gArgc, &gArgv)) {
- gInitialized = true;
-
- if (gStrings.find("isRTL") != gStrings.end() &&
- gStrings["isRTL"] == "yes")
- gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL);
-
- return true;
- }
-
- return false;
-}
-
-void UIShowDefaultUI()
-{
- GtkWidget* errorDialog =
- gtk_message_dialog_new(nullptr, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s", gStrings[ST_CRASHREPORTERDEFAULT].c_str());
-
- gtk_window_set_title(GTK_WINDOW(errorDialog),
- gStrings[ST_CRASHREPORTERTITLE].c_str());
- gtk_dialog_run(GTK_DIALOG(errorDialog));
-}
-
-void UIError_impl(const string& message)
-{
- if (!gInitialized) {
- // Didn't initialize, this is the best we can do
- printf("Error: %s\n", message.c_str());
- return;
- }
-
- GtkWidget* errorDialog =
- gtk_message_dialog_new(nullptr, GTK_DIALOG_MODAL,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s", message.c_str());
-
- gtk_window_set_title(GTK_WINDOW(errorDialog),
- gStrings[ST_CRASHREPORTERTITLE].c_str());
- gtk_dialog_run(GTK_DIALOG(errorDialog));
-}
-
-bool UIGetIniPath(string& path)
-{
- path = gArgv[0];
- path.append(".ini");
-
- return true;
-}
-
-/*
- * Settings are stored in ~/.vendor/product, or
- * ~/.product if vendor is empty.
- */
-bool UIGetSettingsPath(const string& vendor,
- const string& product,
- string& settingsPath)
-{
- char* home = getenv("HOME");
-
- if (!home)
- return false;
-
- settingsPath = home;
- settingsPath += "/.";
- if (!vendor.empty()) {
- string lc_vendor;
- std::transform(vendor.begin(), vendor.end(), back_inserter(lc_vendor),
- (int(*)(int)) std::tolower);
- settingsPath += lc_vendor + "/";
- }
- string lc_product;
- std::transform(product.begin(), product.end(), back_inserter(lc_product),
- (int(*)(int)) std::tolower);
- settingsPath += lc_product + "/Crash Reports";
- return true;
-}
-
-bool UIEnsurePathExists(const string& path)
-{
- int ret = mkdir(path.c_str(), S_IRWXU);
- int e = errno;
- if (ret == -1 && e != EEXIST)
- return false;
-
- return true;
-}
-
-bool UIFileExists(const string& path)
-{
- struct stat sb;
- int ret = stat(path.c_str(), &sb);
- if (ret == -1 || !(sb.st_mode & S_IFREG))
- return false;
-
- return true;
-}
-
-bool UIMoveFile(const string& file, const string& newfile)
-{
- if (!rename(file.c_str(), newfile.c_str()))
- return true;
- if (errno != EXDEV)
- return false;
-
- // use system /bin/mv instead, time to fork
- pid_t pID = vfork();
- if (pID < 0) {
- // Failed to fork
- return false;
- }
- if (pID == 0) {
- char* const args[4] = {
- const_cast<char*>("mv"),
- strdup(file.c_str()),
- strdup(newfile.c_str()),
- 0
- };
- if (args[1] && args[2])
- execve("/bin/mv", args, 0);
- free(args[1]);
- free(args[2]);
- exit(-1);
- }
- int status;
- waitpid(pID, &status, 0);
- return UIFileExists(newfile);
-}
-
-bool UIDeleteFile(const string& file)
-{
- return (unlink(file.c_str()) != -1);
-}
-
-std::ifstream* UIOpenRead(const string& filename)
-{
- return new std::ifstream(filename.c_str(), std::ios::in);
-}
-
-std::ofstream* UIOpenWrite(const string& filename,
- bool append, // append=false
- bool binary) // binary=false
-{
- std::ios_base::openmode mode = std::ios::out;
-
- if (append) {
- mode = mode | std::ios::app;
- }
-
- if (binary) {
- mode = mode | std::ios::binary;
- }
-
- return new std::ofstream(filename.c_str(), mode);
-}
diff --git a/toolkit/crashreporter/client/crashreporter_gtk_common.h b/toolkit/crashreporter/client/crashreporter_gtk_common.h
deleted file mode 100644
index 3a6350c5b..000000000
--- a/toolkit/crashreporter/client/crashreporter_gtk_common.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CRASHREPORTER_GTK_COMMON_H__
-#define CRASHREPORTER_GTK_COMMON_H__
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#include <string>
-#include <vector>
-
-const char kIniFile[] = "crashreporter.ini";
-
-extern GtkWidget* gWindow;
-extern GtkWidget* gSubmitReportCheck;
-extern GtkWidget* gIncludeURLCheck;
-extern GtkWidget* gThrobber;
-extern GtkWidget* gProgressLabel;
-extern GtkWidget* gCloseButton;
-extern GtkWidget* gRestartButton;
-
-extern std::vector<std::string> gRestartArgs;
-extern GThread* gSendThreadID;
-
-extern bool gInitialized;
-extern bool gDidTrySend;
-extern StringTable gFiles;
-extern StringTable gQueryParameters;
-extern std::string gHttpProxy;
-extern std::string gAuth;
-extern std::string gCACertificateFile;
-extern std::string gSendURL;
-extern std::string gURLParameter;
-
-void LoadProxyinfo();
-gpointer SendThread(gpointer args);
-gboolean WindowDeleted(GtkWidget* window,
- GdkEvent* event,
- gpointer userData);
-gboolean check_escape(GtkWidget* window, GdkEventKey* event, gpointer data);
-void SubmitReportChecked(GtkButton* sender, gpointer userData);
-void IncludeURLClicked(GtkButton* sender, gpointer userData);
-void CloseClicked(GtkButton* button,
- gpointer userData);
-void RestartClicked(GtkButton* button,
- gpointer userData);
-
-#endif // CRASHREPORTER_GTK_COMMON_H__
diff --git a/toolkit/crashreporter/client/crashreporter_linux.cpp b/toolkit/crashreporter/client/crashreporter_linux.cpp
deleted file mode 100644
index 6e7ccce40..000000000
--- a/toolkit/crashreporter/client/crashreporter_linux.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <string.h>
-
-#include <cctype>
-
-#include "crashreporter.h"
-#include "crashreporter_gtk_common.h"
-
-#define LABEL_MAX_CHAR_WIDTH 48
-
-using std::string;
-using std::vector;
-
-using namespace CrashReporter;
-
-static GtkWidget* gViewReportButton = 0;
-static GtkWidget* gCommentTextLabel = 0;
-static GtkWidget* gCommentText = 0;
-static GtkWidget* gEmailMeCheck = 0;
-static GtkWidget* gEmailEntryLabel = 0;
-static GtkWidget* gEmailEntry = 0;
-
-static bool gEmailFieldHint = true;
-static bool gCommentFieldHint = true;
-
-// handle from dlopen'ing libgnome
-static void* gnomeLib = nullptr;
-// handle from dlopen'ing libgnomeui
-static void* gnomeuiLib = nullptr;
-
-static void LoadSettings()
-{
- /*
- * NOTE! This code needs to stay in sync with the preference checking
- * code in in nsExceptionHandler.cpp.
- */
-
- StringTable settings;
- if (ReadStringsFromFile(gSettingsPath + "/" + kIniFile, settings, true)) {
- if (settings.find("Email") != settings.end()) {
- gtk_entry_set_text(GTK_ENTRY(gEmailEntry), settings["Email"].c_str());
- gEmailFieldHint = false;
- }
- if (settings.find("EmailMe") != settings.end()) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gEmailMeCheck),
- settings["EmailMe"][0] != '0');
- }
- if (settings.find("IncludeURL") != settings.end() &&
- gIncludeURLCheck != 0) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck),
- settings["IncludeURL"][0] != '0');
- }
- bool enabled;
- if (settings.find("SubmitReport") != settings.end())
- enabled = settings["SubmitReport"][0] != '0';
- else
- enabled = ShouldEnableSending();
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck),
- enabled);
- }
-}
-
-void SaveSettings()
-{
- /*
- * NOTE! This code needs to stay in sync with the preference setting
- * code in in nsExceptionHandler.cpp.
- */
-
- StringTable settings;
-
- ReadStringsFromFile(gSettingsPath + "/" + kIniFile, settings, true);
- if (!gEmailFieldHint)
- settings["Email"] = gtk_entry_get_text(GTK_ENTRY(gEmailEntry));
- else
- settings.erase("Email");
-
- settings["EmailMe"] =
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gEmailMeCheck)) ? "1" : "0";
- if (gIncludeURLCheck != 0)
- settings["IncludeURL"] =
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck))
- ? "1" : "0";
- settings["SubmitReport"] =
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck))
- ? "1" : "0";
-
- WriteStringsToFile(gSettingsPath + "/" + kIniFile,
- "Crash Reporter", settings, true);
-}
-
-void SendReport()
-{
- // disable all our gui controls, show the throbber + change the progress text
- gtk_widget_set_sensitive(gSubmitReportCheck, FALSE);
- gtk_widget_set_sensitive(gViewReportButton, FALSE);
- gtk_widget_set_sensitive(gCommentText, FALSE);
- if (gIncludeURLCheck)
- gtk_widget_set_sensitive(gIncludeURLCheck, FALSE);
- gtk_widget_set_sensitive(gEmailMeCheck, FALSE);
- gtk_widget_set_sensitive(gEmailEntry, FALSE);
- gtk_widget_set_sensitive(gCloseButton, FALSE);
- if (gRestartButton)
- gtk_widget_set_sensitive(gRestartButton, FALSE);
- gtk_widget_show_all(gThrobber);
- gtk_label_set_text(GTK_LABEL(gProgressLabel),
- gStrings[ST_REPORTDURINGSUBMIT].c_str());
-
-#ifdef MOZ_ENABLE_GCONF
- LoadProxyinfo();
-#endif
-
- // and spawn a thread to do the sending
- GError* err;
- gSendThreadID = g_thread_create(SendThread, nullptr, TRUE, &err);
-}
-
-static void ShowReportInfo(GtkTextView* viewReportTextView)
-{
- GtkTextBuffer* buffer =
- gtk_text_view_get_buffer(viewReportTextView);
-
- GtkTextIter start, end;
- gtk_text_buffer_get_start_iter(buffer, &start);
- gtk_text_buffer_get_end_iter(buffer, &end);
-
- gtk_text_buffer_delete(buffer, &start, &end);
-
- for (StringTable::iterator iter = gQueryParameters.begin();
- iter != gQueryParameters.end();
- iter++) {
- gtk_text_buffer_insert(buffer, &end, iter->first.c_str(), -1);
- gtk_text_buffer_insert(buffer, &end, ": ", -1);
- gtk_text_buffer_insert(buffer, &end, iter->second.c_str(), -1);
- gtk_text_buffer_insert(buffer, &end, "\n", -1);
- }
-
- gtk_text_buffer_insert(buffer, &end, "\n", -1);
- gtk_text_buffer_insert(buffer, &end,
- gStrings[ST_EXTRAREPORTINFO].c_str(), -1);
-}
-
-void UpdateSubmit()
-{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck))) {
- gtk_widget_set_sensitive(gViewReportButton, TRUE);
- gtk_widget_set_sensitive(gCommentText, TRUE);
- if (gIncludeURLCheck)
- gtk_widget_set_sensitive(gIncludeURLCheck, TRUE);
- gtk_widget_set_sensitive(gEmailMeCheck, TRUE);
- gtk_widget_set_sensitive(gEmailEntry,
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gEmailMeCheck)));
- gtk_label_set_text(GTK_LABEL(gProgressLabel),
- gStrings[ST_REPORTPRESUBMIT].c_str());
- } else {
- gtk_widget_set_sensitive(gViewReportButton, FALSE);
- gtk_widget_set_sensitive(gCommentText, FALSE);
- if (gIncludeURLCheck)
- gtk_widget_set_sensitive(gIncludeURLCheck, FALSE);
- gtk_widget_set_sensitive(gEmailMeCheck, FALSE);
- gtk_widget_set_sensitive(gEmailEntry, FALSE);
- gtk_label_set_text(GTK_LABEL(gProgressLabel), "");
- }
-}
-
-static void ViewReportClicked(GtkButton* button,
- gpointer userData)
-{
- GtkDialog* dialog =
- GTK_DIALOG(gtk_dialog_new_with_buttons(gStrings[ST_VIEWREPORTTITLE].c_str(),
- GTK_WINDOW(gWindow),
- GTK_DIALOG_MODAL,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- nullptr));
-
- GtkWidget* scrolled = gtk_scrolled_window_new(0, 0);
- gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dialog)), scrolled);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled),
- GTK_SHADOW_IN);
-#if (MOZ_WIDGET_GTK >= 3)
- gtk_widget_set_vexpand(scrolled, TRUE);
-#endif
-
- GtkWidget* viewReportTextView = gtk_text_view_new();
- gtk_container_add(GTK_CONTAINER(scrolled), viewReportTextView);
- gtk_text_view_set_editable(GTK_TEXT_VIEW(viewReportTextView), FALSE);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(viewReportTextView),
- GTK_WRAP_WORD);
- gtk_widget_set_size_request(GTK_WIDGET(viewReportTextView), -1, 100);
-
- ShowReportInfo(GTK_TEXT_VIEW(viewReportTextView));
-
- gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK);
- gtk_widget_set_size_request(GTK_WIDGET(dialog), 400, 200);
- gtk_widget_show_all(GTK_WIDGET(dialog));
- gtk_dialog_run(dialog);
- gtk_widget_destroy(GTK_WIDGET(dialog));
-}
-
-static void CommentChanged(GtkTextBuffer* buffer, gpointer userData)
-{
- GtkTextIter start, end;
- gtk_text_buffer_get_start_iter(buffer, &start);
- gtk_text_buffer_get_end_iter(buffer, &end);
- const char* comment = gtk_text_buffer_get_text(buffer, &start, &end, TRUE);
- if (comment[0] == '\0' || gCommentFieldHint)
- gQueryParameters.erase("Comments");
- else
- gQueryParameters["Comments"] = comment;
-}
-
-static void CommentInsert(GtkTextBuffer* buffer,
- GtkTextIter* location,
- gchar* text,
- gint len,
- gpointer userData)
-{
- GtkTextIter start, end;
- gtk_text_buffer_get_start_iter(buffer, &start);
- gtk_text_buffer_get_end_iter(buffer, &end);
- const char* comment = gtk_text_buffer_get_text(buffer, &start, &end, TRUE);
-
- // limit to 500 bytes in utf-8
- if (strlen(comment) + len > MAX_COMMENT_LENGTH) {
- g_signal_stop_emission_by_name(buffer, "insert-text");
- }
-}
-
-static void UpdateHintText(GtkWidget* widget, gboolean gainedFocus,
- bool* hintShowing, const char* hintText)
-{
- GtkTextBuffer* buffer = nullptr;
- if (GTK_IS_TEXT_VIEW(widget))
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
-
- if (gainedFocus) {
- if (*hintShowing) {
- if (buffer == nullptr) { // sort of cheating
- gtk_entry_set_text(GTK_ENTRY(widget), "");
- }
- else { // GtkTextView
- gtk_text_buffer_set_text(buffer, "", 0);
- }
- gtk_widget_modify_text(widget, GTK_STATE_NORMAL, nullptr);
- *hintShowing = false;
- }
- }
- else {
- // lost focus
- const char* text = nullptr;
- if (buffer == nullptr) {
- text = gtk_entry_get_text(GTK_ENTRY(widget));
- }
- else {
- GtkTextIter start, end;
- gtk_text_buffer_get_start_iter(buffer, &start);
- gtk_text_buffer_get_end_iter(buffer, &end);
- text = gtk_text_buffer_get_text(buffer, &start, &end, TRUE);
- }
-
- if (text == nullptr || text[0] == '\0') {
- *hintShowing = true;
-
- if (buffer == nullptr) {
- gtk_entry_set_text(GTK_ENTRY(widget), hintText);
- }
- else {
- gtk_text_buffer_set_text(buffer, hintText, -1);
- }
-
- gtk_widget_modify_text(widget, GTK_STATE_NORMAL,
- &gtk_widget_get_style(widget)->text[GTK_STATE_INSENSITIVE]);
- }
- }
-}
-
-static gboolean CommentFocusChange(GtkWidget* widget, GdkEventFocus* event,
- gpointer userData)
-{
- UpdateHintText(widget, event->in, &gCommentFieldHint,
- gStrings[ST_COMMENTGRAYTEXT].c_str());
-
- return FALSE;
-}
-
-static void UpdateEmail()
-{
- const char* email = gtk_entry_get_text(GTK_ENTRY(gEmailEntry));
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gEmailMeCheck))) {
- gtk_widget_set_sensitive(gEmailEntry, TRUE);
- } else {
- email = "";
- gtk_widget_set_sensitive(gEmailEntry, FALSE);
- }
- if (email[0] == '\0' || gEmailFieldHint)
- gQueryParameters.erase("Email");
- else
- gQueryParameters["Email"] = email;
-}
-
-static void EmailMeClicked(GtkButton* sender, gpointer userData)
-{
- UpdateEmail();
-}
-
-static void EmailChanged(GtkEditable* editable, gpointer userData)
-{
- UpdateEmail();
-}
-
-static gboolean EmailFocusChange(GtkWidget* widget, GdkEventFocus* event,
- gpointer userData)
-{
- UpdateHintText(widget, event->in, &gEmailFieldHint,
- gStrings[ST_EMAILGRAYTEXT].c_str());
-
- return FALSE;
-}
-
-typedef struct _GnomeProgram GnomeProgram;
-typedef struct _GnomeModuleInfo GnomeModuleInfo;
-typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *,
- const GnomeModuleInfo *, int,
- char **, const char *, ...);
-typedef const GnomeModuleInfo * (*_libgnomeui_module_info_get_fn)();
-
-void TryInitGnome()
-{
- gnomeLib = dlopen("libgnome-2.so.0", RTLD_LAZY);
- if (!gnomeLib)
- return;
-
- gnomeuiLib = dlopen("libgnomeui-2.so.0", RTLD_LAZY);
- if (!gnomeuiLib)
- return;
-
- _gnome_program_init_fn gnome_program_init =
- (_gnome_program_init_fn)(dlsym(gnomeLib, "gnome_program_init"));
- _libgnomeui_module_info_get_fn libgnomeui_module_info_get =
- (_libgnomeui_module_info_get_fn)(dlsym(gnomeuiLib, "libgnomeui_module_info_get"));
-
- if (gnome_program_init && libgnomeui_module_info_get) {
- gnome_program_init("crashreporter", "1.0", libgnomeui_module_info_get(),
- gArgc, gArgv, nullptr);
- }
-
-}
-
-/* === Crashreporter UI Functions === */
-
-/*
- * Anything not listed here is in crashreporter_gtk_common.cpp:
- * UIInit
- * UIShowDefaultUI
- * UIError_impl
- * UIGetIniPath
- * UIGetSettingsPath
- * UIEnsurePathExists
- * UIFileExists
- * UIMoveFile
- * UIDeleteFile
- * UIOpenRead
- * UIOpenWrite
- */
-
-void UIShutdown()
-{
- if (gnomeuiLib)
- dlclose(gnomeuiLib);
- // Don't dlclose gnomeLib as libgnomevfs and libORBit-2 use atexit().
-}
-
-bool UIShowCrashUI(const StringTable& files,
- const StringTable& queryParameters,
- const string& sendURL,
- const vector<string>& restartArgs)
-{
- gFiles = files;
- gQueryParameters = queryParameters;
- gSendURL = sendURL;
- gRestartArgs = restartArgs;
- if (gQueryParameters.find("URL") != gQueryParameters.end())
- gURLParameter = gQueryParameters["URL"];
-
- gWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(gWindow),
- gStrings[ST_CRASHREPORTERTITLE].c_str());
- gtk_window_set_resizable(GTK_WINDOW(gWindow), FALSE);
- gtk_window_set_position(GTK_WINDOW(gWindow), GTK_WIN_POS_CENTER);
- gtk_container_set_border_width(GTK_CONTAINER(gWindow), 12);
- g_signal_connect(gWindow, "delete-event", G_CALLBACK(WindowDeleted), 0);
- g_signal_connect(gWindow, "key_press_event", G_CALLBACK(check_escape), nullptr);
-
- GtkWidget* vbox = gtk_vbox_new(FALSE, 6);
- gtk_container_add(GTK_CONTAINER(gWindow), vbox);
-
- GtkWidget* titleLabel = gtk_label_new("");
- gtk_box_pack_start(GTK_BOX(vbox), titleLabel, FALSE, FALSE, 0);
- gtk_misc_set_alignment(GTK_MISC(titleLabel), 0, 0.5);
- char* markup = g_strdup_printf("<b>%s</b>",
- gStrings[ST_CRASHREPORTERHEADER].c_str());
- gtk_label_set_markup(GTK_LABEL(titleLabel), markup);
- g_free(markup);
-
- GtkWidget* descriptionLabel =
- gtk_label_new(gStrings[ST_CRASHREPORTERDESCRIPTION].c_str());
- gtk_box_pack_start(GTK_BOX(vbox), descriptionLabel, TRUE, TRUE, 0);
- // force the label to line wrap
-#if (MOZ_WIDGET_GTK == 2)
- gtk_widget_set_size_request(descriptionLabel, 400, -1);
-#else
- gtk_label_set_max_width_chars(GTK_LABEL(descriptionLabel), LABEL_MAX_CHAR_WIDTH);
-#endif
- gtk_label_set_line_wrap(GTK_LABEL(descriptionLabel), TRUE);
- gtk_label_set_selectable(GTK_LABEL(descriptionLabel), TRUE);
- gtk_misc_set_alignment(GTK_MISC(descriptionLabel), 0, 0.5);
-
- // this is honestly how they suggest you indent a section
- GtkWidget* indentBox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), indentBox, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(indentBox), gtk_label_new(""), FALSE, FALSE, 6);
-
- GtkWidget* innerVBox1 = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(indentBox), innerVBox1, TRUE, TRUE, 0);
-
- gSubmitReportCheck =
- gtk_check_button_new_with_label(gStrings[ST_CHECKSUBMIT].c_str());
- gtk_box_pack_start(GTK_BOX(innerVBox1), gSubmitReportCheck, FALSE, FALSE, 0);
- g_signal_connect(gSubmitReportCheck, "clicked",
- G_CALLBACK(SubmitReportChecked), 0);
-
- // indent again, below the "submit report" checkbox
- GtkWidget* indentBox2 = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(innerVBox1), indentBox2, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(indentBox2), gtk_label_new(""), FALSE, FALSE, 6);
-
- GtkWidget* innerVBox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(indentBox2), innerVBox, TRUE, TRUE, 0);
- gtk_box_set_spacing(GTK_BOX(innerVBox), 6);
-
- GtkWidget* viewReportButtonBox = gtk_hbutton_box_new();
- gtk_box_pack_start(GTK_BOX(innerVBox), viewReportButtonBox, FALSE, FALSE, 0);
- gtk_box_set_spacing(GTK_BOX(viewReportButtonBox), 6);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(viewReportButtonBox), GTK_BUTTONBOX_START);
-
- gViewReportButton =
- gtk_button_new_with_label(gStrings[ST_VIEWREPORT].c_str());
- gtk_box_pack_start(GTK_BOX(viewReportButtonBox), gViewReportButton, FALSE, FALSE, 0);
- g_signal_connect(gViewReportButton, "clicked", G_CALLBACK(ViewReportClicked), 0);
-
- GtkWidget* scrolled = gtk_scrolled_window_new(0, 0);
- gtk_container_add(GTK_CONTAINER(innerVBox), scrolled);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
- GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled),
- GTK_SHADOW_IN);
-#if (MOZ_WIDGET_GTK >= 3)
- gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled), 100);
-#endif
-
- gCommentTextLabel = gtk_label_new(gStrings[ST_COMMENTGRAYTEXT].c_str());
- gCommentText = gtk_text_view_new();
- gtk_label_set_mnemonic_widget(GTK_LABEL(gCommentTextLabel), gCommentText);
- gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(gCommentText), FALSE);
- g_signal_connect(gCommentText, "focus-in-event", G_CALLBACK(CommentFocusChange), 0);
- g_signal_connect(gCommentText, "focus-out-event", G_CALLBACK(CommentFocusChange), 0);
-
- GtkTextBuffer* commentBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gCommentText));
- g_signal_connect(commentBuffer, "changed", G_CALLBACK(CommentChanged), 0);
- g_signal_connect(commentBuffer, "insert-text", G_CALLBACK(CommentInsert), 0);
-
- gtk_container_add(GTK_CONTAINER(scrolled), gCommentText);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(gCommentText),
- GTK_WRAP_WORD);
- gtk_widget_set_size_request(GTK_WIDGET(gCommentText), -1, 100);
-
- if (gQueryParameters.find("URL") != gQueryParameters.end()) {
- gIncludeURLCheck =
- gtk_check_button_new_with_label(gStrings[ST_CHECKURL].c_str());
- gtk_box_pack_start(GTK_BOX(innerVBox), gIncludeURLCheck, FALSE, FALSE, 0);
- g_signal_connect(gIncludeURLCheck, "clicked", G_CALLBACK(IncludeURLClicked), 0);
- // on by default
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck), TRUE);
- }
-
- gEmailMeCheck =
- gtk_check_button_new_with_label(gStrings[ST_CHECKEMAIL].c_str());
- gtk_box_pack_start(GTK_BOX(innerVBox), gEmailMeCheck, FALSE, FALSE, 0);
- g_signal_connect(gEmailMeCheck, "clicked", G_CALLBACK(EmailMeClicked), 0);
-
- GtkWidget* emailIndentBox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(innerVBox), emailIndentBox, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(emailIndentBox), gtk_label_new(""),
- FALSE, FALSE, 9);
-
- gEmailEntryLabel = gtk_label_new(gStrings[ST_EMAILGRAYTEXT].c_str());
- gEmailEntry = gtk_entry_new();
- gtk_label_set_mnemonic_widget(GTK_LABEL(gEmailEntryLabel), gEmailEntry);
- gtk_box_pack_start(GTK_BOX(emailIndentBox), gEmailEntry, TRUE, TRUE, 0);
- g_signal_connect(gEmailEntry, "changed", G_CALLBACK(EmailChanged), 0);
- g_signal_connect(gEmailEntry, "focus-in-event", G_CALLBACK(EmailFocusChange), 0);
- g_signal_connect(gEmailEntry, "focus-out-event", G_CALLBACK(EmailFocusChange), 0);
-
- GtkWidget* progressBox = gtk_hbox_new(FALSE, 6);
- gtk_box_pack_start(GTK_BOX(vbox), progressBox, TRUE, TRUE, 0);
-
- // Get the throbber image from alongside the executable
- char* dir = g_path_get_dirname(gArgv[0]);
- char* path = g_build_filename(dir, "Throbber-small.gif", nullptr);
- g_free(dir);
- gThrobber = gtk_image_new_from_file(path);
- gtk_box_pack_start(GTK_BOX(progressBox), gThrobber, FALSE, FALSE, 0);
-
- gProgressLabel =
- gtk_label_new(gStrings[ST_REPORTPRESUBMIT].c_str());
- gtk_box_pack_start(GTK_BOX(progressBox), gProgressLabel, TRUE, TRUE, 0);
- // force the label to line wrap
-#if (MOZ_WIDGET_GTK == 2)
- gtk_widget_set_size_request(gProgressLabel, 400, -1);
-#else
- gtk_label_set_max_width_chars(GTK_LABEL(gProgressLabel), LABEL_MAX_CHAR_WIDTH);
-#endif
- gtk_label_set_line_wrap(GTK_LABEL(gProgressLabel), TRUE);
-
- GtkWidget* buttonBox = gtk_hbutton_box_new();
- gtk_box_pack_end(GTK_BOX(vbox), buttonBox, FALSE, FALSE, 0);
- gtk_box_set_spacing(GTK_BOX(buttonBox), 6);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END);
-
- gCloseButton =
- gtk_button_new_with_label(gStrings[ST_QUIT].c_str());
- gtk_box_pack_start(GTK_BOX(buttonBox), gCloseButton, FALSE, FALSE, 0);
- gtk_widget_set_can_default(gCloseButton, TRUE);
- g_signal_connect(gCloseButton, "clicked", G_CALLBACK(CloseClicked), 0);
-
- gRestartButton = 0;
- if (restartArgs.size() > 0) {
- gRestartButton = gtk_button_new_with_label(gStrings[ST_RESTART].c_str());
- gtk_box_pack_start(GTK_BOX(buttonBox), gRestartButton, FALSE, FALSE, 0);
- gtk_widget_set_can_default(gRestartButton, TRUE);
- g_signal_connect(gRestartButton, "clicked", G_CALLBACK(RestartClicked), 0);
- }
-
- gtk_widget_grab_focus(gSubmitReportCheck);
-
- gtk_widget_grab_default(gRestartButton ? gRestartButton : gCloseButton);
-
- LoadSettings();
-
- UpdateEmail();
- UpdateSubmit();
-
- UpdateHintText(gCommentText, FALSE, &gCommentFieldHint,
- gStrings[ST_COMMENTGRAYTEXT].c_str());
- UpdateHintText(gEmailEntry, FALSE, &gEmailFieldHint,
- gStrings[ST_EMAILGRAYTEXT].c_str());
-
- gtk_widget_show_all(gWindow);
- // stick this here to avoid the show_all above...
- gtk_widget_hide(gThrobber);
-
- gtk_main();
-
- return gDidTrySend;
-}
diff --git a/toolkit/crashreporter/client/crashreporter_osx.h b/toolkit/crashreporter/client/crashreporter_osx.h
deleted file mode 100644
index e274de0de..000000000
--- a/toolkit/crashreporter/client/crashreporter_osx.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CRASHREPORTER_OSX_H__
-#define CRASHREPORTER_OSX_H__
-
-#include <Cocoa/Cocoa.h>
-#include "HTTPMultipartUpload.h"
-#include "crashreporter.h"
-
-// Defined below
-@class TextViewWithPlaceHolder;
-
-@interface CrashReporterUI : NSObject
-{
- IBOutlet NSWindow* mWindow;
-
- /* Crash reporter view */
- IBOutlet NSTextField* mHeaderLabel;
- IBOutlet NSTextField* mDescriptionLabel;
- IBOutlet NSButton* mViewReportButton;
- IBOutlet NSScrollView* mCommentScrollView;
- IBOutlet TextViewWithPlaceHolder* mCommentText;
- IBOutlet NSButton* mSubmitReportButton;
- IBOutlet NSButton* mIncludeURLButton;
- IBOutlet NSButton* mEmailMeButton;
- IBOutlet NSTextField* mEmailText;
- IBOutlet NSButton* mCloseButton;
- IBOutlet NSButton* mRestartButton;
- IBOutlet NSProgressIndicator* mProgressIndicator;
- IBOutlet NSTextField* mProgressText;
-
- /* Error view */
- IBOutlet NSView* mErrorView;
- IBOutlet NSTextField* mErrorHeaderLabel;
- IBOutlet NSTextField* mErrorLabel;
- IBOutlet NSButton* mErrorCloseButton;
-
- /* For "show info" alert */
- IBOutlet NSWindow* mViewReportWindow;
- IBOutlet NSTextView* mViewReportTextView;
- IBOutlet NSButton* mViewReportOkButton;
-
- HTTPMultipartUpload* mPost;
-}
-
-- (void)showCrashUI:(const StringTable&)files
- queryParameters:(const StringTable&)queryParameters
- sendURL:(const std::string&)sendURL;
-- (void)showErrorUI:(const std::string&)message;
-- (void)showReportInfo;
-- (void)maybeSubmitReport;
-- (void)closeMeDown:(id)unused;
-
-- (IBAction)submitReportClicked:(id)sender;
-- (IBAction)viewReportClicked:(id)sender;
-- (IBAction)viewReportOkClicked:(id)sender;
-- (IBAction)closeClicked:(id)sender;
-- (IBAction)restartClicked:(id)sender;
-- (IBAction)includeURLClicked:(id)sender;
-- (IBAction)emailMeClicked:(id)sender;
-
-- (void)controlTextDidChange:(NSNotification *)note;
-- (void)textDidChange:(NSNotification *)aNotification;
-- (BOOL)textView:(NSTextView *)aTextView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString;
-
-- (void)doInitialResizing;
-- (float)setStringFitVertically:(NSControl*)control
- string:(NSString*)str
- resizeWindow:(BOOL)resizeWindow;
-- (void)setView:(NSView*)v animate: (BOOL) animate;
-- (void)enableControls:(BOOL)enabled;
-- (void)updateSubmit;
-- (void)updateURL;
-- (void)updateEmail;
-- (void)sendReport;
-- (bool)setupPost;
-- (void)uploadThread:(HTTPMultipartUpload*)post;
-- (void)uploadComplete:(NSData*)data;
-
--(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication;
--(void)applicationWillTerminate:(NSNotification *)aNotification;
-
-@end
-
-/*
- * Subclass NSTextView to provide a text view with placeholder text.
- * Also provide a setEnabled implementation.
- */
-@interface TextViewWithPlaceHolder : NSTextView {
- NSMutableAttributedString *mPlaceHolderString;
-}
-
-- (BOOL)becomeFirstResponder;
-- (void)drawRect:(NSRect)rect;
-- (BOOL)resignFirstResponder;
-- (void)setPlaceholder:(NSString*)placeholder;
-- (void)insertTab:(id)sender;
-- (void)insertBacktab:(id)sender;
-- (void)setEnabled:(BOOL)enabled;
-- (void)dealloc;
-
-@end
-
-#endif
diff --git a/toolkit/crashreporter/client/crashreporter_osx.mm b/toolkit/crashreporter/client/crashreporter_osx.mm
deleted file mode 100644
index 0768d6da3..000000000
--- a/toolkit/crashreporter/client/crashreporter_osx.mm
+++ /dev/null
@@ -1,922 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#import <Cocoa/Cocoa.h>
-#import <CoreFoundation/CoreFoundation.h>
-#include "crashreporter.h"
-#include "crashreporter_osx.h"
-#include <crt_externs.h>
-#include <spawn.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sstream>
-
-using std::string;
-using std::vector;
-using std::ostringstream;
-
-using namespace CrashReporter;
-
-static NSAutoreleasePool* gMainPool;
-static CrashReporterUI* gUI = 0;
-static StringTable gFiles;
-static StringTable gQueryParameters;
-static string gURLParameter;
-static string gSendURL;
-static vector<string> gRestartArgs;
-static bool gDidTrySend = false;
-static bool gRTLlayout = false;
-
-static cpu_type_t pref_cpu_types[2] = {
-#if defined(__i386__)
- CPU_TYPE_X86,
-#elif defined(__x86_64__)
- CPU_TYPE_X86_64,
-#elif defined(__ppc__)
- CPU_TYPE_POWERPC,
-#endif
- CPU_TYPE_ANY };
-
-#define NSSTR(s) [NSString stringWithUTF8String:(s).c_str()]
-
-static NSString* Str(const char* aName)
-{
- string str = gStrings[aName];
- if (str.empty()) str = "?";
- return NSSTR(str);
-}
-
-static bool RestartApplication()
-{
- vector<char*> argv(gRestartArgs.size() + 1);
-
- posix_spawnattr_t spawnattr;
- if (posix_spawnattr_init(&spawnattr) != 0) {
- return false;
- }
-
- // Set spawn attributes.
- size_t attr_count = sizeof(pref_cpu_types) / sizeof(pref_cpu_types[0]);
- size_t attr_ocount = 0;
- if (posix_spawnattr_setbinpref_np(&spawnattr,
- attr_count,
- pref_cpu_types,
- &attr_ocount) != 0 ||
- attr_ocount != attr_count) {
- posix_spawnattr_destroy(&spawnattr);
- return false;
- }
-
- unsigned int i;
- for (i = 0; i < gRestartArgs.size(); i++) {
- argv[i] = (char*)gRestartArgs[i].c_str();
- }
- argv[i] = 0;
-
- char **env = NULL;
- char ***nsEnv = _NSGetEnviron();
- if (nsEnv)
- env = *nsEnv;
- int result = posix_spawnp(NULL,
- argv[0],
- NULL,
- &spawnattr,
- &argv[0],
- env);
-
- posix_spawnattr_destroy(&spawnattr);
-
- return result == 0;
-}
-
-@implementation CrashReporterUI
-
--(void)awakeFromNib
-{
- gUI = self;
- [mWindow center];
-
- [mWindow setTitle:[[NSBundle mainBundle]
- objectForInfoDictionaryKey:@"CFBundleName"]];
-}
-
--(void)showCrashUI:(const StringTable&)files
- queryParameters:(const StringTable&)queryParameters
- sendURL:(const string&)sendURL
-{
- gFiles = files;
- gQueryParameters = queryParameters;
- gSendURL = sendURL;
-
- [mWindow setTitle:Str(ST_CRASHREPORTERTITLE)];
- [mHeaderLabel setStringValue:Str(ST_CRASHREPORTERHEADER)];
-
- NSRect viewReportFrame = [mViewReportButton frame];
- [mViewReportButton setTitle:Str(ST_VIEWREPORT)];
- [mViewReportButton sizeToFit];
- if (gRTLlayout) {
- // sizeToFit will keep the left side fixed, so realign
- float oldWidth = viewReportFrame.size.width;
- viewReportFrame = [mViewReportButton frame];
- viewReportFrame.origin.x += oldWidth - viewReportFrame.size.width;
- [mViewReportButton setFrame: viewReportFrame];
- }
-
- [mSubmitReportButton setTitle:Str(ST_CHECKSUBMIT)];
- [mIncludeURLButton setTitle:Str(ST_CHECKURL)];
- [mEmailMeButton setTitle:Str(ST_CHECKEMAIL)];
- [mViewReportOkButton setTitle:Str(ST_OK)];
-
- [mCommentText setPlaceholder:Str(ST_COMMENTGRAYTEXT)];
- if (gRTLlayout)
- [mCommentText toggleBaseWritingDirection:self];
- [[mEmailText cell] setPlaceholderString:Str(ST_EMAILGRAYTEXT)];
-
- if (gQueryParameters.find("URL") != gQueryParameters.end()) {
- // save the URL value in case the checkbox gets unchecked
- gURLParameter = gQueryParameters["URL"];
- }
- else {
- // no URL specified, hide checkbox
- [mIncludeURLButton removeFromSuperview];
- // shrink window to fit
- NSRect frame = [mWindow frame];
- NSRect includeURLFrame = [mIncludeURLButton frame];
- NSRect emailFrame = [mEmailMeButton frame];
- int buttonMask = [mViewReportButton autoresizingMask];
- int checkMask = [mSubmitReportButton autoresizingMask];
- int commentScrollMask = [mCommentScrollView autoresizingMask];
-
- [mViewReportButton setAutoresizingMask:NSViewMinYMargin];
- [mSubmitReportButton setAutoresizingMask:NSViewMinYMargin];
- [mCommentScrollView setAutoresizingMask:NSViewMinYMargin];
-
- // remove all the space in between
- frame.size.height -= includeURLFrame.origin.y - emailFrame.origin.y;
- [mWindow setFrame:frame display: true animate:NO];
-
- [mViewReportButton setAutoresizingMask:buttonMask];
- [mSubmitReportButton setAutoresizingMask:checkMask];
- [mCommentScrollView setAutoresizingMask:commentScrollMask];
- }
-
- // resize some buttons horizontally and possibly some controls vertically
- [self doInitialResizing];
-
- // load default state of submit checkbox
- // we don't just do this via IB because we want the default to be
- // off a certain percentage of the time
- BOOL submitChecked = NO;
- NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
- if (nil != [userDefaults objectForKey:@"submitReport"]) {
- submitChecked = [userDefaults boolForKey:@"submitReport"];
- }
- else {
- // use compile-time specified enable percentage
- submitChecked = ShouldEnableSending();
- [userDefaults setBool:submitChecked forKey:@"submitReport"];
- }
- [mSubmitReportButton setState:(submitChecked ? NSOnState : NSOffState)];
-
- [self updateSubmit];
- [self updateURL];
- [self updateEmail];
-
- [mWindow makeKeyAndOrderFront:nil];
-}
-
--(void)showErrorUI:(const string&)message
-{
- [self setView: mErrorView animate: NO];
-
- [mErrorHeaderLabel setStringValue:Str(ST_CRASHREPORTERHEADER)];
- [self setStringFitVertically:mErrorLabel
- string:NSSTR(message)
- resizeWindow:YES];
- [mErrorCloseButton setTitle:Str(ST_OK)];
-
- [mErrorCloseButton setKeyEquivalent:@"\r"];
- [mWindow makeFirstResponder:mErrorCloseButton];
- [mWindow makeKeyAndOrderFront:nil];
-}
-
--(void)showReportInfo
-{
- NSDictionary* boldAttr = [NSDictionary
- dictionaryWithObject:
- [NSFont boldSystemFontOfSize:
- [NSFont smallSystemFontSize]]
- forKey:NSFontAttributeName];
- NSDictionary* normalAttr = [NSDictionary
- dictionaryWithObject:
- [NSFont systemFontOfSize:
- [NSFont smallSystemFontSize]]
- forKey:NSFontAttributeName];
-
- [mViewReportTextView setString:@""];
- for (StringTable::iterator iter = gQueryParameters.begin();
- iter != gQueryParameters.end();
- iter++) {
- NSAttributedString* key = [[NSAttributedString alloc]
- initWithString:NSSTR(iter->first + ": ")
- attributes:boldAttr];
- NSAttributedString* value = [[NSAttributedString alloc]
- initWithString:NSSTR(iter->second + "\n")
- attributes:normalAttr];
- [[mViewReportTextView textStorage] appendAttributedString: key];
- [[mViewReportTextView textStorage] appendAttributedString: value];
- [key release];
- [value release];
- }
-
- NSAttributedString* extra = [[NSAttributedString alloc]
- initWithString:NSSTR("\n" + gStrings[ST_EXTRAREPORTINFO])
- attributes:normalAttr];
- [[mViewReportTextView textStorage] appendAttributedString: extra];
- [extra release];
-}
-
-- (void)maybeSubmitReport
-{
- if ([mSubmitReportButton state] == NSOnState) {
- [self setStringFitVertically:mProgressText
- string:Str(ST_REPORTDURINGSUBMIT)
- resizeWindow:YES];
- // disable all the controls
- [self enableControls:NO];
- [mSubmitReportButton setEnabled:NO];
- [mRestartButton setEnabled:NO];
- [mCloseButton setEnabled:NO];
- [mProgressIndicator startAnimation:self];
- gDidTrySend = true;
- [self sendReport];
- } else {
- [NSApp terminate:self];
- }
-}
-
-- (void)closeMeDown:(id)unused
-{
- [NSApp terminate:self];
-}
-
--(IBAction)submitReportClicked:(id)sender
-{
- [self updateSubmit];
- NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
- [userDefaults setBool:([mSubmitReportButton state] == NSOnState)
- forKey:@"submitReport"];
- [userDefaults synchronize];
-}
-
--(IBAction)viewReportClicked:(id)sender
-{
- [self showReportInfo];
- [NSApp beginSheet:mViewReportWindow modalForWindow:mWindow
- modalDelegate:nil didEndSelector:nil contextInfo:nil];
-}
-
-- (IBAction)viewReportOkClicked:(id)sender
-{
- [mViewReportWindow orderOut:nil];
- [NSApp endSheet:mViewReportWindow];
-}
-
--(IBAction)closeClicked:(id)sender
-{
- [self maybeSubmitReport];
-}
-
--(IBAction)restartClicked:(id)sender
-{
- RestartApplication();
- [self maybeSubmitReport];
-}
-
-- (IBAction)includeURLClicked:(id)sender
-{
- [self updateURL];
-}
-
--(IBAction)emailMeClicked:(id)sender
-{
- [self updateEmail];
-}
-
--(void)controlTextDidChange:(NSNotification *)note
-{
- [self updateEmail];
-}
-
-- (void)textDidChange:(NSNotification *)aNotification
-{
- // update comment parameter
- if ([[[mCommentText textStorage] mutableString] length] > 0)
- gQueryParameters["Comments"] = [[[mCommentText textStorage] mutableString]
- UTF8String];
- else
- gQueryParameters.erase("Comments");
-}
-
-// Limit the comment field to 500 bytes in UTF-8
-- (BOOL)textView:(NSTextView *)aTextView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString
-{
- // current string length + replacement text length - replaced range length
- if (([[aTextView string]
- lengthOfBytesUsingEncoding:NSUTF8StringEncoding]
- + [replacementString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]
- - [[[aTextView string] substringWithRange:affectedCharRange]
- lengthOfBytesUsingEncoding:NSUTF8StringEncoding])
- > MAX_COMMENT_LENGTH) {
- return NO;
- }
- return YES;
-}
-
-- (void)doInitialResizing
-{
- NSRect windowFrame = [mWindow frame];
- NSRect restartFrame = [mRestartButton frame];
- NSRect closeFrame = [mCloseButton frame];
- // resize close button to fit text
- float oldCloseWidth = closeFrame.size.width;
- [mCloseButton setTitle:Str(ST_QUIT)];
- [mCloseButton sizeToFit];
- closeFrame = [mCloseButton frame];
- // move close button left if it grew
- if (!gRTLlayout) {
- closeFrame.origin.x -= closeFrame.size.width - oldCloseWidth;
- }
-
- if (gRestartArgs.size() == 0) {
- [mRestartButton removeFromSuperview];
- if (!gRTLlayout) {
- closeFrame.origin.x = restartFrame.origin.x +
- (restartFrame.size.width - closeFrame.size.width);
- }
- else {
- closeFrame.origin.x = restartFrame.origin.x;
- }
- [mCloseButton setFrame: closeFrame];
- [mCloseButton setKeyEquivalent:@"\r"];
- } else {
- [mRestartButton setTitle:Str(ST_RESTART)];
- // resize "restart" button
- float oldRestartWidth = restartFrame.size.width;
- [mRestartButton sizeToFit];
- restartFrame = [mRestartButton frame];
- if (!gRTLlayout) {
- // move left by the amount that the button grew
- restartFrame.origin.x -= restartFrame.size.width - oldRestartWidth;
- closeFrame.origin.x -= restartFrame.size.width - oldRestartWidth;
- }
- else {
- // shift the close button right in RTL
- closeFrame.origin.x += restartFrame.size.width - oldRestartWidth;
- }
- [mRestartButton setFrame: restartFrame];
- [mCloseButton setFrame: closeFrame];
- // possibly resize window if both buttons no longer fit
- // leave 20 px from either side of the window, and 12 px
- // between the buttons
- float neededWidth = closeFrame.size.width + restartFrame.size.width +
- 2*20 + 12;
-
- if (neededWidth > windowFrame.size.width) {
- windowFrame.size.width = neededWidth;
- [mWindow setFrame:windowFrame display: true animate: NO];
- }
- [mRestartButton setKeyEquivalent:@"\r"];
- }
-
- NSButton *checkboxes[] = {
- mSubmitReportButton,
- mIncludeURLButton,
- mEmailMeButton
- };
-
- for (int i=0; i<3; i++) {
- NSRect frame = [checkboxes[i] frame];
- [checkboxes[i] sizeToFit];
- if (gRTLlayout) {
- // sizeToFit will keep the left side fixed, so realign
- float oldWidth = frame.size.width;
- frame = [checkboxes[i] frame];
- frame.origin.x += oldWidth - frame.size.width;
- [checkboxes[i] setFrame: frame];
- }
- // keep existing spacing on left side, + 20 px spare on right
- float neededWidth = frame.origin.x + frame.size.width + 20;
- if (neededWidth > windowFrame.size.width) {
- windowFrame.size.width = neededWidth;
- [mWindow setFrame:windowFrame display: true animate: NO];
- }
- }
-
- // do this down here because we may have made the window wider
- // up above
- [self setStringFitVertically:mDescriptionLabel
- string:Str(ST_CRASHREPORTERDESCRIPTION)
- resizeWindow:YES];
-
- // now pin all the controls (except quit/submit) in place,
- // if we lengthen the window after this, it's just to lengthen
- // the progress text, so nothing above that text should move.
- NSView* views[] = {
- mSubmitReportButton,
- mViewReportButton,
- mCommentScrollView,
- mIncludeURLButton,
- mEmailMeButton,
- mEmailText,
- mProgressIndicator,
- mProgressText
- };
- for (unsigned int i=0; i<sizeof(views)/sizeof(views[0]); i++) {
- [views[i] setAutoresizingMask:NSViewMinYMargin];
- }
-}
-
--(float)setStringFitVertically:(NSControl*)control
- string:(NSString*)str
- resizeWindow:(BOOL)resizeWindow
-{
- // hack to make the text field grow vertically
- NSRect frame = [control frame];
- float oldHeight = frame.size.height;
-
- frame.size.height = 10000;
- NSSize oldCellSize = [[control cell] cellSizeForBounds: frame];
- [control setStringValue: str];
- NSSize newCellSize = [[control cell] cellSizeForBounds: frame];
-
- float delta = newCellSize.height - oldCellSize.height;
- frame.origin.y -= delta;
- frame.size.height = oldHeight + delta;
- [control setFrame: frame];
-
- if (resizeWindow) {
- NSRect frame = [mWindow frame];
- frame.origin.y -= delta;
- frame.size.height += delta;
- [mWindow setFrame:frame display: true animate: NO];
- }
-
- return delta;
-}
-
--(void)setView: (NSView*)v animate: (BOOL)animate
-{
- NSRect frame = [mWindow frame];
-
- NSRect oldViewFrame = [[mWindow contentView] frame];
- NSRect newViewFrame = [v frame];
-
- frame.origin.y += oldViewFrame.size.height - newViewFrame.size.height;
- frame.size.height -= oldViewFrame.size.height - newViewFrame.size.height;
-
- frame.origin.x += oldViewFrame.size.width - newViewFrame.size.width;
- frame.size.width -= oldViewFrame.size.width - newViewFrame.size.width;
-
- [mWindow setContentView:v];
- [mWindow setFrame:frame display:true animate:animate];
-}
-
-- (void)enableControls:(BOOL)enabled
-{
- [mViewReportButton setEnabled:enabled];
- [mIncludeURLButton setEnabled:enabled];
- [mEmailMeButton setEnabled:enabled];
- [mCommentText setEnabled:enabled];
- [mCommentScrollView setHasVerticalScroller:enabled];
- [self updateEmail];
-}
-
--(void)updateSubmit
-{
- if ([mSubmitReportButton state] == NSOnState) {
- [self setStringFitVertically:mProgressText
- string:Str(ST_REPORTPRESUBMIT)
- resizeWindow:YES];
- [mProgressText setHidden:NO];
- // enable all the controls
- [self enableControls:YES];
- }
- else {
- // not submitting, disable all the controls under
- // the submit checkbox, and hide the status text
- [mProgressText setHidden:YES];
- [self enableControls:NO];
- }
-}
-
--(void)updateURL
-{
- if ([mIncludeURLButton state] == NSOnState && !gURLParameter.empty()) {
- gQueryParameters["URL"] = gURLParameter;
- } else {
- gQueryParameters.erase("URL");
- }
-}
-
--(void)updateEmail
-{
- if ([mEmailMeButton state] == NSOnState &&
- [mSubmitReportButton state] == NSOnState) {
- NSString* email = [mEmailText stringValue];
- gQueryParameters["Email"] = [email UTF8String];
- [mEmailText setEnabled:YES];
- } else {
- gQueryParameters.erase("Email");
- [mEmailText setEnabled:NO];
- }
-}
-
--(void)sendReport
-{
- if (![self setupPost]) {
- LogMessage("Crash report submission failed: could not set up POST data");
- [self setStringFitVertically:mProgressText
- string:Str(ST_SUBMITFAILED)
- resizeWindow:YES];
- // quit after 5 seconds
- [self performSelector:@selector(closeMeDown:) withObject:nil
- afterDelay:5.0];
- }
-
- [NSThread detachNewThreadSelector:@selector(uploadThread:)
- toTarget:self
- withObject:mPost];
-}
-
--(bool)setupPost
-{
- NSURL* url = [NSURL URLWithString:[NSSTR(gSendURL) stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
- if (!url) return false;
-
- mPost = [[HTTPMultipartUpload alloc] initWithURL: url];
- if (!mPost) return false;
-
- NSMutableDictionary* parameters =
- [[NSMutableDictionary alloc] initWithCapacity: gQueryParameters.size()];
- if (!parameters) return false;
-
- StringTable::const_iterator end = gQueryParameters.end();
- for (StringTable::const_iterator i = gQueryParameters.begin();
- i != end;
- i++) {
- NSString* key = NSSTR(i->first);
- NSString* value = NSSTR(i->second);
- if (key && value) {
- [parameters setObject: value forKey: key];
- } else {
- ostringstream message;
- message << "Warning: skipping annotation '" << i->first
- << "' due to malformed UTF-8 encoding";
- LogMessage(message.str());
- }
- }
-
- for (StringTable::const_iterator i = gFiles.begin();
- i != gFiles.end();
- i++) {
- [mPost addFileAtPath: NSSTR(i->second) name: NSSTR(i->first)];
- }
-
- [mPost setParameters: parameters];
- [parameters release];
-
- return true;
-}
-
--(void)uploadComplete:(NSData*)data
-{
- NSHTTPURLResponse* response = [mPost response];
- [mPost release];
-
- bool success;
- string reply;
- if (!data || !response || [response statusCode] != 200) {
- success = false;
- reply = "";
-
- // if data is nil, we probably logged an error in uploadThread
- if (data != nil && response != nil) {
- ostringstream message;
- message << "Crash report submission failed: server returned status "
- << [response statusCode];
- LogMessage(message.str());
- }
- } else {
- success = true;
- LogMessage("Crash report submitted successfully");
-
- NSString* encodingName = [response textEncodingName];
- NSStringEncoding encoding;
- if (encodingName) {
- encoding = CFStringConvertEncodingToNSStringEncoding(
- CFStringConvertIANACharSetNameToEncoding((CFStringRef)encodingName));
- } else {
- encoding = NSISOLatin1StringEncoding;
- }
- NSString* r = [[NSString alloc] initWithData: data encoding: encoding];
- reply = [r UTF8String];
- [r release];
- }
-
- SendCompleted(success, reply);
-
- [mProgressIndicator stopAnimation:self];
- if (success) {
- [self setStringFitVertically:mProgressText
- string:Str(ST_REPORTSUBMITSUCCESS)
- resizeWindow:YES];
- } else {
- [self setStringFitVertically:mProgressText
- string:Str(ST_SUBMITFAILED)
- resizeWindow:YES];
- }
- // quit after 5 seconds
- [self performSelector:@selector(closeMeDown:) withObject:nil
- afterDelay:5.0];
-}
-
--(void)uploadThread:(HTTPMultipartUpload*)post
-{
- NSAutoreleasePool* autoreleasepool = [[NSAutoreleasePool alloc] init];
- NSError* error = nil;
- NSData* data = [post send: &error];
- if (error) {
- data = nil;
- NSString* errorDesc = [error localizedDescription];
- string message = [errorDesc UTF8String];
- LogMessage("Crash report submission failed: " + message);
- }
-
- [self performSelectorOnMainThread: @selector(uploadComplete:)
- withObject: data
- waitUntilDone: YES];
-
- [autoreleasepool release];
-}
-
-// to get auto-quit when we close the window
--(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
-{
- return YES;
-}
-
--(void)applicationWillTerminate:(NSNotification *)aNotification
-{
- // since we use [NSApp terminate:] we never return to main,
- // so do our cleanup here
- if (!gDidTrySend)
- DeleteDump();
-}
-
-@end
-
-@implementation TextViewWithPlaceHolder
-
-- (BOOL)becomeFirstResponder
-{
- [self setNeedsDisplay:YES];
- return [super becomeFirstResponder];
-}
-
-- (void)drawRect:(NSRect)rect
-{
- [super drawRect:rect];
- if (mPlaceHolderString && [[self string] isEqualToString:@""] &&
- self != [[self window] firstResponder])
- [mPlaceHolderString drawInRect:[self frame]];
-}
-
-- (BOOL)resignFirstResponder
-{
- [self setNeedsDisplay:YES];
- return [super resignFirstResponder];
-}
-
-- (void)setPlaceholder:(NSString*)placeholder
-{
- NSColor* txtColor = [NSColor disabledControlTextColor];
- NSDictionary* txtDict = [NSDictionary
- dictionaryWithObjectsAndKeys:txtColor,
- NSForegroundColorAttributeName, nil];
- mPlaceHolderString = [[NSMutableAttributedString alloc]
- initWithString:placeholder attributes:txtDict];
- if (gRTLlayout)
- [mPlaceHolderString setAlignment:NSRightTextAlignment
- range:NSMakeRange(0, [placeholder length])];
-
-}
-
-- (void)insertTab:(id)sender
-{
- // don't actually want to insert tabs, just tab to next control
- [[self window] selectNextKeyView:sender];
-}
-
-- (void)insertBacktab:(id)sender
-{
- [[self window] selectPreviousKeyView:sender];
-}
-
-- (void)setEnabled:(BOOL)enabled
-{
- [self setSelectable:enabled];
- [self setEditable:enabled];
- if (![[self string] isEqualToString:@""]) {
- NSAttributedString* colorString;
- NSColor* txtColor;
- if (enabled)
- txtColor = [NSColor textColor];
- else
- txtColor = [NSColor disabledControlTextColor];
- NSDictionary *txtDict = [NSDictionary
- dictionaryWithObjectsAndKeys:txtColor,
- NSForegroundColorAttributeName, nil];
- colorString = [[NSAttributedString alloc]
- initWithString:[self string]
- attributes:txtDict];
- [[self textStorage] setAttributedString: colorString];
- [self setInsertionPointColor:txtColor];
- [colorString release];
- }
-}
-
-- (void)dealloc
-{
- [mPlaceHolderString release];
- [super dealloc];
-}
-
-@end
-
-/* === Crashreporter UI Functions === */
-
-bool UIInit()
-{
- gMainPool = [[NSAutoreleasePool alloc] init];
- [NSApplication sharedApplication];
-
- if (gStrings.find("isRTL") != gStrings.end() &&
- gStrings["isRTL"] == "yes")
- gRTLlayout = true;
-
- [NSBundle loadNibNamed:(gRTLlayout ? @"MainMenuRTL" : @"MainMenu")
- owner:NSApp];
-
- return true;
-}
-
-void UIShutdown()
-{
- [gMainPool release];
-}
-
-void UIShowDefaultUI()
-{
- [gUI showErrorUI: gStrings[ST_CRASHREPORTERDEFAULT]];
- [NSApp run];
-}
-
-bool UIShowCrashUI(const StringTable& files,
- const StringTable& queryParameters,
- const string& sendURL,
- const vector<string>& restartArgs)
-{
- gRestartArgs = restartArgs;
-
- [gUI showCrashUI: files
- queryParameters: queryParameters
- sendURL: sendURL];
- [NSApp run];
-
- return gDidTrySend;
-}
-
-void UIError_impl(const string& message)
-{
- if (!gUI) {
- // UI failed to initialize, printing is the best we can do
- printf("Error: %s\n", message.c_str());
- return;
- }
-
- [gUI showErrorUI: message];
- [NSApp run];
-}
-
-bool UIGetIniPath(string& path)
-{
- NSString* tmpPath = [NSString stringWithUTF8String:gArgv[0]];
- NSString* iniName = [tmpPath lastPathComponent];
- iniName = [iniName stringByAppendingPathExtension:@"ini"];
- tmpPath = [tmpPath stringByDeletingLastPathComponent];
- tmpPath = [tmpPath stringByDeletingLastPathComponent];
- tmpPath = [tmpPath stringByAppendingPathComponent:@"Resources"];
- tmpPath = [tmpPath stringByAppendingPathComponent:iniName];
- path = [tmpPath UTF8String];
- return true;
-}
-
-bool UIGetSettingsPath(const string& vendor,
- const string& product,
- string& settingsPath)
-{
- FSRef foundRef;
- OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType,
- kCreateFolder, &foundRef);
- if (err != noErr)
- return false;
-
- unsigned char path[PATH_MAX];
- FSRefMakePath(&foundRef, path, sizeof(path));
- NSString* destPath = [NSString stringWithUTF8String:reinterpret_cast<char*>(path)];
-
- // Note that MacOS ignores the vendor when creating the profile hierarchy -
- // all application preferences directories live alongside one another in
- // ~/Library/Application Support/
- destPath = [destPath stringByAppendingPathComponent: NSSTR(product)];
- // Thunderbird stores its profile in ~/Library/Thunderbird,
- // but we're going to put stuff in ~/Library/Application Support/Thunderbird
- // anyway, so we have to ensure that path exists.
- string tempPath = [destPath UTF8String];
- if (!UIEnsurePathExists(tempPath))
- return false;
-
- destPath = [destPath stringByAppendingPathComponent: @"Crash Reports"];
-
- settingsPath = [destPath UTF8String];
-
- return true;
-}
-
-bool UIEnsurePathExists(const string& path)
-{
- int ret = mkdir(path.c_str(), S_IRWXU);
- int e = errno;
- if (ret == -1 && e != EEXIST)
- return false;
-
- return true;
-}
-
-bool UIFileExists(const string& path)
-{
- struct stat sb;
- int ret = stat(path.c_str(), &sb);
- if (ret == -1 || !(sb.st_mode & S_IFREG))
- return false;
-
- return true;
-}
-
-bool UIMoveFile(const string& file, const string& newfile)
-{
- if (!rename(file.c_str(), newfile.c_str()))
- return true;
- if (errno != EXDEV)
- return false;
-
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSString *source = [fileManager stringWithFileSystemRepresentation:file.c_str() length:file.length()];
- NSString *dest = [fileManager stringWithFileSystemRepresentation:newfile.c_str() length:newfile.length()];
- if (!source || !dest)
- return false;
-
- [fileManager moveItemAtPath:source toPath:dest error:NULL];
- return UIFileExists(newfile);
-}
-
-bool UIDeleteFile(const string& file)
-{
- return (unlink(file.c_str()) != -1);
-}
-
-std::ifstream* UIOpenRead(const string& filename)
-{
- return new std::ifstream(filename.c_str(), std::ios::in);
-}
-
-std::ofstream* UIOpenWrite(const string& filename,
- bool append, // append=false
- bool binary) // binary=false
-{
- std::ios_base::openmode mode = std::ios::out;
-
- if (append) {
- mode = mode | std::ios::app;
- }
-
- if (binary) {
- mode = mode | std::ios::binary;
- }
-
- return new std::ofstream(filename.c_str(), mode);
-}
diff --git a/toolkit/crashreporter/client/crashreporter_unix_common.cpp b/toolkit/crashreporter/client/crashreporter_unix_common.cpp
deleted file mode 100644
index f42a35616..000000000
--- a/toolkit/crashreporter/client/crashreporter_unix_common.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "crashreporter.h"
-
-#include <algorithm>
-
-#include <dirent.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-using namespace CrashReporter;
-using std::string;
-using std::vector;
-using std::sort;
-
-struct FileData
-{
- time_t timestamp;
- string path;
-};
-
-static bool CompareFDTime(const FileData& fd1, const FileData& fd2)
-{
- return fd1.timestamp > fd2.timestamp;
-}
-
-void UIPruneSavedDumps(const std::string& directory)
-{
- DIR *dirfd = opendir(directory.c_str());
- if (!dirfd)
- return;
-
- vector<FileData> dumpfiles;
-
- while (dirent *dir = readdir(dirfd)) {
- FileData fd;
- fd.path = directory + '/' + dir->d_name;
- if (fd.path.size() < 5)
- continue;
-
- if (fd.path.compare(fd.path.size() - 4, 4, ".dmp") != 0)
- continue;
-
- struct stat st;
- if (stat(fd.path.c_str(), &st)) {
- closedir(dirfd);
- return;
- }
-
- fd.timestamp = st.st_mtime;
-
- dumpfiles.push_back(fd);
- }
-
- sort(dumpfiles.begin(), dumpfiles.end(), CompareFDTime);
-
- while (dumpfiles.size() > kSaveCount) {
- // get the path of the oldest file
- string path = dumpfiles[dumpfiles.size() - 1].path;
- UIDeleteFile(path.c_str());
-
- // s/.dmp/.extra/
- path.replace(path.size() - 4, 4, ".extra");
- UIDeleteFile(path.c_str());
-
- dumpfiles.pop_back();
- }
-}
-
-void UIRunMinidumpAnalyzer(const string& exename, const string& filename)
-{
- // Run the minidump analyzer and wait for it to finish
- pid_t pid = fork();
-
- if (pid == -1) {
- return; // Nothing to do upon failure
- } else if (pid == 0) {
- execl(exename.c_str(), exename.c_str(), filename.c_str(), nullptr);
- } else {
- waitpid(pid, nullptr, 0);
- }
-}
diff --git a/toolkit/crashreporter/client/crashreporter_win.cpp b/toolkit/crashreporter/client/crashreporter_win.cpp
deleted file mode 100644
index 57ca495ba..000000000
--- a/toolkit/crashreporter/client/crashreporter_win.cpp
+++ /dev/null
@@ -1,1568 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef WIN32_LEAN_AND_MEAN
-#undef WIN32_LEAN_AND_MEAN
-#endif
-
-#include "crashreporter.h"
-
-#include <windows.h>
-#include <versionhelpers.h>
-#include <commctrl.h>
-#include <richedit.h>
-#include <shellapi.h>
-#include <shlobj.h>
-#include <shlwapi.h>
-#include <math.h>
-#include <set>
-#include <algorithm>
-#include "resource.h"
-#include "client/windows/sender/crash_report_sender.h"
-#include "common/windows/string_utils-inl.h"
-
-#define CRASH_REPORTER_VALUE L"Enabled"
-#define SUBMIT_REPORT_VALUE L"SubmitCrashReport"
-#define SUBMIT_REPORT_OLD L"SubmitReport"
-#define INCLUDE_URL_VALUE L"IncludeURL"
-#define EMAIL_ME_VALUE L"EmailMe"
-#define EMAIL_VALUE L"Email"
-#define MAX_EMAIL_LENGTH 1024
-
-#define SENDURL_ORIGINAL L"https://crash-reports.mozilla.com/submit"
-#define SENDURL_XPSP2 L"https://crash-reports-xpsp2.mozilla.com/submit"
-
-#define WM_UPLOADCOMPLETE WM_APP
-
-// Thanks, Windows.h :(
-#undef min
-#undef max
-
-using std::string;
-using std::wstring;
-using std::map;
-using std::vector;
-using std::set;
-using std::ios;
-using std::ifstream;
-using std::ofstream;
-
-using namespace CrashReporter;
-
-typedef struct {
- HWND hDlg;
- map<wstring,wstring> queryParameters;
- map<wstring,wstring> files;
- wstring sendURL;
-
- wstring serverResponse;
-} SendThreadData;
-
-/*
- * Per http://msdn2.microsoft.com/en-us/library/ms645398(VS.85).aspx
- * "The DLGTEMPLATEEX structure is not defined in any standard header file.
- * The structure definition is provided here to explain the format of an
- * extended template for a dialog box.
-*/
-typedef struct {
- WORD dlgVer;
- WORD signature;
- DWORD helpID;
- DWORD exStyle;
- // There's more to this struct, but it has weird variable-length
- // members, and I only actually need to touch exStyle on an existing
- // instance, so I've omitted the rest.
-} DLGTEMPLATEEX;
-
-static HANDLE gThreadHandle;
-static SendThreadData gSendData = { 0, };
-static vector<string> gRestartArgs;
-static map<wstring,wstring> gQueryParameters;
-static wstring gCrashReporterKey(L"Software\\Mozilla\\Crash Reporter");
-static wstring gURLParameter;
-static int gCheckboxPadding = 6;
-static bool gRTLlayout = false;
-
-// When vertically resizing the dialog, these items should move down
-static set<UINT> gAttachedBottom;
-
-// Default set of items for gAttachedBottom
-static const UINT kDefaultAttachedBottom[] = {
- IDC_SUBMITREPORTCHECK,
- IDC_VIEWREPORTBUTTON,
- IDC_COMMENTTEXT,
- IDC_INCLUDEURLCHECK,
- IDC_EMAILMECHECK,
- IDC_EMAILTEXT,
- IDC_PROGRESSTEXT,
- IDC_THROBBER,
- IDC_CLOSEBUTTON,
- IDC_RESTARTBUTTON,
-};
-
-static wstring UTF8ToWide(const string& utf8, bool *success = 0);
-static DWORD WINAPI SendThreadProc(LPVOID param);
-
-static wstring Str(const char* key)
-{
- return UTF8ToWide(gStrings[key]);
-}
-
-/* === win32 helper functions === */
-
-static void DoInitCommonControls()
-{
- INITCOMMONCONTROLSEX ic;
- ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
- ic.dwICC = ICC_PROGRESS_CLASS;
- InitCommonControlsEx(&ic);
- // also get the rich edit control
- LoadLibrary(L"Msftedit.dll");
-}
-
-static bool GetBoolValue(HKEY hRegKey, LPCTSTR valueName, DWORD* value)
-{
- DWORD type, dataSize;
- dataSize = sizeof(DWORD);
- if (RegQueryValueEx(hRegKey, valueName, nullptr,
- &type, (LPBYTE)value, &dataSize) == ERROR_SUCCESS &&
- type == REG_DWORD)
- return true;
-
- return false;
-}
-
-// Removes a value from HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER, if it exists.
-static void RemoveUnusedValues(const wchar_t* key, LPCTSTR valueName)
-{
- HKEY hRegKey;
-
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_SET_VALUE, &hRegKey)
- == ERROR_SUCCESS) {
- RegDeleteValue(hRegKey, valueName);
- RegCloseKey(hRegKey);
- }
-
- if (RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_SET_VALUE, &hRegKey)
- == ERROR_SUCCESS) {
- RegDeleteValue(hRegKey, valueName);
- RegCloseKey(hRegKey);
- }
-}
-
-static bool CheckBoolKey(const wchar_t* key,
- const wchar_t* valueName,
- bool* enabled)
-{
- /*
- * NOTE! This code needs to stay in sync with the preference checking
- * code in in nsExceptionHandler.cpp.
- */
- *enabled = false;
- bool found = false;
- HKEY hRegKey;
- DWORD val;
- // see if our reg key is set globally
- if (RegOpenKey(HKEY_LOCAL_MACHINE, key, &hRegKey) == ERROR_SUCCESS) {
- if (GetBoolValue(hRegKey, valueName, &val)) {
- *enabled = (val == 1);
- found = true;
- }
- RegCloseKey(hRegKey);
- } else {
- // look for it in user settings
- if (RegOpenKey(HKEY_CURRENT_USER, key, &hRegKey) == ERROR_SUCCESS) {
- if (GetBoolValue(hRegKey, valueName, &val)) {
- *enabled = (val == 1);
- found = true;
- }
- RegCloseKey(hRegKey);
- }
- }
-
- return found;
-}
-
-static void SetBoolKey(const wchar_t* key, const wchar_t* value, bool enabled)
-{
- /*
- * NOTE! This code needs to stay in sync with the preference setting
- * code in in nsExceptionHandler.cpp.
- */
- HKEY hRegKey;
-
- // remove the old value from the registry if it exists
- RemoveUnusedValues(key, SUBMIT_REPORT_OLD);
-
- if (RegCreateKey(HKEY_CURRENT_USER, key, &hRegKey) == ERROR_SUCCESS) {
- DWORD data = (enabled ? 1 : 0);
- RegSetValueEx(hRegKey, value, 0, REG_DWORD, (LPBYTE)&data, sizeof(data));
- RegCloseKey(hRegKey);
- }
-}
-
-static bool GetStringValue(HKEY hRegKey, LPCTSTR valueName, wstring& value)
-{
- DWORD type, dataSize;
- wchar_t buf[2048];
- dataSize = sizeof(buf);
- if (RegQueryValueEx(hRegKey, valueName, nullptr,
- &type, (LPBYTE)buf, &dataSize) == ERROR_SUCCESS &&
- type == REG_SZ) {
- value = buf;
- return true;
- }
-
- return false;
-}
-
-static bool GetStringKey(const wchar_t* key,
- const wchar_t* valueName,
- wstring& value)
-{
- value = L"";
- bool found = false;
- HKEY hRegKey;
- // see if our reg key is set globally
- if (RegOpenKey(HKEY_LOCAL_MACHINE, key, &hRegKey) == ERROR_SUCCESS) {
- if (GetStringValue(hRegKey, valueName, value)) {
- found = true;
- }
- RegCloseKey(hRegKey);
- } else {
- // look for it in user settings
- if (RegOpenKey(HKEY_CURRENT_USER, key, &hRegKey) == ERROR_SUCCESS) {
- if (GetStringValue(hRegKey, valueName, value)) {
- found = true;
- }
- RegCloseKey(hRegKey);
- }
- }
-
- return found;
-}
-
-static void SetStringKey(const wchar_t* key,
- const wchar_t* valueName,
- const wstring& value)
-{
- HKEY hRegKey;
- if (RegCreateKey(HKEY_CURRENT_USER, key, &hRegKey) == ERROR_SUCCESS) {
- RegSetValueEx(hRegKey, valueName, 0, REG_SZ,
- (LPBYTE)value.c_str(),
- (value.length() + 1) * sizeof(wchar_t));
- RegCloseKey(hRegKey);
- }
-}
-
-static string FormatLastError()
-{
- DWORD err = GetLastError();
- LPWSTR s;
- string message = "Crash report submission failed: ";
- // odds are it's a WinInet error
- HANDLE hInetModule = GetModuleHandle(L"WinInet.dll");
- if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_FROM_HMODULE,
- hInetModule,
- err,
- 0,
- (LPWSTR)&s,
- 0,
- nullptr) != 0) {
- message += WideToUTF8(s, nullptr);
- LocalFree(s);
- // strip off any trailing newlines
- string::size_type n = message.find_last_not_of("\r\n");
- if (n < message.size() - 1) {
- message.erase(n+1);
- }
- }
- else {
- char buf[64];
- sprintf(buf, "Unknown error, error code: 0x%08x", err);
- message += buf;
- }
- return message;
-}
-
-#define TS_DRAW 2
-#define BP_CHECKBOX 3
-
-typedef HANDLE (WINAPI*OpenThemeDataPtr)(HWND hwnd, LPCWSTR pszClassList);
-typedef HRESULT (WINAPI*CloseThemeDataPtr)(HANDLE hTheme);
-typedef HRESULT (WINAPI*GetThemePartSizePtr)(HANDLE hTheme, HDC hdc, int iPartId,
- int iStateId, RECT* prc, int ts,
- SIZE* psz);
-typedef HRESULT (WINAPI*GetThemeContentRectPtr)(HANDLE hTheme, HDC hdc, int iPartId,
- int iStateId, const RECT* pRect,
- RECT* pContentRect);
-
-
-static void GetThemeSizes(HWND hwnd)
-{
- HMODULE themeDLL = LoadLibrary(L"uxtheme.dll");
-
- if (!themeDLL)
- return;
-
- OpenThemeDataPtr openTheme =
- (OpenThemeDataPtr)GetProcAddress(themeDLL, "OpenThemeData");
- CloseThemeDataPtr closeTheme =
- (CloseThemeDataPtr)GetProcAddress(themeDLL, "CloseThemeData");
- GetThemePartSizePtr getThemePartSize =
- (GetThemePartSizePtr)GetProcAddress(themeDLL, "GetThemePartSize");
-
- if (!openTheme || !closeTheme || !getThemePartSize) {
- FreeLibrary(themeDLL);
- return;
- }
-
- HANDLE buttonTheme = openTheme(hwnd, L"Button");
- if (!buttonTheme) {
- FreeLibrary(themeDLL);
- return;
- }
- HDC hdc = GetDC(hwnd);
- SIZE s;
- getThemePartSize(buttonTheme, hdc, BP_CHECKBOX, 0, nullptr, TS_DRAW, &s);
- gCheckboxPadding = s.cx;
- closeTheme(buttonTheme);
- FreeLibrary(themeDLL);
-}
-
-// Gets the position of a window relative to another window's client area
-static void GetRelativeRect(HWND hwnd, HWND hwndParent, RECT* r)
-{
- GetWindowRect(hwnd, r);
- MapWindowPoints(nullptr, hwndParent, (POINT*)r, 2);
-}
-
-static void SetDlgItemVisible(HWND hwndDlg, UINT item, bool visible)
-{
- HWND hwnd = GetDlgItem(hwndDlg, item);
-
- ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
-}
-
-static void SetDlgItemDisabled(HWND hwndDlg, UINT item, bool disabled)
-{
- HWND hwnd = GetDlgItem(hwndDlg, item);
- LONG style = GetWindowLong(hwnd, GWL_STYLE);
- if (!disabled)
- style |= WS_DISABLED;
- else
- style &= ~WS_DISABLED;
-
- SetWindowLong(hwnd, GWL_STYLE, style);
-}
-
-/* === Crash Reporting Dialog === */
-
-static void StretchDialog(HWND hwndDlg, int ydiff)
-{
- RECT r;
- GetWindowRect(hwndDlg, &r);
- r.bottom += ydiff;
- MoveWindow(hwndDlg, r.left, r.top,
- r.right - r.left, r.bottom - r.top, TRUE);
-}
-
-static void ReflowDialog(HWND hwndDlg, int ydiff)
-{
- // Move items attached to the bottom down/up by as much as
- // the window resize
- for (set<UINT>::const_iterator item = gAttachedBottom.begin();
- item != gAttachedBottom.end();
- item++) {
- RECT r;
- HWND hwnd = GetDlgItem(hwndDlg, *item);
- GetRelativeRect(hwnd, hwndDlg, &r);
- r.top += ydiff;
- r.bottom += ydiff;
- MoveWindow(hwnd, r.left, r.top,
- r.right - r.left, r.bottom - r.top, TRUE);
- }
-}
-
-static DWORD WINAPI SendThreadProc(LPVOID param)
-{
- bool finishedOk;
- SendThreadData* td = (SendThreadData*)param;
-
- if (td->sendURL.empty()) {
- finishedOk = false;
- LogMessage("No server URL, not sending report");
- } else {
- google_breakpad::CrashReportSender sender(L"");
- finishedOk = (sender.SendCrashReport(td->sendURL,
- td->queryParameters,
- td->files,
- &td->serverResponse)
- == google_breakpad::RESULT_SUCCEEDED);
- if (finishedOk) {
- LogMessage("Crash report submitted successfully");
- }
- else {
- // get an error string and print it to the log
- //XXX: would be nice to get the HTTP status code here, filed:
- // http://code.google.com/p/google-breakpad/issues/detail?id=220
- LogMessage(FormatLastError());
- }
- }
-
- PostMessage(td->hDlg, WM_UPLOADCOMPLETE, finishedOk ? 1 : 0, 0);
-
- return 0;
-}
-
-static void EndCrashReporterDialog(HWND hwndDlg, int code)
-{
- // Save the current values to the registry
- wchar_t email[MAX_EMAIL_LENGTH];
- GetDlgItemTextW(hwndDlg, IDC_EMAILTEXT, email,
- sizeof(email) / sizeof(email[0]));
- SetStringKey(gCrashReporterKey.c_str(), EMAIL_VALUE, email);
-
- SetBoolKey(gCrashReporterKey.c_str(), INCLUDE_URL_VALUE,
- IsDlgButtonChecked(hwndDlg, IDC_INCLUDEURLCHECK) != 0);
- SetBoolKey(gCrashReporterKey.c_str(), EMAIL_ME_VALUE,
- IsDlgButtonChecked(hwndDlg, IDC_EMAILMECHECK) != 0);
- SetBoolKey(gCrashReporterKey.c_str(), SUBMIT_REPORT_VALUE,
- IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK) != 0);
-
- EndDialog(hwndDlg, code);
-}
-
-static void MaybeResizeProgressText(HWND hwndDlg)
-{
- HWND hwndProgress = GetDlgItem(hwndDlg, IDC_PROGRESSTEXT);
- HDC hdc = GetDC(hwndProgress);
- HFONT hfont = (HFONT)SendMessage(hwndProgress, WM_GETFONT, 0, 0);
- if (hfont)
- SelectObject(hdc, hfont);
- SIZE size;
- RECT rect;
- GetRelativeRect(hwndProgress, hwndDlg, &rect);
-
- wchar_t text[1024];
- GetWindowText(hwndProgress, text, 1024);
-
- if (!GetTextExtentPoint32(hdc, text, wcslen(text), &size))
- return;
-
- if (size.cx < (rect.right - rect.left))
- return;
-
- // Figure out how much we need to resize things vertically
- // This is sort of a fudge, but it should be good enough.
- int wantedHeight = size.cy *
- (int)ceil((float)size.cx / (float)(rect.right - rect.left));
- int diff = wantedHeight - (rect.bottom - rect.top);
- if (diff <= 0)
- return;
-
- MoveWindow(hwndProgress, rect.left, rect.top,
- rect.right - rect.left,
- wantedHeight,
- TRUE);
-
- gAttachedBottom.clear();
- gAttachedBottom.insert(IDC_CLOSEBUTTON);
- gAttachedBottom.insert(IDC_RESTARTBUTTON);
-
- StretchDialog(hwndDlg, diff);
-
- for (int i = 0; i < sizeof(kDefaultAttachedBottom) / sizeof(UINT); i++) {
- gAttachedBottom.insert(kDefaultAttachedBottom[i]);
- }
-}
-
-static void MaybeSendReport(HWND hwndDlg)
-{
- if (!IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK)) {
- EndCrashReporterDialog(hwndDlg, 0);
- return;
- }
-
- // disable all the form controls
- EnableWindow(GetDlgItem(hwndDlg, IDC_SUBMITREPORTCHECK), false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_CLOSEBUTTON), false);
- EnableWindow(GetDlgItem(hwndDlg, IDC_RESTARTBUTTON), false);
-
- SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT, Str(ST_REPORTDURINGSUBMIT).c_str());
- MaybeResizeProgressText(hwndDlg);
- // start throbber
- // play entire AVI, and loop
- Animate_Play(GetDlgItem(hwndDlg, IDC_THROBBER), 0, -1, -1);
- SetDlgItemVisible(hwndDlg, IDC_THROBBER, true);
- gThreadHandle = nullptr;
- gSendData.hDlg = hwndDlg;
- gSendData.queryParameters = gQueryParameters;
-
- gThreadHandle = CreateThread(nullptr, 0, SendThreadProc, &gSendData, 0,
- nullptr);
-}
-
-static void RestartApplication()
-{
- wstring cmdLine;
-
- for (unsigned int i = 0; i < gRestartArgs.size(); i++) {
- cmdLine += L"\"" + UTF8ToWide(gRestartArgs[i]) + L"\" ";
- }
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
-
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_SHOWNORMAL;
- ZeroMemory(&pi, sizeof(pi));
-
- if (CreateProcess(nullptr, (LPWSTR)cmdLine.c_str(), nullptr, nullptr, FALSE,
- 0, nullptr, nullptr, &si, &pi)) {
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
-}
-
-static void ShowReportInfo(HWND hwndDlg)
-{
- wstring description;
-
- for (map<wstring,wstring>::const_iterator i = gQueryParameters.begin();
- i != gQueryParameters.end();
- i++) {
- description += i->first;
- description += L": ";
- description += i->second;
- description += L"\n";
- }
-
- description += L"\n";
- description += Str(ST_EXTRAREPORTINFO);
-
- SetDlgItemText(hwndDlg, IDC_VIEWREPORTTEXT, description.c_str());
-}
-
-static void UpdateURL(HWND hwndDlg)
-{
- if (IsDlgButtonChecked(hwndDlg, IDC_INCLUDEURLCHECK)) {
- gQueryParameters[L"URL"] = gURLParameter;
- } else {
- gQueryParameters.erase(L"URL");
- }
-}
-
-static void UpdateEmail(HWND hwndDlg)
-{
- if (IsDlgButtonChecked(hwndDlg, IDC_EMAILMECHECK)) {
- wchar_t email[MAX_EMAIL_LENGTH];
- GetDlgItemTextW(hwndDlg, IDC_EMAILTEXT, email,
- sizeof(email) / sizeof(email[0]));
- gQueryParameters[L"Email"] = email;
- if (IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK))
- EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), true);
- } else {
- gQueryParameters.erase(L"Email");
- EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), false);
- }
-}
-
-static void UpdateComment(HWND hwndDlg)
-{
- wchar_t comment[MAX_COMMENT_LENGTH + 1];
- GetDlgItemTextW(hwndDlg, IDC_COMMENTTEXT, comment,
- sizeof(comment) / sizeof(comment[0]));
- if (wcslen(comment) > 0)
- gQueryParameters[L"Comments"] = comment;
- else
- gQueryParameters.erase(L"Comments");
-}
-
-/*
- * Dialog procedure for the "view report" dialog.
- */
-static BOOL CALLBACK ViewReportDialogProc(HWND hwndDlg, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
- switch (message) {
- case WM_INITDIALOG: {
- SetWindowText(hwndDlg, Str(ST_VIEWREPORTTITLE).c_str());
- SetDlgItemText(hwndDlg, IDOK, Str(ST_OK).c_str());
- SendDlgItemMessage(hwndDlg, IDC_VIEWREPORTTEXT,
- EM_SETTARGETDEVICE, (WPARAM)nullptr, 0);
- ShowReportInfo(hwndDlg);
- SetFocus(GetDlgItem(hwndDlg, IDOK));
- return FALSE;
- }
-
- case WM_COMMAND: {
- if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
- EndDialog(hwndDlg, 0);
- return FALSE;
- }
- }
- return FALSE;
-}
-
-// Return the number of bytes this string will take encoded
-// in UTF-8
-static inline int BytesInUTF8(wchar_t* str)
-{
- // Just count size of buffer for UTF-8, minus one
- // (we don't need to count the null terminator)
- return WideCharToMultiByte(CP_UTF8, 0, str, -1,
- nullptr, 0, nullptr, nullptr) - 1;
-}
-
-// Calculate the length of the text in this edit control (in bytes,
-// in the UTF-8 encoding) after replacing the current selection
-// with |insert|.
-static int NewTextLength(HWND hwndEdit, wchar_t* insert)
-{
- wchar_t current[MAX_COMMENT_LENGTH + 1];
-
- GetWindowText(hwndEdit, current, MAX_COMMENT_LENGTH + 1);
- DWORD selStart, selEnd;
- SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd);
-
- int selectionLength = 0;
- if (selEnd - selStart > 0) {
- wchar_t selection[MAX_COMMENT_LENGTH + 1];
- google_breakpad::WindowsStringUtils::safe_wcsncpy(selection,
- MAX_COMMENT_LENGTH + 1,
- current + selStart,
- selEnd - selStart);
- selection[selEnd - selStart] = '\0';
- selectionLength = BytesInUTF8(selection);
- }
-
- // current string length + replacement text length
- // - replaced selection length
- return BytesInUTF8(current) + BytesInUTF8(insert) - selectionLength;
-}
-
-// Window procedure for subclassing edit controls
-static LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
- LPARAM lParam)
-{
- static WNDPROC super = nullptr;
-
- if (super == nullptr)
- super = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-
- switch (uMsg) {
- case WM_PAINT: {
- HDC hdc;
- PAINTSTRUCT ps;
- RECT r;
- wchar_t windowText[1024];
-
- GetWindowText(hwnd, windowText, 1024);
- // if the control contains text or is focused, draw it normally
- if (GetFocus() == hwnd || windowText[0] != '\0')
- return CallWindowProc(super, hwnd, uMsg, wParam, lParam);
-
- GetClientRect(hwnd, &r);
- hdc = BeginPaint(hwnd, &ps);
- FillRect(hdc, &r, GetSysColorBrush(IsWindowEnabled(hwnd)
- ? COLOR_WINDOW : COLOR_BTNFACE));
- SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
- SelectObject(hdc, (HFONT)GetStockObject(DEFAULT_GUI_FONT));
- SetBkMode(hdc, TRANSPARENT);
- wchar_t* txt = (wchar_t*)GetProp(hwnd, L"PROP_GRAYTEXT");
- // Get the actual edit control rect
- CallWindowProc(super, hwnd, EM_GETRECT, 0, (LPARAM)&r);
- UINT format = DT_EDITCONTROL | DT_NOPREFIX | DT_WORDBREAK | DT_INTERNAL;
- if (gRTLlayout)
- format |= DT_RIGHT;
- if (txt)
- DrawText(hdc, txt, wcslen(txt), &r, format);
- EndPaint(hwnd, &ps);
- return 0;
- }
-
- // We handle WM_CHAR and WM_PASTE to limit the comment box to 500
- // bytes in UTF-8.
- case WM_CHAR: {
- // Leave accelerator keys and non-printing chars (except LF) alone
- if (wParam & (1<<24) || wParam & (1<<29) ||
- (wParam < ' ' && wParam != '\n'))
- break;
-
- wchar_t ch[2] = { (wchar_t)wParam, 0 };
- if (NewTextLength(hwnd, ch) > MAX_COMMENT_LENGTH)
- return 0;
-
- break;
- }
-
- case WM_PASTE: {
- if (IsClipboardFormatAvailable(CF_UNICODETEXT) &&
- OpenClipboard(hwnd)) {
- HGLOBAL hg = GetClipboardData(CF_UNICODETEXT);
- wchar_t* pastedText = (wchar_t*)GlobalLock(hg);
- int newSize = 0;
-
- if (pastedText)
- newSize = NewTextLength(hwnd, pastedText);
-
- GlobalUnlock(hg);
- CloseClipboard();
-
- if (newSize > MAX_COMMENT_LENGTH)
- return 0;
- }
- break;
- }
-
- case WM_SETFOCUS:
- case WM_KILLFOCUS: {
- RECT r;
- GetClientRect(hwnd, &r);
- InvalidateRect(hwnd, &r, TRUE);
- break;
- }
-
- case WM_DESTROY: {
- // cleanup our property
- HGLOBAL hData = RemoveProp(hwnd, L"PROP_GRAYTEXT");
- if (hData)
- GlobalFree(hData);
- }
- }
-
- return CallWindowProc(super, hwnd, uMsg, wParam, lParam);
-}
-
-// Resize a control to fit this text
-static int ResizeControl(HWND hwndButton, RECT& rect, wstring text,
- bool shiftLeft, int userDefinedPadding)
-{
- HDC hdc = GetDC(hwndButton);
- HFONT hfont = (HFONT)SendMessage(hwndButton, WM_GETFONT, 0, 0);
- if (hfont)
- SelectObject(hdc, hfont);
- SIZE size, oldSize;
- int sizeDiff = 0;
-
- wchar_t oldText[1024];
- GetWindowText(hwndButton, oldText, 1024);
-
- if (GetTextExtentPoint32(hdc, text.c_str(), text.length(), &size)
- // default text on the button
- && GetTextExtentPoint32(hdc, oldText, wcslen(oldText), &oldSize)) {
- /*
- Expand control widths to accomidate wider text strings. For most
- controls (including buttons) the text padding is defined by the
- dialog's rc file. Some controls (such as checkboxes) have padding
- that extends to the end of the dialog, in which case we ignore the
- rc padding and rely on a user defined value passed in through
- userDefinedPadding.
- */
- int textIncrease = size.cx - oldSize.cx;
- if (textIncrease < 0)
- return 0;
- int existingTextPadding;
- if (userDefinedPadding == 0)
- existingTextPadding = (rect.right - rect.left) - oldSize.cx;
- else
- existingTextPadding = userDefinedPadding;
- sizeDiff = textIncrease + existingTextPadding;
-
- if (shiftLeft) {
- // shift left by the amount the button should grow
- rect.left -= sizeDiff;
- }
- else {
- // grow right instead
- rect.right += sizeDiff;
- }
- MoveWindow(hwndButton, rect.left, rect.top,
- rect.right - rect.left,
- rect.bottom - rect.top,
- TRUE);
- }
- return sizeDiff;
-}
-
-// The window was resized horizontally, so widen some of our
-// controls to make use of the space
-static void StretchControlsToFit(HWND hwndDlg)
-{
- int controls[] = {
- IDC_DESCRIPTIONTEXT,
- IDC_SUBMITREPORTCHECK,
- IDC_COMMENTTEXT,
- IDC_INCLUDEURLCHECK,
- IDC_EMAILMECHECK,
- IDC_EMAILTEXT,
- IDC_PROGRESSTEXT
- };
-
- RECT dlgRect;
- GetClientRect(hwndDlg, &dlgRect);
-
- for (int i=0; i<sizeof(controls)/sizeof(controls[0]); i++) {
- RECT r;
- HWND hwndControl = GetDlgItem(hwndDlg, controls[i]);
- GetRelativeRect(hwndControl, hwndDlg, &r);
- // 6 pixel spacing on the right
- if (r.right + 6 != dlgRect.right) {
- r.right = dlgRect.right - 6;
- MoveWindow(hwndControl, r.left, r.top,
- r.right - r.left,
- r.bottom - r.top,
- TRUE);
- }
- }
-}
-
-static void SubmitReportChecked(HWND hwndDlg)
-{
- bool enabled = (IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK) != 0);
- EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), enabled);
- EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), enabled);
- EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), enabled);
- EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), enabled);
- EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT),
- enabled && (IsDlgButtonChecked(hwndDlg, IDC_EMAILMECHECK)
- != 0));
- SetDlgItemVisible(hwndDlg, IDC_PROGRESSTEXT, enabled);
-}
-
-static INT_PTR DialogBoxParamMaybeRTL(UINT idd, HWND hwndParent,
- DLGPROC dlgProc, LPARAM param)
-{
- INT_PTR rv = 0;
- if (gRTLlayout) {
- // We need to toggle the WS_EX_LAYOUTRTL style flag on the dialog
- // template.
- HRSRC hDialogRC = FindResource(nullptr, MAKEINTRESOURCE(idd),
- RT_DIALOG);
- HGLOBAL hDlgTemplate = LoadResource(nullptr, hDialogRC);
- DLGTEMPLATEEX* pDlgTemplate = (DLGTEMPLATEEX*)LockResource(hDlgTemplate);
- unsigned long sizeDlg = SizeofResource(nullptr, hDialogRC);
- HGLOBAL hMyDlgTemplate = GlobalAlloc(GPTR, sizeDlg);
- DLGTEMPLATEEX* pMyDlgTemplate =
- (DLGTEMPLATEEX*)GlobalLock(hMyDlgTemplate);
- memcpy(pMyDlgTemplate, pDlgTemplate, sizeDlg);
-
- pMyDlgTemplate->exStyle |= WS_EX_LAYOUTRTL;
-
- rv = DialogBoxIndirectParam(nullptr, (LPCDLGTEMPLATE)pMyDlgTemplate,
- hwndParent, dlgProc, param);
- GlobalUnlock(hMyDlgTemplate);
- GlobalFree(hMyDlgTemplate);
- }
- else {
- rv = DialogBoxParam(nullptr, MAKEINTRESOURCE(idd), hwndParent,
- dlgProc, param);
- }
-
- return rv;
-}
-
-
-static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
- static int sHeight = 0;
-
- bool success;
- bool enabled;
-
- switch (message) {
- case WM_INITDIALOG: {
- GetThemeSizes(hwndDlg);
- RECT r;
- GetClientRect(hwndDlg, &r);
- sHeight = r.bottom - r.top;
-
- SetWindowText(hwndDlg, Str(ST_CRASHREPORTERTITLE).c_str());
- HICON hIcon = LoadIcon(GetModuleHandle(nullptr),
- MAKEINTRESOURCE(IDI_MAINICON));
- SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
- SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
-
- // resize the "View Report" button based on the string length
- RECT rect;
- HWND hwnd = GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON);
- GetRelativeRect(hwnd, hwndDlg, &rect);
- ResizeControl(hwnd, rect, Str(ST_VIEWREPORT), false, 0);
- SetDlgItemText(hwndDlg, IDC_VIEWREPORTBUTTON, Str(ST_VIEWREPORT).c_str());
-
- hwnd = GetDlgItem(hwndDlg, IDC_SUBMITREPORTCHECK);
- GetRelativeRect(hwnd, hwndDlg, &rect);
- long maxdiff = ResizeControl(hwnd, rect, Str(ST_CHECKSUBMIT), false,
- gCheckboxPadding);
- SetDlgItemText(hwndDlg, IDC_SUBMITREPORTCHECK,
- Str(ST_CHECKSUBMIT).c_str());
-
- if (!CheckBoolKey(gCrashReporterKey.c_str(),
- SUBMIT_REPORT_VALUE, &enabled))
- enabled = ShouldEnableSending();
-
- CheckDlgButton(hwndDlg, IDC_SUBMITREPORTCHECK, enabled ? BST_CHECKED
- : BST_UNCHECKED);
- SubmitReportChecked(hwndDlg);
-
- HWND hwndComment = GetDlgItem(hwndDlg, IDC_COMMENTTEXT);
- WNDPROC OldWndProc = (WNDPROC)SetWindowLongPtr(hwndComment,
- GWLP_WNDPROC,
- (LONG_PTR)EditSubclassProc);
-
- // Subclass comment edit control to get placeholder text
- SetWindowLongPtr(hwndComment, GWLP_USERDATA, (LONG_PTR)OldWndProc);
- wstring commentGrayText = Str(ST_COMMENTGRAYTEXT);
- wchar_t* hMem = (wchar_t*)GlobalAlloc(GPTR, (commentGrayText.length() + 1)*sizeof(wchar_t));
- wcscpy(hMem, commentGrayText.c_str());
- SetProp(hwndComment, L"PROP_GRAYTEXT", hMem);
-
- hwnd = GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK);
- GetRelativeRect(hwnd, hwndDlg, &rect);
- long diff = ResizeControl(hwnd, rect, Str(ST_CHECKURL), false,
- gCheckboxPadding);
- maxdiff = std::max(diff, maxdiff);
- SetDlgItemText(hwndDlg, IDC_INCLUDEURLCHECK, Str(ST_CHECKURL).c_str());
-
- // want this on by default
- if (CheckBoolKey(gCrashReporterKey.c_str(), INCLUDE_URL_VALUE, &enabled) &&
- !enabled) {
- CheckDlgButton(hwndDlg, IDC_INCLUDEURLCHECK, BST_UNCHECKED);
- } else {
- CheckDlgButton(hwndDlg, IDC_INCLUDEURLCHECK, BST_CHECKED);
- }
-
- hwnd = GetDlgItem(hwndDlg, IDC_EMAILMECHECK);
- GetRelativeRect(hwnd, hwndDlg, &rect);
- diff = ResizeControl(hwnd, rect, Str(ST_CHECKEMAIL), false,
- gCheckboxPadding);
- maxdiff = std::max(diff, maxdiff);
- SetDlgItemText(hwndDlg, IDC_EMAILMECHECK, Str(ST_CHECKEMAIL).c_str());
-
- if (CheckBoolKey(gCrashReporterKey.c_str(), EMAIL_ME_VALUE, &enabled) &&
- enabled) {
- CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_CHECKED);
- } else {
- CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_UNCHECKED);
- }
-
- wstring email;
- if (GetStringKey(gCrashReporterKey.c_str(), EMAIL_VALUE, email)) {
- SetDlgItemText(hwndDlg, IDC_EMAILTEXT, email.c_str());
- }
-
- // Subclass email edit control to get placeholder text
- HWND hwndEmail = GetDlgItem(hwndDlg, IDC_EMAILTEXT);
- OldWndProc = (WNDPROC)SetWindowLongPtr(hwndEmail,
- GWLP_WNDPROC,
- (LONG_PTR)EditSubclassProc);
- SetWindowLongPtr(hwndEmail, GWLP_USERDATA, (LONG_PTR)OldWndProc);
- wstring emailGrayText = Str(ST_EMAILGRAYTEXT);
- hMem = (wchar_t*)GlobalAlloc(GPTR, (emailGrayText.length() + 1)*sizeof(wchar_t));
- wcscpy(hMem, emailGrayText.c_str());
- SetProp(hwndEmail, L"PROP_GRAYTEXT", hMem);
-
- SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT, Str(ST_REPORTPRESUBMIT).c_str());
-
- RECT closeRect;
- HWND hwndClose = GetDlgItem(hwndDlg, IDC_CLOSEBUTTON);
- GetRelativeRect(hwndClose, hwndDlg, &closeRect);
-
- RECT restartRect;
- HWND hwndRestart = GetDlgItem(hwndDlg, IDC_RESTARTBUTTON);
- GetRelativeRect(hwndRestart, hwndDlg, &restartRect);
-
- // set the close button text and shift the buttons around
- // since the size may need to change
- int sizeDiff = ResizeControl(hwndClose, closeRect, Str(ST_QUIT),
- true, 0);
- restartRect.left -= sizeDiff;
- restartRect.right -= sizeDiff;
- SetDlgItemText(hwndDlg, IDC_CLOSEBUTTON, Str(ST_QUIT).c_str());
-
- if (gRestartArgs.size() > 0) {
- // Resize restart button to fit text
- ResizeControl(hwndRestart, restartRect, Str(ST_RESTART), true, 0);
- SetDlgItemText(hwndDlg, IDC_RESTARTBUTTON, Str(ST_RESTART).c_str());
- } else {
- // No restart arguments, so just hide the restart button
- SetDlgItemVisible(hwndDlg, IDC_RESTARTBUTTON, false);
- }
- // See if we need to widen the window
- // Leave 6 pixels on either side + 6 pixels between the buttons
- int neededSize = closeRect.right - closeRect.left +
- restartRect.right - restartRect.left + 6 * 3;
- GetClientRect(hwndDlg, &r);
- // We may already have resized one of the checkboxes above
- maxdiff = std::max(maxdiff, neededSize - (r.right - r.left));
-
- if (maxdiff > 0) {
- // widen window
- GetWindowRect(hwndDlg, &r);
- r.right += maxdiff;
- MoveWindow(hwndDlg, r.left, r.top,
- r.right - r.left, r.bottom - r.top, TRUE);
- // shift both buttons right
- if (restartRect.left + maxdiff < 6)
- maxdiff += 6;
- closeRect.left += maxdiff;
- closeRect.right += maxdiff;
- restartRect.left += maxdiff;
- restartRect.right += maxdiff;
- MoveWindow(hwndClose, closeRect.left, closeRect.top,
- closeRect.right - closeRect.left,
- closeRect.bottom - closeRect.top,
- TRUE);
- StretchControlsToFit(hwndDlg);
- }
- // need to move the restart button regardless
- MoveWindow(hwndRestart, restartRect.left, restartRect.top,
- restartRect.right - restartRect.left,
- restartRect.bottom - restartRect.top,
- TRUE);
-
- // Resize the description text last, in case the window was resized
- // before this.
- SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT,
- EM_SETEVENTMASK, (WPARAM)nullptr,
- ENM_REQUESTRESIZE);
-
- wstring description = Str(ST_CRASHREPORTERHEADER);
- description += L"\n\n";
- description += Str(ST_CRASHREPORTERDESCRIPTION);
- SetDlgItemText(hwndDlg, IDC_DESCRIPTIONTEXT, description.c_str());
-
-
- // Make the title bold.
- CHARFORMAT fmt = { 0, };
- fmt.cbSize = sizeof(fmt);
- fmt.dwMask = CFM_BOLD;
- fmt.dwEffects = CFE_BOLD;
- SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT, EM_SETSEL,
- 0, Str(ST_CRASHREPORTERHEADER).length());
- SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT, EM_SETCHARFORMAT,
- SCF_SELECTION, (LPARAM)&fmt);
- SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT, EM_SETSEL, 0, 0);
- // Force redraw.
- SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT,
- EM_SETTARGETDEVICE, (WPARAM)nullptr, 0);
- // Force resize.
- SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT,
- EM_REQUESTRESIZE, 0, 0);
-
- // if no URL was given, hide the URL checkbox
- if (gQueryParameters.find(L"URL") == gQueryParameters.end()) {
- RECT urlCheckRect, emailCheckRect;
- GetWindowRect(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), &urlCheckRect);
- GetWindowRect(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), &emailCheckRect);
-
- SetDlgItemVisible(hwndDlg, IDC_INCLUDEURLCHECK, false);
-
- gAttachedBottom.erase(IDC_VIEWREPORTBUTTON);
- gAttachedBottom.erase(IDC_SUBMITREPORTCHECK);
- gAttachedBottom.erase(IDC_COMMENTTEXT);
-
- StretchDialog(hwndDlg, urlCheckRect.top - emailCheckRect.top);
-
- gAttachedBottom.insert(IDC_VIEWREPORTBUTTON);
- gAttachedBottom.insert(IDC_SUBMITREPORTCHECK);
- gAttachedBottom.insert(IDC_COMMENTTEXT);
- }
-
- MaybeResizeProgressText(hwndDlg);
-
- // Open the AVI resource for the throbber
- Animate_Open(GetDlgItem(hwndDlg, IDC_THROBBER),
- MAKEINTRESOURCE(IDR_THROBBER));
-
- UpdateURL(hwndDlg);
- UpdateEmail(hwndDlg);
-
- SetFocus(GetDlgItem(hwndDlg, IDC_SUBMITREPORTCHECK));
- return FALSE;
- }
- case WM_SIZE: {
- ReflowDialog(hwndDlg, HIWORD(lParam) - sHeight);
- sHeight = HIWORD(lParam);
- InvalidateRect(hwndDlg, nullptr, TRUE);
- return FALSE;
- }
- case WM_NOTIFY: {
- NMHDR* notification = reinterpret_cast<NMHDR*>(lParam);
- if (notification->code == EN_REQUESTRESIZE) {
- // Resizing the rich edit control to fit the description text.
- REQRESIZE* reqresize = reinterpret_cast<REQRESIZE*>(lParam);
- RECT newSize = reqresize->rc;
- RECT oldSize;
- GetRelativeRect(notification->hwndFrom, hwndDlg, &oldSize);
-
- // resize the text box as requested
- MoveWindow(notification->hwndFrom, newSize.left, newSize.top,
- newSize.right - newSize.left, newSize.bottom - newSize.top,
- TRUE);
-
- // Resize the dialog to fit (the WM_SIZE handler will move the controls)
- StretchDialog(hwndDlg, newSize.bottom - oldSize.bottom);
- }
- return FALSE;
- }
- case WM_COMMAND: {
- if (HIWORD(wParam) == BN_CLICKED) {
- switch(LOWORD(wParam)) {
- case IDC_VIEWREPORTBUTTON:
- DialogBoxParamMaybeRTL(IDD_VIEWREPORTDIALOG, hwndDlg,
- (DLGPROC)ViewReportDialogProc, 0);
- break;
- case IDC_SUBMITREPORTCHECK:
- SubmitReportChecked(hwndDlg);
- break;
- case IDC_INCLUDEURLCHECK:
- UpdateURL(hwndDlg);
- break;
- case IDC_EMAILMECHECK:
- UpdateEmail(hwndDlg);
- break;
- case IDC_CLOSEBUTTON:
- MaybeSendReport(hwndDlg);
- break;
- case IDC_RESTARTBUTTON:
- RestartApplication();
- MaybeSendReport(hwndDlg);
- break;
- }
- } else if (HIWORD(wParam) == EN_CHANGE) {
- switch(LOWORD(wParam)) {
- case IDC_EMAILTEXT:
- UpdateEmail(hwndDlg);
- break;
- case IDC_COMMENTTEXT:
- UpdateComment(hwndDlg);
- }
- }
-
- return FALSE;
- }
- case WM_UPLOADCOMPLETE: {
- WaitForSingleObject(gThreadHandle, INFINITE);
- success = (wParam == 1);
- SendCompleted(success, WideToUTF8(gSendData.serverResponse));
- // hide throbber
- Animate_Stop(GetDlgItem(hwndDlg, IDC_THROBBER));
- SetDlgItemVisible(hwndDlg, IDC_THROBBER, false);
-
- SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT,
- success ?
- Str(ST_REPORTSUBMITSUCCESS).c_str() :
- Str(ST_SUBMITFAILED).c_str());
- MaybeResizeProgressText(hwndDlg);
- // close dialog after 5 seconds
- SetTimer(hwndDlg, 0, 5000, nullptr);
- //
- return TRUE;
- }
-
- case WM_LBUTTONDOWN: {
- HWND hwndEmail = GetDlgItem(hwndDlg, IDC_EMAILTEXT);
- POINT p = { LOWORD(lParam), HIWORD(lParam) };
- // if the email edit control is clicked, enable it,
- // check the email checkbox, and focus the email edit control
- if (ChildWindowFromPoint(hwndDlg, p) == hwndEmail &&
- IsWindowEnabled(GetDlgItem(hwndDlg, IDC_RESTARTBUTTON)) &&
- !IsWindowEnabled(hwndEmail) &&
- IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK) != 0) {
- CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_CHECKED);
- UpdateEmail(hwndDlg);
- SetFocus(hwndEmail);
- }
- break;
- }
-
- case WM_TIMER: {
- // The "1" gets used down in UIShowCrashUI to indicate that we at least
- // tried to send the report.
- EndCrashReporterDialog(hwndDlg, 1);
- return FALSE;
- }
-
- case WM_CLOSE: {
- EndCrashReporterDialog(hwndDlg, 0);
- return FALSE;
- }
- }
- return FALSE;
-}
-
-static wstring UTF8ToWide(const string& utf8, bool *success)
-{
- wchar_t* buffer = nullptr;
- int buffer_size = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(),
- -1, nullptr, 0);
- if(buffer_size == 0) {
- if (success)
- *success = false;
- return L"";
- }
-
- buffer = new wchar_t[buffer_size];
- if(buffer == nullptr) {
- if (success)
- *success = false;
- return L"";
- }
-
- MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(),
- -1, buffer, buffer_size);
- wstring str = buffer;
- delete [] buffer;
-
- if (success)
- *success = true;
-
- return str;
-}
-
-static string WideToMBCP(const wstring& wide,
- unsigned int cp,
- bool* success = nullptr)
-{
- char* buffer = nullptr;
- int buffer_size = WideCharToMultiByte(cp, 0, wide.c_str(),
- -1, nullptr, 0, nullptr, nullptr);
- if(buffer_size == 0) {
- if (success)
- *success = false;
- return "";
- }
-
- buffer = new char[buffer_size];
- if(buffer == nullptr) {
- if (success)
- *success = false;
- return "";
- }
-
- WideCharToMultiByte(cp, 0, wide.c_str(),
- -1, buffer, buffer_size, nullptr, nullptr);
- string mb = buffer;
- delete [] buffer;
-
- if (success)
- *success = true;
-
- return mb;
-}
-
-string WideToUTF8(const wstring& wide, bool* success)
-{
- return WideToMBCP(wide, CP_UTF8, success);
-}
-
-/* === Crashreporter UI Functions === */
-
-bool UIInit()
-{
- for (int i = 0; i < sizeof(kDefaultAttachedBottom) / sizeof(UINT); i++) {
- gAttachedBottom.insert(kDefaultAttachedBottom[i]);
- }
-
- DoInitCommonControls();
-
- return true;
-}
-
-void UIShutdown()
-{
-}
-
-void UIShowDefaultUI()
-{
- MessageBox(nullptr, Str(ST_CRASHREPORTERDEFAULT).c_str(),
- L"Crash Reporter",
- MB_OK | MB_ICONSTOP);
-}
-
-static bool CanUseMainCrashReportServer()
-{
- // Any NT from 6.0 and above is fine.
- if (IsWindowsVersionOrGreater(6, 0, 0)) {
- return true;
- }
-
- // On NT 5 servers, we need Server 2003 SP2.
- if (IsWindowsServer()) {
- return IsWindowsVersionOrGreater(5, 2, 2);
- }
-
- // Otherwise we have an NT 5 client.
- // We need exactly XP SP3 (version 5.1 SP3 but not version 5.2).
- return (IsWindowsVersionOrGreater(5, 1, 3) &&
- !IsWindowsVersionOrGreater(5, 2, 0));
-}
-
-bool UIShowCrashUI(const StringTable& files,
- const StringTable& queryParameters,
- const string& sendURL,
- const vector<string>& restartArgs)
-{
- gSendData.hDlg = nullptr;
- gSendData.sendURL = UTF8ToWide(sendURL);
-
- // Older Windows don't support the crash report server's crypto.
- // This is a hack to use an alternate server.
- if (!CanUseMainCrashReportServer() &&
- gSendData.sendURL.find(SENDURL_ORIGINAL) == 0) {
- gSendData.sendURL.replace(0, ARRAYSIZE(SENDURL_ORIGINAL) - 1,
- SENDURL_XPSP2);
- }
-
- for (StringTable::const_iterator i = files.begin();
- i != files.end();
- i++) {
- gSendData.files[UTF8ToWide(i->first)] = UTF8ToWide(i->second);
- }
-
- for (StringTable::const_iterator i = queryParameters.begin();
- i != queryParameters.end();
- i++) {
- gQueryParameters[UTF8ToWide(i->first)] = UTF8ToWide(i->second);
- }
-
- if (gQueryParameters.find(L"Vendor") != gQueryParameters.end()) {
- gCrashReporterKey = L"Software\\";
- if (!gQueryParameters[L"Vendor"].empty()) {
- gCrashReporterKey += gQueryParameters[L"Vendor"] + L"\\";
- }
- gCrashReporterKey += gQueryParameters[L"ProductName"] + L"\\Crash Reporter";
- }
-
- if (gQueryParameters.find(L"URL") != gQueryParameters.end())
- gURLParameter = gQueryParameters[L"URL"];
-
- gRestartArgs = restartArgs;
-
- if (gStrings.find("isRTL") != gStrings.end() &&
- gStrings["isRTL"] == "yes")
- gRTLlayout = true;
-
- return 1 == DialogBoxParamMaybeRTL(IDD_SENDDIALOG, nullptr,
- (DLGPROC)CrashReporterDialogProc, 0);
-}
-
-void UIError_impl(const string& message)
-{
- wstring title = Str(ST_CRASHREPORTERTITLE);
- if (title.empty())
- title = L"Crash Reporter Error";
-
- MessageBox(nullptr, UTF8ToWide(message).c_str(), title.c_str(),
- MB_OK | MB_ICONSTOP);
-}
-
-bool UIGetIniPath(string& path)
-{
- wchar_t fileName[MAX_PATH];
- if (GetModuleFileName(nullptr, fileName, MAX_PATH)) {
- // get crashreporter ini
- wchar_t* s = wcsrchr(fileName, '.');
- if (s) {
- wcscpy(s, L".ini");
- path = WideToUTF8(fileName);
- return true;
- }
- }
-
- return false;
-}
-
-bool UIGetSettingsPath(const string& vendor,
- const string& product,
- string& settings_path)
-{
- wchar_t path[MAX_PATH];
- HRESULT hRes = SHGetFolderPath(nullptr,
- CSIDL_APPDATA,
- nullptr,
- 0,
- path);
- if (FAILED(hRes)) {
- // This provides a fallback for getting the path to APPDATA by querying the
- // registry when the call to SHGetFolderPath is unable to provide this path
- // (Bug 513958).
- HKEY key;
- DWORD type, size, dwRes;
- dwRes = ::RegOpenKeyExW(HKEY_CURRENT_USER,
- L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
- 0,
- KEY_READ,
- &key);
- if (dwRes != ERROR_SUCCESS)
- return false;
-
- dwRes = RegQueryValueExW(key,
- L"AppData",
- nullptr,
- &type,
- (LPBYTE)&path,
- &size);
- ::RegCloseKey(key);
- // The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
- // buffer size must not equal 0, and the buffer size be a multiple of 2.
- if (dwRes != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0)
- return false;
- }
-
- if (!vendor.empty()) {
- PathAppend(path, UTF8ToWide(vendor).c_str());
- }
- PathAppend(path, UTF8ToWide(product).c_str());
- PathAppend(path, L"Crash Reports");
- settings_path = WideToUTF8(path);
- return true;
-}
-
-bool UIEnsurePathExists(const string& path)
-{
- if (CreateDirectory(UTF8ToWide(path).c_str(), nullptr) == 0) {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
-
- return true;
-}
-
-bool UIFileExists(const string& path)
-{
- DWORD attrs = GetFileAttributes(UTF8ToWide(path).c_str());
- return (attrs != INVALID_FILE_ATTRIBUTES);
-}
-
-bool UIMoveFile(const string& oldfile, const string& newfile)
-{
- if (oldfile == newfile)
- return true;
-
- return MoveFile(UTF8ToWide(oldfile).c_str(), UTF8ToWide(newfile).c_str())
- == TRUE;
-}
-
-bool UIDeleteFile(const string& oldfile)
-{
- return DeleteFile(UTF8ToWide(oldfile).c_str()) == TRUE;
-}
-
-ifstream* UIOpenRead(const string& filename)
-{
- // adapted from breakpad's src/common/windows/http_upload.cc
-
-#if defined(_MSC_VER)
- ifstream* file = new ifstream();
- file->open(UTF8ToWide(filename).c_str(), ios::in);
-#else // GCC
- ifstream* file = new ifstream(WideToMBCP(UTF8ToWide(filename), CP_ACP).c_str(),
- ios::in);
-#endif // _MSC_VER
-
- return file;
-}
-
-ofstream* UIOpenWrite(const string& filename,
- bool append, // append=false
- bool binary) // binary=false
-{
- // adapted from breakpad's src/common/windows/http_upload.cc
- std::ios_base::openmode mode = ios::out;
- if (append) {
- mode = mode | ios::app;
- }
- if (binary) {
- mode = mode | ios::binary;
- }
-
-#if defined(_MSC_VER)
- ofstream* file = new ofstream();
- file->open(UTF8ToWide(filename).c_str(), mode);
-#else // GCC
- ofstream* file = new ofstream(WideToMBCP(UTF8ToWide(filename), CP_ACP).c_str(),
- mode);
-#endif // _MSC_VER
-
- return file;
-}
-
-struct FileData
-{
- FILETIME timestamp;
- wstring path;
-};
-
-static bool CompareFDTime(const FileData& fd1, const FileData& fd2)
-{
- return CompareFileTime(&fd1.timestamp, &fd2.timestamp) > 0;
-}
-
-void UIPruneSavedDumps(const std::string& directory)
-{
- wstring wdirectory = UTF8ToWide(directory);
-
- WIN32_FIND_DATA fdata;
- wstring findpath = wdirectory + L"\\*.dmp";
- HANDLE dirlist = FindFirstFile(findpath.c_str(), &fdata);
- if (dirlist == INVALID_HANDLE_VALUE)
- return;
-
- vector<FileData> dumpfiles;
-
- for (BOOL ok = true; ok; ok = FindNextFile(dirlist, &fdata)) {
- FileData fd = {fdata.ftLastWriteTime, wdirectory + L"\\" + fdata.cFileName};
- dumpfiles.push_back(fd);
- }
-
- sort(dumpfiles.begin(), dumpfiles.end(), CompareFDTime);
-
- while (dumpfiles.size() > kSaveCount) {
- // get the path of the oldest file
- wstring path = (--dumpfiles.end())->path;
- DeleteFile(path.c_str());
-
- // s/.dmp/.extra/
- path.replace(path.size() - 4, 4, L".extra");
- DeleteFile(path.c_str());
-
- dumpfiles.pop_back();
- }
-}
-
-void UIRunMinidumpAnalyzer(const string& exename, const string& filename)
-{
- wstring cmdLine;
-
- cmdLine += L"\"" + UTF8ToWide(exename) + L"\" ";
- cmdLine += L"\"" + UTF8ToWide(filename) + L"\" ";
-
- STARTUPINFO si = {};
- PROCESS_INFORMATION pi = {};
-
- si.cb = sizeof(si);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_SHOWNORMAL;
-
- if (CreateProcess(nullptr, (LPWSTR)cmdLine.c_str(), nullptr, nullptr, FALSE,
- 0, nullptr, nullptr, &si, &pi)) {
- WaitForSingleObject(pi.hProcess, INFINITE);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
-}
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Info.plist b/toolkit/crashreporter/client/macbuild/Contents/Info.plist
deleted file mode 100644
index 299581f52..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Info.plist
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleDisplayName</key>
- <string>crashreporter</string>
- <key>CFBundleExecutable</key>
- <string>crashreporter</string>
- <key>CFBundleIconFile</key>
- <string>crashreporter.icns</string>
- <key>CFBundleIdentifier</key>
- <string>org.mozilla.crashreporter</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>crashreporter</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1.0</string>
- <key>LSHasLocalizedDisplayName</key>
- <true/>
- <key>NSMainNibFile</key>
- <string>MainMenu</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
-</dict>
-</plist>
diff --git a/toolkit/crashreporter/client/macbuild/Contents/PkgInfo b/toolkit/crashreporter/client/macbuild/Contents/PkgInfo
deleted file mode 100644
index cae6d0a58..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/PkgInfo
+++ /dev/null
@@ -1,2 +0,0 @@
-APPL????
-
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in b/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
deleted file mode 100644
index 6fe086e35..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
+++ /dev/null
@@ -1,8 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Localized versions of Info.plist keys */
-
-CFBundleName = "Crash Reporter";
-CFBundleDisplayName = "Crash Reporter";
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib b/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib
deleted file mode 100644
index e31ff0bfb..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBClasses</key>
- <array>
- <dict>
- <key>ACTIONS</key>
- <dict>
- <key>closeClicked</key>
- <string>id</string>
- <key>emailMeClicked</key>
- <string>id</string>
- <key>includeURLClicked</key>
- <string>id</string>
- <key>restartClicked</key>
- <string>id</string>
- <key>submitReportClicked</key>
- <string>id</string>
- <key>viewReportClicked</key>
- <string>id</string>
- <key>viewReportOkClicked</key>
- <string>id</string>
- </dict>
- <key>CLASS</key>
- <string>CrashReporterUI</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>OUTLETS</key>
- <dict>
- <key>mCloseButton</key>
- <string>NSButton</string>
- <key>mCommentScrollView</key>
- <string>NSScrollView</string>
- <key>mCommentText</key>
- <string>TextViewWithPlaceHolder</string>
- <key>mDescriptionLabel</key>
- <string>NSTextField</string>
- <key>mEmailMeButton</key>
- <string>NSButton</string>
- <key>mEmailText</key>
- <string>NSTextField</string>
- <key>mErrorCloseButton</key>
- <string>NSButton</string>
- <key>mErrorHeaderLabel</key>
- <string>NSTextField</string>
- <key>mErrorLabel</key>
- <string>NSTextField</string>
- <key>mErrorView</key>
- <string>NSView</string>
- <key>mHeaderLabel</key>
- <string>NSTextField</string>
- <key>mIncludeURLButton</key>
- <string>NSButton</string>
- <key>mProgressIndicator</key>
- <string>NSProgressIndicator</string>
- <key>mProgressText</key>
- <string>NSTextField</string>
- <key>mRestartButton</key>
- <string>NSButton</string>
- <key>mSubmitReportButton</key>
- <string>NSButton</string>
- <key>mViewReportButton</key>
- <string>NSButton</string>
- <key>mViewReportOkButton</key>
- <string>NSButton</string>
- <key>mViewReportTextView</key>
- <string>NSTextView</string>
- <key>mViewReportWindow</key>
- <string>NSWindow</string>
- <key>mWindow</key>
- <string>NSWindow</string>
- </dict>
- <key>SUPERCLASS</key>
- <string>NSObject</string>
- </dict>
- <dict>
- <key>ACTIONS</key>
- <dict>
- <key>insertTab</key>
- <string>id</string>
- </dict>
- <key>CLASS</key>
- <string>TextViewWithPlaceHolder</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>SUPERCLASS</key>
- <string>NSTextView</string>
- </dict>
- <dict>
- <key>CLASS</key>
- <string>FirstResponder</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>SUPERCLASS</key>
- <string>NSObject</string>
- </dict>
- </array>
- <key>IBVersion</key>
- <string>1</string>
-</dict>
-</plist>
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib b/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib
deleted file mode 100644
index 517349ffc..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBFramework Version</key>
- <string>629</string>
- <key>IBOldestOS</key>
- <integer>5</integer>
- <key>IBOpenObjects</key>
- <array>
- <integer>2</integer>
- </array>
- <key>IBSystem Version</key>
- <string>9C7010</string>
- <key>targetFramework</key>
- <string>IBCocoaFramework</string>
-</dict>
-</plist>
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib b/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib
deleted file mode 100644
index bfdcccb74..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib
+++ /dev/null
Binary files differ
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/classes.nib b/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/classes.nib
deleted file mode 100644
index e31ff0bfb..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/classes.nib
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBClasses</key>
- <array>
- <dict>
- <key>ACTIONS</key>
- <dict>
- <key>closeClicked</key>
- <string>id</string>
- <key>emailMeClicked</key>
- <string>id</string>
- <key>includeURLClicked</key>
- <string>id</string>
- <key>restartClicked</key>
- <string>id</string>
- <key>submitReportClicked</key>
- <string>id</string>
- <key>viewReportClicked</key>
- <string>id</string>
- <key>viewReportOkClicked</key>
- <string>id</string>
- </dict>
- <key>CLASS</key>
- <string>CrashReporterUI</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>OUTLETS</key>
- <dict>
- <key>mCloseButton</key>
- <string>NSButton</string>
- <key>mCommentScrollView</key>
- <string>NSScrollView</string>
- <key>mCommentText</key>
- <string>TextViewWithPlaceHolder</string>
- <key>mDescriptionLabel</key>
- <string>NSTextField</string>
- <key>mEmailMeButton</key>
- <string>NSButton</string>
- <key>mEmailText</key>
- <string>NSTextField</string>
- <key>mErrorCloseButton</key>
- <string>NSButton</string>
- <key>mErrorHeaderLabel</key>
- <string>NSTextField</string>
- <key>mErrorLabel</key>
- <string>NSTextField</string>
- <key>mErrorView</key>
- <string>NSView</string>
- <key>mHeaderLabel</key>
- <string>NSTextField</string>
- <key>mIncludeURLButton</key>
- <string>NSButton</string>
- <key>mProgressIndicator</key>
- <string>NSProgressIndicator</string>
- <key>mProgressText</key>
- <string>NSTextField</string>
- <key>mRestartButton</key>
- <string>NSButton</string>
- <key>mSubmitReportButton</key>
- <string>NSButton</string>
- <key>mViewReportButton</key>
- <string>NSButton</string>
- <key>mViewReportOkButton</key>
- <string>NSButton</string>
- <key>mViewReportTextView</key>
- <string>NSTextView</string>
- <key>mViewReportWindow</key>
- <string>NSWindow</string>
- <key>mWindow</key>
- <string>NSWindow</string>
- </dict>
- <key>SUPERCLASS</key>
- <string>NSObject</string>
- </dict>
- <dict>
- <key>ACTIONS</key>
- <dict>
- <key>insertTab</key>
- <string>id</string>
- </dict>
- <key>CLASS</key>
- <string>TextViewWithPlaceHolder</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>SUPERCLASS</key>
- <string>NSTextView</string>
- </dict>
- <dict>
- <key>CLASS</key>
- <string>FirstResponder</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>SUPERCLASS</key>
- <string>NSObject</string>
- </dict>
- </array>
- <key>IBVersion</key>
- <string>1</string>
-</dict>
-</plist>
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/info.nib b/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/info.nib
deleted file mode 100644
index 4a2251aaf..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/info.nib
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBFramework Version</key>
- <string>629</string>
- <key>IBOldestOS</key>
- <integer>5</integer>
- <key>IBOpenObjects</key>
- <array>
- <integer>2</integer>
- </array>
- <key>IBSystem Version</key>
- <string>9D34</string>
- <key>targetFramework</key>
- <string>IBCocoaFramework</string>
-</dict>
-</plist>
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/keyedobjects.nib b/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/keyedobjects.nib
deleted file mode 100644
index 6c93849b9..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/English.lproj/MainMenuRTL.nib/keyedobjects.nib
+++ /dev/null
Binary files differ
diff --git a/toolkit/crashreporter/client/macbuild/Contents/Resources/crashreporter.icns b/toolkit/crashreporter/client/macbuild/Contents/Resources/crashreporter.icns
deleted file mode 100644
index 341cd05a4..000000000
--- a/toolkit/crashreporter/client/macbuild/Contents/Resources/crashreporter.icns
+++ /dev/null
Binary files differ
diff --git a/toolkit/crashreporter/client/moz.build b/toolkit/crashreporter/client/moz.build
deleted file mode 100644
index 456c794af..000000000
--- a/toolkit/crashreporter/client/moz.build
+++ /dev/null
@@ -1,78 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-if CONFIG['OS_TARGET'] != 'Android':
- Program('crashreporter')
-
- UNIFIED_SOURCES += [
- 'crashreporter.cpp',
- ]
-
-if CONFIG['OS_ARCH'] == 'WINNT':
- UNIFIED_SOURCES += [
- 'crashreporter_win.cpp',
- ]
- DEFINES['UNICODE'] = True
- DEFINES['_UNICODE'] = True
- USE_LIBS += [
- 'google_breakpad_libxul_s',
- ]
- OS_LIBS += [
- 'comctl32',
- 'shell32',
- 'wininet',
- 'shlwapi',
- ]
-elif CONFIG['OS_ARCH'] == 'Darwin':
- UNIFIED_SOURCES += [
- 'crashreporter_osx.mm',
- 'crashreporter_unix_common.cpp',
- ]
- LOCAL_INCLUDES += [
- '../google-breakpad/src/common/mac',
- ]
- OS_LIBS += ['-framework Cocoa']
- USE_LIBS += [
- 'breakpad_common_s',
- 'breakpad_mac_common_s',
- ]
-elif CONFIG['OS_ARCH'] == 'SunOS':
- SOURCES += [
- 'crashreporter_linux.cpp',
- 'crashreporter_unix.cpp',
- ]
- USE_LIBS += [
- 'breakpad_solaris_common_s',
- ]
-
-if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
- UNIFIED_SOURCES += [
- 'crashreporter_gtk_common.cpp',
- 'crashreporter_linux.cpp',
- 'crashreporter_unix_common.cpp'
- ]
- USE_LIBS += [
- 'breakpad_linux_common_s',
- ]
- OS_LIBS += CONFIG['TK_LIBS']
- OS_LIBS += CONFIG['MOZ_GTHREAD_LIBS']
- CXXFLAGS += CONFIG['TK_CFLAGS']
- CXXFLAGS += CONFIG['MOZ_GTHREAD_CFLAGS']
-
-if CONFIG['OS_ARCH'] == 'Linux' or CONFIG['OS_ARCH'] == 'SunOS':
- FINAL_TARGET_FILES += [
- '/toolkit/themes/windows/global/throbber/Throbber-small.gif',
- ]
-
-DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX']
-
-RCINCLUDE = 'crashreporter.rc'
-
-# Don't use the STL wrappers in the crashreporter clients; they don't
-# link with -lmozalloc, and it really doesn't matter here anyway.
-DISABLE_STL_WRAPPING = True
-
-include('/toolkit/crashreporter/crashreporter.mozbuild')
diff --git a/toolkit/crashreporter/client/resource.h b/toolkit/crashreporter/client/resource.h
deleted file mode 100644
index d736b0367..000000000
--- a/toolkit/crashreporter/client/resource.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by crashreporter.rc
-//
-#define IDD_SENDDIALOG 102
-#define IDR_THROBBER 103
-#define IDD_VIEWREPORTDIALOG 104
-#define IDI_MAINICON 105
-#define IDC_PROGRESS 1003
-#define IDC_DESCRIPTIONTEXT 1004
-#define IDC_CLOSEBUTTON 1005
-#define IDC_VIEWREPORTBUTTON 1006
-#define IDC_SUBMITREPORTCHECK 1007
-#define IDC_EMAILMECHECK 1008
-#define IDC_EMAILTEXT 1009
-#define IDC_INCLUDEURLCHECK 1010
-#define IDC_COMMENTTEXT 1011
-#define IDC_RESTARTBUTTON 1012
-#define IDC_DESCRIPTIONLABEL 1013
-#define IDC_PROGRESSTEXT 1014
-#define IDC_THROBBER 1015
-#define IDC_VIEWREPORTTEXT 1016
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 106
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1017
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif