xref: /AOO41X/main/crashrep/source/win32/soreport.cpp (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #define UNICODE
29*cdf0e10cSrcweir #define WIN32_LEAN_AND_MEAN
30*cdf0e10cSrcweir #if defined _MSC_VER
31*cdf0e10cSrcweir #pragma warning(push, 1)
32*cdf0e10cSrcweir #pragma warning(disable:4917)
33*cdf0e10cSrcweir #endif
34*cdf0e10cSrcweir #include <windows.h>
35*cdf0e10cSrcweir #include <windowsx.h>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <mapi.h>
38*cdf0e10cSrcweir #include <commctrl.h>
39*cdf0e10cSrcweir #include <commdlg.h>
40*cdf0e10cSrcweir #include <psapi.h>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <shellapi.h>
43*cdf0e10cSrcweir #include <shlobj.h>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #define _UNICODE
46*cdf0e10cSrcweir #include <tchar.h>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #define _RICHEDIT_VER	0x0200
49*cdf0e10cSrcweir #include <richedit.h>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #if defined _MSC_VER
52*cdf0e10cSrcweir #pragma warning(pop)
53*cdf0e10cSrcweir #endif
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #if _RICHEDIT_VER >= 0x0200
56*cdf0e10cSrcweir #define RICHEDIT	TEXT("riched20.dll")
57*cdf0e10cSrcweir #else
58*cdf0e10cSrcweir #define RICHEDIT	TEXT("riched32.dll")
59*cdf0e10cSrcweir #endif
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #include <systools/win32/uwinapi.h>
62*cdf0e10cSrcweir #include <rtl/digest.h>
63*cdf0e10cSrcweir #include <rtl/bootstrap.hxx>
64*cdf0e10cSrcweir #include <osl/file.hxx>
65*cdf0e10cSrcweir #include <osl/process.h>
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir #include <stdlib.h>
68*cdf0e10cSrcweir #include <stdio.h>
69*cdf0e10cSrcweir #include <io.h>
70*cdf0e10cSrcweir #include <fcntl.h>
71*cdf0e10cSrcweir #include <string>
72*cdf0e10cSrcweir #include <hash_map>
73*cdf0e10cSrcweir #include <winsock.h>
74*cdf0e10cSrcweir #include <malloc.h>
75*cdf0e10cSrcweir #include <process.h>
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir #include <_version.h>
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir #include "resource.h"
80*cdf0e10cSrcweir #include "base64.h"
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir #define FORMATBUFSIZE	(8*1024)
83*cdf0e10cSrcweir #define MAX_TEXT_BUFFER (32*1024-1)
84*cdf0e10cSrcweir #define MAX_HOSTNAME	(1024)
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir #ifdef __MINGW32__
87*cdf0e10cSrcweir #include <imagehlp.h>
88*cdf0e10cSrcweir #else
89*cdf0e10cSrcweir #include <dbghelp.h>
90*cdf0e10cSrcweir #endif
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir #ifdef _UNICODE
93*cdf0e10cSrcweir #define tstring	wstring
94*cdf0e10cSrcweir #else
95*cdf0e10cSrcweir #define tstring string
96*cdf0e10cSrcweir #endif
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir using namespace ::std;
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir wstring  g_wstrProductKey;
102*cdf0e10cSrcweir string  g_strDefaultLanguage;
103*cdf0e10cSrcweir FILE	*g_fpStackFile = NULL;
104*cdf0e10cSrcweir FILE	*g_fpChecksumFile = NULL;
105*cdf0e10cSrcweir DWORD	g_dwExceptionCode = 0;
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir CHAR	g_szReportServerA[MAX_HOSTNAME] = "";
108*cdf0e10cSrcweir USHORT	g_uReportPort = 80;
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir TCHAR	g_szBuildId[256] = TEXT("");
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir TCHAR	g_szDumpFileName[MAX_PATH] = TEXT("");
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir CHAR	g_szDumpFileNameA[MAX_PATH] = "";
115*cdf0e10cSrcweir CHAR	g_szCommentFileNameA[MAX_PATH] = "";
116*cdf0e10cSrcweir CHAR	g_szReportFileNameA[MAX_PATH] = "";
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir bool	g_bNoUserInterface = false;
120*cdf0e10cSrcweir bool	g_bSendReport = false;
121*cdf0e10cSrcweir bool	g_bLoadReport = false;
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir #define REPORT_SERVER	g_szReportServerA
124*cdf0e10cSrcweir #define REPORT_PORT		g_uReportPort
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir //***************************************************************************
128*cdf0e10cSrcweir // tmpfile from msvcrt creates the temporary file in the root of the current
129*cdf0e10cSrcweir // volume and can fail.
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir static FILE *_xfopen( const _TCHAR *file, const _TCHAR *mode )
132*cdf0e10cSrcweir {
133*cdf0e10cSrcweir #ifdef UNICODE
134*cdf0e10cSrcweir 	if ( (LONG)GetVersion() < 0 )
135*cdf0e10cSrcweir 	{
136*cdf0e10cSrcweir 		char	afile[MAX_PATH];
137*cdf0e10cSrcweir 		char	amode[16];
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 		WideCharToMultiByte( CP_ACP, 0, file, -1, afile, MAX_PATH, NULL, NULL );
140*cdf0e10cSrcweir 		WideCharToMultiByte( CP_ACP, 0, mode, -1, amode, 16, NULL, NULL );
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir 		return fopen( afile, amode );
144*cdf0e10cSrcweir 	}
145*cdf0e10cSrcweir 	else
146*cdf0e10cSrcweir #endif
147*cdf0e10cSrcweir 		return _tfopen( file, mode );
148*cdf0e10cSrcweir }
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir static FILE *_tmpfile(void)
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir 	FILE *fp = NULL;
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 	TCHAR	szTempPath[MAX_PATH];
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir 	if ( GetTempPath( elementsof(szTempPath), szTempPath ) )
158*cdf0e10cSrcweir 	{
159*cdf0e10cSrcweir 		TCHAR	szFileName[MAX_PATH];
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 		if ( GetTempFileName( szTempPath, TEXT("CRT"), 0, szFileName ) )
162*cdf0e10cSrcweir 		{
163*cdf0e10cSrcweir 			HANDLE	hFile =  CreateFile(
164*cdf0e10cSrcweir 				szFileName,
165*cdf0e10cSrcweir 				GENERIC_READ | GENERIC_WRITE,
166*cdf0e10cSrcweir 				0, NULL,
167*cdf0e10cSrcweir 				OPEN_EXISTING,
168*cdf0e10cSrcweir 				FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_NORMAL,
169*cdf0e10cSrcweir 				NULL );
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir 			if ( IsValidHandle( hFile ) )
172*cdf0e10cSrcweir 			{
173*cdf0e10cSrcweir 				int fd = _open_osfhandle( (int)hFile, 0 );
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 				fp = _fdopen( fd, "w+b" );
176*cdf0e10cSrcweir 			}
177*cdf0e10cSrcweir 		}
178*cdf0e10cSrcweir 	}
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir 	return fp;
181*cdf0e10cSrcweir }
182*cdf0e10cSrcweir //***************************************************************************
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir static BOOL GetCrashDataPath( LPTSTR szBuffer )
185*cdf0e10cSrcweir {
186*cdf0e10cSrcweir 	::rtl::OUString	ustrValue = ::rtl::OUString::createFromAscii("${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}");
187*cdf0e10cSrcweir 	::rtl::Bootstrap::expandMacros( ustrValue );
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 	if ( ustrValue.getLength() )
190*cdf0e10cSrcweir 	{
191*cdf0e10cSrcweir 		ustrValue += ::rtl::OUString::createFromAscii("/user/crashdata");
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 		::osl::FileBase::RC	result = ::osl::Directory::createPath( ustrValue );
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir 		if ( ::osl::FileBase::E_None == result || ::osl::FileBase::E_EXIST == result )
196*cdf0e10cSrcweir 		{
197*cdf0e10cSrcweir 			::rtl::OUString	ustrPath;
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 			result = ::osl::FileBase::getSystemPathFromFileURL( ustrValue, ustrPath );
200*cdf0e10cSrcweir 			if (  ::osl::FileBase::E_None == result  )
201*cdf0e10cSrcweir 			{
202*cdf0e10cSrcweir 				_tcsncpy( szBuffer, reinterpret_cast<LPCWSTR>(ustrPath.getStr()), MAX_PATH );
203*cdf0e10cSrcweir 				return TRUE;
204*cdf0e10cSrcweir 			}
205*cdf0e10cSrcweir 		}
206*cdf0e10cSrcweir 	}
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 	return FALSE;
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir static FILE *_open_reportfile( LPCTSTR lpExt, LPCTSTR lpMode )
213*cdf0e10cSrcweir {
214*cdf0e10cSrcweir 	FILE	*fp = NULL;
215*cdf0e10cSrcweir 	TCHAR	szAppDataPath[MAX_PATH] = _T("");
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir 	if ( GetCrashDataPath( szAppDataPath ) )
218*cdf0e10cSrcweir 	{
219*cdf0e10cSrcweir 		_tcscat( szAppDataPath, _T("\\crashdat") );
220*cdf0e10cSrcweir 		_tcscat( szAppDataPath, lpExt );
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir 		fp = _xfopen( szAppDataPath, lpMode );
223*cdf0e10cSrcweir 	}
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 	return fp;
226*cdf0e10cSrcweir }
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir //***************************************************************************
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir struct CrashReportParams
231*cdf0e10cSrcweir {
232*cdf0e10cSrcweir 	BOOL				fAllowContact;
233*cdf0e10cSrcweir 	tstring				sEmail;
234*cdf0e10cSrcweir 	tstring				sTitle;
235*cdf0e10cSrcweir 	tstring				sComment;
236*cdf0e10cSrcweir 	ULONG				uInternetConnection;
237*cdf0e10cSrcweir 	tstring				sProxyServer;
238*cdf0e10cSrcweir 	tstring				sProxyPort;
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir 	CrashReportParams();
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir 	void WriteToRegistry();
243*cdf0e10cSrcweir 	void ReadFromRegistry();
244*cdf0e10cSrcweir 	void ReadFromEnvironment();
245*cdf0e10cSrcweir };
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir bool SendCrashReport( HWND hwndParent, const CrashReportParams &rParams );
248*cdf0e10cSrcweir BOOL WriteCommentFile( LPCTSTR lpComment );
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir //***************************************************************************
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir LONG RegReadValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPVOID lpData, DWORD cbData )
253*cdf0e10cSrcweir {
254*cdf0e10cSrcweir 	HKEY	hKey = NULL;
255*cdf0e10cSrcweir 	LONG	lResult;
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir 	lResult = RegOpenKeyEx( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir 	if ( ERROR_SUCCESS == lResult )
260*cdf0e10cSrcweir 	{
261*cdf0e10cSrcweir 		lResult = RegQueryValueEx( hKey, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData );
262*cdf0e10cSrcweir 		RegCloseKey( hKey );
263*cdf0e10cSrcweir 	}
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir 	return lResult;
266*cdf0e10cSrcweir }
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir //***************************************************************************
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir LONG RegWriteValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, DWORD dwType, LPCVOID lpData, DWORD cbData )
271*cdf0e10cSrcweir {
272*cdf0e10cSrcweir 	HKEY	hKey = NULL;
273*cdf0e10cSrcweir 	LONG	lResult;
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir 	lResult = RegCreateKeyEx( hBaseKey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL );
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 	if ( ERROR_SUCCESS == lResult )
278*cdf0e10cSrcweir 	{
279*cdf0e10cSrcweir 		lResult = RegSetValueEx( hKey, lpValueName, NULL, dwType, (CONST BYTE *)lpData, cbData );
280*cdf0e10cSrcweir 		RegCloseKey( hKey );
281*cdf0e10cSrcweir 	}
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir 	return lResult;
284*cdf0e10cSrcweir }
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir //***************************************************************************
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir CrashReportParams::CrashReportParams()
289*cdf0e10cSrcweir {
290*cdf0e10cSrcweir 	fAllowContact = FALSE;
291*cdf0e10cSrcweir 	sTitle = TEXT("");
292*cdf0e10cSrcweir 	sComment = TEXT("");
293*cdf0e10cSrcweir 	sEmail = TEXT("");
294*cdf0e10cSrcweir 	uInternetConnection = 0;
295*cdf0e10cSrcweir 	sProxyServer = TEXT("");
296*cdf0e10cSrcweir 	sProxyPort = TEXT("");
297*cdf0e10cSrcweir }
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir //***************************************************************************
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir void CrashReportParams::ReadFromRegistry()
302*cdf0e10cSrcweir {
303*cdf0e10cSrcweir 	TCHAR	szBuffer[2048];
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir 	if ( ERROR_SUCCESS == RegReadValue(
306*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
307*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
308*cdf0e10cSrcweir 		TEXT("HTTPProxyServer"),
309*cdf0e10cSrcweir 		szBuffer,
310*cdf0e10cSrcweir 		sizeof(szBuffer) ) )
311*cdf0e10cSrcweir 		sProxyServer = szBuffer;
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 	DWORD	dwProxyPort;
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir 	if ( ERROR_SUCCESS == RegReadValue(
316*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
317*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
318*cdf0e10cSrcweir 		TEXT("HTTPProxyPort"),
319*cdf0e10cSrcweir 		&dwProxyPort,
320*cdf0e10cSrcweir 		sizeof(dwProxyPort) ) )
321*cdf0e10cSrcweir 	{
322*cdf0e10cSrcweir 		_stprintf( szBuffer, TEXT("%d"), dwProxyPort );
323*cdf0e10cSrcweir 		sProxyPort = szBuffer;
324*cdf0e10cSrcweir 	}
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir 	if ( ERROR_SUCCESS == RegReadValue(
327*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
328*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
329*cdf0e10cSrcweir 		TEXT("ReturnAddress"),
330*cdf0e10cSrcweir 		szBuffer,
331*cdf0e10cSrcweir 		sizeof(szBuffer) ) )
332*cdf0e10cSrcweir 		sEmail = szBuffer;
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir 	RegReadValue(
335*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
336*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
337*cdf0e10cSrcweir 		TEXT("AllowContact"),
338*cdf0e10cSrcweir 		&fAllowContact,
339*cdf0e10cSrcweir 		sizeof(fAllowContact) );
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir 	RegReadValue(
342*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
343*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
344*cdf0e10cSrcweir 		TEXT("HTTPConnection"),
345*cdf0e10cSrcweir 		&uInternetConnection,
346*cdf0e10cSrcweir 		sizeof(uInternetConnection) );
347*cdf0e10cSrcweir }
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir //***************************************************************************
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir void CrashReportParams::WriteToRegistry()
352*cdf0e10cSrcweir {
353*cdf0e10cSrcweir 	RegWriteValue(
354*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
355*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
356*cdf0e10cSrcweir 		TEXT("HTTPProxyServer"), REG_SZ,
357*cdf0e10cSrcweir 		sProxyServer.c_str(),
358*cdf0e10cSrcweir 		sizeof(TCHAR) * (sProxyServer.length() + 1) );
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir 	LPTSTR endptr = NULL;
361*cdf0e10cSrcweir 	DWORD dwProxyPort = _tcstoul( sProxyPort.c_str(), &endptr, 10 );
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir 	RegWriteValue(
364*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
365*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
366*cdf0e10cSrcweir 		TEXT("HTTPProxyPort"), REG_DWORD,
367*cdf0e10cSrcweir 		&dwProxyPort,
368*cdf0e10cSrcweir 		sizeof(DWORD) );
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir 	RegWriteValue(
371*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
372*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
373*cdf0e10cSrcweir 		TEXT("AllowContact"), REG_DWORD,
374*cdf0e10cSrcweir 		&fAllowContact,
375*cdf0e10cSrcweir 		sizeof(DWORD) );
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir 	RegWriteValue(
379*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
380*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
381*cdf0e10cSrcweir 		TEXT("HTTPConnection"), REG_DWORD,
382*cdf0e10cSrcweir 		&uInternetConnection,
383*cdf0e10cSrcweir 		sizeof(DWORD) );
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir 	RegWriteValue(
386*cdf0e10cSrcweir 		HKEY_CURRENT_USER,
387*cdf0e10cSrcweir 		TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
388*cdf0e10cSrcweir 		TEXT("ReturnAddress"), REG_SZ,
389*cdf0e10cSrcweir 		sEmail.c_str(),
390*cdf0e10cSrcweir 		sizeof(TCHAR) * (sEmail.length() + 1) );
391*cdf0e10cSrcweir }
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir //***************************************************************************
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir void CrashReportParams::ReadFromEnvironment()
396*cdf0e10cSrcweir {
397*cdf0e10cSrcweir 	TCHAR	szBuffer[2048];
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir 	DWORD dwResult = GetEnvironmentVariable( TEXT("ERRORREPORT_HTTPPROXYSERVER"), szBuffer, elementsof(szBuffer) );
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir 	if ( dwResult && dwResult < elementsof(szBuffer) )
402*cdf0e10cSrcweir 		sProxyServer = szBuffer;
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir 	dwResult = GetEnvironmentVariable( TEXT("ERRORREPORT_HTTPPROXYPORT"), szBuffer, elementsof(szBuffer) );
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 	if ( dwResult && dwResult < elementsof(szBuffer) )
407*cdf0e10cSrcweir 		sProxyPort = szBuffer;
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir 	dwResult = GetEnvironmentVariable( TEXT("ERRORREPORT_RETURNADDRESS"), szBuffer, elementsof(szBuffer) );
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir 	if ( dwResult && dwResult < elementsof(szBuffer) )
412*cdf0e10cSrcweir 	{
413*cdf0e10cSrcweir 		sEmail = szBuffer;
414*cdf0e10cSrcweir 		// fAllowContact = TRUE;
415*cdf0e10cSrcweir 	}
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir 	dwResult = GetEnvironmentVariable( TEXT("ERRORREPORT_HTTPCONNECTIONTYPE"), szBuffer, elementsof(szBuffer) );
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 	if ( dwResult && dwResult < elementsof(szBuffer) )
420*cdf0e10cSrcweir 	{
421*cdf0e10cSrcweir 		if ( 0 == _tcsicmp( szBuffer, _T("DIRECT") ) )
422*cdf0e10cSrcweir 			uInternetConnection = 1;
423*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( szBuffer, _T("MANUALPROXY") ) )
424*cdf0e10cSrcweir 			uInternetConnection = 2;
425*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( szBuffer, _T("SYSTEMDEFAULT") ) )
426*cdf0e10cSrcweir 			uInternetConnection = 0;
427*cdf0e10cSrcweir 	}
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir 	dwResult = GetEnvironmentVariable( TEXT("ERRORREPORT_SUBJECT"), szBuffer, elementsof(szBuffer) );
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir 	if ( dwResult && dwResult < elementsof(szBuffer) )
432*cdf0e10cSrcweir 		sTitle = szBuffer;
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir 	dwResult = GetEnvironmentVariable( TEXT("ERRORREPORT_BODYFILE"), szBuffer, elementsof(szBuffer) );
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir 	if ( dwResult && dwResult < elementsof(szBuffer) )
438*cdf0e10cSrcweir 	{
439*cdf0e10cSrcweir 		FILE *fp = _xfopen( szBuffer, _T("rb") );
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir 		if ( fp )
442*cdf0e10cSrcweir 		{
443*cdf0e10cSrcweir 			CHAR	aUTF8Buffer[256];
444*cdf0e10cSrcweir 			size_t	nBytesRead;
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir 			sComment = TEXT("");
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir 			while ( 0 != (nBytesRead = fread( aUTF8Buffer, sizeof(aUTF8Buffer[0]), elementsof(aUTF8Buffer), fp )) )
449*cdf0e10cSrcweir 			{
450*cdf0e10cSrcweir 				TCHAR	aBuffer[256+1];
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir 				DWORD	dwCharacters = MultiByteToWideChar( CP_UTF8, 0, aUTF8Buffer, nBytesRead, aBuffer, elementsof(aBuffer) - 1 );
453*cdf0e10cSrcweir 				aBuffer[dwCharacters] = 0;
454*cdf0e10cSrcweir 				sComment += aBuffer;
455*cdf0e10cSrcweir 			}
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir 			fclose( fp );
458*cdf0e10cSrcweir 		}
459*cdf0e10cSrcweir 	}
460*cdf0e10cSrcweir }
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir //***************************************************************************
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir typedef BOOL (WINAPI *MiniDumpWriteDump_PROC)(
465*cdf0e10cSrcweir     IN HANDLE hProcess,
466*cdf0e10cSrcweir     IN DWORD ProcessId,
467*cdf0e10cSrcweir     IN HANDLE hFile,
468*cdf0e10cSrcweir     IN MINIDUMP_TYPE DumpType,
469*cdf0e10cSrcweir     IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
470*cdf0e10cSrcweir     IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
471*cdf0e10cSrcweir     IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
472*cdf0e10cSrcweir     );
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir //***************************************************************************
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir static BOOL WINAPI InitRichEdit()
477*cdf0e10cSrcweir {
478*cdf0e10cSrcweir 	return (NULL != LoadLibrary( RICHEDIT ));
479*cdf0e10cSrcweir }
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir //***************************************************************************
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir static BOOL WINAPI DeinitRichEdit()
484*cdf0e10cSrcweir {
485*cdf0e10cSrcweir 	return FreeLibrary( GetModuleHandle( RICHEDIT ) );
486*cdf0e10cSrcweir }
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir //***************************************************************************
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir static string trim_string( const string& rString )
491*cdf0e10cSrcweir {
492*cdf0e10cSrcweir 	string temp = rString;
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir 	while ( temp.length() && temp[0] == ' ' || temp[0] == '\t' )
495*cdf0e10cSrcweir 		temp.erase( 0, 1 );
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir 	string::size_type	len = temp.length();
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir 	while ( len && temp[len-1] == ' ' || temp[len-1] == '\t' )
500*cdf0e10cSrcweir 	{
501*cdf0e10cSrcweir 		temp.erase( len - 1, 1 );
502*cdf0e10cSrcweir 		len = temp.length();
503*cdf0e10cSrcweir 	}
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir 	return temp;
506*cdf0e10cSrcweir }
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir //***************************************************************************
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir static int LoadAndFormatString( HINSTANCE hInstance, UINT uID, LPTSTR lpBuffer, int nBufferMax )
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir 	TCHAR	szBuffer[FORMATBUFSIZE];
513*cdf0e10cSrcweir 	TCHAR	szBuffer2[FORMATBUFSIZE];
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir 	LoadString( hInstance, uID, szBuffer, elementsof(szBuffer) );
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 	LPCTSTR	src;
518*cdf0e10cSrcweir 	LPTSTR	dest;
519*cdf0e10cSrcweir 	for ( dest = szBuffer2, src = szBuffer; *src; src++, dest++ )
520*cdf0e10cSrcweir 	{
521*cdf0e10cSrcweir 		switch ( *src )
522*cdf0e10cSrcweir 		{
523*cdf0e10cSrcweir 		case '~':
524*cdf0e10cSrcweir 			*dest = '&';
525*cdf0e10cSrcweir 			break;
526*cdf0e10cSrcweir 		case '\\':
527*cdf0e10cSrcweir 			switch ( *(++src) )
528*cdf0e10cSrcweir 			{
529*cdf0e10cSrcweir 			case 'n':
530*cdf0e10cSrcweir 				*dest = '\n';
531*cdf0e10cSrcweir 				break;
532*cdf0e10cSrcweir 			case 'r':
533*cdf0e10cSrcweir 				*dest = '\r';
534*cdf0e10cSrcweir 				break;
535*cdf0e10cSrcweir 			default:
536*cdf0e10cSrcweir 				*dest = *src;
537*cdf0e10cSrcweir 				break;
538*cdf0e10cSrcweir 			}
539*cdf0e10cSrcweir 			break;
540*cdf0e10cSrcweir 		default:
541*cdf0e10cSrcweir 			*dest = *src;
542*cdf0e10cSrcweir 			break;
543*cdf0e10cSrcweir 		}
544*cdf0e10cSrcweir 	}
545*cdf0e10cSrcweir 
546*cdf0e10cSrcweir 	*dest = *src;
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir 	return ExpandEnvironmentStrings( szBuffer2, lpBuffer, nBufferMax );
549*cdf0e10cSrcweir }
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir //***************************************************************************
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir static string wstring2utf8( const wstring &rString )
555*cdf0e10cSrcweir {
556*cdf0e10cSrcweir 	int nBufSize = WideCharToMultiByte( CP_UTF8, 0, rString.c_str(), -1, NULL, 0, NULL, FALSE );
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir 	LPSTR	pBuffer = (LPSTR)alloca( nBufSize );
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir 	WideCharToMultiByte(  CP_UTF8, 0, rString.c_str(), -1, pBuffer, nBufSize, NULL, FALSE );
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir 	return string( pBuffer );
563*cdf0e10cSrcweir }
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir //***************************************************************************
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir static string xml_encode( const string &rString )
568*cdf0e10cSrcweir {
569*cdf0e10cSrcweir 	string temp = rString;
570*cdf0e10cSrcweir     string::size_type pos = 0;
571*cdf0e10cSrcweir 
572*cdf0e10cSrcweir 	// First replace all occurences of '&' because it may occur in further
573*cdf0e10cSrcweir 	// encoded chardters too
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir     for( pos = 0; (pos = temp.find( '&', pos )) != string::npos; pos += 4 )
576*cdf0e10cSrcweir         temp.replace( pos, 1, "&amp;" );
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir 	for( pos = 0; (pos = temp.find( '<', pos )) != string::npos; pos += 4 )
579*cdf0e10cSrcweir         temp.replace( pos, 1, "&lt;" );
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir     for( pos = 0; (pos = temp.find( '>', pos )) != string::npos; pos += 4 )
582*cdf0e10cSrcweir         temp.replace( pos, 1, "&gt;" );
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir 	return temp;
585*cdf0e10cSrcweir }
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir //***************************************************************************
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir static size_t fcopy( FILE *fpin, FILE *fpout )
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir 	char buffer[1024];
592*cdf0e10cSrcweir 	size_t nBytes;
593*cdf0e10cSrcweir 	size_t nBytesWritten = 0;
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir 	if ( fpin && fpout )
596*cdf0e10cSrcweir 	{
597*cdf0e10cSrcweir 		while ( 0 != (nBytes = fread( buffer, 1, sizeof(buffer), fpin )) )
598*cdf0e10cSrcweir 		{
599*cdf0e10cSrcweir 			nBytesWritten += fwrite( buffer, 1, nBytes, fpout );
600*cdf0e10cSrcweir 		}
601*cdf0e10cSrcweir 	}
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir 	return nBytesWritten;
604*cdf0e10cSrcweir }
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir //***************************************************************************
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir static string GetModuleDirectory( HMODULE hModule )
609*cdf0e10cSrcweir {
610*cdf0e10cSrcweir 	TCHAR	szModuleName[MAX_PATH] = TEXT("");
611*cdf0e10cSrcweir 	TCHAR	szDrive[_MAX_DRIVE];
612*cdf0e10cSrcweir 	TCHAR	szDir[_MAX_DIR];
613*cdf0e10cSrcweir 	TCHAR	szFName[_MAX_FNAME];
614*cdf0e10cSrcweir 	TCHAR	szExt[_MAX_EXT];
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir 	if ( GetModuleFileName( hModule, szModuleName, MAX_PATH ) )
617*cdf0e10cSrcweir 	{
618*cdf0e10cSrcweir 		_tsplitpath( szModuleName, szDrive, szDir, szFName, szExt );
619*cdf0e10cSrcweir 		_tmakepath( szModuleName, szDrive, szDir, _T(""), _T("") );
620*cdf0e10cSrcweir 	}
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir 	CHAR	szModuleNameUTF8[MAX_PATH] = "";
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir 	WideCharToMultiByte( CP_UTF8, 0, szModuleName, -1, szModuleNameUTF8, elementsof(szModuleNameUTF8), NULL, NULL );
625*cdf0e10cSrcweir 	return string( szModuleNameUTF8 );
626*cdf0e10cSrcweir }
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir //***************************************************************************
629*cdf0e10cSrcweir 
630*cdf0e10cSrcweir string GetFileDirectory( const string& rFilePath )
631*cdf0e10cSrcweir {
632*cdf0e10cSrcweir 	string aDir = rFilePath;
633*cdf0e10cSrcweir     size_t pos = aDir.rfind( '\\' );
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir 	if ( string::npos != pos )
636*cdf0e10cSrcweir 		aDir.erase( pos + 1 );
637*cdf0e10cSrcweir 	else
638*cdf0e10cSrcweir 		aDir = "";
639*cdf0e10cSrcweir 
640*cdf0e10cSrcweir 	return aDir;
641*cdf0e10cSrcweir }
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir //***************************************************************************
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir string GetFileName( const string& rFilePath )
646*cdf0e10cSrcweir {
647*cdf0e10cSrcweir 	string aName = rFilePath;
648*cdf0e10cSrcweir     size_t pos = aName.rfind( '\\' );
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir 	if ( string::npos != pos )
651*cdf0e10cSrcweir 		return aName.substr( pos + 1 );
652*cdf0e10cSrcweir 	else
653*cdf0e10cSrcweir 		return aName;
654*cdf0e10cSrcweir }
655*cdf0e10cSrcweir 
656*cdf0e10cSrcweir //***************************************************************************
657*cdf0e10cSrcweir 
658*cdf0e10cSrcweir BOOL WriteReportFile( CrashReportParams *pParams )
659*cdf0e10cSrcweir {
660*cdf0e10cSrcweir 	BOOL	fSuccess = FALSE;
661*cdf0e10cSrcweir 	TCHAR	szTempPath[MAX_PATH];
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir 	if ( GetTempPath( elementsof(szTempPath), szTempPath ) )
664*cdf0e10cSrcweir 	{
665*cdf0e10cSrcweir 		TCHAR	szFileName[MAX_PATH];
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir 		if ( GetTempFileName( szTempPath, TEXT("RPM"), 0, szFileName ) )
668*cdf0e10cSrcweir 		{
669*cdf0e10cSrcweir 			HANDLE	hFile =  CreateFile( szFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir 			if ( hFile )
672*cdf0e10cSrcweir 			{
673*cdf0e10cSrcweir 				int	fd = _open_osfhandle( (LONG)hFile, _O_TEXT );
674*cdf0e10cSrcweir 				FILE	*fp = _fdopen( fd, "w+t" );
675*cdf0e10cSrcweir 				CHAR	szTitle[1024] = "";
676*cdf0e10cSrcweir 				CHAR	szBuildId[1024] = "";
677*cdf0e10cSrcweir 				CHAR	szEmail[1024] = "";
678*cdf0e10cSrcweir 				const char *pszUserType = getenv( "STAROFFICE_USERTYPE" );
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir 				WideCharToMultiByte( CP_UTF8, 0, pParams->sTitle.c_str(), -1, szTitle, sizeof(szTitle), NULL, NULL );
681*cdf0e10cSrcweir 				WideCharToMultiByte( CP_UTF8, 0, g_szBuildId, -1, szBuildId, sizeof(szBuildId), NULL, NULL );
682*cdf0e10cSrcweir 				WideCharToMultiByte( CP_UTF8, 0, pParams->sEmail.c_str(), -1, szEmail, sizeof(szEmail), NULL, NULL );
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir 				fprintf( fp,
685*cdf0e10cSrcweir 					"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
686*cdf0e10cSrcweir 					"<!DOCTYPE errormail:errormail PUBLIC \"-//OpenOffice.org//DTD ErrorMail 1.0//EN\" \"errormail.dtd\">\n"
687*cdf0e10cSrcweir 					"<errormail:errormail xmlns:errormail=\"http://openoffice.org/2002/errormail\" usertype=\"%s\">\n"
688*cdf0e10cSrcweir 					"<reportmail:mail xmlns:reportmail=\"http://openoffice.org/2002/reportmail\" version=\"1.1\" feedback=\"%s\" email=\"%s\">\n",
689*cdf0e10cSrcweir 					pszUserType ? pszUserType : "",
690*cdf0e10cSrcweir 					pParams->fAllowContact ? "true" : "false",
691*cdf0e10cSrcweir 					pParams->fAllowContact ? xml_encode(szEmail).c_str() : ""
692*cdf0e10cSrcweir 					);
693*cdf0e10cSrcweir 
694*cdf0e10cSrcweir 				fprintf( fp,
695*cdf0e10cSrcweir 					"<reportmail:title>%s</reportmail:title>\n",
696*cdf0e10cSrcweir 					xml_encode(szTitle).c_str() );
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir 				fprintf( fp,
699*cdf0e10cSrcweir 					"<reportmail:attachment name=\"description.txt\" media-type=\"text/plain;charset=UTF-8\" class=\"UserComment\"/>\n"
700*cdf0e10cSrcweir 					"<reportmail:attachment name=\"user.dmp\" media-type=\"application/octet-stream\" class=\"UserDump\"/>\n"
701*cdf0e10cSrcweir 					"</reportmail:mail>\n"
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir 					"<officeinfo:officeinfo xmlns:officeinfo=\"http://openoffice.org/2002/officeinfo\" build=\"%s\" platform=\"%s\" language=\"%s\" procpath=\"%s\" exceptiontype=\"0x%08X\" product=\"%s\"/>\n",
704*cdf0e10cSrcweir 					szBuildId,
705*cdf0e10cSrcweir 					_INPATH,
706*cdf0e10cSrcweir 					xml_encode(g_strDefaultLanguage).c_str(),
707*cdf0e10cSrcweir 					xml_encode(GetModuleDirectory( NULL )).c_str(),
708*cdf0e10cSrcweir 					g_dwExceptionCode,
709*cdf0e10cSrcweir 					xml_encode(wstring2utf8(g_wstrProductKey)).c_str()
710*cdf0e10cSrcweir 					);
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir 				OSVERSIONINFO	VersionInfo;
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir 				ZeroMemory( &VersionInfo, sizeof(VersionInfo) );
715*cdf0e10cSrcweir 				VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo );
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir 				GetVersionEx( &VersionInfo );
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir 				fprintf( fp,
720*cdf0e10cSrcweir 					"<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
721*cdf0e10cSrcweir 					"<systeminfo:System name=\"%s\" version=\"%d.%d\" build=\"%d\" locale=\"0x%08x\"/>\n"
722*cdf0e10cSrcweir 					,
723*cdf0e10cSrcweir 					VER_PLATFORM_WIN32_NT == VersionInfo.dwPlatformId ? "Windows NT" : "Windows",
724*cdf0e10cSrcweir 					VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion,
725*cdf0e10cSrcweir 					VersionInfo.dwBuildNumber,
726*cdf0e10cSrcweir 					GetUserDefaultLangID()
727*cdf0e10cSrcweir 
728*cdf0e10cSrcweir 					);
729*cdf0e10cSrcweir 				fprintf( fp, "<systeminfo:CPU type=\"x86\"/>\n" );
730*cdf0e10cSrcweir 				fprintf( fp, "</systeminfo:systeminfo>\n" );
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir 				fseek( g_fpStackFile, 0, SEEK_SET );
733*cdf0e10cSrcweir 				fcopy( g_fpStackFile, fp );
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir 				fseek( g_fpChecksumFile, 0, SEEK_SET );
736*cdf0e10cSrcweir 				fcopy( g_fpChecksumFile, fp );
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir 				fprintf( fp, "</errormail:errormail>\n" );
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir 				fclose( fp );
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir 				fSuccess = TRUE;
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir 				WideCharToMultiByte( CP_ACP, 0, szFileName, -1, g_szReportFileNameA, MAX_PATH, NULL, NULL );
745*cdf0e10cSrcweir 			}
746*cdf0e10cSrcweir 
747*cdf0e10cSrcweir 			if ( !fSuccess )
748*cdf0e10cSrcweir 				DeleteFile( szFileName );
749*cdf0e10cSrcweir 		}
750*cdf0e10cSrcweir 	}
751*cdf0e10cSrcweir 
752*cdf0e10cSrcweir 	return fSuccess;
753*cdf0e10cSrcweir }
754*cdf0e10cSrcweir 
755*cdf0e10cSrcweir //***************************************************************************
756*cdf0e10cSrcweir 
757*cdf0e10cSrcweir static BOOL SaveDumpFile( HWND hwndOwner )
758*cdf0e10cSrcweir {
759*cdf0e10cSrcweir 	OPENFILENAME	ofn;
760*cdf0e10cSrcweir 	TCHAR	szFileName[MAX_PATH] = TEXT("");
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir 	ZeroMemory( &ofn, sizeof(ofn) );
763*cdf0e10cSrcweir 	ofn.lStructSize = sizeof(ofn);
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir 	ofn.hwndOwner = hwndOwner;
766*cdf0e10cSrcweir 	ofn.lpstrFilter = TEXT("*.dmp\0*.dmp\0*.*\0*.*\0");
767*cdf0e10cSrcweir 	ofn.lpstrFile = szFileName;
768*cdf0e10cSrcweir 	ofn.nMaxFile = MAX_PATH;
769*cdf0e10cSrcweir 	ofn.Flags = OFN_ENABLESIZING | OFN_LONGNAMES | OFN_OVERWRITEPROMPT;
770*cdf0e10cSrcweir 	ofn.lpstrDefExt = TEXT("dmp");
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir 	if ( GetSaveFileName( &ofn ) )
773*cdf0e10cSrcweir 	{
774*cdf0e10cSrcweir 		return CopyFile( g_szDumpFileName, szFileName, FALSE );
775*cdf0e10cSrcweir 	}
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir 	return FALSE;
779*cdf0e10cSrcweir }
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir //***************************************************************************
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir static BOOL ScreenToClientRect( HWND hwnd, LPRECT lprc )
784*cdf0e10cSrcweir {
785*cdf0e10cSrcweir 	return ScreenToClient( hwnd, (LPPOINT)&lprc->left ) && ScreenToClient( hwnd, (LPPOINT)&lprc->right );
786*cdf0e10cSrcweir }
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir static BOOL SetWindowRect( HWND hwnd, const RECT *lprc, BOOL fRepaint )
789*cdf0e10cSrcweir {
790*cdf0e10cSrcweir 	return MoveWindow( hwnd, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top, fRepaint );
791*cdf0e10cSrcweir }
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir #define GM_LOX	0x01
794*cdf0e10cSrcweir #define GM_HIX	0x02
795*cdf0e10cSrcweir #define GM_LOY	0x04
796*cdf0e10cSrcweir #define GM_HIY	0x08
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir static BOOL SetGrowMode( HWND hwnd, DWORD dwGrowMode )
799*cdf0e10cSrcweir {
800*cdf0e10cSrcweir 	return SetProp( hwnd, TEXT("GrowMode"), (HANDLE)dwGrowMode );
801*cdf0e10cSrcweir }
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir static DWORD GetGrowMode( HWND hwnd )
804*cdf0e10cSrcweir {
805*cdf0e10cSrcweir 	return (DWORD)GetProp( hwnd, TEXT("GrowMode") );
806*cdf0e10cSrcweir }
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir static BOOL GrowWindow( HWND hwnd, LONG dxClient, LONG dyClient, BOOL fRepaint )
809*cdf0e10cSrcweir {
810*cdf0e10cSrcweir 	DWORD	dwGrowMode = GetGrowMode( hwnd );
811*cdf0e10cSrcweir 	RECT	rc;
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir 	GetWindowRect( hwnd, &rc );
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir 	if ( dwGrowMode & GM_LOX )
816*cdf0e10cSrcweir 		rc.left += dxClient;
817*cdf0e10cSrcweir 	if ( dwGrowMode & GM_HIX )
818*cdf0e10cSrcweir 		rc.right += dxClient;
819*cdf0e10cSrcweir 	if ( dwGrowMode & GM_LOY )
820*cdf0e10cSrcweir 		rc.top += dyClient;
821*cdf0e10cSrcweir 	if ( dwGrowMode & GM_HIY )
822*cdf0e10cSrcweir 		rc.bottom += dyClient;
823*cdf0e10cSrcweir 
824*cdf0e10cSrcweir 	ScreenToClientRect( GetParent( hwnd ), &rc );
825*cdf0e10cSrcweir 	SetWindowRect( hwnd, &rc, fRepaint );
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir 	return TRUE;
828*cdf0e10cSrcweir }
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir BOOL CALLBACK GrowChildWindows(
831*cdf0e10cSrcweir   HWND hwnd,      // handle to child window
832*cdf0e10cSrcweir   LPARAM lParam   // application-defined value
833*cdf0e10cSrcweir )
834*cdf0e10cSrcweir {
835*cdf0e10cSrcweir 	LONG	cx = (SHORT)LOWORD( lParam );
836*cdf0e10cSrcweir 	LONG	cy = (SHORT)HIWORD( lParam );
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 	GrowWindow( hwnd, cx, cy, TRUE );
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir 	return TRUE;
841*cdf0e10cSrcweir }
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir /*
844*cdf0e10cSrcweir BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
845*cdf0e10cSrcweir {
846*cdf0e10cSrcweir     HFONT aFont = *((HFONT*) lParam);
847*cdf0e10cSrcweir     HDC hDC = GetDC( hwndChild );
848*cdf0e10cSrcweir     SelectObject( hDC, aFont );
849*cdf0e10cSrcweir     ReleaseDC( hwndChild, hDC );
850*cdf0e10cSrcweir     return TRUE;
851*cdf0e10cSrcweir }
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir void ApplySystemFont( HWND hwndDlg )
854*cdf0e10cSrcweir {
855*cdf0e10cSrcweir     NONCLIENTMETRICSA aNonClientMetrics;
856*cdf0e10cSrcweir     aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
857*cdf0e10cSrcweir     if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
858*cdf0e10cSrcweir     {
859*cdf0e10cSrcweir         HFONT aSysFont = CreateFontIndirectA( &aNonClientMetrics.lfMessageFont );
860*cdf0e10cSrcweir         EnumChildWindows(hwndDlg, EnumChildProc, (LPARAM) &aSysFont);
861*cdf0e10cSrcweir     }
862*cdf0e10cSrcweir }
863*cdf0e10cSrcweir */
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir BOOL CALLBACK PreviewDialogProc(
866*cdf0e10cSrcweir 	HWND hwndDlg,
867*cdf0e10cSrcweir 	UINT uMsg,
868*cdf0e10cSrcweir 	WPARAM wParam,
869*cdf0e10cSrcweir 	LPARAM lParam
870*cdf0e10cSrcweir 	)
871*cdf0e10cSrcweir {
872*cdf0e10cSrcweir 	static RECT	rcClient;
873*cdf0e10cSrcweir 
874*cdf0e10cSrcweir 	switch ( uMsg )
875*cdf0e10cSrcweir 	{
876*cdf0e10cSrcweir 	case WM_SIZE:
877*cdf0e10cSrcweir 		{
878*cdf0e10cSrcweir 		LONG	cx = LOWORD( lParam );
879*cdf0e10cSrcweir 		LONG	cy = HIWORD( lParam );
880*cdf0e10cSrcweir 		LONG	dxClient, dyClient;
881*cdf0e10cSrcweir 
882*cdf0e10cSrcweir 		dxClient = cx - rcClient.right;
883*cdf0e10cSrcweir 		dyClient = cy - rcClient.bottom;
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir 		EnumChildWindows( hwndDlg, GrowChildWindows, MAKELONG( (SHORT)dxClient, (SHORT)dyClient) );
886*cdf0e10cSrcweir 
887*cdf0e10cSrcweir 		GetClientRect( hwndDlg, &rcClient );
888*cdf0e10cSrcweir 		}
889*cdf0e10cSrcweir 		break;
890*cdf0e10cSrcweir 	case WM_INITDIALOG:
891*cdf0e10cSrcweir 		{
892*cdf0e10cSrcweir 			GetClientRect( hwndDlg, &rcClient );
893*cdf0e10cSrcweir 			SetGrowMode( GetDlgItem(hwndDlg, IDC_EDIT_PREVIEW), GM_HIX | GM_HIY );
894*cdf0e10cSrcweir 			SetGrowMode( GetDlgItem(hwndDlg, IDOK), GM_LOX | GM_HIX | GM_LOY | GM_HIY );
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir 			CrashReportParams *pParams = (CrashReportParams *)lParam;
897*cdf0e10cSrcweir 
898*cdf0e10cSrcweir 			TCHAR	szBuffer[256] = TEXT("");
899*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong( hwndDlg, GWL_HINSTANCE );
900*cdf0e10cSrcweir 			HWND	hwndParent = (HWND)GetWindowLong( hwndDlg, GWL_HWNDPARENT );
901*cdf0e10cSrcweir 
902*cdf0e10cSrcweir 			GetWindowText( hwndParent, szBuffer, elementsof(szBuffer) );
903*cdf0e10cSrcweir 			SetWindowText( hwndDlg, szBuffer );
904*cdf0e10cSrcweir 
905*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_OK_BUTTON, szBuffer, elementsof(szBuffer) );
906*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDOK), szBuffer );
907*cdf0e10cSrcweir 
908*cdf0e10cSrcweir 			basic_string<TCHAR>	aString;
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir 			aString.append( pParams->sTitle );
911*cdf0e10cSrcweir 			aString.append( _T("\r\n\r\n") );
912*cdf0e10cSrcweir 			aString.append( pParams->sComment );
913*cdf0e10cSrcweir 			aString.append( _T("\r\n---------- report ----------\r\n") );
914*cdf0e10cSrcweir 
915*cdf0e10cSrcweir 			FILE	*fp = fopen( g_szReportFileNameA, "r" );
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir 			if ( fp )
918*cdf0e10cSrcweir 			{
919*cdf0e10cSrcweir 				char	buf[1024];
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir 				while ( fgets( buf, elementsof(buf), fp ) != NULL )
922*cdf0e10cSrcweir 				{
923*cdf0e10cSrcweir 					WCHAR	bufW[1024];
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir 					MultiByteToWideChar( CP_UTF8, 0, buf, -1, bufW, elementsof(bufW) );
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir 					aString.append( bufW );
928*cdf0e10cSrcweir 				}
929*cdf0e10cSrcweir 
930*cdf0e10cSrcweir 				fclose( fp );
931*cdf0e10cSrcweir 			}
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir 			aString.append( _T("\r\n---------- stack ----------\r\n") );
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir 			fp = fopen( g_szDumpFileNameA, "rb" );
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir 			if ( fp )
938*cdf0e10cSrcweir 			{
939*cdf0e10cSrcweir 				unsigned char	buf[16];
940*cdf0e10cSrcweir 				int		count;
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir 				do
943*cdf0e10cSrcweir 				{
944*cdf0e10cSrcweir 					int i;
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir 					count = fread( buf, sizeof(buf[0]), sizeof(buf)/sizeof(buf[0]), fp );
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir 					for ( i = 0; i < count; i++ )
949*cdf0e10cSrcweir 					{
950*cdf0e10cSrcweir 						TCHAR	output[16];
951*cdf0e10cSrcweir 
952*cdf0e10cSrcweir 						_sntprintf( output, elementsof(output), _T("%02X\x20"), buf[i] );
953*cdf0e10cSrcweir 						aString.append( output );
954*cdf0e10cSrcweir 					}
955*cdf0e10cSrcweir 					for ( ; i < elementsof(buf); i++ )
956*cdf0e10cSrcweir 					{
957*cdf0e10cSrcweir 						aString.append( _T("\x20\x20\x20") );
958*cdf0e10cSrcweir 					}
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir 					for ( i = 0; i < count; i++ )
961*cdf0e10cSrcweir 					{
962*cdf0e10cSrcweir 						TCHAR	output[2];
963*cdf0e10cSrcweir 
964*cdf0e10cSrcweir 						if ( (int)buf[i] >= 0x20 && (int)buf[i] <= 0x7F )
965*cdf0e10cSrcweir 							output[0] = (TCHAR)buf[i];
966*cdf0e10cSrcweir 						else
967*cdf0e10cSrcweir 							output[0] = '.';
968*cdf0e10cSrcweir 						output[1] = 0;
969*cdf0e10cSrcweir 						aString.append( output );
970*cdf0e10cSrcweir 					}
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir 					aString.append( _T("\r\n") );
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir 				} while ( count );
975*cdf0e10cSrcweir 
976*cdf0e10cSrcweir 				fclose( fp );
977*cdf0e10cSrcweir 			}
978*cdf0e10cSrcweir 
979*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_EDIT_PREVIEW), aString.c_str() );
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir 			SetWindowFont( GetDlgItem(hwndDlg, IDC_EDIT_PREVIEW), GetStockObject( SYSTEM_FIXED_FONT ), TRUE );
983*cdf0e10cSrcweir 		}
984*cdf0e10cSrcweir 		return TRUE;
985*cdf0e10cSrcweir 	case WM_COMMAND:
986*cdf0e10cSrcweir 		switch ( LOWORD(wParam) )
987*cdf0e10cSrcweir 		{
988*cdf0e10cSrcweir 		case IDOK:
989*cdf0e10cSrcweir 		case IDCANCEL:
990*cdf0e10cSrcweir 			EndDialog( hwndDlg, wParam );
991*cdf0e10cSrcweir 			return TRUE;
992*cdf0e10cSrcweir 		}
993*cdf0e10cSrcweir 		break;
994*cdf0e10cSrcweir 	default:
995*cdf0e10cSrcweir 		break;
996*cdf0e10cSrcweir 	}
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir 	return FALSE;
999*cdf0e10cSrcweir }
1000*cdf0e10cSrcweir //***************************************************************************
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir static void PreviewReport( HWND hwndParent, CrashReportParams *pParams )
1003*cdf0e10cSrcweir {
1004*cdf0e10cSrcweir 	HINSTANCE	hInstance = (HINSTANCE)GetWindowLong(hwndParent, GWL_HINSTANCE );
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir 	WriteReportFile( pParams );
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir 	DialogBoxParam(
1009*cdf0e10cSrcweir 		hInstance,
1010*cdf0e10cSrcweir 		MAKEINTRESOURCE(IDD_PREVIEW_FRAME),
1011*cdf0e10cSrcweir 		hwndParent,
1012*cdf0e10cSrcweir 		PreviewDialogProc,
1013*cdf0e10cSrcweir 		(LPARAM)pParams
1014*cdf0e10cSrcweir 		);
1015*cdf0e10cSrcweir 
1016*cdf0e10cSrcweir 	DeleteFileA( g_szReportFileNameA );
1017*cdf0e10cSrcweir }
1018*cdf0e10cSrcweir //***************************************************************************
1019*cdf0e10cSrcweir void UpdateOptionsDialogControls( HWND hwndDlg )
1020*cdf0e10cSrcweir {
1021*cdf0e10cSrcweir 	if ( Button_GetCheck( GetDlgItem(hwndDlg, IDC_RADIO_MANUAL) ) & BST_CHECKED )
1022*cdf0e10cSrcweir 	{
1023*cdf0e10cSrcweir 		EnableWindow( GetDlgItem(hwndDlg, IDC_EDIT_PROXYSERVER), TRUE );
1024*cdf0e10cSrcweir 		EnableWindow( GetDlgItem(hwndDlg, IDC_EDIT_PROXYPORT), TRUE );
1025*cdf0e10cSrcweir 	}
1026*cdf0e10cSrcweir 	else
1027*cdf0e10cSrcweir 	{
1028*cdf0e10cSrcweir 		EnableWindow( GetDlgItem(hwndDlg, IDC_EDIT_PROXYSERVER), FALSE );
1029*cdf0e10cSrcweir 		EnableWindow( GetDlgItem(hwndDlg, IDC_EDIT_PROXYPORT), FALSE );
1030*cdf0e10cSrcweir 	}
1031*cdf0e10cSrcweir }
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir //***************************************************************************
1034*cdf0e10cSrcweir 
1035*cdf0e10cSrcweir BOOL CALLBACK OptionsDialogProc(
1036*cdf0e10cSrcweir 	HWND hwndDlg,
1037*cdf0e10cSrcweir 	UINT uMsg,
1038*cdf0e10cSrcweir 	WPARAM wParam,
1039*cdf0e10cSrcweir 	LPARAM lParam
1040*cdf0e10cSrcweir 	)
1041*cdf0e10cSrcweir {
1042*cdf0e10cSrcweir 	static CrashReportParams *pParams;
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir 	switch ( uMsg )
1045*cdf0e10cSrcweir 	{
1046*cdf0e10cSrcweir 	case WM_INITDIALOG:
1047*cdf0e10cSrcweir 		{
1048*cdf0e10cSrcweir 			TCHAR	szBuffer[1024] = TEXT("");
1049*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong( hwndDlg, GWL_HINSTANCE );
1050*cdf0e10cSrcweir 			//HWND	hwndParent = (HWND)GetWindowLong( hwndDlg, GWL_HWNDPARENT );
1051*cdf0e10cSrcweir 
1052*cdf0e10cSrcweir 			pParams = (CrashReportParams *)lParam;
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_OPTIONS_CAPTION, szBuffer, elementsof(szBuffer) );
1055*cdf0e10cSrcweir 			SetWindowText( hwndDlg, szBuffer );
1056*cdf0e10cSrcweir 
1057*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_PROXY_SETTINGS_HEADER, szBuffer, elementsof(szBuffer) );
1058*cdf0e10cSrcweir 			Static_SetText( GetDlgItem(hwndDlg, IDC_PROXY_SETTINGS), szBuffer );
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_PROXY_SYSTEM, szBuffer, elementsof(szBuffer) );
1061*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_RADIO_SYSTEM), szBuffer );
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_PROXY_DIRECT, szBuffer, elementsof(szBuffer) );
1064*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_RADIO_DIRECT), szBuffer );
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_PROXY_MANUAL, szBuffer, elementsof(szBuffer) );
1067*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_RADIO_MANUAL), szBuffer );
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_LABEL_PROXYSERVER, szBuffer, elementsof(szBuffer) );
1070*cdf0e10cSrcweir 			Static_SetText( GetDlgItem(hwndDlg, IDC_LABEL_PROXYSERVER), szBuffer );
1071*cdf0e10cSrcweir 
1072*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_LABEL_PROXYPORT, szBuffer, elementsof(szBuffer) );
1073*cdf0e10cSrcweir 			Static_SetText( GetDlgItem(hwndDlg, IDC_LABEL_PROXYPORT), szBuffer );
1074*cdf0e10cSrcweir 
1075*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_OK_BUTTON, szBuffer, elementsof(szBuffer) );
1076*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDOK), szBuffer );
1077*cdf0e10cSrcweir 
1078*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_CANCEL_BUTTON, szBuffer, elementsof(szBuffer) );
1079*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDCANCEL), szBuffer );
1080*cdf0e10cSrcweir 
1081*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_EDIT_PROXYSERVER), pParams->sProxyServer.c_str() );
1082*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_EDIT_PROXYPORT), pParams->sProxyPort.c_str() );
1083*cdf0e10cSrcweir 
1084*cdf0e10cSrcweir 			Button_SetCheck( GetDlgItem(hwndDlg, IDC_RADIO_SYSTEM + pParams->uInternetConnection), BST_CHECKED );
1085*cdf0e10cSrcweir 
1086*cdf0e10cSrcweir 			SendMessage(
1087*cdf0e10cSrcweir 				GetDlgItem(hwndDlg, IDC_PROXY_DESCRIPTION),
1088*cdf0e10cSrcweir 				EM_SETBKGNDCOLOR,
1089*cdf0e10cSrcweir 				(WPARAM)FALSE,
1090*cdf0e10cSrcweir 				GetSysColor( COLOR_3DFACE ) );
1091*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_PROXY_DESCRIPTION, szBuffer, elementsof(szBuffer) );
1092*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_PROXY_DESCRIPTION), szBuffer );
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir 			UpdateOptionsDialogControls( hwndDlg );
1095*cdf0e10cSrcweir 		}
1096*cdf0e10cSrcweir 		return TRUE;
1097*cdf0e10cSrcweir 	case WM_COMMAND:
1098*cdf0e10cSrcweir 		switch ( LOWORD(wParam) )
1099*cdf0e10cSrcweir 		{
1100*cdf0e10cSrcweir 		case IDC_RADIO_SYSTEM:
1101*cdf0e10cSrcweir 		case IDC_RADIO_DIRECT:
1102*cdf0e10cSrcweir 		case IDC_RADIO_MANUAL:
1103*cdf0e10cSrcweir 			if ( BN_CLICKED == HIWORD(wParam) )
1104*cdf0e10cSrcweir 				UpdateOptionsDialogControls( hwndDlg );
1105*cdf0e10cSrcweir 			break;
1106*cdf0e10cSrcweir 		case IDOK:
1107*cdf0e10cSrcweir 			{
1108*cdf0e10cSrcweir 			TCHAR szBuffer[1024];
1109*cdf0e10cSrcweir 
1110*cdf0e10cSrcweir 			Edit_GetText( GetDlgItem(hwndDlg, IDC_EDIT_PROXYSERVER), szBuffer, elementsof(szBuffer) );
1111*cdf0e10cSrcweir 			pParams->sProxyServer = szBuffer;
1112*cdf0e10cSrcweir 
1113*cdf0e10cSrcweir 			Edit_GetText( GetDlgItem(hwndDlg, IDC_EDIT_PROXYPORT), szBuffer, elementsof(szBuffer) );
1114*cdf0e10cSrcweir 			pParams->sProxyPort = szBuffer;
1115*cdf0e10cSrcweir 
1116*cdf0e10cSrcweir 			if ( Button_GetCheck( GetDlgItem(hwndDlg, IDC_RADIO_DIRECT) ) & BST_CHECKED )
1117*cdf0e10cSrcweir 				pParams->uInternetConnection = 1;
1118*cdf0e10cSrcweir 			else if ( Button_GetCheck( GetDlgItem(hwndDlg, IDC_RADIO_MANUAL) ) & BST_CHECKED )
1119*cdf0e10cSrcweir 				pParams->uInternetConnection = 2;
1120*cdf0e10cSrcweir 			else
1121*cdf0e10cSrcweir 				pParams->uInternetConnection = 0;
1122*cdf0e10cSrcweir 			}
1123*cdf0e10cSrcweir 		case IDCANCEL:
1124*cdf0e10cSrcweir 			EndDialog( hwndDlg, wParam );
1125*cdf0e10cSrcweir 			return TRUE;
1126*cdf0e10cSrcweir 		}
1127*cdf0e10cSrcweir 		break;
1128*cdf0e10cSrcweir 	default:
1129*cdf0e10cSrcweir 		break;
1130*cdf0e10cSrcweir 	}
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir 	return FALSE;
1133*cdf0e10cSrcweir }
1134*cdf0e10cSrcweir 
1135*cdf0e10cSrcweir //***************************************************************************
1136*cdf0e10cSrcweir 
1137*cdf0e10cSrcweir static void OptionsDialog( HWND hwndParent, CrashReportParams *pParams )
1138*cdf0e10cSrcweir {
1139*cdf0e10cSrcweir 	HINSTANCE	hInstance = (HINSTANCE)GetWindowLong(hwndParent, GWL_HINSTANCE );
1140*cdf0e10cSrcweir 
1141*cdf0e10cSrcweir 	if ( IDOK == DialogBoxParam(
1142*cdf0e10cSrcweir 		hInstance,
1143*cdf0e10cSrcweir 		MAKEINTRESOURCE(IDD_OPTIONS_FRAME),
1144*cdf0e10cSrcweir 		hwndParent,
1145*cdf0e10cSrcweir 		OptionsDialogProc,
1146*cdf0e10cSrcweir 		(LPARAM)pParams
1147*cdf0e10cSrcweir 		) )
1148*cdf0e10cSrcweir 		pParams->WriteToRegistry();
1149*cdf0e10cSrcweir 
1150*cdf0e10cSrcweir }
1151*cdf0e10cSrcweir //***************************************************************************
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir void UpdateReportDialogControls( HWND hwndDlg )
1154*cdf0e10cSrcweir {
1155*cdf0e10cSrcweir 	EnableWindow(
1156*cdf0e10cSrcweir 		GetDlgItem(hwndDlg, IDC_EDIT_EMAIL),
1157*cdf0e10cSrcweir 		Button_GetCheck(GetDlgItem(hwndDlg, IDC_ALLOW_CONTACT)) & BST_CHECKED ? TRUE : FALSE );
1158*cdf0e10cSrcweir 	EnableWindow(
1159*cdf0e10cSrcweir 		GetDlgItem(hwndDlg, IDC_LABEL_EMAIL),
1160*cdf0e10cSrcweir 		Button_GetCheck(GetDlgItem(hwndDlg, IDC_ALLOW_CONTACT)) & BST_CHECKED ? TRUE : FALSE );
1161*cdf0e10cSrcweir }
1162*cdf0e10cSrcweir 
1163*cdf0e10cSrcweir //***************************************************************************
1164*cdf0e10cSrcweir 
1165*cdf0e10cSrcweir BOOL CALLBACK ReportDialogProc(
1166*cdf0e10cSrcweir 	HWND hwndDlg,
1167*cdf0e10cSrcweir 	UINT uMsg,
1168*cdf0e10cSrcweir 	WPARAM wParam,
1169*cdf0e10cSrcweir 	LPARAM
1170*cdf0e10cSrcweir 	)
1171*cdf0e10cSrcweir {
1172*cdf0e10cSrcweir 	switch ( uMsg )
1173*cdf0e10cSrcweir 	{
1174*cdf0e10cSrcweir 	case WM_INITDIALOG:
1175*cdf0e10cSrcweir 		{
1176*cdf0e10cSrcweir 		    CrashReportParams	*pParams = (CrashReportParams*)GetWindowLong( GetParent(hwndDlg), GWL_USERDATA );
1177*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong(hwndDlg, GWL_HINSTANCE );
1178*cdf0e10cSrcweir 			TCHAR		szBuffer[FORMATBUFSIZE];
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_REPORT_INTRO, szBuffer, elementsof(szBuffer) );
1181*cdf0e10cSrcweir 			Static_SetText( GetDlgItem(hwndDlg, IDC_REPORT_INTRO), szBuffer );
1182*cdf0e10cSrcweir 
1183*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_EDIT3), szBuffer );
1184*cdf0e10cSrcweir 
1185*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_ENTER_TITLE, szBuffer, elementsof(szBuffer) );
1186*cdf0e10cSrcweir 			Static_SetText( GetDlgItem(hwndDlg, IDC_ENTER_TITLE), szBuffer );
1187*cdf0e10cSrcweir 
1188*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_ENTER_DESCRIPTION, szBuffer, elementsof(szBuffer) );
1189*cdf0e10cSrcweir 			Static_SetText( GetDlgItem(hwndDlg, IDC_ENTER_DESCRIPTION), szBuffer );
1190*cdf0e10cSrcweir 
1191*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_SHOW_REPORT_BUTTON, szBuffer, elementsof(szBuffer) );
1192*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_SHOW_REPORT), szBuffer );
1193*cdf0e10cSrcweir 
1194*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_SAVE_REPORT_BUTTON, szBuffer, elementsof(szBuffer) );
1195*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_SAVE_REPORT), szBuffer );
1196*cdf0e10cSrcweir 
1197*cdf0e10cSrcweir 			const char *pszUserType = getenv( "STAROFFICE_USERTYPE" );
1198*cdf0e10cSrcweir 			if ( pszUserType )
1199*cdf0e10cSrcweir 				ShowWindow( GetDlgItem(hwndDlg, IDC_SAVE_REPORT), SW_SHOW );
1200*cdf0e10cSrcweir 			else
1201*cdf0e10cSrcweir 				ShowWindow( GetDlgItem(hwndDlg, IDC_SAVE_REPORT), SW_HIDE );
1202*cdf0e10cSrcweir 
1203*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_OPTIONS_BUTTON, szBuffer, elementsof(szBuffer) );
1204*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_OPTIONS), szBuffer );
1205*cdf0e10cSrcweir 
1206*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_ALLOW_CONTACT, szBuffer, elementsof(szBuffer) );
1207*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_ALLOW_CONTACT), szBuffer );
1208*cdf0e10cSrcweir 			Button_SetCheck( GetDlgItem(hwndDlg, IDC_ALLOW_CONTACT), pParams->fAllowContact ? BST_CHECKED : BST_UNCHECKED );
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_LABEL_EMAIL, szBuffer, elementsof(szBuffer) );
1211*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDC_LABEL_EMAIL), szBuffer );
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_EDIT_EMAIL), pParams->sEmail.c_str() );
1214*cdf0e10cSrcweir 
1215*cdf0e10cSrcweir 			UpdateReportDialogControls( hwndDlg );
1216*cdf0e10cSrcweir 		}
1217*cdf0e10cSrcweir 		return TRUE;
1218*cdf0e10cSrcweir 	case WM_SHOWWINDOW:
1219*cdf0e10cSrcweir 		if ( (BOOL)wParam )
1220*cdf0e10cSrcweir 		{
1221*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong(hwndDlg, GWL_HINSTANCE );
1222*cdf0e10cSrcweir 			CrashReportParams	*pParams = (CrashReportParams*)GetWindowLong( GetParent(hwndDlg), GWL_USERDATA );
1223*cdf0e10cSrcweir 			TCHAR		szBuffer[FORMATBUFSIZE];
1224*cdf0e10cSrcweir 
1225*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_REPORT_CAPTION, szBuffer, elementsof(szBuffer) );
1226*cdf0e10cSrcweir 			SetWindowText( GetParent(hwndDlg), szBuffer );
1227*cdf0e10cSrcweir 
1228*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_REPORT_HEADER, szBuffer, elementsof(szBuffer) );
1229*cdf0e10cSrcweir 			SetWindowText( GetDlgItem(GetParent(hwndDlg), IDC_HEADER), szBuffer );
1230*cdf0e10cSrcweir 
1231*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_DONOT_SEND_BUTTON, szBuffer, elementsof(szBuffer) );
1232*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(GetParent(hwndDlg), IDCANCEL), szBuffer );
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir 			ShowWindow( GetDlgItem(GetParent(hwndDlg),IDBACK), TRUE );
1236*cdf0e10cSrcweir 			ShowWindow( GetDlgItem(GetParent(hwndDlg),IDFINISH), TRUE );
1237*cdf0e10cSrcweir 			ShowWindow( GetDlgItem(GetParent(hwndDlg),IDNEXT), FALSE );
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_EDIT_TITLE), pParams->sTitle.c_str() );
1240*cdf0e10cSrcweir 			Edit_SetText( GetDlgItem(hwndDlg, IDC_EDIT_DESCRIPTION), pParams->sComment.c_str() );
1241*cdf0e10cSrcweir 
1242*cdf0e10cSrcweir             /*
1243*cdf0e10cSrcweir 			SetWindowLong( GetDlgItem(GetParent(hwndDlg),IDFINISH), GWL_STYLE,
1244*cdf0e10cSrcweir                 GetWindowLong( GetDlgItem(GetParent(hwndDlg),IDFINISH), GWL_STYLE) | BS_DEFPUSHBUTTON );
1245*cdf0e10cSrcweir 			SetWindowLong( GetDlgItem(GetParent(hwndDlg),IDBACK), GWL_STYLE,
1246*cdf0e10cSrcweir                 GetWindowLong( GetDlgItem(GetParent(hwndDlg),IDBACK), GWL_STYLE) &~ BS_DEFPUSHBUTTON );
1247*cdf0e10cSrcweir                 */
1248*cdf0e10cSrcweir 			SetFocus( GetDlgItem(hwndDlg,IDC_EDIT_TITLE) );
1249*cdf0e10cSrcweir 		}
1250*cdf0e10cSrcweir 		break;
1251*cdf0e10cSrcweir 	case WM_COMMAND:
1252*cdf0e10cSrcweir 		switch ( LOWORD(wParam) )
1253*cdf0e10cSrcweir 		{
1254*cdf0e10cSrcweir 		case IDC_SHOW_REPORT:
1255*cdf0e10cSrcweir 			{
1256*cdf0e10cSrcweir 				TCHAR	szBuffer[32767];
1257*cdf0e10cSrcweir 
1258*cdf0e10cSrcweir 				CrashReportParams	*pParams = (CrashReportParams*)GetWindowLong( GetParent(hwndDlg), GWL_USERDATA );
1259*cdf0e10cSrcweir 
1260*cdf0e10cSrcweir 				pParams->fAllowContact = Button_GetCheck( GetDlgItem(hwndDlg, IDC_ALLOW_CONTACT) ) ? TRUE : FALSE;
1261*cdf0e10cSrcweir 
1262*cdf0e10cSrcweir 				Edit_GetText( GetDlgItem(hwndDlg, IDC_EDIT_TITLE), szBuffer, elementsof(szBuffer) );
1263*cdf0e10cSrcweir 				pParams->sTitle = szBuffer;
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir 				Edit_GetText( GetDlgItem(hwndDlg, IDC_EDIT_DESCRIPTION), szBuffer, elementsof(szBuffer) );
1266*cdf0e10cSrcweir 				pParams->sComment = szBuffer;
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir 				Edit_GetText( GetDlgItem(hwndDlg, IDC_EDIT_EMAIL), szBuffer, elementsof(szBuffer) );
1269*cdf0e10cSrcweir 				pParams->sEmail = szBuffer;
1270*cdf0e10cSrcweir 
1271*cdf0e10cSrcweir 				PreviewReport( GetParent(hwndDlg), pParams );
1272*cdf0e10cSrcweir 			}
1273*cdf0e10cSrcweir 			return TRUE;
1274*cdf0e10cSrcweir 		case IDC_SAVE_REPORT:
1275*cdf0e10cSrcweir 			SaveDumpFile( GetParent(hwndDlg) );
1276*cdf0e10cSrcweir 			return TRUE;
1277*cdf0e10cSrcweir 		case IDC_OPTIONS:
1278*cdf0e10cSrcweir 			{
1279*cdf0e10cSrcweir 				CrashReportParams	*pParams = (CrashReportParams*)GetWindowLong( GetParent(hwndDlg), GWL_USERDATA );
1280*cdf0e10cSrcweir 				OptionsDialog( GetParent(hwndDlg), pParams );
1281*cdf0e10cSrcweir 			}
1282*cdf0e10cSrcweir 			return TRUE;
1283*cdf0e10cSrcweir 		case IDC_ALLOW_CONTACT:
1284*cdf0e10cSrcweir 			if ( BN_CLICKED == HIWORD(wParam) )
1285*cdf0e10cSrcweir 				UpdateReportDialogControls( hwndDlg );
1286*cdf0e10cSrcweir 			return TRUE;
1287*cdf0e10cSrcweir 		}
1288*cdf0e10cSrcweir 		break;
1289*cdf0e10cSrcweir 	default:
1290*cdf0e10cSrcweir 		break;
1291*cdf0e10cSrcweir 	}
1292*cdf0e10cSrcweir 
1293*cdf0e10cSrcweir 	return FALSE;
1294*cdf0e10cSrcweir }
1295*cdf0e10cSrcweir //***************************************************************************
1296*cdf0e10cSrcweir 
1297*cdf0e10cSrcweir BOOL CALLBACK WelcomeDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
1298*cdf0e10cSrcweir {
1299*cdf0e10cSrcweir 	switch ( uMsg )
1300*cdf0e10cSrcweir 	{
1301*cdf0e10cSrcweir 	case WM_INITDIALOG:
1302*cdf0e10cSrcweir 		{
1303*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong(hwndDlg, GWL_HINSTANCE );
1304*cdf0e10cSrcweir 			HWND	hwndRichEdit = GetDlgItem(hwndDlg, IDC_RICHEDIT21);
1305*cdf0e10cSrcweir 			TCHAR	szBuffer[FORMATBUFSIZE];
1306*cdf0e10cSrcweir 			TCHAR	szBuffer2[FORMATBUFSIZE];
1307*cdf0e10cSrcweir 			TCHAR	szURL[256];
1308*cdf0e10cSrcweir 			TCHAR	szCaption[256];
1309*cdf0e10cSrcweir 
1310*cdf0e10cSrcweir 			SendMessage(
1311*cdf0e10cSrcweir 				hwndRichEdit,
1312*cdf0e10cSrcweir 				EM_SETBKGNDCOLOR,
1313*cdf0e10cSrcweir 				(WPARAM)FALSE,
1314*cdf0e10cSrcweir 				GetSysColor( COLOR_3DFACE ) );
1315*cdf0e10cSrcweir 
1316*cdf0e10cSrcweir 			SendMessage( hwndRichEdit, EM_SETEVENTMASK, 0, ENM_LINK );
1317*cdf0e10cSrcweir 			SendMessage( hwndRichEdit, EM_AUTOURLDETECT, TRUE, 0 );
1318*cdf0e10cSrcweir 
1319*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_WELCOME_BODY1, szBuffer, elementsof(szBuffer) );
1320*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_WELCOME_BODY2, szBuffer2, elementsof(szBuffer2) );
1321*cdf0e10cSrcweir 			_tcsncat( szBuffer, szBuffer2, elementsof(szBuffer) );
1322*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_WELCOME_BODY3, szBuffer2, elementsof(szBuffer2) );
1323*cdf0e10cSrcweir 			_tcsncat( szBuffer, szBuffer2, elementsof(szBuffer) );
1324*cdf0e10cSrcweir 			LoadString( hInstance, IDS_PRIVACY_URL, szURL, elementsof(szURL) );
1325*cdf0e10cSrcweir 			_tcsncat( szBuffer, szURL, elementsof(szBuffer) );
1326*cdf0e10cSrcweir 			SetWindowText( hwndRichEdit, szBuffer );
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_WELCOME_CAPTION, szCaption, elementsof(szCaption) );
1329*cdf0e10cSrcweir 			SetWindowText( GetParent(hwndDlg), szCaption );
1330*cdf0e10cSrcweir 
1331*cdf0e10cSrcweir 		}
1332*cdf0e10cSrcweir 		return TRUE;
1333*cdf0e10cSrcweir 	case WM_SHOWWINDOW:
1334*cdf0e10cSrcweir 		if ( (BOOL)wParam )
1335*cdf0e10cSrcweir 		{
1336*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong(hwndDlg, GWL_HINSTANCE );
1337*cdf0e10cSrcweir 			TCHAR		szBuffer[FORMATBUFSIZE];
1338*cdf0e10cSrcweir 
1339*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_WELCOME_CAPTION, szBuffer, elementsof(szBuffer) );
1340*cdf0e10cSrcweir 			SetWindowText( GetParent(hwndDlg), szBuffer );
1341*cdf0e10cSrcweir 
1342*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_WELCOME_HEADER, szBuffer, elementsof(szBuffer) );
1343*cdf0e10cSrcweir 			SetWindowText( GetDlgItem(GetParent(hwndDlg), IDC_HEADER), szBuffer );
1344*cdf0e10cSrcweir 
1345*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_CANCEL_BUTTON, szBuffer, elementsof(szBuffer) );
1346*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(GetParent(hwndDlg), IDCANCEL), szBuffer );
1347*cdf0e10cSrcweir 
1348*cdf0e10cSrcweir 			ShowWindow( GetDlgItem(GetParent(hwndDlg),IDBACK), FALSE );
1349*cdf0e10cSrcweir 			ShowWindow( GetDlgItem(GetParent(hwndDlg),IDFINISH), FALSE );
1350*cdf0e10cSrcweir 			ShowWindow( GetDlgItem(GetParent(hwndDlg),IDNEXT), TRUE );
1351*cdf0e10cSrcweir 
1352*cdf0e10cSrcweir 			SetFocus( GetDlgItem(GetParent(hwndDlg),IDNEXT) );
1353*cdf0e10cSrcweir 		}
1354*cdf0e10cSrcweir 		break;
1355*cdf0e10cSrcweir 	case WM_NOTIFY:
1356*cdf0e10cSrcweir 		{
1357*cdf0e10cSrcweir 			LPNMHDR	pnmh = (LPNMHDR)lParam;
1358*cdf0e10cSrcweir 
1359*cdf0e10cSrcweir 			if ( pnmh->idFrom == IDC_RICHEDIT21 && pnmh->code == EN_LINK )
1360*cdf0e10cSrcweir 			{
1361*cdf0e10cSrcweir 				ENLINK	*plink = (ENLINK*)lParam;
1362*cdf0e10cSrcweir 
1363*cdf0e10cSrcweir 				if ( plink->msg == WM_LBUTTONUP )
1364*cdf0e10cSrcweir 				{
1365*cdf0e10cSrcweir 					TCHAR	szBuffer[256];
1366*cdf0e10cSrcweir 					TEXTRANGE	range;
1367*cdf0e10cSrcweir 
1368*cdf0e10cSrcweir 					range.chrg = plink->chrg;
1369*cdf0e10cSrcweir 					range.lpstrText = szBuffer;
1370*cdf0e10cSrcweir 
1371*cdf0e10cSrcweir 					SendMessage( pnmh->hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&range );
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir 					ShellExecute( hwndDlg, NULL, szBuffer, NULL, NULL, SW_SHOWDEFAULT );
1374*cdf0e10cSrcweir 				}
1375*cdf0e10cSrcweir 
1376*cdf0e10cSrcweir 			}
1377*cdf0e10cSrcweir 		}
1378*cdf0e10cSrcweir 		break;
1379*cdf0e10cSrcweir 	default:
1380*cdf0e10cSrcweir 		break;
1381*cdf0e10cSrcweir 	}
1382*cdf0e10cSrcweir 
1383*cdf0e10cSrcweir 	return FALSE;
1384*cdf0e10cSrcweir }
1385*cdf0e10cSrcweir //***************************************************************************
1386*cdf0e10cSrcweir 
1387*cdf0e10cSrcweir BOOL CALLBACK DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
1388*cdf0e10cSrcweir {
1389*cdf0e10cSrcweir 	static	HWND	hwndPages[2] = { NULL };
1390*cdf0e10cSrcweir 	static	int		iActualPage = 0;
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir 	switch ( uMsg )
1393*cdf0e10cSrcweir 	{
1394*cdf0e10cSrcweir 	case WM_INITDIALOG:
1395*cdf0e10cSrcweir 		{
1396*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong(hwndDlg, GWL_HINSTANCE );
1397*cdf0e10cSrcweir 			TCHAR		szBuffer[FORMATBUFSIZE];
1398*cdf0e10cSrcweir 
1399*cdf0e10cSrcweir 			SetWindowLong( hwndDlg, GWL_USERDATA, (LONG)lParam );
1400*cdf0e10cSrcweir 			hwndPages[0] = CreateDialog(
1401*cdf0e10cSrcweir 				hInstance,
1402*cdf0e10cSrcweir 				MAKEINTRESOURCE(IDD_WELCOME_PAGE),
1403*cdf0e10cSrcweir 				hwndDlg,
1404*cdf0e10cSrcweir 				WelcomeDialogProc );
1405*cdf0e10cSrcweir 
1406*cdf0e10cSrcweir 			hwndPages[1] = CreateDialog(
1407*cdf0e10cSrcweir 				hInstance,
1408*cdf0e10cSrcweir 				MAKEINTRESOURCE(IDD_REPORT_PAGE),
1409*cdf0e10cSrcweir 				hwndDlg,
1410*cdf0e10cSrcweir 				ReportDialogProc );
1411*cdf0e10cSrcweir 
1412*cdf0e10cSrcweir 			CHARFORMAT	chfmt;
1413*cdf0e10cSrcweir 
1414*cdf0e10cSrcweir 			chfmt.cbSize = sizeof(chfmt);
1415*cdf0e10cSrcweir 			chfmt.dwMask = CFM_BOLD;
1416*cdf0e10cSrcweir 			chfmt.dwEffects = CFE_BOLD;
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir 			SendMessage(
1419*cdf0e10cSrcweir 				GetDlgItem(hwndDlg, IDC_HEADER),
1420*cdf0e10cSrcweir 				EM_SETCHARFORMAT,
1421*cdf0e10cSrcweir 				SCF_ALL,
1422*cdf0e10cSrcweir 				(LPARAM)&chfmt );
1423*cdf0e10cSrcweir 
1424*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_CANCEL_BUTTON, szBuffer, elementsof(szBuffer) );
1425*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDCANCEL), szBuffer );
1426*cdf0e10cSrcweir 
1427*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_NEXT_BUTTON, szBuffer, elementsof(szBuffer) );
1428*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDNEXT), szBuffer );
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_SEND_BUTTON, szBuffer, elementsof(szBuffer) );
1431*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDFINISH), szBuffer );
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_BACK_BUTTON, szBuffer, elementsof(szBuffer) );
1434*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDBACK), szBuffer );
1435*cdf0e10cSrcweir 
1436*cdf0e10cSrcweir 			ShowWindow( hwndPages[1], SW_HIDE );
1437*cdf0e10cSrcweir 			ShowWindow( hwndPages[0], SW_SHOW );
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir 			// Let Crash Reporter window stay on top of all other windows
1440*cdf0e10cSrcweir 			SetWindowPos( hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
1441*cdf0e10cSrcweir 		}
1442*cdf0e10cSrcweir 		return FALSE;
1443*cdf0e10cSrcweir 	case WM_CTLCOLORSTATIC:
1444*cdf0e10cSrcweir 		return (BOOL)CreateSolidBrush(GetSysColor(COLOR_WINDOW));
1445*cdf0e10cSrcweir 	case WM_COMMAND:
1446*cdf0e10cSrcweir 		switch ( LOWORD(wParam) )
1447*cdf0e10cSrcweir 		{
1448*cdf0e10cSrcweir 		case IDBACK:
1449*cdf0e10cSrcweir 			if ( iActualPage > 0 )
1450*cdf0e10cSrcweir 			{
1451*cdf0e10cSrcweir 				ShowWindow( hwndPages[iActualPage], SW_HIDE );
1452*cdf0e10cSrcweir 				ShowWindow( hwndPages[--iActualPage], SW_SHOW );
1453*cdf0e10cSrcweir 			}
1454*cdf0e10cSrcweir 			return TRUE;
1455*cdf0e10cSrcweir 		case IDNEXT:
1456*cdf0e10cSrcweir 			if ( iActualPage < elementsof(hwndPages) - 1 )
1457*cdf0e10cSrcweir 			{
1458*cdf0e10cSrcweir 				ShowWindow( hwndPages[iActualPage], SW_HIDE );
1459*cdf0e10cSrcweir 				ShowWindow( hwndPages[++iActualPage], SW_SHOW );
1460*cdf0e10cSrcweir 			}
1461*cdf0e10cSrcweir 			return TRUE;
1462*cdf0e10cSrcweir 		case IDFINISH:
1463*cdf0e10cSrcweir 			{
1464*cdf0e10cSrcweir 				TCHAR	szBuffer[32767];
1465*cdf0e10cSrcweir 				CrashReportParams	*pParams = (CrashReportParams*)GetWindowLong( hwndDlg, GWL_USERDATA );
1466*cdf0e10cSrcweir 
1467*cdf0e10cSrcweir 				pParams->fAllowContact = Button_GetCheck( GetDlgItem(hwndPages[1], IDC_ALLOW_CONTACT) ) ? TRUE : FALSE;
1468*cdf0e10cSrcweir 
1469*cdf0e10cSrcweir 				Edit_GetText( GetDlgItem(hwndPages[1], IDC_EDIT_TITLE), szBuffer, elementsof(szBuffer) );
1470*cdf0e10cSrcweir 				pParams->sTitle = szBuffer;
1471*cdf0e10cSrcweir 
1472*cdf0e10cSrcweir 				Edit_GetText( GetDlgItem(hwndPages[1], IDC_EDIT_DESCRIPTION), szBuffer, elementsof(szBuffer) );
1473*cdf0e10cSrcweir 				pParams->sComment = szBuffer;
1474*cdf0e10cSrcweir 
1475*cdf0e10cSrcweir 				Edit_GetText( GetDlgItem(hwndPages[1], IDC_EDIT_EMAIL), szBuffer, elementsof(szBuffer) );
1476*cdf0e10cSrcweir 				pParams->sEmail = szBuffer;
1477*cdf0e10cSrcweir 
1478*cdf0e10cSrcweir 				if ( pParams->fAllowContact && !pParams->sEmail.length() )
1479*cdf0e10cSrcweir 				{
1480*cdf0e10cSrcweir 					TCHAR	szMessage[MAX_TEXT_BUFFER];
1481*cdf0e10cSrcweir 
1482*cdf0e10cSrcweir 					LoadAndFormatString( GetModuleHandle(NULL), IDS_ERROR_MSG_NOEMAILADDRESS, szMessage, elementsof(szMessage) );
1483*cdf0e10cSrcweir 
1484*cdf0e10cSrcweir 					MessageBox( hwndDlg, szMessage, NULL, MB_ICONERROR | MB_OK );
1485*cdf0e10cSrcweir 					break;  // Don't end the dialog
1486*cdf0e10cSrcweir 				}
1487*cdf0e10cSrcweir 				else
1488*cdf0e10cSrcweir 				{
1489*cdf0e10cSrcweir 					pParams->WriteToRegistry();
1490*cdf0e10cSrcweir 
1491*cdf0e10cSrcweir 					WriteCommentFile( pParams->sComment.c_str() );
1492*cdf0e10cSrcweir 					WriteReportFile( pParams );
1493*cdf0e10cSrcweir 
1494*cdf0e10cSrcweir 					if ( !SendCrashReport( hwndDlg, *pParams ) )
1495*cdf0e10cSrcweir 						break; // Don't end the dialog
1496*cdf0e10cSrcweir 				}
1497*cdf0e10cSrcweir 			}
1498*cdf0e10cSrcweir 			// Fallthrough !!!
1499*cdf0e10cSrcweir 		case IDCANCEL:
1500*cdf0e10cSrcweir 			EndDialog( hwndDlg, wParam );
1501*cdf0e10cSrcweir 			return TRUE;
1502*cdf0e10cSrcweir 		}
1503*cdf0e10cSrcweir 		break;
1504*cdf0e10cSrcweir 	default:
1505*cdf0e10cSrcweir 		break;
1506*cdf0e10cSrcweir 	}
1507*cdf0e10cSrcweir 
1508*cdf0e10cSrcweir 	return FALSE;
1509*cdf0e10cSrcweir }
1510*cdf0e10cSrcweir 
1511*cdf0e10cSrcweir 
1512*cdf0e10cSrcweir 
1513*cdf0e10cSrcweir //*****************************************************************************
1514*cdf0e10cSrcweir //* Generate MD5 checksum
1515*cdf0e10cSrcweir //*****************************************************************************
1516*cdf0e10cSrcweir 
1517*cdf0e10cSrcweir #define MAGIC_DESCRIPTION_FILLER	'x'
1518*cdf0e10cSrcweir #define MAGIC_DESCRIPTION_COUNT		80
1519*cdf0e10cSrcweir 
1520*cdf0e10cSrcweir static void repatch_soffice_exe( void *pBuffer, size_t nBufSize )
1521*cdf0e10cSrcweir {
1522*cdf0e10cSrcweir 	wchar_t DescriptionBuffer[MAGIC_DESCRIPTION_COUNT];
1523*cdf0e10cSrcweir 
1524*cdf0e10cSrcweir 	memset( DescriptionBuffer, 0, sizeof(DescriptionBuffer) );
1525*cdf0e10cSrcweir 	wcsncpy( DescriptionBuffer, g_wstrProductKey.c_str(), elementsof(DescriptionBuffer) - 1 );
1526*cdf0e10cSrcweir 
1527*cdf0e10cSrcweir 	bool bPatched = false;
1528*cdf0e10cSrcweir 
1529*cdf0e10cSrcweir 	do
1530*cdf0e10cSrcweir 	{
1531*cdf0e10cSrcweir 		void *pFound = memchr( pBuffer, ((char *)DescriptionBuffer)[0], nBufSize );
1532*cdf0e10cSrcweir 
1533*cdf0e10cSrcweir 		if ( pFound )
1534*cdf0e10cSrcweir 		{
1535*cdf0e10cSrcweir 			size_t distance = (char *)pFound - (char *)pBuffer;
1536*cdf0e10cSrcweir 
1537*cdf0e10cSrcweir 			if ( nBufSize >= distance )
1538*cdf0e10cSrcweir 			{
1539*cdf0e10cSrcweir 				nBufSize -= distance;
1540*cdf0e10cSrcweir 
1541*cdf0e10cSrcweir 				if ( nBufSize >= sizeof(DescriptionBuffer) &&
1542*cdf0e10cSrcweir 					0 == memcmp( pFound, DescriptionBuffer, sizeof(DescriptionBuffer) ) )
1543*cdf0e10cSrcweir 				{
1544*cdf0e10cSrcweir 					for ( int i = 0; i < 80; i++ )
1545*cdf0e10cSrcweir 					{
1546*cdf0e10cSrcweir 						((wchar_t *)pFound)[i] = MAGIC_DESCRIPTION_FILLER;
1547*cdf0e10cSrcweir 					}
1548*cdf0e10cSrcweir 					bPatched = true;
1549*cdf0e10cSrcweir 				}
1550*cdf0e10cSrcweir 				else
1551*cdf0e10cSrcweir 				{
1552*cdf0e10cSrcweir 					pBuffer = (void *)(((char *)pFound) + 1);
1553*cdf0e10cSrcweir 					nBufSize--;
1554*cdf0e10cSrcweir 				}
1555*cdf0e10cSrcweir 			}
1556*cdf0e10cSrcweir 			else
1557*cdf0e10cSrcweir 				nBufSize = 0;
1558*cdf0e10cSrcweir 		}
1559*cdf0e10cSrcweir 		else
1560*cdf0e10cSrcweir 			nBufSize = 0;
1561*cdf0e10cSrcweir 	} while ( !bPatched && nBufSize );
1562*cdf0e10cSrcweir }
1563*cdf0e10cSrcweir 
1564*cdf0e10cSrcweir // Normalize executable/library images to prevent different MD5 checksums due
1565*cdf0e10cSrcweir // to a different PE header date/checksum (this doesn't affect the code/data
1566*cdf0e10cSrcweir // sections of a executable/library. Please see tools/source/bootstrp/md5.cxx
1567*cdf0e10cSrcweir // where the same method is also used. The tool so_checksum creates the MD5
1568*cdf0e10cSrcweir // checksums during build time. You have to make sure that both methods use the
1569*cdf0e10cSrcweir // same algorithm otherwise there could be problems with stack reports.
1570*cdf0e10cSrcweir static void normalize_pe_image(sal_uInt8* buffer, size_t nBufferSize)
1571*cdf0e10cSrcweir {
1572*cdf0e10cSrcweir 	const int OFFSET_PE_OFFSET                  = 0x3c;
1573*cdf0e10cSrcweir 	const int OFFSET_COFF_TIMEDATESTAMP         = 4;
1574*cdf0e10cSrcweir 	const int PE_SIGNATURE_SIZE                 = 4;
1575*cdf0e10cSrcweir 	const int COFFHEADER_SIZE                   = 20;
1576*cdf0e10cSrcweir 	const int OFFSET_PE_OPTIONALHEADER_CHECKSUM = 64;
1577*cdf0e10cSrcweir 
1578*cdf0e10cSrcweir 	// Check the header part of the file buffer
1579*cdf0e10cSrcweir 	if (buffer[0] == 'M' && buffer[1] == 'Z')
1580*cdf0e10cSrcweir 	{
1581*cdf0e10cSrcweir 		unsigned long PEHeaderOffset = (long)buffer[OFFSET_PE_OFFSET];
1582*cdf0e10cSrcweir 		if (PEHeaderOffset < nBufferSize-4)
1583*cdf0e10cSrcweir 		{
1584*cdf0e10cSrcweir 			if ( buffer[PEHeaderOffset] == 'P' &&
1585*cdf0e10cSrcweir 				 buffer[PEHeaderOffset+1] == 'E' &&
1586*cdf0e10cSrcweir 				 buffer[PEHeaderOffset+2] == 0 &&
1587*cdf0e10cSrcweir 				 buffer[PEHeaderOffset+3] == 0 )
1588*cdf0e10cSrcweir 			{
1589*cdf0e10cSrcweir 				PEHeaderOffset += PE_SIGNATURE_SIZE;
1590*cdf0e10cSrcweir 				if (PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP < nBufferSize-4)
1591*cdf0e10cSrcweir 				{
1592*cdf0e10cSrcweir 					// Set timedatestamp and checksum fields to a normalized
1593*cdf0e10cSrcweir 					// value to enforce the same MD5 checksum for identical
1594*cdf0e10cSrcweir 					// Windows	executables/libraries.
1595*cdf0e10cSrcweir 					buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP] = 0;
1596*cdf0e10cSrcweir 					buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+1] = 0;
1597*cdf0e10cSrcweir 					buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+2] = 0;
1598*cdf0e10cSrcweir 					buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+3] = 0;
1599*cdf0e10cSrcweir 				}
1600*cdf0e10cSrcweir 
1601*cdf0e10cSrcweir 				if (PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM < nBufferSize-4)
1602*cdf0e10cSrcweir 				{
1603*cdf0e10cSrcweir 					// Set checksum to a normalized value
1604*cdf0e10cSrcweir 					buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM] = 0;
1605*cdf0e10cSrcweir 					buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+1] = 0;
1606*cdf0e10cSrcweir 					buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+2] = 0;
1607*cdf0e10cSrcweir 					buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+3] = 0;
1608*cdf0e10cSrcweir 				}
1609*cdf0e10cSrcweir 			}
1610*cdf0e10cSrcweir 		}
1611*cdf0e10cSrcweir 	}
1612*cdf0e10cSrcweir }
1613*cdf0e10cSrcweir 
1614*cdf0e10cSrcweir static sal_uInt32 calc_md5_checksum(  const char *filename, sal_uInt8 *pChecksum, sal_uInt32 nChecksumLen )
1615*cdf0e10cSrcweir {
1616*cdf0e10cSrcweir 	const int MINIMAL_FILESIZE = 512;
1617*cdf0e10cSrcweir 
1618*cdf0e10cSrcweir 	sal_uInt32	nBytesProcessed = 0;
1619*cdf0e10cSrcweir 
1620*cdf0e10cSrcweir 	FILE *fp = fopen( filename, "rb" );
1621*cdf0e10cSrcweir 
1622*cdf0e10cSrcweir 	if ( fp )
1623*cdf0e10cSrcweir 	{
1624*cdf0e10cSrcweir 		long	nFileSize;
1625*cdf0e10cSrcweir 
1626*cdf0e10cSrcweir 		if ( 0 == fseek( fp, 0, SEEK_END ) && -1 != (nFileSize = ftell(fp)) )
1627*cdf0e10cSrcweir 		{
1628*cdf0e10cSrcweir 			rewind( fp );
1629*cdf0e10cSrcweir 
1630*cdf0e10cSrcweir 			sal_uInt8 *pBuffer = new sal_uInt8[nFileSize];
1631*cdf0e10cSrcweir 			size_t nBytesRead = fread( pBuffer, 1, nFileSize, fp );
1632*cdf0e10cSrcweir 
1633*cdf0e10cSrcweir 			if ( sal::static_int_cast<long>(nBytesRead) == nFileSize )
1634*cdf0e10cSrcweir 			{
1635*cdf0e10cSrcweir 				if ( 0 == stricmp( GetFileName(filename).c_str(), "soffice.bin" ) )
1636*cdf0e10cSrcweir 					repatch_soffice_exe( pBuffer, nBytesRead );
1637*cdf0e10cSrcweir 				else if ( nFileSize > MINIMAL_FILESIZE )
1638*cdf0e10cSrcweir 					normalize_pe_image( pBuffer, nBytesRead );
1639*cdf0e10cSrcweir 
1640*cdf0e10cSrcweir 				rtlDigestError error = rtl_digest_MD5 (
1641*cdf0e10cSrcweir 					pBuffer,   nBytesRead,
1642*cdf0e10cSrcweir 					pChecksum, nChecksumLen	);
1643*cdf0e10cSrcweir 
1644*cdf0e10cSrcweir 				if ( rtl_Digest_E_None == error )
1645*cdf0e10cSrcweir 					nBytesProcessed = nBytesRead;
1646*cdf0e10cSrcweir 			}
1647*cdf0e10cSrcweir 
1648*cdf0e10cSrcweir 			delete[] pBuffer;
1649*cdf0e10cSrcweir 		}
1650*cdf0e10cSrcweir 
1651*cdf0e10cSrcweir 		fclose( fp );
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir 	}
1654*cdf0e10cSrcweir 
1655*cdf0e10cSrcweir 	return nBytesProcessed;
1656*cdf0e10cSrcweir }
1657*cdf0e10cSrcweir 
1658*cdf0e10cSrcweir #if 0
1659*cdf0e10cSrcweir static sal_uInt32 calc_md5_checksum( const char *filename, sal_uInt8 *pChecksum, sal_uInt32 nChecksumLen )
1660*cdf0e10cSrcweir {
1661*cdf0e10cSrcweir 	sal_uInt32	nBytesProcessed = 0;
1662*cdf0e10cSrcweir 
1663*cdf0e10cSrcweir 	FILE *fp = fopen( filename, "rb" );
1664*cdf0e10cSrcweir 
1665*cdf0e10cSrcweir 	if ( fp )
1666*cdf0e10cSrcweir 	{
1667*cdf0e10cSrcweir 		rtlDigest digest = rtl_digest_createMD5();
1668*cdf0e10cSrcweir 
1669*cdf0e10cSrcweir 		if ( digest )
1670*cdf0e10cSrcweir 		{
1671*cdf0e10cSrcweir 			size_t			nBytesRead;
1672*cdf0e10cSrcweir 			sal_uInt8		buffer[4096];
1673*cdf0e10cSrcweir 			rtlDigestError	error = rtl_Digest_E_None;
1674*cdf0e10cSrcweir 
1675*cdf0e10cSrcweir 			while ( rtl_Digest_E_None == error &&
1676*cdf0e10cSrcweir 				0 != (nBytesRead = fread( buffer, 1, sizeof(buffer), fp )) )
1677*cdf0e10cSrcweir 			{
1678*cdf0e10cSrcweir 				error = rtl_digest_updateMD5( digest, buffer, nBytesRead );
1679*cdf0e10cSrcweir 				nBytesProcessed += nBytesRead;
1680*cdf0e10cSrcweir 			}
1681*cdf0e10cSrcweir 
1682*cdf0e10cSrcweir 			if ( rtl_Digest_E_None == error )
1683*cdf0e10cSrcweir 			{
1684*cdf0e10cSrcweir 				error = rtl_digest_getMD5( digest, pChecksum, nChecksumLen );
1685*cdf0e10cSrcweir 			}
1686*cdf0e10cSrcweir 
1687*cdf0e10cSrcweir 			if ( rtl_Digest_E_None != error )
1688*cdf0e10cSrcweir 				nBytesProcessed = 0;
1689*cdf0e10cSrcweir 
1690*cdf0e10cSrcweir 			rtl_digest_destroyMD5( digest );
1691*cdf0e10cSrcweir 		}
1692*cdf0e10cSrcweir 
1693*cdf0e10cSrcweir 		fclose( fp );
1694*cdf0e10cSrcweir 	}
1695*cdf0e10cSrcweir 
1696*cdf0e10cSrcweir 	return nBytesProcessed;
1697*cdf0e10cSrcweir }
1698*cdf0e10cSrcweir 
1699*cdf0e10cSrcweir #endif
1700*cdf0e10cSrcweir //***************************************************************************
1701*cdf0e10cSrcweir 
1702*cdf0e10cSrcweir static bool WriteStackFile( FILE *fout, hash_map< string, string >& rLibraries, DWORD dwProcessId, PEXCEPTION_POINTERS pExceptionPointers )
1703*cdf0e10cSrcweir {
1704*cdf0e10cSrcweir 	bool	fSuccess = false;
1705*cdf0e10cSrcweir 
1706*cdf0e10cSrcweir 	if ( fout && dwProcessId && pExceptionPointers )
1707*cdf0e10cSrcweir 	{
1708*cdf0e10cSrcweir 		HANDLE	hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
1709*cdf0e10cSrcweir 
1710*cdf0e10cSrcweir 		if ( IsValidHandle(hProcess) )
1711*cdf0e10cSrcweir 		{
1712*cdf0e10cSrcweir 			EXCEPTION_POINTERS	aExceptionPointers;
1713*cdf0e10cSrcweir 			CONTEXT				aContextRecord;
1714*cdf0e10cSrcweir 
1715*cdf0e10cSrcweir 			ReadProcessMemory(
1716*cdf0e10cSrcweir 				hProcess,
1717*cdf0e10cSrcweir 				pExceptionPointers,
1718*cdf0e10cSrcweir 				&aExceptionPointers,
1719*cdf0e10cSrcweir 				sizeof(aExceptionPointers),
1720*cdf0e10cSrcweir 				NULL );
1721*cdf0e10cSrcweir 
1722*cdf0e10cSrcweir 			ReadProcessMemory(
1723*cdf0e10cSrcweir 				hProcess,
1724*cdf0e10cSrcweir 				aExceptionPointers.ContextRecord,
1725*cdf0e10cSrcweir 				&aContextRecord,
1726*cdf0e10cSrcweir 				sizeof(aContextRecord),
1727*cdf0e10cSrcweir 				NULL );
1728*cdf0e10cSrcweir 
1729*cdf0e10cSrcweir 			STACKFRAME	frame;
1730*cdf0e10cSrcweir 
1731*cdf0e10cSrcweir 			ZeroMemory( &frame, sizeof(frame) );
1732*cdf0e10cSrcweir 			frame.AddrPC.Offset = aContextRecord.Eip;
1733*cdf0e10cSrcweir 			frame.AddrPC.Mode = AddrModeFlat;
1734*cdf0e10cSrcweir 			frame.AddrFrame.Offset = aContextRecord.Ebp;
1735*cdf0e10cSrcweir 			frame.AddrFrame.Mode = AddrModeFlat;
1736*cdf0e10cSrcweir 
1737*cdf0e10cSrcweir 			BOOL bSuccess;
1738*cdf0e10cSrcweir 			int frameNum = 0;
1739*cdf0e10cSrcweir 
1740*cdf0e10cSrcweir 			SymInitialize( hProcess, NULL, TRUE );
1741*cdf0e10cSrcweir 
1742*cdf0e10cSrcweir 			fprintf( fout, "<errormail:Stack type=\"Win32\">\n" );
1743*cdf0e10cSrcweir 
1744*cdf0e10cSrcweir 			do
1745*cdf0e10cSrcweir 			{
1746*cdf0e10cSrcweir 				fSuccess = true;
1747*cdf0e10cSrcweir 
1748*cdf0e10cSrcweir 				bSuccess = StackWalk( IMAGE_FILE_MACHINE_I386,
1749*cdf0e10cSrcweir 					hProcess,
1750*cdf0e10cSrcweir 					NULL,
1751*cdf0e10cSrcweir 					&frame,
1752*cdf0e10cSrcweir 					&aContextRecord,
1753*cdf0e10cSrcweir 					(PREAD_PROCESS_MEMORY_ROUTINE)ReadProcessMemory,
1754*cdf0e10cSrcweir 					SymFunctionTableAccess,
1755*cdf0e10cSrcweir 					SymGetModuleBase,
1756*cdf0e10cSrcweir 					NULL );
1757*cdf0e10cSrcweir 
1758*cdf0e10cSrcweir 				if ( bSuccess )
1759*cdf0e10cSrcweir 				{
1760*cdf0e10cSrcweir 					// Note: ImageHelp ANSI functions do not have an A postfix while
1761*cdf0e10cSrcweir 					//       Unicode versions have a W postfix. There's no macro
1762*cdf0e10cSrcweir 					//       that depends on define UNICODE
1763*cdf0e10cSrcweir 
1764*cdf0e10cSrcweir 					IMAGEHLP_MODULE	moduleInfo;
1765*cdf0e10cSrcweir 
1766*cdf0e10cSrcweir 					ZeroMemory( &moduleInfo, sizeof(moduleInfo) );
1767*cdf0e10cSrcweir 					moduleInfo.SizeOfStruct = sizeof(moduleInfo);
1768*cdf0e10cSrcweir 
1769*cdf0e10cSrcweir 					if ( SymGetModuleInfo( hProcess, frame.AddrPC.Offset, &moduleInfo ) )
1770*cdf0e10cSrcweir 					{
1771*cdf0e10cSrcweir 						rLibraries[ GetFileName( moduleInfo.LoadedImageName ).c_str() ] = moduleInfo.LoadedImageName;
1772*cdf0e10cSrcweir 
1773*cdf0e10cSrcweir 						DWORD	dwRelOffset = 0;
1774*cdf0e10cSrcweir 						BYTE	symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 256 ];
1775*cdf0e10cSrcweir 						PIMAGEHLP_SYMBOL	pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer;
1776*cdf0e10cSrcweir 
1777*cdf0e10cSrcweir 						ZeroMemory( symbolBuffer, sizeof(symbolBuffer) );
1778*cdf0e10cSrcweir 						pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
1779*cdf0e10cSrcweir 						pSymbol->MaxNameLength = 256;
1780*cdf0e10cSrcweir 
1781*cdf0e10cSrcweir 						if ( SymGetSymFromAddr( hProcess, frame.AddrPC.Offset, &dwRelOffset, pSymbol ) )
1782*cdf0e10cSrcweir 							fprintf( fout, "<errormail:StackInfo " \
1783*cdf0e10cSrcweir 								"pos=\"%d\" ip=\"0x%p\" rel=\"0x%p\" ordinal=\"%s+0x%p\" name=\"%s\" path=\"%s\"/>\n",
1784*cdf0e10cSrcweir 								frameNum,
1785*cdf0e10cSrcweir 								frame.AddrPC.Offset,
1786*cdf0e10cSrcweir 								frame.AddrPC.Offset - moduleInfo.BaseOfImage,
1787*cdf0e10cSrcweir 								xml_encode(pSymbol->Name).c_str(),
1788*cdf0e10cSrcweir 								frame.AddrPC.Offset - pSymbol->Address,
1789*cdf0e10cSrcweir 								xml_encode(GetFileName( moduleInfo.LoadedImageName )).c_str(),
1790*cdf0e10cSrcweir 								xml_encode( GetFileDirectory( moduleInfo.LoadedImageName )).c_str()
1791*cdf0e10cSrcweir 								);
1792*cdf0e10cSrcweir 						else
1793*cdf0e10cSrcweir 							fprintf( fout, "<errormail:StackInfo " \
1794*cdf0e10cSrcweir 								"pos=\"%d\" ip=\"0x%p\" rel=\"0x%p\" name=\"%s\" path=\"%s\"/>\n",
1795*cdf0e10cSrcweir 								frameNum,
1796*cdf0e10cSrcweir 								frame.AddrPC.Offset,
1797*cdf0e10cSrcweir 								frame.AddrPC.Offset - moduleInfo.BaseOfImage,
1798*cdf0e10cSrcweir 								xml_encode(GetFileName( moduleInfo.LoadedImageName )).c_str(),
1799*cdf0e10cSrcweir 								xml_encode(GetFileDirectory( moduleInfo.LoadedImageName )).c_str()
1800*cdf0e10cSrcweir 								);
1801*cdf0e10cSrcweir 					}
1802*cdf0e10cSrcweir 					else
1803*cdf0e10cSrcweir 						fprintf( fout, "<errormail:StackInfo pos=\"%d\" ip=\"0x%p\"/>\n",
1804*cdf0e10cSrcweir 							frameNum,
1805*cdf0e10cSrcweir 							frame.AddrPC.Offset
1806*cdf0e10cSrcweir 							);
1807*cdf0e10cSrcweir 
1808*cdf0e10cSrcweir 					frameNum++;
1809*cdf0e10cSrcweir 				}
1810*cdf0e10cSrcweir 
1811*cdf0e10cSrcweir 			} while ( bSuccess );
1812*cdf0e10cSrcweir 
1813*cdf0e10cSrcweir 			fprintf( fout, "</errormail:Stack>\n" );
1814*cdf0e10cSrcweir 
1815*cdf0e10cSrcweir 			SymCleanup( hProcess );
1816*cdf0e10cSrcweir 
1817*cdf0e10cSrcweir 			CloseHandle( hProcess );
1818*cdf0e10cSrcweir 		}
1819*cdf0e10cSrcweir 
1820*cdf0e10cSrcweir 	}
1821*cdf0e10cSrcweir 
1822*cdf0e10cSrcweir 	return fSuccess;
1823*cdf0e10cSrcweir }
1824*cdf0e10cSrcweir 
1825*cdf0e10cSrcweir bool WriteChecksumFile( FILE *fchksum, const hash_map< string, string >& rLibraries )
1826*cdf0e10cSrcweir {
1827*cdf0e10cSrcweir 	bool success = false;
1828*cdf0e10cSrcweir 
1829*cdf0e10cSrcweir 	if ( fchksum && rLibraries.size() )
1830*cdf0e10cSrcweir 	{
1831*cdf0e10cSrcweir 		fprintf( fchksum, "<errormail:Checksums type=\"MD5\">\n" );
1832*cdf0e10cSrcweir 
1833*cdf0e10cSrcweir 		hash_map< string, string >::const_iterator iter;
1834*cdf0e10cSrcweir 
1835*cdf0e10cSrcweir 		for ( iter = rLibraries.begin();
1836*cdf0e10cSrcweir 			iter != rLibraries.end();
1837*cdf0e10cSrcweir 			iter++ )
1838*cdf0e10cSrcweir 		{
1839*cdf0e10cSrcweir 			sal_uInt8 checksum[RTL_DIGEST_LENGTH_MD5];
1840*cdf0e10cSrcweir 			sal_uInt32 nBytesProcessed = calc_md5_checksum(
1841*cdf0e10cSrcweir 				iter->second.c_str(),
1842*cdf0e10cSrcweir 				checksum, sizeof(checksum) );
1843*cdf0e10cSrcweir 
1844*cdf0e10cSrcweir 			if ( nBytesProcessed )
1845*cdf0e10cSrcweir 			{
1846*cdf0e10cSrcweir 				fprintf( fchksum, "<errormail:Checksum sum=\"0x" );
1847*cdf0e10cSrcweir 				for ( int i = 0; i < sizeof(checksum); fprintf( fchksum, "%02X", checksum[i++] ) );
1848*cdf0e10cSrcweir 				fprintf( fchksum, "\" bytes=\"%d\" file=\"%s\"/>\n",
1849*cdf0e10cSrcweir 					nBytesProcessed,
1850*cdf0e10cSrcweir 					GetFileName( iter->first ).c_str() );
1851*cdf0e10cSrcweir 			}
1852*cdf0e10cSrcweir 		}
1853*cdf0e10cSrcweir 
1854*cdf0e10cSrcweir 		fprintf( fchksum, "</errormail:Checksums>\n" );
1855*cdf0e10cSrcweir 
1856*cdf0e10cSrcweir 		success = true;
1857*cdf0e10cSrcweir 	}
1858*cdf0e10cSrcweir 
1859*cdf0e10cSrcweir 	return success;
1860*cdf0e10cSrcweir }
1861*cdf0e10cSrcweir 
1862*cdf0e10cSrcweir //***************************************************************************
1863*cdf0e10cSrcweir 
1864*cdf0e10cSrcweir BOOL FindDumpFile()
1865*cdf0e10cSrcweir {
1866*cdf0e10cSrcweir 	TCHAR	szFileName[MAX_PATH];
1867*cdf0e10cSrcweir 
1868*cdf0e10cSrcweir 	if ( GetCrashDataPath( szFileName ) )
1869*cdf0e10cSrcweir 	{
1870*cdf0e10cSrcweir 		_tcscat( szFileName, _T("\\crashdat.dmp") );
1871*cdf0e10cSrcweir 
1872*cdf0e10cSrcweir 		HANDLE	hFile =  CreateFile(
1873*cdf0e10cSrcweir 			szFileName,
1874*cdf0e10cSrcweir 			GENERIC_READ,
1875*cdf0e10cSrcweir 			0, NULL,
1876*cdf0e10cSrcweir 			OPEN_EXISTING,
1877*cdf0e10cSrcweir 			FILE_ATTRIBUTE_NORMAL, NULL );
1878*cdf0e10cSrcweir 
1879*cdf0e10cSrcweir 		if ( hFile )
1880*cdf0e10cSrcweir 		{
1881*cdf0e10cSrcweir 			CloseHandle( hFile );
1882*cdf0e10cSrcweir 
1883*cdf0e10cSrcweir 			WideCharToMultiByte( CP_ACP, 0, szFileName, -1, g_szDumpFileNameA, MAX_PATH, NULL, NULL );
1884*cdf0e10cSrcweir 			_tcscpy( g_szDumpFileName, szFileName );
1885*cdf0e10cSrcweir 
1886*cdf0e10cSrcweir 			return TRUE;
1887*cdf0e10cSrcweir 		}
1888*cdf0e10cSrcweir 	}
1889*cdf0e10cSrcweir 
1890*cdf0e10cSrcweir 	return FALSE;
1891*cdf0e10cSrcweir }
1892*cdf0e10cSrcweir 
1893*cdf0e10cSrcweir BOOL WriteDumpFile( DWORD dwProcessId, PEXCEPTION_POINTERS pExceptionPointers, DWORD dwThreadId )
1894*cdf0e10cSrcweir {
1895*cdf0e10cSrcweir 	BOOL	fSuccess = FALSE;
1896*cdf0e10cSrcweir 	PMINIDUMP_EXCEPTION_INFORMATION	lpExceptionParam = NULL;
1897*cdf0e10cSrcweir 	MINIDUMP_EXCEPTION_INFORMATION	ExceptionParam;
1898*cdf0e10cSrcweir 
1899*cdf0e10cSrcweir 	HMODULE	hDbgHelp = LoadLibrary( _T("DBGHELP.DLL" ) );
1900*cdf0e10cSrcweir 	MiniDumpWriteDump_PROC	pMiniDumpWriteDump = NULL;
1901*cdf0e10cSrcweir 
1902*cdf0e10cSrcweir 	if ( hDbgHelp )
1903*cdf0e10cSrcweir 	{
1904*cdf0e10cSrcweir 		pMiniDumpWriteDump = (MiniDumpWriteDump_PROC)GetProcAddress( hDbgHelp, "MiniDumpWriteDump" );
1905*cdf0e10cSrcweir 
1906*cdf0e10cSrcweir 		if ( !pMiniDumpWriteDump )
1907*cdf0e10cSrcweir 		{
1908*cdf0e10cSrcweir 			FreeLibrary( hDbgHelp );
1909*cdf0e10cSrcweir 			return false;
1910*cdf0e10cSrcweir 		}
1911*cdf0e10cSrcweir 	}
1912*cdf0e10cSrcweir 
1913*cdf0e10cSrcweir 	if ( !pMiniDumpWriteDump )
1914*cdf0e10cSrcweir 		return false;
1915*cdf0e10cSrcweir 
1916*cdf0e10cSrcweir 	HANDLE	hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId );
1917*cdf0e10cSrcweir 
1918*cdf0e10cSrcweir 	if ( IsValidHandle(hProcess) )
1919*cdf0e10cSrcweir 	{
1920*cdf0e10cSrcweir 		TCHAR	szTempPath[MAX_PATH];
1921*cdf0e10cSrcweir 
1922*cdf0e10cSrcweir //		if ( GetTempPath( elementsof(szTempPath), szTempPath ) )
1923*cdf0e10cSrcweir 		if ( GetCrashDataPath( szTempPath ) )
1924*cdf0e10cSrcweir 		{
1925*cdf0e10cSrcweir 			TCHAR	szFileName[MAX_PATH];
1926*cdf0e10cSrcweir 
1927*cdf0e10cSrcweir //			if ( GetTempFileName( szTempPath, TEXT("DMP"), 0, szFileName ) )
1928*cdf0e10cSrcweir 			_tcscpy( szFileName, szTempPath );
1929*cdf0e10cSrcweir 			_tcscat( szFileName, _T("\\crashdat.dmp") );
1930*cdf0e10cSrcweir 			{
1931*cdf0e10cSrcweir 				HANDLE	hFile =  CreateFile(
1932*cdf0e10cSrcweir 					szFileName,
1933*cdf0e10cSrcweir 					GENERIC_READ | GENERIC_WRITE,
1934*cdf0e10cSrcweir 					0, NULL,
1935*cdf0e10cSrcweir //					OPEN_EXISTING,
1936*cdf0e10cSrcweir 					CREATE_ALWAYS,
1937*cdf0e10cSrcweir 					FILE_ATTRIBUTE_NORMAL, NULL );
1938*cdf0e10cSrcweir 
1939*cdf0e10cSrcweir 				if ( hFile )
1940*cdf0e10cSrcweir 				{
1941*cdf0e10cSrcweir 					if ( pExceptionPointers && dwThreadId )
1942*cdf0e10cSrcweir 					{
1943*cdf0e10cSrcweir 						ExceptionParam.ThreadId = dwThreadId;
1944*cdf0e10cSrcweir 						ExceptionParam.ExceptionPointers = pExceptionPointers;
1945*cdf0e10cSrcweir 						ExceptionParam.ClientPointers = TRUE;
1946*cdf0e10cSrcweir 
1947*cdf0e10cSrcweir 						EXCEPTION_POINTERS	aExceptionPointers;
1948*cdf0e10cSrcweir 						EXCEPTION_RECORD	aExceptionRecord;
1949*cdf0e10cSrcweir 
1950*cdf0e10cSrcweir 						ReadProcessMemory(
1951*cdf0e10cSrcweir 							hProcess,
1952*cdf0e10cSrcweir 							pExceptionPointers,
1953*cdf0e10cSrcweir 							&aExceptionPointers,
1954*cdf0e10cSrcweir 							sizeof(aExceptionPointers),
1955*cdf0e10cSrcweir 							NULL );
1956*cdf0e10cSrcweir 
1957*cdf0e10cSrcweir 
1958*cdf0e10cSrcweir 						ReadProcessMemory(
1959*cdf0e10cSrcweir 							hProcess,
1960*cdf0e10cSrcweir 							aExceptionPointers.ExceptionRecord,
1961*cdf0e10cSrcweir 							&aExceptionRecord,
1962*cdf0e10cSrcweir 							sizeof(aExceptionRecord),
1963*cdf0e10cSrcweir 							NULL );
1964*cdf0e10cSrcweir 
1965*cdf0e10cSrcweir 						g_dwExceptionCode = aExceptionRecord.ExceptionCode;
1966*cdf0e10cSrcweir 
1967*cdf0e10cSrcweir 						lpExceptionParam = &ExceptionParam;
1968*cdf0e10cSrcweir 					}
1969*cdf0e10cSrcweir 
1970*cdf0e10cSrcweir 					fSuccess = pMiniDumpWriteDump( hProcess, dwProcessId, hFile, MiniDumpNormal, lpExceptionParam, NULL, NULL );
1971*cdf0e10cSrcweir 
1972*cdf0e10cSrcweir 					CloseHandle( hFile );
1973*cdf0e10cSrcweir 
1974*cdf0e10cSrcweir 					WideCharToMultiByte( CP_ACP, 0, szFileName, -1, g_szDumpFileNameA, MAX_PATH, NULL, NULL );
1975*cdf0e10cSrcweir 					_tcscpy( g_szDumpFileName, szFileName );
1976*cdf0e10cSrcweir 				}
1977*cdf0e10cSrcweir 
1978*cdf0e10cSrcweir 				if ( !fSuccess )
1979*cdf0e10cSrcweir 					DeleteFile( szFileName );
1980*cdf0e10cSrcweir 			}
1981*cdf0e10cSrcweir 		}
1982*cdf0e10cSrcweir 
1983*cdf0e10cSrcweir 		CloseHandle( hProcess );
1984*cdf0e10cSrcweir 	}
1985*cdf0e10cSrcweir 
1986*cdf0e10cSrcweir 	FreeLibrary( hDbgHelp );
1987*cdf0e10cSrcweir 
1988*cdf0e10cSrcweir 	return fSuccess;
1989*cdf0e10cSrcweir }
1990*cdf0e10cSrcweir 
1991*cdf0e10cSrcweir //***************************************************************************
1992*cdf0e10cSrcweir 
1993*cdf0e10cSrcweir static DWORD FindProcessForImage( LPCTSTR lpImagePath )
1994*cdf0e10cSrcweir {
1995*cdf0e10cSrcweir 	DWORD	dwProcessId = 0;
1996*cdf0e10cSrcweir 	DWORD	aProcesses[1024];
1997*cdf0e10cSrcweir 	DWORD	dwSize = 0;
1998*cdf0e10cSrcweir 	TCHAR	szShortImagePath[MAX_PATH];
1999*cdf0e10cSrcweir 
2000*cdf0e10cSrcweir 	if ( GetShortPathName( lpImagePath, szShortImagePath, elementsof(szShortImagePath) ) &&
2001*cdf0e10cSrcweir 		EnumProcesses( aProcesses, sizeof(aProcesses), &dwSize ) )
2002*cdf0e10cSrcweir 	{
2003*cdf0e10cSrcweir 		unsigned nProcesses = dwSize / sizeof(aProcesses[0]);
2004*cdf0e10cSrcweir 
2005*cdf0e10cSrcweir 		for ( unsigned i = 0; !dwProcessId && i < nProcesses; i++ )
2006*cdf0e10cSrcweir 		{
2007*cdf0e10cSrcweir 			HANDLE	hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i] );
2008*cdf0e10cSrcweir 
2009*cdf0e10cSrcweir 			if ( IsValidHandle(hProcess) )
2010*cdf0e10cSrcweir 			{
2011*cdf0e10cSrcweir 				TCHAR	szModulePath[MAX_PATH+1];
2012*cdf0e10cSrcweir 
2013*cdf0e10cSrcweir 				if ( GetModuleFileNameEx( hProcess, NULL, szModulePath, MAX_PATH ) )
2014*cdf0e10cSrcweir 				{
2015*cdf0e10cSrcweir 					TCHAR	szShortModulePath[MAX_PATH];
2016*cdf0e10cSrcweir 
2017*cdf0e10cSrcweir 					if ( GetShortPathName( szModulePath, szShortModulePath, elementsof(szShortModulePath) ) )
2018*cdf0e10cSrcweir 					{
2019*cdf0e10cSrcweir 						if ( 0 == _tcsicmp( szShortModulePath, szShortImagePath ) )
2020*cdf0e10cSrcweir 							dwProcessId = aProcesses[i];
2021*cdf0e10cSrcweir 					}
2022*cdf0e10cSrcweir 				}
2023*cdf0e10cSrcweir 
2024*cdf0e10cSrcweir 				CloseHandle( hProcess );
2025*cdf0e10cSrcweir 			}
2026*cdf0e10cSrcweir 		}
2027*cdf0e10cSrcweir 	}
2028*cdf0e10cSrcweir 
2029*cdf0e10cSrcweir 	return dwProcessId;
2030*cdf0e10cSrcweir }
2031*cdf0e10cSrcweir //***************************************************************************
2032*cdf0e10cSrcweir 
2033*cdf0e10cSrcweir static bool ParseCommandArgs( LPDWORD pdwProcessId, PEXCEPTION_POINTERS* ppException, LPDWORD pdwThreadId )
2034*cdf0e10cSrcweir {
2035*cdf0e10cSrcweir 	int		argc = __argc;
2036*cdf0e10cSrcweir #ifdef __MINGW32__
2037*cdf0e10cSrcweir #ifdef _UNICODE
2038*cdf0e10cSrcweir 	TCHAR	**argv = reinterpret_cast<TCHAR **>(alloca((argc+1)*sizeof(WCHAR*)));
2039*cdf0e10cSrcweir 	int *sizes = reinterpret_cast<int *>(alloca(argc*sizeof(int)));
2040*cdf0e10cSrcweir 	int argsize=0;
2041*cdf0e10cSrcweir 	char **ptr;
2042*cdf0e10cSrcweir 	int i;
2043*cdf0e10cSrcweir 	ptr=__argv;
2044*cdf0e10cSrcweir 	for (i = 0; i < argc; ++i)
2045*cdf0e10cSrcweir 	{
2046*cdf0e10cSrcweir 		sizes[i]=MultiByteToWideChar(CP_ACP, 0, *ptr, -1, NULL, 0);
2047*cdf0e10cSrcweir 		argsize+=sizes[i]+1;
2048*cdf0e10cSrcweir 		++ptr;
2049*cdf0e10cSrcweir 	}
2050*cdf0e10cSrcweir 	++argsize;
2051*cdf0e10cSrcweir 	TCHAR	*args = reinterpret_cast<TCHAR *>(alloca(argsize*sizeof(WCHAR)));
2052*cdf0e10cSrcweir 	ptr=__argv;
2053*cdf0e10cSrcweir 	TCHAR *cptr=args;
2054*cdf0e10cSrcweir 	for (i = 0; i < argc; ++i)
2055*cdf0e10cSrcweir 	{
2056*cdf0e10cSrcweir 		argv[i]=cptr;
2057*cdf0e10cSrcweir 		MultiByteToWideChar( CP_ACP, 0, *ptr, -1, cptr, sizes[i] );
2058*cdf0e10cSrcweir 		++ptr;
2059*cdf0e10cSrcweir 		cptr+=sizes[i];
2060*cdf0e10cSrcweir 		*cptr=0;
2061*cdf0e10cSrcweir 		++cptr;
2062*cdf0e10cSrcweir 	}
2063*cdf0e10cSrcweir 	argv[i]=cptr;
2064*cdf0e10cSrcweir 	*cptr=0;
2065*cdf0e10cSrcweir #else
2066*cdf0e10cSrcweir 	TCHAR	**argv = __argv;
2067*cdf0e10cSrcweir #endif
2068*cdf0e10cSrcweir #else
2069*cdf0e10cSrcweir 	TCHAR	**argv = __targv;
2070*cdf0e10cSrcweir #endif
2071*cdf0e10cSrcweir 	bool	bSuccess = true;
2072*cdf0e10cSrcweir 
2073*cdf0e10cSrcweir 	for ( int argn = 1; bSuccess && argn < argc; argn++ )
2074*cdf0e10cSrcweir 	{
2075*cdf0e10cSrcweir 		if ( 0 == _tcsicmp( argv[argn], _T("-h") ) ||
2076*cdf0e10cSrcweir 			 0 == _tcsicmp( argv[argn], _T("/h") ) ||
2077*cdf0e10cSrcweir 			 0 == _tcsicmp( argv[argn], _T("-?") ) ||
2078*cdf0e10cSrcweir 			 0 == _tcsicmp( argv[argn], _T("/?") ) ||
2079*cdf0e10cSrcweir 			 0 == _tcsicmp( argv[argn], _T("/help") ) ||
2080*cdf0e10cSrcweir 			 0 == _tcsicmp( argv[argn], _T("-help") ) ||
2081*cdf0e10cSrcweir 			 0 == _tcsicmp( argv[argn], _T("--help") )
2082*cdf0e10cSrcweir 			 )
2083*cdf0e10cSrcweir 		{
2084*cdf0e10cSrcweir 			HINSTANCE	hInstance = GetModuleHandle(NULL);
2085*cdf0e10cSrcweir 			TCHAR	szUsage[FORMATBUFSIZE];
2086*cdf0e10cSrcweir 			TCHAR	szProcess[FORMATBUFSIZE];
2087*cdf0e10cSrcweir 			TCHAR	szProcessDescription[FORMATBUFSIZE];
2088*cdf0e10cSrcweir 			TCHAR	szHelpDescription[FORMATBUFSIZE];
2089*cdf0e10cSrcweir 
2090*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_MSG_CMDLINE_USAGE, szUsage, elementsof(szUsage) );
2091*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_MSG_PARAM_PROCESSID, szProcess, elementsof(szProcess) );
2092*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_MSG_PARAM_PROCESSID_DESCRIPTION, szProcessDescription, elementsof(szProcessDescription) );
2093*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_MSG_PARAM_HELP_DESCRIPTION, szHelpDescription, elementsof(szHelpDescription) );
2094*cdf0e10cSrcweir 
2095*cdf0e10cSrcweir 			_tprintf(
2096*cdf0e10cSrcweir 				TEXT("\n%s: crashrep %s\n\n")
2097*cdf0e10cSrcweir 				TEXT("/?, -h[elp]          %s\n\n")
2098*cdf0e10cSrcweir 				TEXT("%-20s %s\n\n"),
2099*cdf0e10cSrcweir 				szUsage, szProcess, szHelpDescription, szProcess, szProcessDescription
2100*cdf0e10cSrcweir 				);
2101*cdf0e10cSrcweir 
2102*cdf0e10cSrcweir 			return true;
2103*cdf0e10cSrcweir 		}
2104*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( argv[argn], _T("-p") ) ||
2105*cdf0e10cSrcweir 			 0 == _tcsicmp( argv[argn], _T("/p") ) )
2106*cdf0e10cSrcweir 		{
2107*cdf0e10cSrcweir 			if ( ++argn < argc )
2108*cdf0e10cSrcweir 				*pdwProcessId = _tcstoul( argv[argn], NULL, 0 );
2109*cdf0e10cSrcweir 			else
2110*cdf0e10cSrcweir 				bSuccess = false;
2111*cdf0e10cSrcweir 		}
2112*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( argv[argn], _T("-excp") ) ||
2113*cdf0e10cSrcweir 			      0 == _tcsicmp( argv[argn], _T("/excp") ) )
2114*cdf0e10cSrcweir 		{
2115*cdf0e10cSrcweir 			if ( ++argn < argc )
2116*cdf0e10cSrcweir 				*ppException = (PEXCEPTION_POINTERS)_tcstoul( argv[argn], NULL, 0 );
2117*cdf0e10cSrcweir 			else
2118*cdf0e10cSrcweir 				bSuccess = false;
2119*cdf0e10cSrcweir 		}
2120*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( argv[argn], _T("-t") ) ||
2121*cdf0e10cSrcweir 			      0 == _tcsicmp( argv[argn], _T("/t") ) )
2122*cdf0e10cSrcweir 		{
2123*cdf0e10cSrcweir 			if ( ++argn < argc )
2124*cdf0e10cSrcweir 				*pdwThreadId = _tcstoul( argv[argn], NULL, 0 );
2125*cdf0e10cSrcweir 			else
2126*cdf0e10cSrcweir 				bSuccess = false;
2127*cdf0e10cSrcweir 		}
2128*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( argv[argn], _T("-noui") ) ||
2129*cdf0e10cSrcweir 			      0 == _tcsicmp( argv[argn], _T("/noui") ) )
2130*cdf0e10cSrcweir 		{
2131*cdf0e10cSrcweir 			g_bNoUserInterface = true;
2132*cdf0e10cSrcweir 		}
2133*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( argv[argn], _T("-send") ) ||
2134*cdf0e10cSrcweir 			      0 == _tcsicmp( argv[argn], _T("/send") ) )
2135*cdf0e10cSrcweir 		{
2136*cdf0e10cSrcweir 			g_bSendReport = true;
2137*cdf0e10cSrcweir 		}
2138*cdf0e10cSrcweir 		else if ( 0 == _tcsicmp( argv[argn], _T("-load") ) ||
2139*cdf0e10cSrcweir 			      0 == _tcsicmp( argv[argn], _T("/load") ) )
2140*cdf0e10cSrcweir 		{
2141*cdf0e10cSrcweir 			g_bLoadReport = true;
2142*cdf0e10cSrcweir 		}
2143*cdf0e10cSrcweir 		else // treat parameter as image path
2144*cdf0e10cSrcweir 		{
2145*cdf0e10cSrcweir 			TCHAR	szImagePath[MAX_PATH];
2146*cdf0e10cSrcweir 			LPTSTR	lpImageName;
2147*cdf0e10cSrcweir 
2148*cdf0e10cSrcweir 			if ( GetFullPathName( argv[argn], MAX_PATH, szImagePath, &lpImageName ) )
2149*cdf0e10cSrcweir 			{
2150*cdf0e10cSrcweir 				DWORD	dwProcessId = FindProcessForImage( szImagePath );
2151*cdf0e10cSrcweir 
2152*cdf0e10cSrcweir 				if ( dwProcessId )
2153*cdf0e10cSrcweir 					*pdwProcessId = dwProcessId;
2154*cdf0e10cSrcweir 				else
2155*cdf0e10cSrcweir 					bSuccess = false;
2156*cdf0e10cSrcweir 			}
2157*cdf0e10cSrcweir 		}
2158*cdf0e10cSrcweir 	}
2159*cdf0e10cSrcweir 
2160*cdf0e10cSrcweir 	if ( !*pdwProcessId && !g_bLoadReport )
2161*cdf0e10cSrcweir 	{
2162*cdf0e10cSrcweir 		TCHAR	szImagePath[MAX_PATH];
2163*cdf0e10cSrcweir 		LPTSTR	lpImageName;
2164*cdf0e10cSrcweir 
2165*cdf0e10cSrcweir 		if ( GetFullPathName( TEXT("soffice.exe"), MAX_PATH, szImagePath, &lpImageName ) )
2166*cdf0e10cSrcweir 		{
2167*cdf0e10cSrcweir 			DWORD	dwProcessId = FindProcessForImage( szImagePath );
2168*cdf0e10cSrcweir 
2169*cdf0e10cSrcweir 			if ( dwProcessId )
2170*cdf0e10cSrcweir 				*pdwProcessId = dwProcessId;
2171*cdf0e10cSrcweir 			else
2172*cdf0e10cSrcweir 				bSuccess = false;
2173*cdf0e10cSrcweir 		}
2174*cdf0e10cSrcweir 	}
2175*cdf0e10cSrcweir 
2176*cdf0e10cSrcweir 	return bSuccess;
2177*cdf0e10cSrcweir }
2178*cdf0e10cSrcweir 
2179*cdf0e10cSrcweir //***************************************************************************
2180*cdf0e10cSrcweir 
2181*cdf0e10cSrcweir BOOL WriteCommentFile( LPCTSTR lpComment )
2182*cdf0e10cSrcweir {
2183*cdf0e10cSrcweir 	BOOL	fSuccess = FALSE;
2184*cdf0e10cSrcweir 	TCHAR	szTempPath[MAX_PATH];
2185*cdf0e10cSrcweir 
2186*cdf0e10cSrcweir 	if ( GetTempPath( elementsof(szTempPath), szTempPath ) )
2187*cdf0e10cSrcweir 	{
2188*cdf0e10cSrcweir 		TCHAR	szFileName[MAX_PATH];
2189*cdf0e10cSrcweir 
2190*cdf0e10cSrcweir 		if ( GetTempFileName( szTempPath, TEXT("CMT"), 0, szFileName ) )
2191*cdf0e10cSrcweir 		{
2192*cdf0e10cSrcweir 			HANDLE	hFile =  CreateFile( szFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
2193*cdf0e10cSrcweir 
2194*cdf0e10cSrcweir 			if ( hFile )
2195*cdf0e10cSrcweir 			{
2196*cdf0e10cSrcweir 				DWORD	dwBytesWritten;
2197*cdf0e10cSrcweir 
2198*cdf0e10cSrcweir 				int needed = WideCharToMultiByte( CP_UTF8, 0, lpComment, -1, NULL, 0, NULL, NULL );
2199*cdf0e10cSrcweir 				if ( needed )
2200*cdf0e10cSrcweir 				{
2201*cdf0e10cSrcweir 					char *lpCommentUTF8 = (char *)alloca( needed );
2202*cdf0e10cSrcweir 					WideCharToMultiByte( CP_UTF8, 0, lpComment, -1, lpCommentUTF8, needed, NULL, NULL );
2203*cdf0e10cSrcweir 					fSuccess = WriteFile( hFile, lpCommentUTF8, strlen(lpCommentUTF8), &dwBytesWritten, NULL );
2204*cdf0e10cSrcweir 				}
2205*cdf0e10cSrcweir 				else
2206*cdf0e10cSrcweir 					fSuccess = TRUE;
2207*cdf0e10cSrcweir 
2208*cdf0e10cSrcweir 
2209*cdf0e10cSrcweir 				CloseHandle( hFile );
2210*cdf0e10cSrcweir 
2211*cdf0e10cSrcweir 				WideCharToMultiByte( CP_ACP, 0, szFileName, -1, g_szCommentFileNameA, MAX_PATH, NULL, NULL );
2212*cdf0e10cSrcweir 			}
2213*cdf0e10cSrcweir 
2214*cdf0e10cSrcweir 			if ( !fSuccess )
2215*cdf0e10cSrcweir 				DeleteFile( szFileName );
2216*cdf0e10cSrcweir 		}
2217*cdf0e10cSrcweir 	}
2218*cdf0e10cSrcweir 
2219*cdf0e10cSrcweir 	return fSuccess;
2220*cdf0e10cSrcweir }
2221*cdf0e10cSrcweir 
2222*cdf0e10cSrcweir //***************************************************************************
2223*cdf0e10cSrcweir 
2224*cdf0e10cSrcweir static int _tsetenv( const _TCHAR *lpVar, const _TCHAR *lpValue )
2225*cdf0e10cSrcweir {
2226*cdf0e10cSrcweir 	if ( !lpValue )
2227*cdf0e10cSrcweir 		lpValue = _T("");
2228*cdf0e10cSrcweir 
2229*cdf0e10cSrcweir 	_TCHAR	*envstr = (TCHAR *)alloca( (_tcslen( lpVar ) + _tcslen( lpValue ) + 2) * sizeof(_TCHAR) );
2230*cdf0e10cSrcweir 
2231*cdf0e10cSrcweir 	_tcscpy( envstr, lpVar );
2232*cdf0e10cSrcweir 	_tcscat( envstr, _T("=") );
2233*cdf0e10cSrcweir 	_tcscat( envstr, lpValue );
2234*cdf0e10cSrcweir 
2235*cdf0e10cSrcweir 	return _tputenv( envstr );
2236*cdf0e10cSrcweir }
2237*cdf0e10cSrcweir 
2238*cdf0e10cSrcweir static bool read_line( FILE *fp, string& rLine )
2239*cdf0e10cSrcweir {
2240*cdf0e10cSrcweir 	char szBuffer[1024];
2241*cdf0e10cSrcweir 	bool bSuccess = false;
2242*cdf0e10cSrcweir 	bool bEOL = false;
2243*cdf0e10cSrcweir 	string	line;
2244*cdf0e10cSrcweir 
2245*cdf0e10cSrcweir 
2246*cdf0e10cSrcweir 	while ( !bEOL && fgets( szBuffer, sizeof(szBuffer), fp ) )
2247*cdf0e10cSrcweir 	{
2248*cdf0e10cSrcweir 		int	len = strlen(szBuffer);
2249*cdf0e10cSrcweir 
2250*cdf0e10cSrcweir 		bSuccess = true;
2251*cdf0e10cSrcweir 
2252*cdf0e10cSrcweir 		while ( len && szBuffer[len - 1] == '\n' )
2253*cdf0e10cSrcweir 		{
2254*cdf0e10cSrcweir 			szBuffer[--len] = 0;
2255*cdf0e10cSrcweir 			bEOL = true;
2256*cdf0e10cSrcweir 		}
2257*cdf0e10cSrcweir 
2258*cdf0e10cSrcweir 		line.append( szBuffer );
2259*cdf0e10cSrcweir 	}
2260*cdf0e10cSrcweir 
2261*cdf0e10cSrcweir 	rLine = line;
2262*cdf0e10cSrcweir 	return bSuccess;
2263*cdf0e10cSrcweir }
2264*cdf0e10cSrcweir 
2265*cdf0e10cSrcweir static string get_script_string( const char *pFileName, const char *pKeyName )
2266*cdf0e10cSrcweir {
2267*cdf0e10cSrcweir 	FILE	*fp = fopen( pFileName, "rt" );
2268*cdf0e10cSrcweir 	string	retValue;
2269*cdf0e10cSrcweir 
2270*cdf0e10cSrcweir 	if ( fp )
2271*cdf0e10cSrcweir 	{
2272*cdf0e10cSrcweir 		string line;
2273*cdf0e10cSrcweir 		string section;
2274*cdf0e10cSrcweir 
2275*cdf0e10cSrcweir 		while ( read_line( fp, line ) )
2276*cdf0e10cSrcweir 		{
2277*cdf0e10cSrcweir 			line = trim_string( line );
2278*cdf0e10cSrcweir 
2279*cdf0e10cSrcweir 
2280*cdf0e10cSrcweir 			string::size_type iEqualSign = line.find( '=', 0 );
2281*cdf0e10cSrcweir 
2282*cdf0e10cSrcweir 			if ( iEqualSign != string::npos )
2283*cdf0e10cSrcweir 			{
2284*cdf0e10cSrcweir 				string	keyname = line.substr( 0, iEqualSign );
2285*cdf0e10cSrcweir 				keyname = trim_string( keyname );
2286*cdf0e10cSrcweir 
2287*cdf0e10cSrcweir 				string	value = line.substr( sal::static_int_cast<string::size_type>(iEqualSign + 1) );
2288*cdf0e10cSrcweir 				value = trim_string( value );
2289*cdf0e10cSrcweir 
2290*cdf0e10cSrcweir 				if ( value.length() && '\"' == value[0] )
2291*cdf0e10cSrcweir 				{
2292*cdf0e10cSrcweir 					value.erase( 0, 1 );
2293*cdf0e10cSrcweir 
2294*cdf0e10cSrcweir 					string::size_type iQuotes = value.find( '"', 0 );
2295*cdf0e10cSrcweir 
2296*cdf0e10cSrcweir 					if ( iQuotes != string::npos )
2297*cdf0e10cSrcweir 						value.erase( iQuotes );
2298*cdf0e10cSrcweir 				}
2299*cdf0e10cSrcweir 
2300*cdf0e10cSrcweir 				if ( 0 == stricmp( keyname.c_str(), pKeyName ) )
2301*cdf0e10cSrcweir 				{
2302*cdf0e10cSrcweir 					retValue = value;
2303*cdf0e10cSrcweir 					break;
2304*cdf0e10cSrcweir 				}
2305*cdf0e10cSrcweir 			}
2306*cdf0e10cSrcweir 		}
2307*cdf0e10cSrcweir 
2308*cdf0e10cSrcweir 		fclose( fp );
2309*cdf0e10cSrcweir 	}
2310*cdf0e10cSrcweir 
2311*cdf0e10cSrcweir 	return retValue;
2312*cdf0e10cSrcweir }
2313*cdf0e10cSrcweir 
2314*cdf0e10cSrcweir static bool ReadBootstrapParams( CrashReportParams &rParams )
2315*cdf0e10cSrcweir {
2316*cdf0e10cSrcweir 	TCHAR	szBuffer[256] = TEXT("");
2317*cdf0e10cSrcweir 	TCHAR	szModuleName[MAX_PATH];
2318*cdf0e10cSrcweir 	TCHAR	szModuleVersionName[MAX_PATH];
2319*cdf0e10cSrcweir 	TCHAR	szDrive[_MAX_DRIVE];
2320*cdf0e10cSrcweir 	TCHAR	szDir[_MAX_DIR];
2321*cdf0e10cSrcweir 	TCHAR	szFName[_MAX_FNAME];
2322*cdf0e10cSrcweir 	TCHAR	szExt[_MAX_EXT];
2323*cdf0e10cSrcweir 	TCHAR	szReportServer[MAX_HOSTNAME];
2324*cdf0e10cSrcweir 	TCHAR	szReportPort[256];
2325*cdf0e10cSrcweir 	bool	bSuccess = false;
2326*cdf0e10cSrcweir 
2327*cdf0e10cSrcweir 	GetModuleFileName( NULL, szModuleName, MAX_PATH );
2328*cdf0e10cSrcweir 	_tsplitpath( szModuleName, szDrive, szDir, szFName, szExt );
2329*cdf0e10cSrcweir 	_tmakepath( szModuleName, szDrive, szDir, _T("bootstrap"), _T(".ini") );
2330*cdf0e10cSrcweir 	_tmakepath( szModuleVersionName, szDrive, szDir, _T("version"), _T(".ini") );
2331*cdf0e10cSrcweir 
2332*cdf0e10cSrcweir 	if (
2333*cdf0e10cSrcweir 		GetPrivateProfileString(
2334*cdf0e10cSrcweir 		TEXT("Bootstrap"),
2335*cdf0e10cSrcweir 		TEXT("ProductKey"),
2336*cdf0e10cSrcweir 		TEXT("OpenOffice.org"),
2337*cdf0e10cSrcweir 		szBuffer,
2338*cdf0e10cSrcweir 		elementsof(szBuffer),
2339*cdf0e10cSrcweir 		szModuleName )
2340*cdf0e10cSrcweir 		)
2341*cdf0e10cSrcweir 	{
2342*cdf0e10cSrcweir 		TCHAR	*pVersion = _tcschr( szBuffer, ' ' );
2343*cdf0e10cSrcweir 
2344*cdf0e10cSrcweir 		g_wstrProductKey = szBuffer;
2345*cdf0e10cSrcweir 
2346*cdf0e10cSrcweir 		if ( pVersion )
2347*cdf0e10cSrcweir 		{
2348*cdf0e10cSrcweir 			*pVersion = 0;
2349*cdf0e10cSrcweir 			pVersion++;
2350*cdf0e10cSrcweir 		}
2351*cdf0e10cSrcweir 		else
2352*cdf0e10cSrcweir 			pVersion = TEXT("");
2353*cdf0e10cSrcweir 
2354*cdf0e10cSrcweir 		if ( !_tgetenv( _T("PRODUCTNAME") ) )
2355*cdf0e10cSrcweir 		{
2356*cdf0e10cSrcweir 			_tsetenv( TEXT("PRODUCTNAME"), szBuffer );
2357*cdf0e10cSrcweir 		}
2358*cdf0e10cSrcweir 		if ( !_tgetenv( _T("PRODUCTVERSION") ) )
2359*cdf0e10cSrcweir 			_tsetenv( TEXT("PRODUCTVERSION"), pVersion );
2360*cdf0e10cSrcweir 	}
2361*cdf0e10cSrcweir 
2362*cdf0e10cSrcweir 	GetPrivateProfileString(
2363*cdf0e10cSrcweir 		TEXT("Version"),
2364*cdf0e10cSrcweir 		TEXT("buildid"),
2365*cdf0e10cSrcweir 		TEXT("unknown"),
2366*cdf0e10cSrcweir 		g_szBuildId, elementsof(g_szBuildId),
2367*cdf0e10cSrcweir 		szModuleVersionName );
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir 	g_strDefaultLanguage = get_script_string( "instdb.inf", "DefaultLanguage" );
2370*cdf0e10cSrcweir 
2371*cdf0e10cSrcweir 	if ( GetPrivateProfileString(
2372*cdf0e10cSrcweir 		TEXT("ErrorReport"),
2373*cdf0e10cSrcweir 		TEXT("ErrorReportPort"),
2374*cdf0e10cSrcweir 		TEXT("80"),
2375*cdf0e10cSrcweir 		szReportPort, elementsof(szReportPort),
2376*cdf0e10cSrcweir 		szModuleName
2377*cdf0e10cSrcweir 		) )
2378*cdf0e10cSrcweir 	{
2379*cdf0e10cSrcweir 		TCHAR *endptr = NULL;
2380*cdf0e10cSrcweir 
2381*cdf0e10cSrcweir 		unsigned short uReportPort = (unsigned short)_tcstoul( szReportPort, &endptr, 10 );
2382*cdf0e10cSrcweir 		if ( uReportPort )
2383*cdf0e10cSrcweir 			g_uReportPort = uReportPort;
2384*cdf0e10cSrcweir 	}
2385*cdf0e10cSrcweir 
2386*cdf0e10cSrcweir 	if ( GetPrivateProfileString(
2387*cdf0e10cSrcweir 		TEXT("ErrorReport"),
2388*cdf0e10cSrcweir 		TEXT("ErrorReportServer"),
2389*cdf0e10cSrcweir 		TEXT(""),
2390*cdf0e10cSrcweir 		szReportServer, elementsof(szReportServer),
2391*cdf0e10cSrcweir 		szModuleName
2392*cdf0e10cSrcweir 		) )
2393*cdf0e10cSrcweir 	{
2394*cdf0e10cSrcweir 		bSuccess = 0 != WideCharToMultiByte( CP_ACP, 0, szReportServer, -1, g_szReportServerA, elementsof(g_szReportServerA), NULL, NULL );
2395*cdf0e10cSrcweir 	}
2396*cdf0e10cSrcweir 
2397*cdf0e10cSrcweir 	LPCTSTR	lpEnvString;
2398*cdf0e10cSrcweir 
2399*cdf0e10cSrcweir 	if ( 0 != (lpEnvString = _tgetenv( _T("ERRORREPORT_PROXYSERVER") )) )
2400*cdf0e10cSrcweir 		rParams.sProxyServer = lpEnvString;
2401*cdf0e10cSrcweir 
2402*cdf0e10cSrcweir 	if ( 0 != (lpEnvString = _tgetenv( _T("ERRORREPORT_PROXYPORT") )) )
2403*cdf0e10cSrcweir 		rParams.sProxyPort = lpEnvString;
2404*cdf0e10cSrcweir 
2405*cdf0e10cSrcweir 	if ( 0 != (lpEnvString = _tgetenv( _T("ERRORREPORT_SENDERADDRESS") )) )
2406*cdf0e10cSrcweir 		rParams.sEmail = lpEnvString;
2407*cdf0e10cSrcweir 
2408*cdf0e10cSrcweir 	return bSuccess;
2409*cdf0e10cSrcweir }
2410*cdf0e10cSrcweir 
2411*cdf0e10cSrcweir //***************************************************************************
2412*cdf0e10cSrcweir 
2413*cdf0e10cSrcweir bool SendHTTPRequest(
2414*cdf0e10cSrcweir 				FILE *fp,
2415*cdf0e10cSrcweir 				const char *pszServer,
2416*cdf0e10cSrcweir 				unsigned short uPort = 80,
2417*cdf0e10cSrcweir 				const char *pszProxyServer = NULL,
2418*cdf0e10cSrcweir 				unsigned short uProxyPort = 8080 )
2419*cdf0e10cSrcweir {
2420*cdf0e10cSrcweir 	bool success = false;
2421*cdf0e10cSrcweir 
2422*cdf0e10cSrcweir 	struct hostent *hp;
2423*cdf0e10cSrcweir 
2424*cdf0e10cSrcweir 	if ( pszProxyServer )
2425*cdf0e10cSrcweir 		hp = gethostbyname( pszProxyServer );
2426*cdf0e10cSrcweir 	else
2427*cdf0e10cSrcweir 		hp = gethostbyname( pszServer );
2428*cdf0e10cSrcweir 
2429*cdf0e10cSrcweir 	if ( hp )
2430*cdf0e10cSrcweir 	{
2431*cdf0e10cSrcweir 		SOCKET	s = socket( AF_INET, SOCK_STREAM, 0 );
2432*cdf0e10cSrcweir 
2433*cdf0e10cSrcweir 		if ( s )
2434*cdf0e10cSrcweir 		{
2435*cdf0e10cSrcweir 			struct sockaddr_in address;
2436*cdf0e10cSrcweir 
2437*cdf0e10cSrcweir 			memcpy(&(address.sin_addr.s_addr), *(hp->h_addr_list),sizeof(struct in_addr));
2438*cdf0e10cSrcweir 			address.sin_family = AF_INET;
2439*cdf0e10cSrcweir 
2440*cdf0e10cSrcweir 			if ( pszProxyServer )
2441*cdf0e10cSrcweir 				address.sin_port = ntohs( uProxyPort );
2442*cdf0e10cSrcweir 			else
2443*cdf0e10cSrcweir 				address.sin_port = ntohs( uPort );
2444*cdf0e10cSrcweir 
2445*cdf0e10cSrcweir 			if ( 0 == connect( s, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) )
2446*cdf0e10cSrcweir 			{
2447*cdf0e10cSrcweir 				fseek( fp, 0, SEEK_END );
2448*cdf0e10cSrcweir 				size_t length = ftell( fp );
2449*cdf0e10cSrcweir 				fseek( fp, 0, SEEK_SET );
2450*cdf0e10cSrcweir 
2451*cdf0e10cSrcweir 				char buffer[2048];
2452*cdf0e10cSrcweir 
2453*cdf0e10cSrcweir 				if ( pszProxyServer )
2454*cdf0e10cSrcweir 					sprintf( buffer,
2455*cdf0e10cSrcweir 					"POST http://%s:%d/soap/servlet/rpcrouter HTTP/1.0\r\n"
2456*cdf0e10cSrcweir 						"Content-Type: text/xml; charset=\"utf-8\"\r\n"
2457*cdf0e10cSrcweir 						"Content-Length: %d\r\n"
2458*cdf0e10cSrcweir 						"SOAPAction: \"\"\r\n\r\n",
2459*cdf0e10cSrcweir 						pszServer,
2460*cdf0e10cSrcweir 						uPort,
2461*cdf0e10cSrcweir 						length
2462*cdf0e10cSrcweir 						);
2463*cdf0e10cSrcweir 				else
2464*cdf0e10cSrcweir 					sprintf( buffer,
2465*cdf0e10cSrcweir 						"POST /soap/servlet/rpcrouter HTTP/1.0\r\n"
2466*cdf0e10cSrcweir 						"Content-Type: text/xml; charset=\"utf-8\"\r\n"
2467*cdf0e10cSrcweir 						"Content-Length: %d\r\n"
2468*cdf0e10cSrcweir 						"SOAPAction: \"\"\r\n\r\n",
2469*cdf0e10cSrcweir 						length
2470*cdf0e10cSrcweir 						);
2471*cdf0e10cSrcweir 
2472*cdf0e10cSrcweir 				if ( SOCKET_ERROR != send( s, buffer, strlen(buffer), 0 ) )
2473*cdf0e10cSrcweir 				{
2474*cdf0e10cSrcweir 					size_t nBytes;
2475*cdf0e10cSrcweir 
2476*cdf0e10cSrcweir 					do
2477*cdf0e10cSrcweir 					{
2478*cdf0e10cSrcweir 						nBytes = fread( buffer, 1, sizeof(buffer), fp );
2479*cdf0e10cSrcweir 
2480*cdf0e10cSrcweir 						if ( nBytes )
2481*cdf0e10cSrcweir 							success = SOCKET_ERROR != send( s, buffer, nBytes, 0 );
2482*cdf0e10cSrcweir 					} while( nBytes && success );
2483*cdf0e10cSrcweir 
2484*cdf0e10cSrcweir 					if ( success )
2485*cdf0e10cSrcweir 					{
2486*cdf0e10cSrcweir 						memset( buffer, 0, sizeof(buffer) );
2487*cdf0e10cSrcweir 						success = SOCKET_ERROR != recv( s, buffer, sizeof(buffer), 0 );
2488*cdf0e10cSrcweir 						if ( success )
2489*cdf0e10cSrcweir 						{
2490*cdf0e10cSrcweir 							char szHTTPSignature[sizeof(buffer)] = "";
2491*cdf0e10cSrcweir 							unsigned uHTTPReturnCode = 0;
2492*cdf0e10cSrcweir 
2493*cdf0e10cSrcweir 							sscanf( buffer, "%s %d ", szHTTPSignature, &uHTTPReturnCode );
2494*cdf0e10cSrcweir 							success = uHTTPReturnCode == 200;
2495*cdf0e10cSrcweir 						}
2496*cdf0e10cSrcweir 					}
2497*cdf0e10cSrcweir 				}
2498*cdf0e10cSrcweir 
2499*cdf0e10cSrcweir 			}
2500*cdf0e10cSrcweir 
2501*cdf0e10cSrcweir 			closesocket( s );
2502*cdf0e10cSrcweir 		}
2503*cdf0e10cSrcweir 	}
2504*cdf0e10cSrcweir 
2505*cdf0e10cSrcweir 	return success;
2506*cdf0e10cSrcweir }
2507*cdf0e10cSrcweir 
2508*cdf0e10cSrcweir //***************************************************************************
2509*cdf0e10cSrcweir 
2510*cdf0e10cSrcweir static void WriteSOAPRequest( FILE *fp )
2511*cdf0e10cSrcweir {
2512*cdf0e10cSrcweir 	fprintf( fp,
2513*cdf0e10cSrcweir 		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
2514*cdf0e10cSrcweir 		"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
2515*cdf0e10cSrcweir 		"xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n"
2516*cdf0e10cSrcweir 		"xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n"
2517*cdf0e10cSrcweir 		"xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n"
2518*cdf0e10cSrcweir 		"xmlns:rds=\"urn:ReportDataService\"\n"
2519*cdf0e10cSrcweir 		"xmlns:apache=\"http://xml.apache.org/xml-soap\"\n"
2520*cdf0e10cSrcweir 		"SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
2521*cdf0e10cSrcweir 		"<SOAP-ENV:Body>\n"
2522*cdf0e10cSrcweir 		);
2523*cdf0e10cSrcweir 
2524*cdf0e10cSrcweir 	fprintf( fp, "<rds:submitReport>\n"  );
2525*cdf0e10cSrcweir 	fprintf( fp, "<body xsi:type=\"xsd:string\">This is an autogenerated crash report mail.</body>\n" );
2526*cdf0e10cSrcweir 	fprintf( fp, "<hash xsi:type=\"apache:Map\">\n" );
2527*cdf0e10cSrcweir 
2528*cdf0e10cSrcweir 	FILE	*fpin = fopen( g_szReportFileNameA, "r" );
2529*cdf0e10cSrcweir 	if ( fpin )
2530*cdf0e10cSrcweir 	{
2531*cdf0e10cSrcweir 		fprintf( fp,
2532*cdf0e10cSrcweir 			"<item>\n"
2533*cdf0e10cSrcweir 			"<key xsi:type=\"xsd:string\">reportmail.xml</key>\n"
2534*cdf0e10cSrcweir 			"<value xsi:type=\"xsd:string\"><![CDATA[" );
2535*cdf0e10cSrcweir 		fcopy( fpin, fp );
2536*cdf0e10cSrcweir 		fprintf( fp, "]]></value></item>\n" );
2537*cdf0e10cSrcweir 		fclose( fpin );
2538*cdf0e10cSrcweir 	}
2539*cdf0e10cSrcweir 
2540*cdf0e10cSrcweir 	fpin = fopen( g_szCommentFileNameA, "r" );
2541*cdf0e10cSrcweir 	if ( fpin )
2542*cdf0e10cSrcweir 	{
2543*cdf0e10cSrcweir 		fprintf( fp,
2544*cdf0e10cSrcweir 			"<item>\n"
2545*cdf0e10cSrcweir 			"<key xsi:type=\"xsd:string\">description.txt</key>\n"
2546*cdf0e10cSrcweir 			"<value xsi:type=\"xsd:string\"><![CDATA[" );
2547*cdf0e10cSrcweir 		fcopy( fpin, fp );
2548*cdf0e10cSrcweir 		fprintf( fp, "]]></value></item>\n" );
2549*cdf0e10cSrcweir 		fclose( fpin );
2550*cdf0e10cSrcweir 	};
2551*cdf0e10cSrcweir 
2552*cdf0e10cSrcweir 
2553*cdf0e10cSrcweir 	fpin = fopen( g_szDumpFileNameA, "rb" );
2554*cdf0e10cSrcweir 	if ( fpin )
2555*cdf0e10cSrcweir 	{
2556*cdf0e10cSrcweir 		FILE *fptemp = _tmpfile();
2557*cdf0e10cSrcweir 
2558*cdf0e10cSrcweir 		if ( fptemp )
2559*cdf0e10cSrcweir 		{
2560*cdf0e10cSrcweir 			if ( base64_encode( fpin, fptemp ) )
2561*cdf0e10cSrcweir 			{
2562*cdf0e10cSrcweir 				fseek( fptemp, 0, SEEK_SET );
2563*cdf0e10cSrcweir 				fprintf( fp,
2564*cdf0e10cSrcweir 					"<item>\n"
2565*cdf0e10cSrcweir 					"<key xsi:type=\"xsd:string\">user.dmp</key>\n"
2566*cdf0e10cSrcweir 					"<value xsi:type=\"xsd:string\">" );
2567*cdf0e10cSrcweir 				fcopy( fptemp, fp );
2568*cdf0e10cSrcweir 				fprintf( fp, "</value></item>\n" );
2569*cdf0e10cSrcweir 			}
2570*cdf0e10cSrcweir 			fclose( fptemp );
2571*cdf0e10cSrcweir 		}
2572*cdf0e10cSrcweir 		fclose( fpin );
2573*cdf0e10cSrcweir 	}
2574*cdf0e10cSrcweir 
2575*cdf0e10cSrcweir 	fprintf( fp,
2576*cdf0e10cSrcweir 		"</hash>\n"
2577*cdf0e10cSrcweir 		"</rds:submitReport>\n"
2578*cdf0e10cSrcweir 		"</SOAP-ENV:Body>\n"
2579*cdf0e10cSrcweir 		"</SOAP-ENV:Envelope>\n"
2580*cdf0e10cSrcweir 		);
2581*cdf0e10cSrcweir }
2582*cdf0e10cSrcweir 
2583*cdf0e10cSrcweir //***************************************************************************
2584*cdf0e10cSrcweir 
2585*cdf0e10cSrcweir struct RequestParams
2586*cdf0e10cSrcweir {
2587*cdf0e10cSrcweir 	bool	success;
2588*cdf0e10cSrcweir 	FILE	*fpin;
2589*cdf0e10cSrcweir 	const char *lpServer;
2590*cdf0e10cSrcweir 	unsigned short uPort;
2591*cdf0e10cSrcweir 	const char *lpProxyServer;
2592*cdf0e10cSrcweir 	unsigned short uProxyPort;
2593*cdf0e10cSrcweir 	HWND	hwndStatus;
2594*cdf0e10cSrcweir };
2595*cdf0e10cSrcweir 
2596*cdf0e10cSrcweir void _cdecl SendingThread( void *lpArgs )
2597*cdf0e10cSrcweir {
2598*cdf0e10cSrcweir 	RequestParams *pParams = (RequestParams *)lpArgs;
2599*cdf0e10cSrcweir 
2600*cdf0e10cSrcweir     pParams->success = SendHTTPRequest( pParams->fpin, pParams->lpServer, pParams->uPort, pParams->lpProxyServer, pParams->uProxyPort );
2601*cdf0e10cSrcweir 
2602*cdf0e10cSrcweir 	PostMessage( pParams->hwndStatus, WM_COMMAND, IDOK, 0 );
2603*cdf0e10cSrcweir }
2604*cdf0e10cSrcweir 
2605*cdf0e10cSrcweir //***************************************************************************
2606*cdf0e10cSrcweir 
2607*cdf0e10cSrcweir BOOL CALLBACK SendingStatusDialogProc(
2608*cdf0e10cSrcweir 	HWND hwndDlg,
2609*cdf0e10cSrcweir 	UINT uMsg,
2610*cdf0e10cSrcweir 	WPARAM wParam,
2611*cdf0e10cSrcweir 	LPARAM lParam
2612*cdf0e10cSrcweir 	)
2613*cdf0e10cSrcweir {
2614*cdf0e10cSrcweir 	static RequestParams *pRequest = NULL;
2615*cdf0e10cSrcweir 	static HANDLE hSendingThread = NULL;
2616*cdf0e10cSrcweir 
2617*cdf0e10cSrcweir 	switch ( uMsg )
2618*cdf0e10cSrcweir 	{
2619*cdf0e10cSrcweir 	case WM_INITDIALOG:
2620*cdf0e10cSrcweir 		{
2621*cdf0e10cSrcweir 			TCHAR	szBuffer[1024] = TEXT("");
2622*cdf0e10cSrcweir 			HINSTANCE	hInstance = (HINSTANCE)GetWindowLong( hwndDlg, GWL_HINSTANCE );
2623*cdf0e10cSrcweir 			//HWND	hwndParent = (HWND)GetWindowLong( hwndDlg, GWL_HWNDPARENT );
2624*cdf0e10cSrcweir 
2625*cdf0e10cSrcweir 			pRequest = (RequestParams *)lParam;
2626*cdf0e10cSrcweir 
2627*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_SENDING_REPORT_HEADER, szBuffer, elementsof(szBuffer) );
2628*cdf0e10cSrcweir 			SetWindowText( hwndDlg, szBuffer );
2629*cdf0e10cSrcweir 
2630*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_SENDING_REPORT_STATUS, szBuffer, elementsof(szBuffer) );
2631*cdf0e10cSrcweir 			Static_SetText( GetDlgItem(hwndDlg, IDC_SENDING_REPORT_STATUS), szBuffer );
2632*cdf0e10cSrcweir 
2633*cdf0e10cSrcweir 			LoadAndFormatString( hInstance, IDS_CANCEL_BUTTON, szBuffer, elementsof(szBuffer) );
2634*cdf0e10cSrcweir 			Button_SetText( GetDlgItem(hwndDlg, IDCANCEL), szBuffer );
2635*cdf0e10cSrcweir 
2636*cdf0e10cSrcweir 			pRequest->hwndStatus = hwndDlg;
2637*cdf0e10cSrcweir 
2638*cdf0e10cSrcweir 			hSendingThread = (HANDLE)_beginthread( SendingThread, 0, pRequest );
2639*cdf0e10cSrcweir 		}
2640*cdf0e10cSrcweir 		return TRUE;
2641*cdf0e10cSrcweir 	case WM_COMMAND:
2642*cdf0e10cSrcweir 		switch ( LOWORD(wParam) )
2643*cdf0e10cSrcweir 		{
2644*cdf0e10cSrcweir 		case IDCANCEL:
2645*cdf0e10cSrcweir 			TerminateThread( hSendingThread, 0 );
2646*cdf0e10cSrcweir 		case IDOK:
2647*cdf0e10cSrcweir 			WaitForSingleObject( hSendingThread, INFINITE );
2648*cdf0e10cSrcweir 			CloseHandle( hSendingThread );
2649*cdf0e10cSrcweir 			EndDialog( hwndDlg, wParam );
2650*cdf0e10cSrcweir 			return TRUE;
2651*cdf0e10cSrcweir 		}
2652*cdf0e10cSrcweir 		break;
2653*cdf0e10cSrcweir 	default:
2654*cdf0e10cSrcweir 		break;
2655*cdf0e10cSrcweir 	}
2656*cdf0e10cSrcweir 
2657*cdf0e10cSrcweir 	return FALSE;
2658*cdf0e10cSrcweir }
2659*cdf0e10cSrcweir 
2660*cdf0e10cSrcweir //***************************************************************************
2661*cdf0e10cSrcweir 
2662*cdf0e10cSrcweir bool SendCrashReport( HWND hwndParent, const CrashReportParams &rParams )
2663*cdf0e10cSrcweir {
2664*cdf0e10cSrcweir 	bool success = false;
2665*cdf0e10cSrcweir 	char szProxyServer[1024] = "";
2666*cdf0e10cSrcweir 	unsigned short uProxyPort = 8080;
2667*cdf0e10cSrcweir 	TCHAR *endptr = NULL;
2668*cdf0e10cSrcweir 
2669*cdf0e10cSrcweir 	switch ( rParams.uInternetConnection )
2670*cdf0e10cSrcweir 	{
2671*cdf0e10cSrcweir 	case 2:
2672*cdf0e10cSrcweir 		{
2673*cdf0e10cSrcweir 			WideCharToMultiByte(
2674*cdf0e10cSrcweir 				CP_ACP, 0, rParams.sProxyServer.c_str(), -1,
2675*cdf0e10cSrcweir 				szProxyServer, sizeof(szProxyServer), NULL, NULL );
2676*cdf0e10cSrcweir 			uProxyPort = (unsigned short)_tcstoul( rParams.sProxyPort.c_str(), &endptr, 10 );
2677*cdf0e10cSrcweir 		}
2678*cdf0e10cSrcweir 		break;
2679*cdf0e10cSrcweir 	case 0:
2680*cdf0e10cSrcweir 		{
2681*cdf0e10cSrcweir 			DWORD	dwProxyEnable = 0;
2682*cdf0e10cSrcweir 
2683*cdf0e10cSrcweir 			RegReadValue( HKEY_CURRENT_USER,
2684*cdf0e10cSrcweir 				TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
2685*cdf0e10cSrcweir 				TEXT("ProxyEnable"),
2686*cdf0e10cSrcweir 				&dwProxyEnable,
2687*cdf0e10cSrcweir 				sizeof(dwProxyEnable) );
2688*cdf0e10cSrcweir 
2689*cdf0e10cSrcweir 			if ( dwProxyEnable )
2690*cdf0e10cSrcweir 			{
2691*cdf0e10cSrcweir 				TCHAR	tszProxyServers[1024] = TEXT("");
2692*cdf0e10cSrcweir 
2693*cdf0e10cSrcweir 				if ( ERROR_SUCCESS == RegReadValue( HKEY_CURRENT_USER,
2694*cdf0e10cSrcweir 					TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),				TEXT("ProxyServer"),
2695*cdf0e10cSrcweir 					tszProxyServers,
2696*cdf0e10cSrcweir 					sizeof(tszProxyServers) ) )
2697*cdf0e10cSrcweir 				{
2698*cdf0e10cSrcweir 					TCHAR *lpHttpStart = _tcsstr( tszProxyServers, TEXT("http=") );
2699*cdf0e10cSrcweir 
2700*cdf0e10cSrcweir 					if ( lpHttpStart )
2701*cdf0e10cSrcweir 						lpHttpStart += 5;
2702*cdf0e10cSrcweir 					else
2703*cdf0e10cSrcweir 						lpHttpStart = tszProxyServers;
2704*cdf0e10cSrcweir 
2705*cdf0e10cSrcweir 					TCHAR *lpHttpEnd = _tcschr( lpHttpStart, ';' );
2706*cdf0e10cSrcweir 
2707*cdf0e10cSrcweir 					if ( lpHttpEnd )
2708*cdf0e10cSrcweir 						*lpHttpEnd = 0;
2709*cdf0e10cSrcweir 
2710*cdf0e10cSrcweir 					char	szHTTPProxyServer[1024] = "";
2711*cdf0e10cSrcweir 					WideCharToMultiByte( CP_ACP, 0, lpHttpStart, -1, szHTTPProxyServer, sizeof(szHTTPProxyServer), NULL, NULL );
2712*cdf0e10cSrcweir 
2713*cdf0e10cSrcweir 					char *lpColon = strchr( szHTTPProxyServer, ':' );
2714*cdf0e10cSrcweir 
2715*cdf0e10cSrcweir 					if ( lpColon )
2716*cdf0e10cSrcweir 					{
2717*cdf0e10cSrcweir 						char *endptr = NULL;
2718*cdf0e10cSrcweir 
2719*cdf0e10cSrcweir 						*lpColon = 0;
2720*cdf0e10cSrcweir 						uProxyPort = (unsigned short)strtoul( lpColon + 1, &endptr, 10 );
2721*cdf0e10cSrcweir 					}
2722*cdf0e10cSrcweir 					else
2723*cdf0e10cSrcweir 						uProxyPort = 8080;
2724*cdf0e10cSrcweir 
2725*cdf0e10cSrcweir 					strcpy( szProxyServer, szHTTPProxyServer );
2726*cdf0e10cSrcweir 
2727*cdf0e10cSrcweir 				}
2728*cdf0e10cSrcweir 			}
2729*cdf0e10cSrcweir 		}
2730*cdf0e10cSrcweir 		break;
2731*cdf0e10cSrcweir 	default:
2732*cdf0e10cSrcweir 	case 1:
2733*cdf0e10cSrcweir 		break;
2734*cdf0e10cSrcweir 	}
2735*cdf0e10cSrcweir 
2736*cdf0e10cSrcweir 	FILE	*fptemp = _tmpfile();
2737*cdf0e10cSrcweir 	if ( fptemp )
2738*cdf0e10cSrcweir 	{
2739*cdf0e10cSrcweir 		RequestParams	request;
2740*cdf0e10cSrcweir 
2741*cdf0e10cSrcweir 		request.success = false;
2742*cdf0e10cSrcweir 		request.fpin = fptemp;
2743*cdf0e10cSrcweir 		request.lpServer = REPORT_SERVER;
2744*cdf0e10cSrcweir 		request.uPort = REPORT_PORT;
2745*cdf0e10cSrcweir 		request.lpProxyServer = szProxyServer[0] ? szProxyServer : NULL;
2746*cdf0e10cSrcweir 		request.uProxyPort = uProxyPort;
2747*cdf0e10cSrcweir 		request.hwndStatus = NULL;
2748*cdf0e10cSrcweir 
2749*cdf0e10cSrcweir 		WriteSOAPRequest( fptemp );
2750*cdf0e10cSrcweir 		fseek( fptemp, 0, SEEK_SET );
2751*cdf0e10cSrcweir 
2752*cdf0e10cSrcweir 		if ( hwndParent )
2753*cdf0e10cSrcweir 		{
2754*cdf0e10cSrcweir 			int retid = DialogBoxParam(
2755*cdf0e10cSrcweir 				GetModuleHandle(NULL),
2756*cdf0e10cSrcweir 				MAKEINTRESOURCE(IDD_SENDING_STATUS),
2757*cdf0e10cSrcweir 				hwndParent,
2758*cdf0e10cSrcweir 				SendingStatusDialogProc,
2759*cdf0e10cSrcweir 				(LPARAM)&request
2760*cdf0e10cSrcweir 				);
2761*cdf0e10cSrcweir 
2762*cdf0e10cSrcweir 			success = request.success;
2763*cdf0e10cSrcweir 
2764*cdf0e10cSrcweir 			if ( IDOK == retid )
2765*cdf0e10cSrcweir 			{
2766*cdf0e10cSrcweir 				if ( !success )
2767*cdf0e10cSrcweir 				{
2768*cdf0e10cSrcweir 					TCHAR	szMessage[1024];
2769*cdf0e10cSrcweir 
2770*cdf0e10cSrcweir 					LoadAndFormatString( GetModuleHandle(NULL), IDS_ERROR_MSG_PROXY, szMessage, elementsof(szMessage) );
2771*cdf0e10cSrcweir 
2772*cdf0e10cSrcweir 					MessageBox( hwndParent, szMessage, NULL, MB_ICONERROR | MB_OK );
2773*cdf0e10cSrcweir 				}
2774*cdf0e10cSrcweir 				else
2775*cdf0e10cSrcweir 				{
2776*cdf0e10cSrcweir 					TCHAR	szMessage[1024];
2777*cdf0e10cSrcweir 					TCHAR	szTitle[1024];
2778*cdf0e10cSrcweir 
2779*cdf0e10cSrcweir 					LoadAndFormatString( GetModuleHandle(NULL), IDS_SENDING_REPORT_STATUS_FINISHED, szMessage, elementsof(szMessage) );
2780*cdf0e10cSrcweir 					LoadAndFormatString( GetModuleHandle(NULL), IDS_SENDING_REPORT_HEADER, szTitle, elementsof(szTitle) );
2781*cdf0e10cSrcweir 
2782*cdf0e10cSrcweir 					MessageBox( hwndParent, szMessage, szTitle, MB_ICONINFORMATION | MB_OK );
2783*cdf0e10cSrcweir 				}
2784*cdf0e10cSrcweir 			}
2785*cdf0e10cSrcweir 
2786*cdf0e10cSrcweir 		}
2787*cdf0e10cSrcweir 		else
2788*cdf0e10cSrcweir 		{
2789*cdf0e10cSrcweir 			HANDLE hSendingThread = (HANDLE)_beginthread( SendingThread, 0, (void *)&request );
2790*cdf0e10cSrcweir 
2791*cdf0e10cSrcweir 			WaitForSingleObject( hSendingThread, INFINITE );
2792*cdf0e10cSrcweir 
2793*cdf0e10cSrcweir 			success = request.success;
2794*cdf0e10cSrcweir 			if ( !success )
2795*cdf0e10cSrcweir 			{
2796*cdf0e10cSrcweir 				TCHAR	szMessage[1024];
2797*cdf0e10cSrcweir 
2798*cdf0e10cSrcweir 				LoadAndFormatString( GetModuleHandle(NULL), IDS_ERROR_MSG_PROXY, szMessage, elementsof(szMessage) );
2799*cdf0e10cSrcweir 				_ftprintf( stderr, _T("ERROR: %s\n"), szMessage );
2800*cdf0e10cSrcweir 			}
2801*cdf0e10cSrcweir 			else
2802*cdf0e10cSrcweir 			{
2803*cdf0e10cSrcweir 				TCHAR	szMessage[1024];
2804*cdf0e10cSrcweir 
2805*cdf0e10cSrcweir 				LoadAndFormatString( GetModuleHandle(NULL), IDS_SENDING_REPORT_STATUS_FINISHED, szMessage, elementsof(szMessage) );
2806*cdf0e10cSrcweir 
2807*cdf0e10cSrcweir 				_ftprintf( stderr, _T("SUCCESS: %s\n"), szMessage );
2808*cdf0e10cSrcweir 			}
2809*cdf0e10cSrcweir 		}
2810*cdf0e10cSrcweir 		fclose( fptemp );
2811*cdf0e10cSrcweir 	}
2812*cdf0e10cSrcweir 	else
2813*cdf0e10cSrcweir 	{
2814*cdf0e10cSrcweir 		TCHAR	szMessage[1024];
2815*cdf0e10cSrcweir 
2816*cdf0e10cSrcweir 		LoadAndFormatString( GetModuleHandle(NULL), IDS_ERROR_MSG_DISK_FULL, szMessage, elementsof(szMessage) );
2817*cdf0e10cSrcweir 
2818*cdf0e10cSrcweir 		if ( hwndParent )
2819*cdf0e10cSrcweir 			MessageBox( hwndParent, szMessage, NULL, MB_ICONERROR | MB_OK );
2820*cdf0e10cSrcweir 		else
2821*cdf0e10cSrcweir 			_ftprintf( stderr, _T("ERROR: %s\n"), szMessage );
2822*cdf0e10cSrcweir 	}
2823*cdf0e10cSrcweir 
2824*cdf0e10cSrcweir 	return success;
2825*cdf0e10cSrcweir }
2826*cdf0e10cSrcweir 
2827*cdf0e10cSrcweir //***************************************************************************
2828*cdf0e10cSrcweir 
2829*cdf0e10cSrcweir #ifdef __MINGW32__
2830*cdf0e10cSrcweir int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR /*lpCmdLine*/, int )
2831*cdf0e10cSrcweir #else
2832*cdf0e10cSrcweir int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE, LPTSTR /*lpCmdLine*/, int )
2833*cdf0e10cSrcweir #endif
2834*cdf0e10cSrcweir {
2835*cdf0e10cSrcweir 	int exitcode = -1;
2836*cdf0e10cSrcweir 	int argc = __argc;
2837*cdf0e10cSrcweir 
2838*cdf0e10cSrcweir #ifdef __MINGW32__
2839*cdf0e10cSrcweir 	char **argv = __argv;
2840*cdf0e10cSrcweir #else
2841*cdf0e10cSrcweir #ifdef _UNICODE
2842*cdf0e10cSrcweir 	char **argv = new char *[argc + 1];
2843*cdf0e10cSrcweir 
2844*cdf0e10cSrcweir 	for ( int argn = 0; argn < argc; argn++ )
2845*cdf0e10cSrcweir 	{
2846*cdf0e10cSrcweir 		int nBytes = WideCharToMultiByte( CP_ACP, 0, __targv[argn], -1, NULL, 0, NULL, NULL );
2847*cdf0e10cSrcweir 		argv[argn] = new char[nBytes];
2848*cdf0e10cSrcweir 		WideCharToMultiByte( CP_ACP, 0, __targv[argn], -1, argv[argn], nBytes, NULL, NULL );
2849*cdf0e10cSrcweir 	}
2850*cdf0e10cSrcweir 	argv[argc] = NULL;
2851*cdf0e10cSrcweir #else
2852*cdf0e10cSrcweir 	char **argv = __targv;
2853*cdf0e10cSrcweir #endif
2854*cdf0e10cSrcweir #endif
2855*cdf0e10cSrcweir 
2856*cdf0e10cSrcweir 	osl_setCommandArgs( argc, argv );
2857*cdf0e10cSrcweir 
2858*cdf0e10cSrcweir 	PEXCEPTION_POINTERS	pExceptionPointers = NULL;
2859*cdf0e10cSrcweir 	DWORD				dwProcessId = 0;
2860*cdf0e10cSrcweir 	DWORD				dwThreadId = 0;
2861*cdf0e10cSrcweir 
2862*cdf0e10cSrcweir 	WSADATA wsaData;
2863*cdf0e10cSrcweir 	WORD    wVersionRequested;
2864*cdf0e10cSrcweir 
2865*cdf0e10cSrcweir 	wVersionRequested = MAKEWORD(1, 1);
2866*cdf0e10cSrcweir 	WSAStartup(wVersionRequested, &wsaData);
2867*cdf0e10cSrcweir 
2868*cdf0e10cSrcweir 	CrashReportParams	Params;
2869*cdf0e10cSrcweir 
2870*cdf0e10cSrcweir 	Params.ReadFromRegistry();
2871*cdf0e10cSrcweir 	Params.ReadFromEnvironment();
2872*cdf0e10cSrcweir 
2873*cdf0e10cSrcweir 	if ( ReadBootstrapParams( Params ) &&
2874*cdf0e10cSrcweir 		ParseCommandArgs( &dwProcessId, &pExceptionPointers, &dwThreadId ) )
2875*cdf0e10cSrcweir 	{
2876*cdf0e10cSrcweir 		bool	bGotDumpFile;
2877*cdf0e10cSrcweir 
2878*cdf0e10cSrcweir 		if ( g_bLoadReport )
2879*cdf0e10cSrcweir 			bGotDumpFile = FindDumpFile();
2880*cdf0e10cSrcweir 		else
2881*cdf0e10cSrcweir 			bGotDumpFile = WriteDumpFile( dwProcessId, pExceptionPointers, dwThreadId );
2882*cdf0e10cSrcweir 
2883*cdf0e10cSrcweir 		if( bGotDumpFile )
2884*cdf0e10cSrcweir 		{
2885*cdf0e10cSrcweir 			hash_map< string, string > aLibraries;
2886*cdf0e10cSrcweir 
2887*cdf0e10cSrcweir 			if ( g_bLoadReport )
2888*cdf0e10cSrcweir 			{
2889*cdf0e10cSrcweir 				g_fpStackFile = _open_reportfile( _T(".stk"), _T("rb") );
2890*cdf0e10cSrcweir 				g_fpChecksumFile = _open_reportfile( _T(".chk"), _T("rb") );
2891*cdf0e10cSrcweir 			}
2892*cdf0e10cSrcweir 			else
2893*cdf0e10cSrcweir 			{
2894*cdf0e10cSrcweir 				if ( g_bSendReport )
2895*cdf0e10cSrcweir 				{
2896*cdf0e10cSrcweir 					g_fpStackFile = _tmpfile();
2897*cdf0e10cSrcweir 					g_fpChecksumFile = _tmpfile();
2898*cdf0e10cSrcweir 				}
2899*cdf0e10cSrcweir 				else
2900*cdf0e10cSrcweir 				{
2901*cdf0e10cSrcweir 					g_fpStackFile = _open_reportfile( _T(".stk"), _T("w+b") );
2902*cdf0e10cSrcweir 					g_fpChecksumFile = _open_reportfile( _T(".chk"), _T("w+b") );
2903*cdf0e10cSrcweir 
2904*cdf0e10cSrcweir 					FILE	*fpUnsent = _open_reportfile( _T(".lck"), _T("w+b") );
2905*cdf0e10cSrcweir 					if ( fpUnsent )
2906*cdf0e10cSrcweir 					{
2907*cdf0e10cSrcweir 						fprintf( fpUnsent, "Unsent\r\n" );
2908*cdf0e10cSrcweir 						fclose( fpUnsent );
2909*cdf0e10cSrcweir 					}
2910*cdf0e10cSrcweir 				}
2911*cdf0e10cSrcweir 
2912*cdf0e10cSrcweir 				WriteStackFile( g_fpStackFile, aLibraries, dwProcessId, pExceptionPointers );
2913*cdf0e10cSrcweir 				WriteChecksumFile( g_fpChecksumFile, aLibraries );
2914*cdf0e10cSrcweir 				WriteReportFile( &Params );
2915*cdf0e10cSrcweir 
2916*cdf0e10cSrcweir 				FILE	*fpPreview = _open_reportfile( _T(".prv"), _T("w+b") );
2917*cdf0e10cSrcweir 
2918*cdf0e10cSrcweir 				if ( fpPreview )
2919*cdf0e10cSrcweir 				{
2920*cdf0e10cSrcweir 					FILE	 *fp = fopen( g_szReportFileNameA, "rb" );
2921*cdf0e10cSrcweir 					if ( fp )
2922*cdf0e10cSrcweir 					{
2923*cdf0e10cSrcweir 						fcopy( fp, fpPreview );
2924*cdf0e10cSrcweir 						fclose( fp );
2925*cdf0e10cSrcweir 					}
2926*cdf0e10cSrcweir 					fclose( fpPreview );
2927*cdf0e10cSrcweir 				}
2928*cdf0e10cSrcweir 			}
2929*cdf0e10cSrcweir 
2930*cdf0e10cSrcweir 			if ( g_bSendReport )
2931*cdf0e10cSrcweir 			{
2932*cdf0e10cSrcweir 				InitCommonControls();
2933*cdf0e10cSrcweir 
2934*cdf0e10cSrcweir 				// Actually this should never be true anymore
2935*cdf0e10cSrcweir 				if ( !g_bNoUserInterface && InitRichEdit() )
2936*cdf0e10cSrcweir 				{
2937*cdf0e10cSrcweir 
2938*cdf0e10cSrcweir 					INT_PTR result = DialogBoxParam( hInstance, MAKEINTRESOURCE(IDD_DIALOG_FRAME), NULL, DialogProc, (LPARAM)&Params );
2939*cdf0e10cSrcweir 
2940*cdf0e10cSrcweir 					if ( result > 0 )
2941*cdf0e10cSrcweir 					{
2942*cdf0e10cSrcweir 						exitcode = 0;
2943*cdf0e10cSrcweir 					}
2944*cdf0e10cSrcweir 					DeinitRichEdit();
2945*cdf0e10cSrcweir 				}
2946*cdf0e10cSrcweir 				else
2947*cdf0e10cSrcweir 				{
2948*cdf0e10cSrcweir 					WriteCommentFile( Params.sComment.c_str() );
2949*cdf0e10cSrcweir 					WriteReportFile( &Params );
2950*cdf0e10cSrcweir 					if ( SendCrashReport( NULL, Params ) )
2951*cdf0e10cSrcweir 						exitcode = 0;
2952*cdf0e10cSrcweir 				}
2953*cdf0e10cSrcweir 
2954*cdf0e10cSrcweir 
2955*cdf0e10cSrcweir 				if ( g_szReportFileNameA[0] )
2956*cdf0e10cSrcweir 					DeleteFileA( g_szReportFileNameA );
2957*cdf0e10cSrcweir 
2958*cdf0e10cSrcweir 				if ( g_szCommentFileNameA[0] )
2959*cdf0e10cSrcweir 					DeleteFileA( g_szCommentFileNameA );
2960*cdf0e10cSrcweir 			}
2961*cdf0e10cSrcweir 			else
2962*cdf0e10cSrcweir 			{
2963*cdf0e10cSrcweir 				if ( g_szReportFileNameA[0] )
2964*cdf0e10cSrcweir 					DeleteFileA( g_szReportFileNameA );
2965*cdf0e10cSrcweir 				exitcode = 0;
2966*cdf0e10cSrcweir 			}
2967*cdf0e10cSrcweir 
2968*cdf0e10cSrcweir 			if ( g_szDumpFileNameA[0] && g_bSendReport )
2969*cdf0e10cSrcweir 					DeleteFileA( g_szDumpFileNameA );
2970*cdf0e10cSrcweir 
2971*cdf0e10cSrcweir 			if ( g_fpStackFile )
2972*cdf0e10cSrcweir 				fclose( g_fpStackFile );
2973*cdf0e10cSrcweir 
2974*cdf0e10cSrcweir 			if ( g_fpChecksumFile )
2975*cdf0e10cSrcweir 				fclose( g_fpChecksumFile );
2976*cdf0e10cSrcweir 		}
2977*cdf0e10cSrcweir 	}
2978*cdf0e10cSrcweir 
2979*cdf0e10cSrcweir 
2980*cdf0e10cSrcweir 	return exitcode;
2981*cdf0e10cSrcweir }
2982*cdf0e10cSrcweir 
2983