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