xref: /trunk/main/crashrep/source/win32/soreport.cpp (revision ad94bf9d2249ac332a7605ba62964ae3eb51a1f2) !
1e7917716SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
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
10cdf0e10cSrcweir  *
11e7917716SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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)
49cdf0e10cSrcweir #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 
97cdf0e10cSrcweir wstring g_wstrProductKey;
98cdf0e10cSrcweir 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         {
159cdf0e10cSrcweir             HANDLE  hFile =  CreateFile(
160cdf0e10cSrcweir                 szFileName,
161cdf0e10cSrcweir                 GENERIC_READ | GENERIC_WRITE,
162cdf0e10cSrcweir                 0, NULL,
163cdf0e10cSrcweir                 OPEN_EXISTING,
164cdf0e10cSrcweir                 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;
211cdf0e10cSrcweir     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 
301cdf0e10cSrcweir     if ( ERROR_SUCCESS == RegReadValue(
302cdf0e10cSrcweir         HKEY_CURRENT_USER,
303*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
304cdf0e10cSrcweir         TEXT("HTTPProxyServer"),
305cdf0e10cSrcweir         szBuffer,
306cdf0e10cSrcweir         sizeof(szBuffer) ) )
307cdf0e10cSrcweir         sProxyServer = szBuffer;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     DWORD   dwProxyPort;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     if ( ERROR_SUCCESS == RegReadValue(
312cdf0e10cSrcweir         HKEY_CURRENT_USER,
313*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
314cdf0e10cSrcweir         TEXT("HTTPProxyPort"),
315cdf0e10cSrcweir         &dwProxyPort,
316cdf0e10cSrcweir         sizeof(dwProxyPort) ) )
317cdf0e10cSrcweir     {
318cdf0e10cSrcweir         _stprintf( szBuffer, TEXT("%d"), dwProxyPort );
319cdf0e10cSrcweir         sProxyPort = szBuffer;
320cdf0e10cSrcweir     }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir     if ( ERROR_SUCCESS == RegReadValue(
323cdf0e10cSrcweir         HKEY_CURRENT_USER,
324*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
325cdf0e10cSrcweir         TEXT("ReturnAddress"),
326cdf0e10cSrcweir         szBuffer,
327cdf0e10cSrcweir         sizeof(szBuffer) ) )
328cdf0e10cSrcweir         sEmail = szBuffer;
329cdf0e10cSrcweir 
330cdf0e10cSrcweir     RegReadValue(
331cdf0e10cSrcweir         HKEY_CURRENT_USER,
332*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
333cdf0e10cSrcweir         TEXT("AllowContact"),
334cdf0e10cSrcweir         &fAllowContact,
335cdf0e10cSrcweir         sizeof(fAllowContact) );
336cdf0e10cSrcweir 
337cdf0e10cSrcweir     RegReadValue(
338cdf0e10cSrcweir         HKEY_CURRENT_USER,
339*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
340cdf0e10cSrcweir         TEXT("HTTPConnection"),
341cdf0e10cSrcweir         &uInternetConnection,
342cdf0e10cSrcweir         sizeof(uInternetConnection) );
343cdf0e10cSrcweir }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir //***************************************************************************
346cdf0e10cSrcweir 
WriteToRegistry()347cdf0e10cSrcweir void CrashReportParams::WriteToRegistry()
348cdf0e10cSrcweir {
349cdf0e10cSrcweir     RegWriteValue(
350cdf0e10cSrcweir         HKEY_CURRENT_USER,
351*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
352cdf0e10cSrcweir         TEXT("HTTPProxyServer"), REG_SZ,
353cdf0e10cSrcweir         sProxyServer.c_str(),
354cdf0e10cSrcweir         sizeof(TCHAR) * (sProxyServer.length() + 1) );
355cdf0e10cSrcweir 
356cdf0e10cSrcweir     LPTSTR endptr = NULL;
357cdf0e10cSrcweir     DWORD dwProxyPort = _tcstoul( sProxyPort.c_str(), &endptr, 10 );
358cdf0e10cSrcweir 
359cdf0e10cSrcweir     RegWriteValue(
360cdf0e10cSrcweir         HKEY_CURRENT_USER,
361*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
362cdf0e10cSrcweir         TEXT("HTTPProxyPort"), REG_DWORD,
363cdf0e10cSrcweir         &dwProxyPort,
364cdf0e10cSrcweir         sizeof(DWORD) );
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     RegWriteValue(
367cdf0e10cSrcweir         HKEY_CURRENT_USER,
368*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
369cdf0e10cSrcweir         TEXT("AllowContact"), REG_DWORD,
370cdf0e10cSrcweir         &fAllowContact,
371cdf0e10cSrcweir         sizeof(DWORD) );
372cdf0e10cSrcweir 
373cdf0e10cSrcweir 
374cdf0e10cSrcweir     RegWriteValue(
375cdf0e10cSrcweir         HKEY_CURRENT_USER,
376*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
377cdf0e10cSrcweir         TEXT("HTTPConnection"), REG_DWORD,
378cdf0e10cSrcweir         &uInternetConnection,
379cdf0e10cSrcweir         sizeof(DWORD) );
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     RegWriteValue(
382cdf0e10cSrcweir         HKEY_CURRENT_USER,
383*ad94bf9dSmseidel         TEXT("SOFTWARE\\OpenOffice\\CrashReport"),
384cdf0e10cSrcweir         TEXT("ReturnAddress"), REG_SZ,
385cdf0e10cSrcweir         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 
448cdf0e10cSrcweir                 DWORD   dwCharacters = MultiByteToWideChar( CP_UTF8, 0, aUTF8Buffer, nBytesRead, aBuffer, elementsof(aBuffer) - 1 );
449cdf0e10cSrcweir                 aBuffer[dwCharacters] = 0;
450cdf0e10cSrcweir                 sComment += aBuffer;
451cdf0e10cSrcweir             }
452cdf0e10cSrcweir 
453cdf0e10cSrcweir             fclose( fp );
454cdf0e10cSrcweir         }
455cdf0e10cSrcweir     }
456cdf0e10cSrcweir }
457cdf0e10cSrcweir 
458cdf0e10cSrcweir //***************************************************************************
459cdf0e10cSrcweir 
460cdf0e10cSrcweir typedef BOOL (WINAPI *MiniDumpWriteDump_PROC)(
461cdf0e10cSrcweir     IN HANDLE hProcess,
462cdf0e10cSrcweir     IN DWORD ProcessId,
463cdf0e10cSrcweir     IN HANDLE hFile,
464cdf0e10cSrcweir     IN MINIDUMP_TYPE DumpType,
465cdf0e10cSrcweir     IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
466cdf0e10cSrcweir     IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
467cdf0e10cSrcweir     IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
468cdf0e10cSrcweir     );
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;
489cdf0e10cSrcweir 
490cdf0e10cSrcweir     while ( temp.length() && temp[0] == ' ' || temp[0] == '\t' )
491cdf0e10cSrcweir         temp.erase( 0, 1 );
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     string::size_type   len = temp.length();
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     while ( len && temp[len-1] == ' ' || temp[len-1] == '\t' )
496cdf0e10cSrcweir     {
497cdf0e10cSrcweir         temp.erase( len - 1, 1 );
498cdf0e10cSrcweir         len = temp.length();
499cdf0e10cSrcweir     }
500cdf0e10cSrcweir 
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;
566cdf0e10cSrcweir     string::size_type pos = 0;
567cdf0e10cSrcweir 
56807a3d7f1SPedro Giffuni     // First replace all occurrences of '&' because it may occur in further
569*ad94bf9dSmseidel     // encoded characters too
570cdf0e10cSrcweir 
571cdf0e10cSrcweir     for( pos = 0; (pos = temp.find( '&', pos )) != string::npos; pos += 4 )
572cdf0e10cSrcweir         temp.replace( pos, 1, "&amp;" );
573cdf0e10cSrcweir 
574cdf0e10cSrcweir     for( pos = 0; (pos = temp.find( '<', pos )) != string::npos; pos += 4 )
575cdf0e10cSrcweir         temp.replace( pos, 1, "&lt;" );
576cdf0e10cSrcweir 
577cdf0e10cSrcweir     for( pos = 0; (pos = temp.find( '>', pos )) != string::npos; pos += 4 )
578cdf0e10cSrcweir         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;
629cdf0e10cSrcweir     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;
644cdf0e10cSrcweir     size_t pos = aName.rfind( '\\' );
645cdf0e10cSrcweir 
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             {
669cdf0e10cSrcweir                 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 );
679cdf0e10cSrcweir 
680cdf0e10cSrcweir                 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 
699cdf0e10cSrcweir                     "<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(
827cdf0e10cSrcweir     HWND hwnd, // handle to child window
828cdf0e10cSrcweir     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 /*
840cdf0e10cSrcweir BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
841cdf0e10cSrcweir {
842cdf0e10cSrcweir     HFONT aFont = *((HFONT*) lParam);
843cdf0e10cSrcweir     HDC hDC = GetDC( hwndChild );
844cdf0e10cSrcweir     SelectObject( hDC, aFont );
845cdf0e10cSrcweir     ReleaseDC( hwndChild, hDC );
846cdf0e10cSrcweir     return TRUE;
847cdf0e10cSrcweir }
848cdf0e10cSrcweir 
849cdf0e10cSrcweir void ApplySystemFont( HWND hwndDlg )
850cdf0e10cSrcweir {
851cdf0e10cSrcweir     NONCLIENTMETRICSA aNonClientMetrics;
852cdf0e10cSrcweir     aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
853cdf0e10cSrcweir     if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
854cdf0e10cSrcweir     {
855cdf0e10cSrcweir         HFONT aSysFont = CreateFontIndirectA( &aNonClientMetrics.lfMessageFont );
856cdf0e10cSrcweir         EnumChildWindows(hwndDlg, EnumChildProc, (LPARAM) &aSysFont);
857cdf0e10cSrcweir     }
858cdf0e10cSrcweir }
859cdf0e10cSrcweir */
860cdf0e10cSrcweir 
PreviewDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)861cdf0e10cSrcweir BOOL CALLBACK PreviewDialogProc(
862cdf0e10cSrcweir     HWND hwndDlg,
863cdf0e10cSrcweir     UINT uMsg,
864cdf0e10cSrcweir     WPARAM wParam,
865cdf0e10cSrcweir     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 );
897cdf0e10cSrcweir 
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 
1004cdf0e10cSrcweir     DialogBoxParam(
1005cdf0e10cSrcweir         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)1031cdf0e10cSrcweir BOOL CALLBACK OptionsDialogProc(
1032cdf0e10cSrcweir     HWND hwndDlg,
1033cdf0e10cSrcweir     UINT uMsg,
1034cdf0e10cSrcweir     WPARAM wParam,
1035cdf0e10cSrcweir     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 
1082cdf0e10cSrcweir             SendMessage(
1083cdf0e10cSrcweir                 GetDlgItem(hwndDlg, IDC_PROXY_DESCRIPTION),
1084cdf0e10cSrcweir                 EM_SETBKGNDCOLOR,
1085cdf0e10cSrcweir                 (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 
1137cdf0e10cSrcweir     if ( IDOK == DialogBoxParam(
1138cdf0e10cSrcweir         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 {
1151cdf0e10cSrcweir     EnableWindow(
1152cdf0e10cSrcweir         GetDlgItem(hwndDlg, IDC_EDIT_EMAIL),
1153cdf0e10cSrcweir         Button_GetCheck(GetDlgItem(hwndDlg, IDC_ALLOW_CONTACT)) & BST_CHECKED ? TRUE : FALSE );
1154cdf0e10cSrcweir     EnableWindow(
1155cdf0e10cSrcweir         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)1161cdf0e10cSrcweir BOOL CALLBACK ReportDialogProc(
1162cdf0e10cSrcweir     HWND hwndDlg,
1163cdf0e10cSrcweir     UINT uMsg,
1164cdf0e10cSrcweir     WPARAM wParam,
1165cdf0e10cSrcweir     LPARAM
1166cdf0e10cSrcweir     )
1167cdf0e10cSrcweir {
1168cdf0e10cSrcweir     switch ( uMsg )
1169cdf0e10cSrcweir     {
1170cdf0e10cSrcweir     case WM_INITDIALOG:
1171cdf0e10cSrcweir         {
1172cdf0e10cSrcweir             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 
1238cdf0e10cSrcweir             /*
1239cdf0e10cSrcweir             SetWindowLong( GetDlgItem(GetParent(hwndDlg),IDFINISH), GWL_STYLE,
1240cdf0e10cSrcweir                 GetWindowLong( GetDlgItem(GetParent(hwndDlg),IDFINISH), GWL_STYLE) | BS_DEFPUSHBUTTON );
1241cdf0e10cSrcweir             SetWindowLong( GetDlgItem(GetParent(hwndDlg),IDBACK), GWL_STYLE,
1242cdf0e10cSrcweir                 GetWindowLong( GetDlgItem(GetParent(hwndDlg),IDBACK), GWL_STYLE) &~ BS_DEFPUSHBUTTON );
1243cdf0e10cSrcweir                 */
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 
1306cdf0e10cSrcweir             SendMessage(
1307cdf0e10cSrcweir                 hwndRichEdit,
1308cdf0e10cSrcweir                 EM_SETBKGNDCOLOR,
1309cdf0e10cSrcweir                 (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 );
1326cdf0e10cSrcweir 
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;
1354cdf0e10cSrcweir 
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     }
1378cdf0e10cSrcweir 
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 );
1396cdf0e10cSrcweir             hwndPages[0] = CreateDialog(
1397cdf0e10cSrcweir                 hInstance,
1398cdf0e10cSrcweir                 MAKEINTRESOURCE(IDD_WELCOME_PAGE),
1399cdf0e10cSrcweir                 hwndDlg,
1400cdf0e10cSrcweir                 WelcomeDialogProc );
1401cdf0e10cSrcweir 
1402cdf0e10cSrcweir             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 
1414cdf0e10cSrcweir             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 );
1481cdf0e10cSrcweir                     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 {
1568cdf0e10cSrcweir     const int OFFSET_PE_OFFSET                  = 0x3c;
1569cdf0e10cSrcweir     const int OFFSET_COFF_TIMEDATESTAMP         = 4;
1570cdf0e10cSrcweir     const int PE_SIGNATURE_SIZE                 = 4;
1571cdf0e10cSrcweir     const int COFFHEADER_SIZE                   = 20;
1572cdf0e10cSrcweir     const int OFFSET_PE_OPTIONALHEADER_CHECKSUM = 64;
1573cdf0e10cSrcweir 
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)1610cdf0e10cSrcweir static sal_uInt32 calc_md5_checksum( const char *filename, sal_uInt8 *pChecksum, sal_uInt32 nChecksumLen )
1611cdf0e10cSrcweir {
1612cdf0e10cSrcweir     const int MINIMAL_FILESIZE = 512;
1613cdf0e10cSrcweir 
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 );
1628cdf0e10cSrcweir 
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 (
1637cdf0e10cSrcweir                     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             {
1674cdf0e10cSrcweir                 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 
1711cdf0e10cSrcweir             ReadProcessMemory(
1712cdf0e10cSrcweir                 hProcess,
1713cdf0e10cSrcweir                 pExceptionPointers,
1714cdf0e10cSrcweir                 &aExceptionPointers,
1715cdf0e10cSrcweir                 sizeof(aExceptionPointers),
1716cdf0e10cSrcweir                 NULL );
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir             ReadProcessMemory(
1719cdf0e10cSrcweir                 hProcess,
1720cdf0e10cSrcweir                 aExceptionPointers.ContextRecord,
1721cdf0e10cSrcweir                 &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 
1744cdf0e10cSrcweir                 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,
1801cdf0e10cSrcweir                             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 
1831cdf0e10cSrcweir         for ( iter = rLibraries.begin();
1832cdf0e10cSrcweir             iter != rLibraries.end();
1833cdf0e10cSrcweir             iter++ )
1834cdf0e10cSrcweir         {
1835cdf0e10cSrcweir             sal_uInt8 checksum[RTL_DIGEST_LENGTH_MD5];
1836cdf0e10cSrcweir             sal_uInt32 nBytesProcessed = calc_md5_checksum(
1837cdf0e10cSrcweir                 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++] ) );
1844cdf0e10cSrcweir                 fprintf( fchksum, "\" bytes=\"%d\" file=\"%s\"/>\n",
1845cdf0e10cSrcweir                     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 
1868cdf0e10cSrcweir         HANDLE  hFile = CreateFile(
1869cdf0e10cSrcweir             szFileName,
1870cdf0e10cSrcweir             GENERIC_READ,
1871cdf0e10cSrcweir             0, NULL,
1872cdf0e10cSrcweir             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" );
1901cdf0e10cSrcweir 
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             {
1927cdf0e10cSrcweir                 HANDLE  hFile = CreateFile(
1928cdf0e10cSrcweir                     szFileName,
1929cdf0e10cSrcweir                     GENERIC_READ | GENERIC_WRITE,
1930cdf0e10cSrcweir                     0, NULL,
1931cdf0e10cSrcweir //                  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 
1946cdf0e10cSrcweir                         ReadProcessMemory(
1947cdf0e10cSrcweir                             hProcess,
1948cdf0e10cSrcweir                             pExceptionPointers,
1949cdf0e10cSrcweir                             &aExceptionPointers,
1950cdf0e10cSrcweir                             sizeof(aExceptionPointers),
1951cdf0e10cSrcweir                             NULL );
1952cdf0e10cSrcweir 
1953cdf0e10cSrcweir 
1954cdf0e10cSrcweir                         ReadProcessMemory(
1955cdf0e10cSrcweir                             hProcess,
1956cdf0e10cSrcweir                             aExceptionPointers.ExceptionRecord,
1957cdf0e10cSrcweir                             &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 
2091cdf0e10cSrcweir             _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") ) ||
2109cdf0e10cSrcweir                   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         }
2116cdf0e10cSrcweir         else if ( 0 == _tcsicmp( argv[argn], _T("-t") ) ||
2117cdf0e10cSrcweir                   0 == _tcsicmp( argv[argn], _T("/t") ) )
2118cdf0e10cSrcweir         {
2119cdf0e10cSrcweir             if ( ++argn < argc )
2120cdf0e10cSrcweir                 *pdwThreadId = _tcstoul( argv[argn], NULL, 0 );
2121cdf0e10cSrcweir             else
2122cdf0e10cSrcweir                 bSuccess = false;
2123cdf0e10cSrcweir         }
2124cdf0e10cSrcweir         else if ( 0 == _tcsicmp( argv[argn], _T("-noui") ) ||
2125cdf0e10cSrcweir                   0 == _tcsicmp( argv[argn], _T("/noui") ) )
2126cdf0e10cSrcweir         {
2127cdf0e10cSrcweir             g_bNoUserInterface = true;
2128cdf0e10cSrcweir         }
2129cdf0e10cSrcweir         else if ( 0 == _tcsicmp( argv[argn], _T("-send") ) ||
2130cdf0e10cSrcweir                   0 == _tcsicmp( argv[argn], _T("/send") ) )
2131cdf0e10cSrcweir         {
2132cdf0e10cSrcweir             g_bSendReport = true;
2133cdf0e10cSrcweir         }
2134cdf0e10cSrcweir         else if ( 0 == _tcsicmp( argv[argn], _T("-load") ) ||
2135cdf0e10cSrcweir                   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         {
2188cdf0e10cSrcweir             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 
2241cdf0e10cSrcweir 
2242cdf0e10cSrcweir     while ( !bEOL && fgets( szBuffer, sizeof(szBuffer), fp ) )
2243cdf0e10cSrcweir     {
2244cdf0e10cSrcweir         int len = strlen(szBuffer);
2245cdf0e10cSrcweir 
2246cdf0e10cSrcweir         bSuccess = true;
2247cdf0e10cSrcweir 
2248cdf0e10cSrcweir         while ( len && szBuffer[len - 1] == '\n' )
2249cdf0e10cSrcweir         {
2250cdf0e10cSrcweir             szBuffer[--len] = 0;
2251cdf0e10cSrcweir             bEOL = true;
2252cdf0e10cSrcweir         }
2253cdf0e10cSrcweir 
2254cdf0e10cSrcweir         line.append( szBuffer );
2255cdf0e10cSrcweir     }
2256cdf0e10cSrcweir 
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;
2265cdf0e10cSrcweir 
2266cdf0e10cSrcweir     if ( fp )
2267cdf0e10cSrcweir     {
2268cdf0e10cSrcweir         string line;
2269cdf0e10cSrcweir         string section;
2270cdf0e10cSrcweir 
2271cdf0e10cSrcweir         while ( read_line( fp, line ) )
2272cdf0e10cSrcweir         {
2273cdf0e10cSrcweir             line = trim_string( line );
2274cdf0e10cSrcweir 
2275cdf0e10cSrcweir 
2276cdf0e10cSrcweir             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 );
2282cdf0e10cSrcweir 
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                 }
2295cdf0e10cSrcweir 
2296cdf0e10cSrcweir                 if ( 0 == stricmp( keyname.c_str(), pKeyName ) )
2297cdf0e10cSrcweir                 {
2298cdf0e10cSrcweir                     retValue = value;
2299cdf0e10cSrcweir                     break;
2300cdf0e10cSrcweir                 }
2301cdf0e10cSrcweir             }
2302cdf0e10cSrcweir         }
2303cdf0e10cSrcweir 
2304cdf0e10cSrcweir         fclose( fp );
2305cdf0e10cSrcweir     }
2306cdf0e10cSrcweir 
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 
2328cdf0e10cSrcweir     if (
2329cdf0e10cSrcweir         GetPrivateProfileString(
2330cdf0e10cSrcweir         TEXT("Bootstrap"),
2331cdf0e10cSrcweir         TEXT("ProductKey"),
2332*ad94bf9dSmseidel         TEXT("OpenOffice"),
2333cdf0e10cSrcweir         szBuffer,
2334cdf0e10cSrcweir         elementsof(szBuffer),
2335cdf0e10cSrcweir         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 
2358cdf0e10cSrcweir     GetPrivateProfileString(
2359cdf0e10cSrcweir         TEXT("Version"),
2360cdf0e10cSrcweir         TEXT("buildid"),
2361cdf0e10cSrcweir         TEXT("unknown"),
2362cdf0e10cSrcweir         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)2409cdf0e10cSrcweir bool SendHTTPRequest(
2410cdf0e10cSrcweir                 FILE *fp,
2411cdf0e10cSrcweir                 const char *pszServer,
2412cdf0e10cSrcweir                 unsigned short uPort = 80,
2413cdf0e10cSrcweir                 const char *pszProxyServer = NULL,
2414cdf0e10cSrcweir                 unsigned short uProxyPort = 8080 )
2415cdf0e10cSrcweir {
2416cdf0e10cSrcweir     bool success = false;
2417cdf0e10cSrcweir 
2418cdf0e10cSrcweir     struct hostent *hp;
2419cdf0e10cSrcweir 
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 )
2450cdf0e10cSrcweir                     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
2460cdf0e10cSrcweir                     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;
2471cdf0e10cSrcweir 
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 
2520cdf0e10cSrcweir     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     {
2527cdf0e10cSrcweir         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     {
2539cdf0e10cSrcweir         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 );
2559cdf0e10cSrcweir                 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 
2571cdf0e10cSrcweir     fprintf( fp,
2572cdf0e10cSrcweir         "</hash>\n"
2573cdf0e10cSrcweir         "</rds:submitReport>\n"
2574cdf0e10cSrcweir         "</SOAP-ENV:Body>\n"
2575cdf0e10cSrcweir         "</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 
2596cdf0e10cSrcweir     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)2603cdf0e10cSrcweir BOOL CALLBACK SendingStatusDialogProc(
2604cdf0e10cSrcweir     HWND hwndDlg,
2605cdf0e10cSrcweir     UINT uMsg,
2606cdf0e10cSrcweir     WPARAM wParam,
2607cdf0e10cSrcweir     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         {
2669cdf0e10cSrcweir             WideCharToMultiByte(
2670cdf0e10cSrcweir                 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 
2679cdf0e10cSrcweir             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 
2689cdf0e10cSrcweir                 if ( ERROR_SUCCESS == RegReadValue( HKEY_CURRENT_USER,
2690*ad94bf9dSmseidel                     TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
2691*ad94bf9dSmseidel                     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         {
2751cdf0e10cSrcweir             int retid = DialogBoxParam(
2752cdf0e10cSrcweir                 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 
2859cdf0e10cSrcweir     WSADATA wsaData;
2860cdf0e10cSrcweir     WORD    wVersionRequested;
2861cdf0e10cSrcweir 
2862cdf0e10cSrcweir     wVersionRequested = MAKEWORD(1, 1);
2863cdf0e10cSrcweir     WSAStartup(wVersionRequested, &wsaData);
2864cdf0e10cSrcweir 
2865cdf0e10cSrcweir     CrashReportParams   Params;
2866cdf0e10cSrcweir 
2867cdf0e10cSrcweir     Params.ReadFromRegistry();
2868cdf0e10cSrcweir     Params.ReadFromEnvironment();
2869cdf0e10cSrcweir 
2870cdf0e10cSrcweir     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                 }
2950cdf0e10cSrcweir 
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