2007-07-24 18:05:54 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Toolkit Crash Reporter
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Ted Mielczarek <ted.mielczarek@gmail.com>
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2006
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#ifdef WIN32_LEAN_AND_MEAN
|
|
|
|
#undef WIN32_LEAN_AND_MEAN
|
|
|
|
#endif
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
#include "crashreporter.h"
|
|
|
|
|
2007-07-24 18:05:54 -07:00
|
|
|
#include <windows.h>
|
|
|
|
#include <commctrl.h>
|
|
|
|
#include <richedit.h>
|
|
|
|
#include <shellapi.h>
|
2007-07-24 18:06:08 -07:00
|
|
|
#include <shlobj.h>
|
|
|
|
#include <shlwapi.h>
|
2007-07-24 18:05:54 -07:00
|
|
|
#include "resource.h"
|
|
|
|
#include "client/windows/sender/crash_report_sender.h"
|
2007-07-24 18:06:08 -07:00
|
|
|
#include "common/windows/string_utils-inl.h"
|
2007-07-24 18:05:54 -07:00
|
|
|
|
|
|
|
#define CRASH_REPORTER_KEY L"Software\\Mozilla\\Crash Reporter"
|
|
|
|
#define CRASH_REPORTER_VALUE L"Enabled"
|
|
|
|
|
|
|
|
#define WM_UPLOADCOMPLETE WM_APP
|
|
|
|
|
2007-07-24 18:05:55 -07:00
|
|
|
using std::string;
|
2007-07-24 18:05:54 -07:00
|
|
|
using std::wstring;
|
|
|
|
using std::map;
|
2007-07-24 18:06:03 -07:00
|
|
|
|
|
|
|
static wstring UTF8ToWide(const string& utf8, bool *success = 0);
|
|
|
|
static string WideToUTF8(const wstring& wide, bool *success = 0);
|
|
|
|
static DWORD WINAPI SendThreadProc(LPVOID param);
|
2007-07-24 18:05:54 -07:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
HWND hDlg;
|
2007-07-24 18:05:55 -07:00
|
|
|
wstring dumpFile;
|
2007-07-24 18:06:03 -07:00
|
|
|
const StringTable* query_parameters;
|
|
|
|
wstring send_url;
|
2007-07-24 18:06:08 -07:00
|
|
|
wstring* server_response;
|
2007-07-24 18:05:54 -07:00
|
|
|
} SENDTHREADDATA;
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static wstring Str(const char* key)
|
|
|
|
{
|
|
|
|
return UTF8ToWide(gStrings[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DoInitCommonControls()
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
|
|
|
INITCOMMONCONTROLSEX ic;
|
|
|
|
ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
|
|
|
ic.dwICC = ICC_PROGRESS_CLASS;
|
|
|
|
InitCommonControlsEx(&ic);
|
|
|
|
// also get the rich edit control
|
|
|
|
LoadLibrary(L"riched20.dll");
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static BOOL CALLBACK EnableDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
2007-07-24 18:06:03 -07:00
|
|
|
SetWindowText(hwndDlg, Str(ST_CRASHREPORTERTITLE).c_str());
|
|
|
|
SetDlgItemText(hwndDlg, IDOK, Str(ST_OK).c_str());
|
|
|
|
SetDlgItemText(hwndDlg, IDC_RADIOENABLE, Str(ST_RADIOENABLE).c_str());
|
|
|
|
SetDlgItemText(hwndDlg, IDC_RADIODISABLE, Str(ST_RADIODISABLE).c_str());
|
|
|
|
SetDlgItemText(hwndDlg, IDC_DESCRIPTIONTEXT, Str(ST_CRASHREPORTERDESCRIPTION).c_str());
|
2007-07-24 18:05:54 -07:00
|
|
|
SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT, EM_SETTARGETDEVICE, (WPARAM)NULL, 0);
|
|
|
|
SetFocus(GetDlgItem(hwndDlg, IDC_RADIOENABLE));
|
|
|
|
CheckRadioButton(hwndDlg, IDC_RADIOENABLE, IDC_RADIODISABLE, lParam ? IDC_RADIOENABLE : IDC_RADIODISABLE);
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
case WM_COMMAND:
|
|
|
|
if (LOWORD(wParam) == IDOK && HIWORD(wParam) == BN_CLICKED)
|
|
|
|
{
|
|
|
|
UINT enableChecked = IsDlgButtonChecked(hwndDlg, IDC_RADIOENABLE);
|
|
|
|
EndDialog(hwndDlg, (enableChecked > 0) ? 1 : 0);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static bool GetRegValue(HKEY hRegKey, LPCTSTR valueName, DWORD* value)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
|
|
|
DWORD type, dataSize;
|
|
|
|
dataSize = sizeof(DWORD);
|
|
|
|
if (RegQueryValueEx(hRegKey, valueName, NULL, &type, (LPBYTE)value, &dataSize) == ERROR_SUCCESS
|
|
|
|
&& type == REG_DWORD)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static bool CheckCrashReporterEnabled(bool* enabled)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
|
|
|
*enabled = false;
|
|
|
|
bool found = false;
|
|
|
|
HKEY hRegKey;
|
|
|
|
DWORD val;
|
|
|
|
// see if our reg key is set globally
|
|
|
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, CRASH_REPORTER_KEY, &hRegKey) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
if (GetRegValue(hRegKey, CRASH_REPORTER_VALUE, &val))
|
|
|
|
{
|
|
|
|
*enabled = (val == 1);
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
RegCloseKey(hRegKey);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// look for it in user settings
|
|
|
|
if (RegOpenKey(HKEY_CURRENT_USER, CRASH_REPORTER_KEY, &hRegKey) == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
if (GetRegValue(hRegKey, CRASH_REPORTER_VALUE, &val))
|
|
|
|
{
|
|
|
|
*enabled = (val == 1);
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
RegCloseKey(hRegKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// didn't find our reg key, ask user
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static void SetCrashReporterEnabled(bool enabled)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
|
|
|
HKEY hRegKey;
|
|
|
|
if (RegCreateKey(HKEY_CURRENT_USER, CRASH_REPORTER_KEY, &hRegKey) == ERROR_SUCCESS) {
|
|
|
|
DWORD data = (enabled ? 1 : 0);
|
|
|
|
RegSetValueEx(hRegKey, CRASH_REPORTER_VALUE, 0, REG_DWORD, (LPBYTE)&data, sizeof(data));
|
|
|
|
RegCloseKey(hRegKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static BOOL CALLBACK SendDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
|
|
|
static bool finishedOk = false;
|
|
|
|
static HANDLE hThread = NULL;
|
|
|
|
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
{
|
|
|
|
//init strings
|
2007-07-24 18:06:03 -07:00
|
|
|
SetWindowText(hwndDlg, Str(ST_SENDTITLE).c_str());
|
|
|
|
SetDlgItemText(hwndDlg, IDCANCEL, Str(ST_CANCEL).c_str());
|
2007-07-24 18:05:54 -07:00
|
|
|
// init progressmeter
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETPOS, 0, 0);
|
|
|
|
// now create a thread to actually do the sending
|
2007-07-24 18:05:55 -07:00
|
|
|
SENDTHREADDATA* td = (SENDTHREADDATA*)lParam;
|
|
|
|
td->hDlg = hwndDlg;
|
|
|
|
CreateThread(NULL, 0, SendThreadProc, td, 0, NULL);
|
2007-07-24 18:05:54 -07:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case WM_UPLOADCOMPLETE:
|
|
|
|
WaitForSingleObject(hThread, INFINITE);
|
|
|
|
finishedOk = (wParam == 1);
|
|
|
|
if (finishedOk) {
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETPOS, 100, 0);
|
2007-07-24 18:06:03 -07:00
|
|
|
MessageBox(hwndDlg,
|
|
|
|
Str(ST_SUBMITSUCCESS).c_str(),
|
|
|
|
Str(ST_CRASHREPORTERTITLE).c_str(),
|
|
|
|
MB_OK | MB_ICONINFORMATION);
|
2007-07-24 18:05:54 -07:00
|
|
|
}
|
|
|
|
else {
|
2007-07-24 18:06:03 -07:00
|
|
|
MessageBox(hwndDlg,
|
|
|
|
Str(ST_SUBMITFAILED).c_str(),
|
|
|
|
Str(ST_CRASHREPORTERTITLE).c_str(),
|
|
|
|
MB_OK | MB_ICONERROR);
|
2007-07-24 18:05:54 -07:00
|
|
|
}
|
|
|
|
EndDialog(hwndDlg, finishedOk ? 1 : 0);
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case WM_COMMAND:
|
|
|
|
if (LOWORD(wParam) == IDCANCEL && HIWORD(wParam) == BN_CLICKED) {
|
|
|
|
EndDialog(hwndDlg, finishedOk ? 1 : 0);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static bool SendCrashReport(wstring dumpFile,
|
|
|
|
const StringTable* query_parameters,
|
|
|
|
wstring send_url,
|
|
|
|
wstring* server_response)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
2007-07-24 18:05:55 -07:00
|
|
|
SENDTHREADDATA td;
|
|
|
|
td.hDlg = NULL;
|
|
|
|
td.dumpFile = dumpFile;
|
|
|
|
td.query_parameters = query_parameters;
|
2007-07-24 18:06:03 -07:00
|
|
|
td.send_url = send_url;
|
2007-07-24 18:06:08 -07:00
|
|
|
td.server_response = server_response;
|
2007-07-24 18:05:55 -07:00
|
|
|
|
|
|
|
int res = (int)DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_SENDDIALOG), NULL,
|
|
|
|
(DLGPROC)SendDialogProc, (LPARAM)&td);
|
|
|
|
|
2007-07-24 18:05:54 -07:00
|
|
|
return (res >= 0);
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static DWORD WINAPI SendThreadProc(LPVOID param)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
2007-07-24 18:06:04 -07:00
|
|
|
bool finishedOk;
|
2007-07-24 18:05:54 -07:00
|
|
|
SENDTHREADDATA* td = (SENDTHREADDATA*)param;
|
2007-07-24 18:05:55 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
if (td->send_url.empty()) {
|
2007-07-24 18:06:04 -07:00
|
|
|
finishedOk = false;
|
|
|
|
}
|
|
|
|
else {
|
2007-07-24 18:06:03 -07:00
|
|
|
map<wstring,wstring>query_parameters;
|
|
|
|
StringTable::const_iterator end = td->query_parameters->end();
|
|
|
|
for (StringTable::const_iterator i = td->query_parameters->begin();
|
|
|
|
i != end;
|
|
|
|
i++) {
|
|
|
|
query_parameters[UTF8ToWide(i->first)] = UTF8ToWide(i->second);
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:05:56 -07:00
|
|
|
finishedOk = (google_breakpad::CrashReportSender
|
2007-07-24 18:06:03 -07:00
|
|
|
::SendCrashReport(td->send_url,
|
|
|
|
query_parameters,
|
2007-07-24 18:05:56 -07:00
|
|
|
td->dumpFile,
|
2007-07-24 18:06:08 -07:00
|
|
|
td->server_response)
|
2007-07-24 18:05:56 -07:00
|
|
|
== google_breakpad::RESULT_SUCCEEDED);
|
2007-07-24 18:06:04 -07:00
|
|
|
}
|
2007-07-24 18:05:54 -07:00
|
|
|
PostMessage(td->hDlg, WM_UPLOADCOMPLETE, finishedOk ? 1 : 0, 0);
|
2007-07-24 18:05:56 -07:00
|
|
|
|
2007-07-24 18:05:54 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static wstring UTF8ToWide(const string& utf8, bool *success)
|
2007-07-24 18:05:54 -07:00
|
|
|
{
|
2007-07-24 18:06:08 -07:00
|
|
|
wchar_t* buffer = NULL;
|
2007-07-24 18:06:03 -07:00
|
|
|
int buffer_size = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(),
|
2007-07-24 18:05:55 -07:00
|
|
|
-1, NULL, 0);
|
2007-07-24 18:06:03 -07:00
|
|
|
if(buffer_size == 0) {
|
|
|
|
if (success)
|
|
|
|
*success = false;
|
|
|
|
return L"";
|
|
|
|
}
|
2007-07-24 18:05:55 -07:00
|
|
|
|
|
|
|
buffer = new wchar_t[buffer_size];
|
2007-07-24 18:06:03 -07:00
|
|
|
if(buffer == NULL) {
|
|
|
|
if (success)
|
|
|
|
*success = false;
|
|
|
|
return L"";
|
|
|
|
}
|
|
|
|
|
|
|
|
MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(),
|
2007-07-24 18:05:55 -07:00
|
|
|
-1, buffer, buffer_size);
|
2007-07-24 18:06:03 -07:00
|
|
|
wstring str = buffer;
|
2007-07-24 18:05:55 -07:00
|
|
|
delete [] buffer;
|
2007-07-24 18:06:03 -07:00
|
|
|
|
|
|
|
if (success)
|
|
|
|
*success = true;
|
|
|
|
|
|
|
|
return str;
|
2007-07-24 18:05:55 -07:00
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
static string WideToUTF8(const wstring& wide, bool *success)
|
2007-07-24 18:06:08 -07:00
|
|
|
{
|
|
|
|
char* buffer = NULL;
|
2007-07-24 18:06:03 -07:00
|
|
|
int buffer_size = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(),
|
2007-07-24 18:06:08 -07:00
|
|
|
-1, NULL, 0, NULL, NULL);
|
2007-07-24 18:06:03 -07:00
|
|
|
if(buffer_size == 0) {
|
|
|
|
if (success)
|
|
|
|
*success = false;
|
|
|
|
return "";
|
|
|
|
}
|
2007-07-24 18:06:08 -07:00
|
|
|
|
|
|
|
buffer = new char[buffer_size];
|
2007-07-24 18:06:03 -07:00
|
|
|
if(buffer == NULL) {
|
|
|
|
if (success)
|
|
|
|
*success = false;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
WideCharToMultiByte(CP_UTF8, 0, wide.c_str(),
|
2007-07-24 18:06:08 -07:00
|
|
|
-1, buffer, buffer_size, NULL, NULL);
|
2007-07-24 18:06:03 -07:00
|
|
|
string utf8 = buffer;
|
2007-07-24 18:06:08 -07:00
|
|
|
delete [] buffer;
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
if (success)
|
|
|
|
*success = true;
|
|
|
|
|
|
|
|
return utf8;
|
2007-07-24 18:06:08 -07:00
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
/* === Crashreporter UI Functions === */
|
|
|
|
|
|
|
|
bool UIInit()
|
2007-07-24 18:05:55 -07:00
|
|
|
{
|
2007-07-24 18:06:03 -07:00
|
|
|
DoInitCommonControls();
|
2007-07-24 18:06:08 -07:00
|
|
|
return true;
|
2007-07-24 18:05:54 -07:00
|
|
|
}
|
2007-07-24 18:05:55 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
void UIShutdown()
|
2007-07-24 18:05:55 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
void UIShowDefaultUI()
|
2007-07-24 18:06:08 -07:00
|
|
|
{
|
2007-07-24 18:06:03 -07:00
|
|
|
bool enabled;
|
|
|
|
// no dump file specified, just ask about enabling
|
|
|
|
if (!CheckCrashReporterEnabled(&enabled))
|
|
|
|
enabled = true;
|
2007-07-24 18:06:08 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
enabled = (1 == DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_ENABLEDIALOG), NULL, (DLGPROC)EnableDialogProc, (LPARAM)enabled));
|
|
|
|
SetCrashReporterEnabled(enabled);
|
2007-07-24 18:06:08 -07:00
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
void UIShowCrashUI(const string& dumpfile,
|
|
|
|
const StringTable& query_parameters,
|
|
|
|
const string& send_url)
|
2007-07-24 18:05:55 -07:00
|
|
|
{
|
2007-07-24 18:06:03 -07:00
|
|
|
bool enabled;
|
|
|
|
if (!CheckCrashReporterEnabled(&enabled)) {
|
|
|
|
//ask user if crash reporter should be enabled
|
|
|
|
enabled = (1 == DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_ENABLEDIALOG), NULL, (DLGPROC)EnableDialogProc, (LPARAM)true));
|
|
|
|
SetCrashReporterEnabled(enabled);
|
2007-07-24 18:05:55 -07:00
|
|
|
}
|
2007-07-24 18:06:03 -07:00
|
|
|
// if enabled, send crash report
|
|
|
|
if (enabled) {
|
|
|
|
wstring server_response;
|
|
|
|
bool success = SendCrashReport(UTF8ToWide(dumpfile),
|
|
|
|
&query_parameters,
|
|
|
|
UTF8ToWide(send_url),
|
|
|
|
&server_response);
|
|
|
|
CrashReporterSendCompleted(success, WideToUTF8(server_response));
|
2007-07-24 18:05:55 -07:00
|
|
|
}
|
2007-07-24 18:06:03 -07:00
|
|
|
}
|
2007-07-24 18:05:55 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
void UIError(const string& message)
|
|
|
|
{
|
|
|
|
wstring title = Str(ST_CRASHREPORTERTITLE);
|
|
|
|
if (title.empty())
|
|
|
|
title = L"Crash Reporter Error";
|
2007-07-24 18:05:55 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
MessageBox(NULL, UTF8ToWide(message).c_str(), title.c_str(),
|
|
|
|
MB_OK | MB_ICONSTOP);
|
|
|
|
}
|
2007-07-24 18:06:08 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
bool UIGetIniPath(string& path)
|
|
|
|
{
|
|
|
|
wchar_t fileName[MAX_PATH];
|
|
|
|
if (GetModuleFileName(NULL, fileName, MAX_PATH)) {
|
|
|
|
// get crashreporter ini
|
|
|
|
wchar_t* s = wcsrchr(fileName, '.');
|
|
|
|
if (s) {
|
|
|
|
wcscpy(s, L".ini");
|
|
|
|
path = WideToUTF8(fileName);
|
|
|
|
return true;
|
2007-07-24 18:06:08 -07:00
|
|
|
}
|
2007-07-24 18:06:03 -07:00
|
|
|
}
|
2007-07-24 18:06:08 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
return false;
|
|
|
|
}
|
2007-07-24 18:06:08 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
bool UIGetSettingsPath(const string& vendor,
|
|
|
|
const string& product,
|
|
|
|
string& settings_path)
|
|
|
|
{
|
|
|
|
wchar_t path[MAX_PATH];
|
|
|
|
if(SUCCEEDED(SHGetFolderPath(NULL,
|
|
|
|
CSIDL_APPDATA,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
path))) {
|
|
|
|
if (!vendor.empty()) {
|
|
|
|
PathAppend(path, UTF8ToWide(vendor).c_str());
|
2007-07-24 18:06:08 -07:00
|
|
|
}
|
2007-07-24 18:06:03 -07:00
|
|
|
PathAppend(path, UTF8ToWide(product).c_str());
|
|
|
|
PathAppend(path, L"Crash Reports");
|
|
|
|
// in case it doesn't exist
|
|
|
|
CreateDirectory(path, NULL);
|
|
|
|
settings_path = WideToUTF8(path);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2007-07-24 18:06:08 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
bool UIEnsurePathExists(const string& path)
|
|
|
|
{
|
|
|
|
if (CreateDirectory(UTF8ToWide(path).c_str(), NULL) == 0) {
|
|
|
|
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
|
|
|
return false;
|
|
|
|
}
|
2007-07-24 18:06:08 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
return true;
|
|
|
|
}
|
2007-07-24 18:05:55 -07:00
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
bool UIMoveFile(const string& oldfile, const string& newfile)
|
|
|
|
{
|
2007-07-24 18:06:03 -07:00
|
|
|
return MoveFile(UTF8ToWide(oldfile).c_str(), UTF8ToWide(newfile).c_str())
|
|
|
|
== TRUE;
|
2007-07-24 18:05:55 -07:00
|
|
|
}
|
|
|
|
|
2007-07-24 18:06:03 -07:00
|
|
|
bool UIDeleteFile(const string& oldfile)
|
2007-07-24 18:05:55 -07:00
|
|
|
{
|
2007-07-24 18:06:03 -07:00
|
|
|
return DeleteFile(UTF8ToWide(oldfile).c_str()) == TRUE;
|
2007-07-24 18:05:55 -07:00
|
|
|
}
|