1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: soreport.cpp,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 #define WIN32_LEAN_AND_MEAN
34 #pragma warning(push, 1)
35 #pragma warning(disable:4917)
51 #define _RICHEDIT_VER 0x0200
58 #if _RICHEDIT_VER >= 0x0200
59 #define RICHEDIT TEXT("riched20.dll")
61 #define RICHEDIT TEXT("riched32.dll")
64 #include <systools/win32/uwinapi.h>
65 #include <rtl/digest.h>
66 #include <rtl/bootstrap.hxx>
67 #include <osl/file.hxx>
68 #include <osl/process.h>
85 #define FORMATBUFSIZE (8*1024)
86 #define MAX_TEXT_BUFFER (32*1024-1)
87 #define MAX_HOSTNAME (1024)
96 #define tstring wstring
98 #define tstring string
101 using namespace ::std
;
104 wstring g_wstrProductKey
;
105 string g_strDefaultLanguage
;
106 FILE *g_fpStackFile
= NULL
;
107 FILE *g_fpChecksumFile
= NULL
;
108 DWORD g_dwExceptionCode
= 0;
110 CHAR g_szReportServerA
[MAX_HOSTNAME
] = "";
111 USHORT g_uReportPort
= 80;
113 TCHAR g_szBuildId
[256] = TEXT("");
115 TCHAR g_szDumpFileName
[MAX_PATH
] = TEXT("");
117 CHAR g_szDumpFileNameA
[MAX_PATH
] = "";
118 CHAR g_szCommentFileNameA
[MAX_PATH
] = "";
119 CHAR g_szReportFileNameA
[MAX_PATH
] = "";
122 bool g_bNoUserInterface
= false;
123 bool g_bSendReport
= false;
124 bool g_bLoadReport
= false;
126 #define REPORT_SERVER g_szReportServerA
127 #define REPORT_PORT g_uReportPort
130 //***************************************************************************
131 // tmpfile from msvcrt creates the temporary file in the root of the current
132 // volume and can fail.
134 static FILE *_xfopen( const _TCHAR
*file
, const _TCHAR
*mode
)
137 if ( (LONG
)GetVersion() < 0 )
139 char afile
[MAX_PATH
];
142 WideCharToMultiByte( CP_ACP
, 0, file
, -1, afile
, MAX_PATH
, NULL
, NULL
);
143 WideCharToMultiByte( CP_ACP
, 0, mode
, -1, amode
, 16, NULL
, NULL
);
146 return fopen( afile
, amode
);
150 return _tfopen( file
, mode
);
154 static FILE *_tmpfile(void)
158 TCHAR szTempPath
[MAX_PATH
];
160 if ( GetTempPath( elementsof(szTempPath
), szTempPath
) )
162 TCHAR szFileName
[MAX_PATH
];
164 if ( GetTempFileName( szTempPath
, TEXT("CRT"), 0, szFileName
) )
166 HANDLE hFile
= CreateFile(
168 GENERIC_READ
| GENERIC_WRITE
,
171 FILE_FLAG_DELETE_ON_CLOSE
| FILE_ATTRIBUTE_NORMAL
,
174 if ( IsValidHandle( hFile
) )
176 int fd
= _open_osfhandle( (int)hFile
, 0 );
178 fp
= _fdopen( fd
, "w+b" );
185 //***************************************************************************
187 static BOOL
GetCrashDataPath( LPTSTR szBuffer
)
189 ::rtl::OUString ustrValue
= ::rtl::OUString::createFromAscii("${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}");
190 ::rtl::Bootstrap::expandMacros( ustrValue
);
192 if ( ustrValue
.getLength() )
194 ustrValue
+= ::rtl::OUString::createFromAscii("/user/crashdata");
196 ::osl::FileBase::RC result
= ::osl::Directory::createPath( ustrValue
);
198 if ( ::osl::FileBase::E_None
== result
|| ::osl::FileBase::E_EXIST
== result
)
200 ::rtl::OUString ustrPath
;
202 result
= ::osl::FileBase::getSystemPathFromFileURL( ustrValue
, ustrPath
);
203 if ( ::osl::FileBase::E_None
== result
)
205 _tcsncpy( szBuffer
, reinterpret_cast<LPCWSTR
>(ustrPath
.getStr()), MAX_PATH
);
215 static FILE *_open_reportfile( LPCTSTR lpExt
, LPCTSTR lpMode
)
218 TCHAR szAppDataPath
[MAX_PATH
] = _T("");
220 if ( GetCrashDataPath( szAppDataPath
) )
222 _tcscat( szAppDataPath
, _T("\\crashdat") );
223 _tcscat( szAppDataPath
, lpExt
);
225 fp
= _xfopen( szAppDataPath
, lpMode
);
231 //***************************************************************************
233 struct CrashReportParams
239 ULONG uInternetConnection
;
240 tstring sProxyServer
;
245 void WriteToRegistry();
246 void ReadFromRegistry();
247 void ReadFromEnvironment();
250 bool SendCrashReport( HWND hwndParent
, const CrashReportParams
&rParams
);
251 BOOL
WriteCommentFile( LPCTSTR lpComment
);
253 //***************************************************************************
255 LONG
RegReadValue( HKEY hBaseKey
, LPCTSTR lpSubKey
, LPCTSTR lpValueName
, LPVOID lpData
, DWORD cbData
)
260 lResult
= RegOpenKeyEx( hBaseKey
, lpSubKey
, 0, KEY_QUERY_VALUE
, &hKey
);
262 if ( ERROR_SUCCESS
== lResult
)
264 lResult
= RegQueryValueEx( hKey
, lpValueName
, NULL
, NULL
, (LPBYTE
)lpData
, &cbData
);
271 //***************************************************************************
273 LONG
RegWriteValue( HKEY hBaseKey
, LPCTSTR lpSubKey
, LPCTSTR lpValueName
, DWORD dwType
, LPCVOID lpData
, DWORD cbData
)
278 lResult
= RegCreateKeyEx( hBaseKey
, lpSubKey
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hKey
, NULL
);
280 if ( ERROR_SUCCESS
== lResult
)
282 lResult
= RegSetValueEx( hKey
, lpValueName
, NULL
, dwType
, (CONST BYTE
*)lpData
, cbData
);
289 //***************************************************************************
291 CrashReportParams::CrashReportParams()
293 fAllowContact
= FALSE
;
297 uInternetConnection
= 0;
298 sProxyServer
= TEXT("");
299 sProxyPort
= TEXT("");
302 //***************************************************************************
304 void CrashReportParams::ReadFromRegistry()
306 TCHAR szBuffer
[2048];
308 if ( ERROR_SUCCESS
== RegReadValue(
310 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
311 TEXT("HTTPProxyServer"),
314 sProxyServer
= szBuffer
;
318 if ( ERROR_SUCCESS
== RegReadValue(
320 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
321 TEXT("HTTPProxyPort"),
323 sizeof(dwProxyPort
) ) )
325 _stprintf( szBuffer
, TEXT("%d"), dwProxyPort
);
326 sProxyPort
= szBuffer
;
329 if ( ERROR_SUCCESS
== RegReadValue(
331 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
332 TEXT("ReturnAddress"),
339 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
340 TEXT("AllowContact"),
342 sizeof(fAllowContact
) );
346 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
347 TEXT("HTTPConnection"),
348 &uInternetConnection
,
349 sizeof(uInternetConnection
) );
352 //***************************************************************************
354 void CrashReportParams::WriteToRegistry()
358 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
359 TEXT("HTTPProxyServer"), REG_SZ
,
360 sProxyServer
.c_str(),
361 sizeof(TCHAR
) * (sProxyServer
.length() + 1) );
363 LPTSTR endptr
= NULL
;
364 DWORD dwProxyPort
= _tcstoul( sProxyPort
.c_str(), &endptr
, 10 );
368 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
369 TEXT("HTTPProxyPort"), REG_DWORD
,
375 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
376 TEXT("AllowContact"), REG_DWORD
,
383 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
384 TEXT("HTTPConnection"), REG_DWORD
,
385 &uInternetConnection
,
390 TEXT("SOFTWARE\\OpenOffice.org\\CrashReport"),
391 TEXT("ReturnAddress"), REG_SZ
,
393 sizeof(TCHAR
) * (sEmail
.length() + 1) );
396 //***************************************************************************
398 void CrashReportParams::ReadFromEnvironment()
400 TCHAR szBuffer
[2048];
402 DWORD dwResult
= GetEnvironmentVariable( TEXT("ERRORREPORT_HTTPPROXYSERVER"), szBuffer
, elementsof(szBuffer
) );
404 if ( dwResult
&& dwResult
< elementsof(szBuffer
) )
405 sProxyServer
= szBuffer
;
407 dwResult
= GetEnvironmentVariable( TEXT("ERRORREPORT_HTTPPROXYPORT"), szBuffer
, elementsof(szBuffer
) );
409 if ( dwResult
&& dwResult
< elementsof(szBuffer
) )
410 sProxyPort
= szBuffer
;
412 dwResult
= GetEnvironmentVariable( TEXT("ERRORREPORT_RETURNADDRESS"), szBuffer
, elementsof(szBuffer
) );
414 if ( dwResult
&& dwResult
< elementsof(szBuffer
) )
417 // fAllowContact = TRUE;
420 dwResult
= GetEnvironmentVariable( TEXT("ERRORREPORT_HTTPCONNECTIONTYPE"), szBuffer
, elementsof(szBuffer
) );
422 if ( dwResult
&& dwResult
< elementsof(szBuffer
) )
424 if ( 0 == _tcsicmp( szBuffer
, _T("DIRECT") ) )
425 uInternetConnection
= 1;
426 else if ( 0 == _tcsicmp( szBuffer
, _T("MANUALPROXY") ) )
427 uInternetConnection
= 2;
428 else if ( 0 == _tcsicmp( szBuffer
, _T("SYSTEMDEFAULT") ) )
429 uInternetConnection
= 0;
432 dwResult
= GetEnvironmentVariable( TEXT("ERRORREPORT_SUBJECT"), szBuffer
, elementsof(szBuffer
) );
434 if ( dwResult
&& dwResult
< elementsof(szBuffer
) )
438 dwResult
= GetEnvironmentVariable( TEXT("ERRORREPORT_BODYFILE"), szBuffer
, elementsof(szBuffer
) );
440 if ( dwResult
&& dwResult
< elementsof(szBuffer
) )
442 FILE *fp
= _xfopen( szBuffer
, _T("rb") );
446 CHAR aUTF8Buffer
[256];
451 while ( 0 != (nBytesRead
= fread( aUTF8Buffer
, sizeof(aUTF8Buffer
[0]), elementsof(aUTF8Buffer
), fp
)) )
453 TCHAR aBuffer
[256+1];
455 DWORD dwCharacters
= MultiByteToWideChar( CP_UTF8
, 0, aUTF8Buffer
, nBytesRead
, aBuffer
, elementsof(aBuffer
) - 1 );
456 aBuffer
[dwCharacters
] = 0;
465 //***************************************************************************
467 typedef BOOL (WINAPI
*MiniDumpWriteDump_PROC
)(
471 IN MINIDUMP_TYPE DumpType
,
472 IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam
, OPTIONAL
473 IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam
, OPTIONAL
474 IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
477 //***************************************************************************
479 static BOOL WINAPI
InitRichEdit()
481 return (NULL
!= LoadLibrary( RICHEDIT
));
484 //***************************************************************************
486 static BOOL WINAPI
DeinitRichEdit()
488 return FreeLibrary( GetModuleHandle( RICHEDIT
) );
491 //***************************************************************************
493 static string
trim_string( const string
& rString
)
495 string temp
= rString
;
497 while ( temp
.length() && temp
[0] == ' ' || temp
[0] == '\t' )
500 string::size_type len
= temp
.length();
502 while ( len
&& temp
[len
-1] == ' ' || temp
[len
-1] == '\t' )
504 temp
.erase( len
- 1, 1 );
511 //***************************************************************************
513 static int LoadAndFormatString( HINSTANCE hInstance
, UINT uID
, LPTSTR lpBuffer
, int nBufferMax
)
515 TCHAR szBuffer
[FORMATBUFSIZE
];
516 TCHAR szBuffer2
[FORMATBUFSIZE
];
518 LoadString( hInstance
, uID
, szBuffer
, elementsof(szBuffer
) );
522 for ( dest
= szBuffer2
, src
= szBuffer
; *src
; src
++, dest
++ )
551 return ExpandEnvironmentStrings( szBuffer2
, lpBuffer
, nBufferMax
);
555 //***************************************************************************
557 static string
wstring2utf8( const wstring
&rString
)
559 int nBufSize
= WideCharToMultiByte( CP_UTF8
, 0, rString
.c_str(), -1, NULL
, 0, NULL
, FALSE
);
561 LPSTR pBuffer
= (LPSTR
)alloca( nBufSize
);
563 WideCharToMultiByte( CP_UTF8
, 0, rString
.c_str(), -1, pBuffer
, nBufSize
, NULL
, FALSE
);
565 return string( pBuffer
);
568 //***************************************************************************
570 static string
xml_encode( const string
&rString
)
572 string temp
= rString
;
573 string::size_type pos
= 0;
575 // First replace all occurences of '&' because it may occur in further
576 // encoded chardters too
578 for( pos
= 0; (pos
= temp
.find( '&', pos
)) != string::npos
; pos
+= 4 )
579 temp
.replace( pos
, 1, "&" );
581 for( pos
= 0; (pos
= temp
.find( '<', pos
)) != string::npos
; pos
+= 4 )
582 temp
.replace( pos
, 1, "<" );
584 for( pos
= 0; (pos
= temp
.find( '>', pos
)) != string::npos
; pos
+= 4 )
585 temp
.replace( pos
, 1, ">" );
590 //***************************************************************************
592 static size_t fcopy( FILE *fpin
, FILE *fpout
)
596 size_t nBytesWritten
= 0;
600 while ( 0 != (nBytes
= fread( buffer
, 1, sizeof(buffer
), fpin
)) )
602 nBytesWritten
+= fwrite( buffer
, 1, nBytes
, fpout
);
606 return nBytesWritten
;
609 //***************************************************************************
611 static string
GetModuleDirectory( HMODULE hModule
)
613 TCHAR szModuleName
[MAX_PATH
] = TEXT("");
614 TCHAR szDrive
[_MAX_DRIVE
];
615 TCHAR szDir
[_MAX_DIR
];
616 TCHAR szFName
[_MAX_FNAME
];
617 TCHAR szExt
[_MAX_EXT
];
619 if ( GetModuleFileName( hModule
, szModuleName
, MAX_PATH
) )
621 _tsplitpath( szModuleName
, szDrive
, szDir
, szFName
, szExt
);
622 _tmakepath( szModuleName
, szDrive
, szDir
, _T(""), _T("") );
625 CHAR szModuleNameUTF8
[MAX_PATH
] = "";
627 WideCharToMultiByte( CP_UTF8
, 0, szModuleName
, -1, szModuleNameUTF8
, elementsof(szModuleNameUTF8
), NULL
, NULL
);
628 return string( szModuleNameUTF8
);
631 //***************************************************************************
633 string
GetFileDirectory( const string
& rFilePath
)
635 string aDir
= rFilePath
;
636 size_t pos
= aDir
.rfind( '\\' );
638 if ( string::npos
!= pos
)
639 aDir
.erase( pos
+ 1 );
646 //***************************************************************************
648 string
GetFileName( const string
& rFilePath
)
650 string aName
= rFilePath
;
651 size_t pos
= aName
.rfind( '\\' );
653 if ( string::npos
!= pos
)
654 return aName
.substr( pos
+ 1 );
659 //***************************************************************************
661 BOOL
WriteReportFile( CrashReportParams
*pParams
)
663 BOOL fSuccess
= FALSE
;
664 TCHAR szTempPath
[MAX_PATH
];
666 if ( GetTempPath( elementsof(szTempPath
), szTempPath
) )
668 TCHAR szFileName
[MAX_PATH
];
670 if ( GetTempFileName( szTempPath
, TEXT("RPM"), 0, szFileName
) )
672 HANDLE hFile
= CreateFile( szFileName
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
676 int fd
= _open_osfhandle( (LONG
)hFile
, _O_TEXT
);
677 FILE *fp
= _fdopen( fd
, "w+t" );
678 CHAR szTitle
[1024] = "";
679 CHAR szBuildId
[1024] = "";
680 CHAR szEmail
[1024] = "";
681 const char *pszUserType
= getenv( "STAROFFICE_USERTYPE" );
683 WideCharToMultiByte( CP_UTF8
, 0, pParams
->sTitle
.c_str(), -1, szTitle
, sizeof(szTitle
), NULL
, NULL
);
684 WideCharToMultiByte( CP_UTF8
, 0, g_szBuildId
, -1, szBuildId
, sizeof(szBuildId
), NULL
, NULL
);
685 WideCharToMultiByte( CP_UTF8
, 0, pParams
->sEmail
.c_str(), -1, szEmail
, sizeof(szEmail
), NULL
, NULL
);
688 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
689 "<!DOCTYPE errormail:errormail PUBLIC \"-//OpenOffice.org//DTD ErrorMail 1.0//EN\" \"errormail.dtd\">\n"
690 "<errormail:errormail xmlns:errormail=\"http://openoffice.org/2002/errormail\" usertype=\"%s\">\n"
691 "<reportmail:mail xmlns:reportmail=\"http://openoffice.org/2002/reportmail\" version=\"1.1\" feedback=\"%s\" email=\"%s\">\n",
692 pszUserType
? pszUserType
: "",
693 pParams
->fAllowContact
? "true" : "false",
694 pParams
->fAllowContact
? xml_encode(szEmail
).c_str() : ""
698 "<reportmail:title>%s</reportmail:title>\n",
699 xml_encode(szTitle
).c_str() );
702 "<reportmail:attachment name=\"description.txt\" media-type=\"text/plain;charset=UTF-8\" class=\"UserComment\"/>\n"
703 "<reportmail:attachment name=\"user.dmp\" media-type=\"application/octet-stream\" class=\"UserDump\"/>\n"
704 "</reportmail:mail>\n"
706 "<officeinfo:officeinfo xmlns:officeinfo=\"http://openoffice.org/2002/officeinfo\" build=\"%s\" platform=\"%s\" language=\"%s\" procpath=\"%s\" exceptiontype=\"0x%08X\" product=\"%s\"/>\n",
709 xml_encode(g_strDefaultLanguage
).c_str(),
710 xml_encode(GetModuleDirectory( NULL
)).c_str(),
712 xml_encode(wstring2utf8(g_wstrProductKey
)).c_str()
715 OSVERSIONINFO VersionInfo
;
717 ZeroMemory( &VersionInfo
, sizeof(VersionInfo
) );
718 VersionInfo
.dwOSVersionInfoSize
= sizeof(VersionInfo
);
720 GetVersionEx( &VersionInfo
);
723 "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
724 "<systeminfo:System name=\"%s\" version=\"%d.%d\" build=\"%d\" locale=\"0x%08x\"/>\n"
726 VER_PLATFORM_WIN32_NT
== VersionInfo
.dwPlatformId
? "Windows NT" : "Windows",
727 VersionInfo
.dwMajorVersion
, VersionInfo
.dwMinorVersion
,
728 VersionInfo
.dwBuildNumber
,
729 GetUserDefaultLangID()
732 fprintf( fp
, "<systeminfo:CPU type=\"x86\"/>\n" );
733 fprintf( fp
, "</systeminfo:systeminfo>\n" );
735 fseek( g_fpStackFile
, 0, SEEK_SET
);
736 fcopy( g_fpStackFile
, fp
);
738 fseek( g_fpChecksumFile
, 0, SEEK_SET
);
739 fcopy( g_fpChecksumFile
, fp
);
741 fprintf( fp
, "</errormail:errormail>\n" );
747 WideCharToMultiByte( CP_ACP
, 0, szFileName
, -1, g_szReportFileNameA
, MAX_PATH
, NULL
, NULL
);
751 DeleteFile( szFileName
);
758 //***************************************************************************
760 static BOOL
SaveDumpFile( HWND hwndOwner
)
763 TCHAR szFileName
[MAX_PATH
] = TEXT("");
765 ZeroMemory( &ofn
, sizeof(ofn
) );
766 ofn
.lStructSize
= sizeof(ofn
);
768 ofn
.hwndOwner
= hwndOwner
;
769 ofn
.lpstrFilter
= TEXT("*.dmp\0*.dmp\0*.*\0*.*\0");
770 ofn
.lpstrFile
= szFileName
;
771 ofn
.nMaxFile
= MAX_PATH
;
772 ofn
.Flags
= OFN_ENABLESIZING
| OFN_LONGNAMES
| OFN_OVERWRITEPROMPT
;
773 ofn
.lpstrDefExt
= TEXT("dmp");
775 if ( GetSaveFileName( &ofn
) )
777 return CopyFile( g_szDumpFileName
, szFileName
, FALSE
);
784 //***************************************************************************
786 static BOOL
ScreenToClientRect( HWND hwnd
, LPRECT lprc
)
788 return ScreenToClient( hwnd
, (LPPOINT
)&lprc
->left
) && ScreenToClient( hwnd
, (LPPOINT
)&lprc
->right
);
791 static BOOL
SetWindowRect( HWND hwnd
, const RECT
*lprc
, BOOL fRepaint
)
793 return MoveWindow( hwnd
, lprc
->left
, lprc
->top
, lprc
->right
- lprc
->left
, lprc
->bottom
- lprc
->top
, fRepaint
);
801 static BOOL
SetGrowMode( HWND hwnd
, DWORD dwGrowMode
)
803 return SetProp( hwnd
, TEXT("GrowMode"), (HANDLE
)dwGrowMode
);
806 static DWORD
GetGrowMode( HWND hwnd
)
808 return (DWORD
)GetProp( hwnd
, TEXT("GrowMode") );
811 static BOOL
GrowWindow( HWND hwnd
, LONG dxClient
, LONG dyClient
, BOOL fRepaint
)
813 DWORD dwGrowMode
= GetGrowMode( hwnd
);
816 GetWindowRect( hwnd
, &rc
);
818 if ( dwGrowMode
& GM_LOX
)
820 if ( dwGrowMode
& GM_HIX
)
821 rc
.right
+= dxClient
;
822 if ( dwGrowMode
& GM_LOY
)
824 if ( dwGrowMode
& GM_HIY
)
825 rc
.bottom
+= dyClient
;
827 ScreenToClientRect( GetParent( hwnd
), &rc
);
828 SetWindowRect( hwnd
, &rc
, fRepaint
);
833 BOOL CALLBACK
GrowChildWindows(
834 HWND hwnd
, // handle to child window
835 LPARAM lParam
// application-defined value
838 LONG cx
= (SHORT
)LOWORD( lParam
);
839 LONG cy
= (SHORT
)HIWORD( lParam
);
841 GrowWindow( hwnd
, cx
, cy
, TRUE
);
847 BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
849 HFONT aFont = *((HFONT*) lParam);
850 HDC hDC = GetDC( hwndChild );
851 SelectObject( hDC, aFont );
852 ReleaseDC( hwndChild, hDC );
856 void ApplySystemFont( HWND hwndDlg )
858 NONCLIENTMETRICSA aNonClientMetrics;
859 aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
860 if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
862 HFONT aSysFont = CreateFontIndirectA( &aNonClientMetrics.lfMessageFont );
863 EnumChildWindows(hwndDlg, EnumChildProc, (LPARAM) &aSysFont);
868 BOOL CALLBACK
PreviewDialogProc(
875 static RECT rcClient
;
881 LONG cx
= LOWORD( lParam
);
882 LONG cy
= HIWORD( lParam
);
883 LONG dxClient
, dyClient
;
885 dxClient
= cx
- rcClient
.right
;
886 dyClient
= cy
- rcClient
.bottom
;
888 EnumChildWindows( hwndDlg
, GrowChildWindows
, MAKELONG( (SHORT
)dxClient
, (SHORT
)dyClient
) );
890 GetClientRect( hwndDlg
, &rcClient
);
895 GetClientRect( hwndDlg
, &rcClient
);
896 SetGrowMode( GetDlgItem(hwndDlg
, IDC_EDIT_PREVIEW
), GM_HIX
| GM_HIY
);
897 SetGrowMode( GetDlgItem(hwndDlg
, IDOK
), GM_LOX
| GM_HIX
| GM_LOY
| GM_HIY
);
899 CrashReportParams
*pParams
= (CrashReportParams
*)lParam
;
901 TCHAR szBuffer
[256] = TEXT("");
902 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong( hwndDlg
, GWL_HINSTANCE
);
903 HWND hwndParent
= (HWND
)GetWindowLong( hwndDlg
, GWL_HWNDPARENT
);
905 GetWindowText( hwndParent
, szBuffer
, elementsof(szBuffer
) );
906 SetWindowText( hwndDlg
, szBuffer
);
908 LoadAndFormatString( hInstance
, IDS_OK_BUTTON
, szBuffer
, elementsof(szBuffer
) );
909 Button_SetText( GetDlgItem(hwndDlg
, IDOK
), szBuffer
);
911 basic_string
<TCHAR
> aString
;
913 aString
.append( pParams
->sTitle
);
914 aString
.append( _T("\r\n\r\n") );
915 aString
.append( pParams
->sComment
);
916 aString
.append( _T("\r\n---------- report ----------\r\n") );
918 FILE *fp
= fopen( g_szReportFileNameA
, "r" );
924 while ( fgets( buf
, elementsof(buf
), fp
) != NULL
)
928 MultiByteToWideChar( CP_UTF8
, 0, buf
, -1, bufW
, elementsof(bufW
) );
930 aString
.append( bufW
);
936 aString
.append( _T("\r\n---------- stack ----------\r\n") );
938 fp
= fopen( g_szDumpFileNameA
, "rb" );
942 unsigned char buf
[16];
949 count
= fread( buf
, sizeof(buf
[0]), sizeof(buf
)/sizeof(buf
[0]), fp
);
951 for ( i
= 0; i
< count
; i
++ )
955 _sntprintf( output
, elementsof(output
), _T("%02X\x20"), buf
[i
] );
956 aString
.append( output
);
958 for ( ; i
< elementsof(buf
); i
++ )
960 aString
.append( _T("\x20\x20\x20") );
963 for ( i
= 0; i
< count
; i
++ )
967 if ( (int)buf
[i
] >= 0x20 && (int)buf
[i
] <= 0x7F )
968 output
[0] = (TCHAR
)buf
[i
];
972 aString
.append( output
);
975 aString
.append( _T("\r\n") );
982 Edit_SetText( GetDlgItem(hwndDlg
, IDC_EDIT_PREVIEW
), aString
.c_str() );
985 SetWindowFont( GetDlgItem(hwndDlg
, IDC_EDIT_PREVIEW
), GetStockObject( SYSTEM_FIXED_FONT
), TRUE
);
989 switch ( LOWORD(wParam
) )
993 EndDialog( hwndDlg
, wParam
);
1003 //***************************************************************************
1005 static void PreviewReport( HWND hwndParent
, CrashReportParams
*pParams
)
1007 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong(hwndParent
, GWL_HINSTANCE
);
1009 WriteReportFile( pParams
);
1013 MAKEINTRESOURCE(IDD_PREVIEW_FRAME
),
1019 DeleteFileA( g_szReportFileNameA
);
1021 //***************************************************************************
1022 void UpdateOptionsDialogControls( HWND hwndDlg
)
1024 if ( Button_GetCheck( GetDlgItem(hwndDlg
, IDC_RADIO_MANUAL
) ) & BST_CHECKED
)
1026 EnableWindow( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYSERVER
), TRUE
);
1027 EnableWindow( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYPORT
), TRUE
);
1031 EnableWindow( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYSERVER
), FALSE
);
1032 EnableWindow( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYPORT
), FALSE
);
1036 //***************************************************************************
1038 BOOL CALLBACK
OptionsDialogProc(
1045 static CrashReportParams
*pParams
;
1051 TCHAR szBuffer
[1024] = TEXT("");
1052 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong( hwndDlg
, GWL_HINSTANCE
);
1053 //HWND hwndParent = (HWND)GetWindowLong( hwndDlg, GWL_HWNDPARENT );
1055 pParams
= (CrashReportParams
*)lParam
;
1057 LoadAndFormatString( hInstance
, IDS_OPTIONS_CAPTION
, szBuffer
, elementsof(szBuffer
) );
1058 SetWindowText( hwndDlg
, szBuffer
);
1060 LoadAndFormatString( hInstance
, IDS_PROXY_SETTINGS_HEADER
, szBuffer
, elementsof(szBuffer
) );
1061 Static_SetText( GetDlgItem(hwndDlg
, IDC_PROXY_SETTINGS
), szBuffer
);
1063 LoadAndFormatString( hInstance
, IDS_PROXY_SYSTEM
, szBuffer
, elementsof(szBuffer
) );
1064 Button_SetText( GetDlgItem(hwndDlg
, IDC_RADIO_SYSTEM
), szBuffer
);
1066 LoadAndFormatString( hInstance
, IDS_PROXY_DIRECT
, szBuffer
, elementsof(szBuffer
) );
1067 Button_SetText( GetDlgItem(hwndDlg
, IDC_RADIO_DIRECT
), szBuffer
);
1069 LoadAndFormatString( hInstance
, IDS_PROXY_MANUAL
, szBuffer
, elementsof(szBuffer
) );
1070 Button_SetText( GetDlgItem(hwndDlg
, IDC_RADIO_MANUAL
), szBuffer
);
1072 LoadAndFormatString( hInstance
, IDS_LABEL_PROXYSERVER
, szBuffer
, elementsof(szBuffer
) );
1073 Static_SetText( GetDlgItem(hwndDlg
, IDC_LABEL_PROXYSERVER
), szBuffer
);
1075 LoadAndFormatString( hInstance
, IDS_LABEL_PROXYPORT
, szBuffer
, elementsof(szBuffer
) );
1076 Static_SetText( GetDlgItem(hwndDlg
, IDC_LABEL_PROXYPORT
), szBuffer
);
1078 LoadAndFormatString( hInstance
, IDS_OK_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1079 Button_SetText( GetDlgItem(hwndDlg
, IDOK
), szBuffer
);
1081 LoadAndFormatString( hInstance
, IDS_CANCEL_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1082 Button_SetText( GetDlgItem(hwndDlg
, IDCANCEL
), szBuffer
);
1084 Edit_SetText( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYSERVER
), pParams
->sProxyServer
.c_str() );
1085 Edit_SetText( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYPORT
), pParams
->sProxyPort
.c_str() );
1087 Button_SetCheck( GetDlgItem(hwndDlg
, IDC_RADIO_SYSTEM
+ pParams
->uInternetConnection
), BST_CHECKED
);
1090 GetDlgItem(hwndDlg
, IDC_PROXY_DESCRIPTION
),
1093 GetSysColor( COLOR_3DFACE
) );
1094 LoadAndFormatString( hInstance
, IDS_PROXY_DESCRIPTION
, szBuffer
, elementsof(szBuffer
) );
1095 Edit_SetText( GetDlgItem(hwndDlg
, IDC_PROXY_DESCRIPTION
), szBuffer
);
1097 UpdateOptionsDialogControls( hwndDlg
);
1101 switch ( LOWORD(wParam
) )
1103 case IDC_RADIO_SYSTEM
:
1104 case IDC_RADIO_DIRECT
:
1105 case IDC_RADIO_MANUAL
:
1106 if ( BN_CLICKED
== HIWORD(wParam
) )
1107 UpdateOptionsDialogControls( hwndDlg
);
1111 TCHAR szBuffer
[1024];
1113 Edit_GetText( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYSERVER
), szBuffer
, elementsof(szBuffer
) );
1114 pParams
->sProxyServer
= szBuffer
;
1116 Edit_GetText( GetDlgItem(hwndDlg
, IDC_EDIT_PROXYPORT
), szBuffer
, elementsof(szBuffer
) );
1117 pParams
->sProxyPort
= szBuffer
;
1119 if ( Button_GetCheck( GetDlgItem(hwndDlg
, IDC_RADIO_DIRECT
) ) & BST_CHECKED
)
1120 pParams
->uInternetConnection
= 1;
1121 else if ( Button_GetCheck( GetDlgItem(hwndDlg
, IDC_RADIO_MANUAL
) ) & BST_CHECKED
)
1122 pParams
->uInternetConnection
= 2;
1124 pParams
->uInternetConnection
= 0;
1127 EndDialog( hwndDlg
, wParam
);
1138 //***************************************************************************
1140 static void OptionsDialog( HWND hwndParent
, CrashReportParams
*pParams
)
1142 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong(hwndParent
, GWL_HINSTANCE
);
1144 if ( IDOK
== DialogBoxParam(
1146 MAKEINTRESOURCE(IDD_OPTIONS_FRAME
),
1151 pParams
->WriteToRegistry();
1154 //***************************************************************************
1156 void UpdateReportDialogControls( HWND hwndDlg
)
1159 GetDlgItem(hwndDlg
, IDC_EDIT_EMAIL
),
1160 Button_GetCheck(GetDlgItem(hwndDlg
, IDC_ALLOW_CONTACT
)) & BST_CHECKED
? TRUE
: FALSE
);
1162 GetDlgItem(hwndDlg
, IDC_LABEL_EMAIL
),
1163 Button_GetCheck(GetDlgItem(hwndDlg
, IDC_ALLOW_CONTACT
)) & BST_CHECKED
? TRUE
: FALSE
);
1166 //***************************************************************************
1168 BOOL CALLBACK
ReportDialogProc(
1179 CrashReportParams
*pParams
= (CrashReportParams
*)GetWindowLong( GetParent(hwndDlg
), GWL_USERDATA
);
1180 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong(hwndDlg
, GWL_HINSTANCE
);
1181 TCHAR szBuffer
[FORMATBUFSIZE
];
1183 LoadAndFormatString( hInstance
, IDS_REPORT_INTRO
, szBuffer
, elementsof(szBuffer
) );
1184 Static_SetText( GetDlgItem(hwndDlg
, IDC_REPORT_INTRO
), szBuffer
);
1186 Edit_SetText( GetDlgItem(hwndDlg
, IDC_EDIT3
), szBuffer
);
1188 LoadAndFormatString( hInstance
, IDS_ENTER_TITLE
, szBuffer
, elementsof(szBuffer
) );
1189 Static_SetText( GetDlgItem(hwndDlg
, IDC_ENTER_TITLE
), szBuffer
);
1191 LoadAndFormatString( hInstance
, IDS_ENTER_DESCRIPTION
, szBuffer
, elementsof(szBuffer
) );
1192 Static_SetText( GetDlgItem(hwndDlg
, IDC_ENTER_DESCRIPTION
), szBuffer
);
1194 LoadAndFormatString( hInstance
, IDS_SHOW_REPORT_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1195 Button_SetText( GetDlgItem(hwndDlg
, IDC_SHOW_REPORT
), szBuffer
);
1197 LoadAndFormatString( hInstance
, IDS_SAVE_REPORT_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1198 Button_SetText( GetDlgItem(hwndDlg
, IDC_SAVE_REPORT
), szBuffer
);
1200 const char *pszUserType
= getenv( "STAROFFICE_USERTYPE" );
1202 ShowWindow( GetDlgItem(hwndDlg
, IDC_SAVE_REPORT
), SW_SHOW
);
1204 ShowWindow( GetDlgItem(hwndDlg
, IDC_SAVE_REPORT
), SW_HIDE
);
1206 LoadAndFormatString( hInstance
, IDS_OPTIONS_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1207 Button_SetText( GetDlgItem(hwndDlg
, IDC_OPTIONS
), szBuffer
);
1209 LoadAndFormatString( hInstance
, IDS_ALLOW_CONTACT
, szBuffer
, elementsof(szBuffer
) );
1210 Button_SetText( GetDlgItem(hwndDlg
, IDC_ALLOW_CONTACT
), szBuffer
);
1211 Button_SetCheck( GetDlgItem(hwndDlg
, IDC_ALLOW_CONTACT
), pParams
->fAllowContact
? BST_CHECKED
: BST_UNCHECKED
);
1213 LoadAndFormatString( hInstance
, IDS_LABEL_EMAIL
, szBuffer
, elementsof(szBuffer
) );
1214 Button_SetText( GetDlgItem(hwndDlg
, IDC_LABEL_EMAIL
), szBuffer
);
1216 Edit_SetText( GetDlgItem(hwndDlg
, IDC_EDIT_EMAIL
), pParams
->sEmail
.c_str() );
1218 UpdateReportDialogControls( hwndDlg
);
1224 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong(hwndDlg
, GWL_HINSTANCE
);
1225 CrashReportParams
*pParams
= (CrashReportParams
*)GetWindowLong( GetParent(hwndDlg
), GWL_USERDATA
);
1226 TCHAR szBuffer
[FORMATBUFSIZE
];
1228 LoadAndFormatString( hInstance
, IDS_REPORT_CAPTION
, szBuffer
, elementsof(szBuffer
) );
1229 SetWindowText( GetParent(hwndDlg
), szBuffer
);
1231 LoadAndFormatString( hInstance
, IDS_REPORT_HEADER
, szBuffer
, elementsof(szBuffer
) );
1232 SetWindowText( GetDlgItem(GetParent(hwndDlg
), IDC_HEADER
), szBuffer
);
1234 LoadAndFormatString( hInstance
, IDS_DONOT_SEND_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1235 Button_SetText( GetDlgItem(GetParent(hwndDlg
), IDCANCEL
), szBuffer
);
1238 ShowWindow( GetDlgItem(GetParent(hwndDlg
),IDBACK
), TRUE
);
1239 ShowWindow( GetDlgItem(GetParent(hwndDlg
),IDFINISH
), TRUE
);
1240 ShowWindow( GetDlgItem(GetParent(hwndDlg
),IDNEXT
), FALSE
);
1242 Edit_SetText( GetDlgItem(hwndDlg
, IDC_EDIT_TITLE
), pParams
->sTitle
.c_str() );
1243 Edit_SetText( GetDlgItem(hwndDlg
, IDC_EDIT_DESCRIPTION
), pParams
->sComment
.c_str() );
1246 SetWindowLong( GetDlgItem(GetParent(hwndDlg),IDFINISH), GWL_STYLE,
1247 GetWindowLong( GetDlgItem(GetParent(hwndDlg),IDFINISH), GWL_STYLE) | BS_DEFPUSHBUTTON );
1248 SetWindowLong( GetDlgItem(GetParent(hwndDlg),IDBACK), GWL_STYLE,
1249 GetWindowLong( GetDlgItem(GetParent(hwndDlg),IDBACK), GWL_STYLE) &~ BS_DEFPUSHBUTTON );
1251 SetFocus( GetDlgItem(hwndDlg
,IDC_EDIT_TITLE
) );
1255 switch ( LOWORD(wParam
) )
1257 case IDC_SHOW_REPORT
:
1259 TCHAR szBuffer
[32767];
1261 CrashReportParams
*pParams
= (CrashReportParams
*)GetWindowLong( GetParent(hwndDlg
), GWL_USERDATA
);
1263 pParams
->fAllowContact
= Button_GetCheck( GetDlgItem(hwndDlg
, IDC_ALLOW_CONTACT
) ) ? TRUE
: FALSE
;
1265 Edit_GetText( GetDlgItem(hwndDlg
, IDC_EDIT_TITLE
), szBuffer
, elementsof(szBuffer
) );
1266 pParams
->sTitle
= szBuffer
;
1268 Edit_GetText( GetDlgItem(hwndDlg
, IDC_EDIT_DESCRIPTION
), szBuffer
, elementsof(szBuffer
) );
1269 pParams
->sComment
= szBuffer
;
1271 Edit_GetText( GetDlgItem(hwndDlg
, IDC_EDIT_EMAIL
), szBuffer
, elementsof(szBuffer
) );
1272 pParams
->sEmail
= szBuffer
;
1274 PreviewReport( GetParent(hwndDlg
), pParams
);
1277 case IDC_SAVE_REPORT
:
1278 SaveDumpFile( GetParent(hwndDlg
) );
1282 CrashReportParams
*pParams
= (CrashReportParams
*)GetWindowLong( GetParent(hwndDlg
), GWL_USERDATA
);
1283 OptionsDialog( GetParent(hwndDlg
), pParams
);
1286 case IDC_ALLOW_CONTACT
:
1287 if ( BN_CLICKED
== HIWORD(wParam
) )
1288 UpdateReportDialogControls( hwndDlg
);
1298 //***************************************************************************
1300 BOOL CALLBACK
WelcomeDialogProc( HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1306 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong(hwndDlg
, GWL_HINSTANCE
);
1307 HWND hwndRichEdit
= GetDlgItem(hwndDlg
, IDC_RICHEDIT21
);
1308 TCHAR szBuffer
[FORMATBUFSIZE
];
1309 TCHAR szBuffer2
[FORMATBUFSIZE
];
1311 TCHAR szCaption
[256];
1317 GetSysColor( COLOR_3DFACE
) );
1319 SendMessage( hwndRichEdit
, EM_SETEVENTMASK
, 0, ENM_LINK
);
1320 SendMessage( hwndRichEdit
, EM_AUTOURLDETECT
, TRUE
, 0 );
1322 LoadAndFormatString( hInstance
, IDS_WELCOME_BODY1
, szBuffer
, elementsof(szBuffer
) );
1323 LoadAndFormatString( hInstance
, IDS_WELCOME_BODY2
, szBuffer2
, elementsof(szBuffer2
) );
1324 _tcsncat( szBuffer
, szBuffer2
, elementsof(szBuffer
) );
1325 LoadAndFormatString( hInstance
, IDS_WELCOME_BODY3
, szBuffer2
, elementsof(szBuffer2
) );
1326 _tcsncat( szBuffer
, szBuffer2
, elementsof(szBuffer
) );
1327 LoadString( hInstance
, IDS_PRIVACY_URL
, szURL
, elementsof(szURL
) );
1328 _tcsncat( szBuffer
, szURL
, elementsof(szBuffer
) );
1329 SetWindowText( hwndRichEdit
, szBuffer
);
1331 LoadAndFormatString( hInstance
, IDS_WELCOME_CAPTION
, szCaption
, elementsof(szCaption
) );
1332 SetWindowText( GetParent(hwndDlg
), szCaption
);
1339 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong(hwndDlg
, GWL_HINSTANCE
);
1340 TCHAR szBuffer
[FORMATBUFSIZE
];
1342 LoadAndFormatString( hInstance
, IDS_WELCOME_CAPTION
, szBuffer
, elementsof(szBuffer
) );
1343 SetWindowText( GetParent(hwndDlg
), szBuffer
);
1345 LoadAndFormatString( hInstance
, IDS_WELCOME_HEADER
, szBuffer
, elementsof(szBuffer
) );
1346 SetWindowText( GetDlgItem(GetParent(hwndDlg
), IDC_HEADER
), szBuffer
);
1348 LoadAndFormatString( hInstance
, IDS_CANCEL_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1349 Button_SetText( GetDlgItem(GetParent(hwndDlg
), IDCANCEL
), szBuffer
);
1351 ShowWindow( GetDlgItem(GetParent(hwndDlg
),IDBACK
), FALSE
);
1352 ShowWindow( GetDlgItem(GetParent(hwndDlg
),IDFINISH
), FALSE
);
1353 ShowWindow( GetDlgItem(GetParent(hwndDlg
),IDNEXT
), TRUE
);
1355 SetFocus( GetDlgItem(GetParent(hwndDlg
),IDNEXT
) );
1360 LPNMHDR pnmh
= (LPNMHDR
)lParam
;
1362 if ( pnmh
->idFrom
== IDC_RICHEDIT21
&& pnmh
->code
== EN_LINK
)
1364 ENLINK
*plink
= (ENLINK
*)lParam
;
1366 if ( plink
->msg
== WM_LBUTTONUP
)
1368 TCHAR szBuffer
[256];
1371 range
.chrg
= plink
->chrg
;
1372 range
.lpstrText
= szBuffer
;
1374 SendMessage( pnmh
->hwndFrom
, EM_GETTEXTRANGE
, 0, (LPARAM
)&range
);
1376 ShellExecute( hwndDlg
, NULL
, szBuffer
, NULL
, NULL
, SW_SHOWDEFAULT
);
1388 //***************************************************************************
1390 BOOL CALLBACK
DialogProc( HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1392 static HWND hwndPages
[2] = { NULL
};
1393 static int iActualPage
= 0;
1399 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong(hwndDlg
, GWL_HINSTANCE
);
1400 TCHAR szBuffer
[FORMATBUFSIZE
];
1402 SetWindowLong( hwndDlg
, GWL_USERDATA
, (LONG
)lParam
);
1403 hwndPages
[0] = CreateDialog(
1405 MAKEINTRESOURCE(IDD_WELCOME_PAGE
),
1407 WelcomeDialogProc
);
1409 hwndPages
[1] = CreateDialog(
1411 MAKEINTRESOURCE(IDD_REPORT_PAGE
),
1417 chfmt
.cbSize
= sizeof(chfmt
);
1418 chfmt
.dwMask
= CFM_BOLD
;
1419 chfmt
.dwEffects
= CFE_BOLD
;
1422 GetDlgItem(hwndDlg
, IDC_HEADER
),
1427 LoadAndFormatString( hInstance
, IDS_CANCEL_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1428 Button_SetText( GetDlgItem(hwndDlg
, IDCANCEL
), szBuffer
);
1430 LoadAndFormatString( hInstance
, IDS_NEXT_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1431 Button_SetText( GetDlgItem(hwndDlg
, IDNEXT
), szBuffer
);
1433 LoadAndFormatString( hInstance
, IDS_SEND_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1434 Button_SetText( GetDlgItem(hwndDlg
, IDFINISH
), szBuffer
);
1436 LoadAndFormatString( hInstance
, IDS_BACK_BUTTON
, szBuffer
, elementsof(szBuffer
) );
1437 Button_SetText( GetDlgItem(hwndDlg
, IDBACK
), szBuffer
);
1439 ShowWindow( hwndPages
[1], SW_HIDE
);
1440 ShowWindow( hwndPages
[0], SW_SHOW
);
1442 // Let Crash Reporter window stay on top of all other windows
1443 SetWindowPos( hwndDlg
, HWND_TOPMOST
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
1446 case WM_CTLCOLORSTATIC
:
1447 return (BOOL
)CreateSolidBrush(GetSysColor(COLOR_WINDOW
));
1449 switch ( LOWORD(wParam
) )
1452 if ( iActualPage
> 0 )
1454 ShowWindow( hwndPages
[iActualPage
], SW_HIDE
);
1455 ShowWindow( hwndPages
[--iActualPage
], SW_SHOW
);
1459 if ( iActualPage
< elementsof(hwndPages
) - 1 )
1461 ShowWindow( hwndPages
[iActualPage
], SW_HIDE
);
1462 ShowWindow( hwndPages
[++iActualPage
], SW_SHOW
);
1467 TCHAR szBuffer
[32767];
1468 CrashReportParams
*pParams
= (CrashReportParams
*)GetWindowLong( hwndDlg
, GWL_USERDATA
);
1470 pParams
->fAllowContact
= Button_GetCheck( GetDlgItem(hwndPages
[1], IDC_ALLOW_CONTACT
) ) ? TRUE
: FALSE
;
1472 Edit_GetText( GetDlgItem(hwndPages
[1], IDC_EDIT_TITLE
), szBuffer
, elementsof(szBuffer
) );
1473 pParams
->sTitle
= szBuffer
;
1475 Edit_GetText( GetDlgItem(hwndPages
[1], IDC_EDIT_DESCRIPTION
), szBuffer
, elementsof(szBuffer
) );
1476 pParams
->sComment
= szBuffer
;
1478 Edit_GetText( GetDlgItem(hwndPages
[1], IDC_EDIT_EMAIL
), szBuffer
, elementsof(szBuffer
) );
1479 pParams
->sEmail
= szBuffer
;
1481 if ( pParams
->fAllowContact
&& !pParams
->sEmail
.length() )
1483 TCHAR szMessage
[MAX_TEXT_BUFFER
];
1485 LoadAndFormatString( GetModuleHandle(NULL
), IDS_ERROR_MSG_NOEMAILADDRESS
, szMessage
, elementsof(szMessage
) );
1487 MessageBox( hwndDlg
, szMessage
, NULL
, MB_ICONERROR
| MB_OK
);
1488 break; // Don't end the dialog
1492 pParams
->WriteToRegistry();
1494 WriteCommentFile( pParams
->sComment
.c_str() );
1495 WriteReportFile( pParams
);
1497 if ( !SendCrashReport( hwndDlg
, *pParams
) )
1498 break; // Don't end the dialog
1503 EndDialog( hwndDlg
, wParam
);
1516 //*****************************************************************************
1517 //* Generate MD5 checksum
1518 //*****************************************************************************
1520 #define MAGIC_DESCRIPTION_FILLER 'x'
1521 #define MAGIC_DESCRIPTION_COUNT 80
1523 static void repatch_soffice_exe( void *pBuffer
, size_t nBufSize
)
1525 wchar_t DescriptionBuffer
[MAGIC_DESCRIPTION_COUNT
];
1527 memset( DescriptionBuffer
, 0, sizeof(DescriptionBuffer
) );
1528 wcsncpy( DescriptionBuffer
, g_wstrProductKey
.c_str(), elementsof(DescriptionBuffer
) - 1 );
1530 bool bPatched
= false;
1534 void *pFound
= memchr( pBuffer
, ((char *)DescriptionBuffer
)[0], nBufSize
);
1538 size_t distance
= (char *)pFound
- (char *)pBuffer
;
1540 if ( nBufSize
>= distance
)
1542 nBufSize
-= distance
;
1544 if ( nBufSize
>= sizeof(DescriptionBuffer
) &&
1545 0 == memcmp( pFound
, DescriptionBuffer
, sizeof(DescriptionBuffer
) ) )
1547 for ( int i
= 0; i
< 80; i
++ )
1549 ((wchar_t *)pFound
)[i
] = MAGIC_DESCRIPTION_FILLER
;
1555 pBuffer
= (void *)(((char *)pFound
) + 1);
1564 } while ( !bPatched
&& nBufSize
);
1567 // Normalize executable/library images to prevent different MD5 checksums due
1568 // to a different PE header date/checksum (this doesn't affect the code/data
1569 // sections of a executable/library. Please see tools/source/bootstrp/md5.cxx
1570 // where the same method is also used. The tool so_checksum creates the MD5
1571 // checksums during build time. You have to make sure that both methods use the
1572 // same algorithm otherwise there could be problems with stack reports.
1573 static void normalize_pe_image(sal_uInt8
* buffer
, size_t nBufferSize
)
1575 const int OFFSET_PE_OFFSET
= 0x3c;
1576 const int OFFSET_COFF_TIMEDATESTAMP
= 4;
1577 const int PE_SIGNATURE_SIZE
= 4;
1578 const int COFFHEADER_SIZE
= 20;
1579 const int OFFSET_PE_OPTIONALHEADER_CHECKSUM
= 64;
1581 // Check the header part of the file buffer
1582 if (buffer
[0] == 'M' && buffer
[1] == 'Z')
1584 unsigned long PEHeaderOffset
= (long)buffer
[OFFSET_PE_OFFSET
];
1585 if (PEHeaderOffset
< nBufferSize
-4)
1587 if ( buffer
[PEHeaderOffset
] == 'P' &&
1588 buffer
[PEHeaderOffset
+1] == 'E' &&
1589 buffer
[PEHeaderOffset
+2] == 0 &&
1590 buffer
[PEHeaderOffset
+3] == 0 )
1592 PEHeaderOffset
+= PE_SIGNATURE_SIZE
;
1593 if (PEHeaderOffset
+OFFSET_COFF_TIMEDATESTAMP
< nBufferSize
-4)
1595 // Set timedatestamp and checksum fields to a normalized
1596 // value to enforce the same MD5 checksum for identical
1597 // Windows executables/libraries.
1598 buffer
[PEHeaderOffset
+OFFSET_COFF_TIMEDATESTAMP
] = 0;
1599 buffer
[PEHeaderOffset
+OFFSET_COFF_TIMEDATESTAMP
+1] = 0;
1600 buffer
[PEHeaderOffset
+OFFSET_COFF_TIMEDATESTAMP
+2] = 0;
1601 buffer
[PEHeaderOffset
+OFFSET_COFF_TIMEDATESTAMP
+3] = 0;
1604 if (PEHeaderOffset
+COFFHEADER_SIZE
+OFFSET_PE_OPTIONALHEADER_CHECKSUM
< nBufferSize
-4)
1606 // Set checksum to a normalized value
1607 buffer
[PEHeaderOffset
+COFFHEADER_SIZE
+OFFSET_PE_OPTIONALHEADER_CHECKSUM
] = 0;
1608 buffer
[PEHeaderOffset
+COFFHEADER_SIZE
+OFFSET_PE_OPTIONALHEADER_CHECKSUM
+1] = 0;
1609 buffer
[PEHeaderOffset
+COFFHEADER_SIZE
+OFFSET_PE_OPTIONALHEADER_CHECKSUM
+2] = 0;
1610 buffer
[PEHeaderOffset
+COFFHEADER_SIZE
+OFFSET_PE_OPTIONALHEADER_CHECKSUM
+3] = 0;
1617 static sal_uInt32
calc_md5_checksum( const char *filename
, sal_uInt8
*pChecksum
, sal_uInt32 nChecksumLen
)
1619 const int MINIMAL_FILESIZE
= 512;
1621 sal_uInt32 nBytesProcessed
= 0;
1623 FILE *fp
= fopen( filename
, "rb" );
1629 if ( 0 == fseek( fp
, 0, SEEK_END
) && -1 != (nFileSize
= ftell(fp
)) )
1633 sal_uInt8
*pBuffer
= new sal_uInt8
[nFileSize
];
1634 size_t nBytesRead
= fread( pBuffer
, 1, nFileSize
, fp
);
1636 if ( sal::static_int_cast
<long>(nBytesRead
) == nFileSize
)
1638 if ( 0 == stricmp( GetFileName(filename
).c_str(), "soffice.bin" ) )
1639 repatch_soffice_exe( pBuffer
, nBytesRead
);
1640 else if ( nFileSize
> MINIMAL_FILESIZE
)
1641 normalize_pe_image( pBuffer
, nBytesRead
);
1643 rtlDigestError error
= rtl_digest_MD5 (
1644 pBuffer
, nBytesRead
,
1645 pChecksum
, nChecksumLen
);
1647 if ( rtl_Digest_E_None
== error
)
1648 nBytesProcessed
= nBytesRead
;
1658 return nBytesProcessed
;
1662 static sal_uInt32
calc_md5_checksum( const char *filename
, sal_uInt8
*pChecksum
, sal_uInt32 nChecksumLen
)
1664 sal_uInt32 nBytesProcessed
= 0;
1666 FILE *fp
= fopen( filename
, "rb" );
1670 rtlDigest digest
= rtl_digest_createMD5();
1675 sal_uInt8 buffer
[4096];
1676 rtlDigestError error
= rtl_Digest_E_None
;
1678 while ( rtl_Digest_E_None
== error
&&
1679 0 != (nBytesRead
= fread( buffer
, 1, sizeof(buffer
), fp
)) )
1681 error
= rtl_digest_updateMD5( digest
, buffer
, nBytesRead
);
1682 nBytesProcessed
+= nBytesRead
;
1685 if ( rtl_Digest_E_None
== error
)
1687 error
= rtl_digest_getMD5( digest
, pChecksum
, nChecksumLen
);
1690 if ( rtl_Digest_E_None
!= error
)
1691 nBytesProcessed
= 0;
1693 rtl_digest_destroyMD5( digest
);
1699 return nBytesProcessed
;
1703 //***************************************************************************
1705 static bool WriteStackFile( FILE *fout
, hash_map
< string
, string
>& rLibraries
, DWORD dwProcessId
, PEXCEPTION_POINTERS pExceptionPointers
)
1707 bool fSuccess
= false;
1709 if ( fout
&& dwProcessId
&& pExceptionPointers
)
1711 HANDLE hProcess
= OpenProcess( PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, dwProcessId
);
1713 if ( IsValidHandle(hProcess
) )
1715 EXCEPTION_POINTERS aExceptionPointers
;
1716 CONTEXT aContextRecord
;
1721 &aExceptionPointers
,
1722 sizeof(aExceptionPointers
),
1727 aExceptionPointers
.ContextRecord
,
1729 sizeof(aContextRecord
),
1734 ZeroMemory( &frame
, sizeof(frame
) );
1735 frame
.AddrPC
.Offset
= aContextRecord
.Eip
;
1736 frame
.AddrPC
.Mode
= AddrModeFlat
;
1737 frame
.AddrFrame
.Offset
= aContextRecord
.Ebp
;
1738 frame
.AddrFrame
.Mode
= AddrModeFlat
;
1743 SymInitialize( hProcess
, NULL
, TRUE
);
1745 fprintf( fout
, "<errormail:Stack type=\"Win32\">\n" );
1751 bSuccess
= StackWalk( IMAGE_FILE_MACHINE_I386
,
1756 (PREAD_PROCESS_MEMORY_ROUTINE
)ReadProcessMemory
,
1757 SymFunctionTableAccess
,
1763 // Note: ImageHelp ANSI functions do not have an A postfix while
1764 // Unicode versions have a W postfix. There's no macro
1765 // that depends on define UNICODE
1767 IMAGEHLP_MODULE moduleInfo
;
1769 ZeroMemory( &moduleInfo
, sizeof(moduleInfo
) );
1770 moduleInfo
.SizeOfStruct
= sizeof(moduleInfo
);
1772 if ( SymGetModuleInfo( hProcess
, frame
.AddrPC
.Offset
, &moduleInfo
) )
1774 rLibraries
[ GetFileName( moduleInfo
.LoadedImageName
).c_str() ] = moduleInfo
.LoadedImageName
;
1776 DWORD dwRelOffset
= 0;
1777 BYTE symbolBuffer
[sizeof(IMAGEHLP_SYMBOL
) + 256 ];
1778 PIMAGEHLP_SYMBOL pSymbol
= (PIMAGEHLP_SYMBOL
)symbolBuffer
;
1780 ZeroMemory( symbolBuffer
, sizeof(symbolBuffer
) );
1781 pSymbol
->SizeOfStruct
= sizeof(IMAGEHLP_SYMBOL
);
1782 pSymbol
->MaxNameLength
= 256;
1784 if ( SymGetSymFromAddr( hProcess
, frame
.AddrPC
.Offset
, &dwRelOffset
, pSymbol
) )
1785 fprintf( fout
, "<errormail:StackInfo " \
1786 "pos=\"%d\" ip=\"0x%p\" rel=\"0x%p\" ordinal=\"%s+0x%p\" name=\"%s\" path=\"%s\"/>\n",
1788 frame
.AddrPC
.Offset
,
1789 frame
.AddrPC
.Offset
- moduleInfo
.BaseOfImage
,
1790 xml_encode(pSymbol
->Name
).c_str(),
1791 frame
.AddrPC
.Offset
- pSymbol
->Address
,
1792 xml_encode(GetFileName( moduleInfo
.LoadedImageName
)).c_str(),
1793 xml_encode( GetFileDirectory( moduleInfo
.LoadedImageName
)).c_str()
1796 fprintf( fout
, "<errormail:StackInfo " \
1797 "pos=\"%d\" ip=\"0x%p\" rel=\"0x%p\" name=\"%s\" path=\"%s\"/>\n",
1799 frame
.AddrPC
.Offset
,
1800 frame
.AddrPC
.Offset
- moduleInfo
.BaseOfImage
,
1801 xml_encode(GetFileName( moduleInfo
.LoadedImageName
)).c_str(),
1802 xml_encode(GetFileDirectory( moduleInfo
.LoadedImageName
)).c_str()
1806 fprintf( fout
, "<errormail:StackInfo pos=\"%d\" ip=\"0x%p\"/>\n",
1814 } while ( bSuccess
);
1816 fprintf( fout
, "</errormail:Stack>\n" );
1818 SymCleanup( hProcess
);
1820 CloseHandle( hProcess
);
1828 bool WriteChecksumFile( FILE *fchksum
, const hash_map
< string
, string
>& rLibraries
)
1830 bool success
= false;
1832 if ( fchksum
&& rLibraries
.size() )
1834 fprintf( fchksum
, "<errormail:Checksums type=\"MD5\">\n" );
1836 hash_map
< string
, string
>::const_iterator iter
;
1838 for ( iter
= rLibraries
.begin();
1839 iter
!= rLibraries
.end();
1842 sal_uInt8 checksum
[RTL_DIGEST_LENGTH_MD5
];
1843 sal_uInt32 nBytesProcessed
= calc_md5_checksum(
1844 iter
->second
.c_str(),
1845 checksum
, sizeof(checksum
) );
1847 if ( nBytesProcessed
)
1849 fprintf( fchksum
, "<errormail:Checksum sum=\"0x" );
1850 for ( int i
= 0; i
< sizeof(checksum
); fprintf( fchksum
, "%02X", checksum
[i
++] ) );
1851 fprintf( fchksum
, "\" bytes=\"%d\" file=\"%s\"/>\n",
1853 GetFileName( iter
->first
) );
1857 fprintf( fchksum
, "</errormail:Checksums>\n" );
1865 //***************************************************************************
1869 TCHAR szFileName
[MAX_PATH
];
1871 if ( GetCrashDataPath( szFileName
) )
1873 _tcscat( szFileName
, _T("\\crashdat.dmp") );
1875 HANDLE hFile
= CreateFile(
1880 FILE_ATTRIBUTE_NORMAL
, NULL
);
1884 CloseHandle( hFile
);
1886 WideCharToMultiByte( CP_ACP
, 0, szFileName
, -1, g_szDumpFileNameA
, MAX_PATH
, NULL
, NULL
);
1887 _tcscpy( g_szDumpFileName
, szFileName
);
1896 BOOL
WriteDumpFile( DWORD dwProcessId
, PEXCEPTION_POINTERS pExceptionPointers
, DWORD dwThreadId
)
1898 BOOL fSuccess
= FALSE
;
1899 PMINIDUMP_EXCEPTION_INFORMATION lpExceptionParam
= NULL
;
1900 MINIDUMP_EXCEPTION_INFORMATION ExceptionParam
;
1902 HMODULE hDbgHelp
= LoadLibrary( _T("DBGHELP.DLL" ) );
1903 MiniDumpWriteDump_PROC pMiniDumpWriteDump
= NULL
;
1907 pMiniDumpWriteDump
= (MiniDumpWriteDump_PROC
)GetProcAddress( hDbgHelp
, "MiniDumpWriteDump" );
1909 if ( !pMiniDumpWriteDump
)
1911 FreeLibrary( hDbgHelp
);
1916 if ( !pMiniDumpWriteDump
)
1919 HANDLE hProcess
= OpenProcess( PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, dwProcessId
);
1921 if ( IsValidHandle(hProcess
) )
1923 TCHAR szTempPath
[MAX_PATH
];
1925 // if ( GetTempPath( elementsof(szTempPath), szTempPath ) )
1926 if ( GetCrashDataPath( szTempPath
) )
1928 TCHAR szFileName
[MAX_PATH
];
1930 // if ( GetTempFileName( szTempPath, TEXT("DMP"), 0, szFileName ) )
1931 _tcscpy( szFileName
, szTempPath
);
1932 _tcscat( szFileName
, _T("\\crashdat.dmp") );
1934 HANDLE hFile
= CreateFile(
1936 GENERIC_READ
| GENERIC_WRITE
,
1940 FILE_ATTRIBUTE_NORMAL
, NULL
);
1944 if ( pExceptionPointers
&& dwThreadId
)
1946 ExceptionParam
.ThreadId
= dwThreadId
;
1947 ExceptionParam
.ExceptionPointers
= pExceptionPointers
;
1948 ExceptionParam
.ClientPointers
= TRUE
;
1950 EXCEPTION_POINTERS aExceptionPointers
;
1951 EXCEPTION_RECORD aExceptionRecord
;
1956 &aExceptionPointers
,
1957 sizeof(aExceptionPointers
),
1963 aExceptionPointers
.ExceptionRecord
,
1965 sizeof(aExceptionRecord
),
1968 g_dwExceptionCode
= aExceptionRecord
.ExceptionCode
;
1970 lpExceptionParam
= &ExceptionParam
;
1973 fSuccess
= pMiniDumpWriteDump( hProcess
, dwProcessId
, hFile
, MiniDumpNormal
, lpExceptionParam
, NULL
, NULL
);
1975 CloseHandle( hFile
);
1977 WideCharToMultiByte( CP_ACP
, 0, szFileName
, -1, g_szDumpFileNameA
, MAX_PATH
, NULL
, NULL
);
1978 _tcscpy( g_szDumpFileName
, szFileName
);
1982 DeleteFile( szFileName
);
1986 CloseHandle( hProcess
);
1989 FreeLibrary( hDbgHelp
);
1994 //***************************************************************************
1996 static DWORD
FindProcessForImage( LPCTSTR lpImagePath
)
1998 DWORD dwProcessId
= 0;
1999 DWORD aProcesses
[1024];
2001 TCHAR szShortImagePath
[MAX_PATH
];
2003 if ( GetShortPathName( lpImagePath
, szShortImagePath
, elementsof(szShortImagePath
) ) &&
2004 EnumProcesses( aProcesses
, sizeof(aProcesses
), &dwSize
) )
2006 unsigned nProcesses
= dwSize
/ sizeof(aProcesses
[0]);
2008 for ( unsigned i
= 0; !dwProcessId
&& i
< nProcesses
; i
++ )
2010 HANDLE hProcess
= OpenProcess( PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, aProcesses
[i
] );
2012 if ( IsValidHandle(hProcess
) )
2014 TCHAR szModulePath
[MAX_PATH
+1];
2016 if ( GetModuleFileNameEx( hProcess
, NULL
, szModulePath
, MAX_PATH
) )
2018 TCHAR szShortModulePath
[MAX_PATH
];
2020 if ( GetShortPathName( szModulePath
, szShortModulePath
, elementsof(szShortModulePath
) ) )
2022 if ( 0 == _tcsicmp( szShortModulePath
, szShortImagePath
) )
2023 dwProcessId
= aProcesses
[i
];
2027 CloseHandle( hProcess
);
2034 //***************************************************************************
2036 static bool ParseCommandArgs( LPDWORD pdwProcessId
, PEXCEPTION_POINTERS
* ppException
, LPDWORD pdwThreadId
)
2041 TCHAR
**argv
= reinterpret_cast<TCHAR
**>(alloca((argc
+1)*sizeof(WCHAR
*)));
2042 int *sizes
= reinterpret_cast<int *>(alloca(argc
*sizeof(int)));
2047 for (i
= 0; i
< argc
; ++i
)
2049 sizes
[i
]=MultiByteToWideChar(CP_ACP
, 0, *ptr
, -1, NULL
, 0);
2050 argsize
+=sizes
[i
]+1;
2054 TCHAR
*args
= reinterpret_cast<TCHAR
*>(alloca(argsize
*sizeof(WCHAR
)));
2057 for (i
= 0; i
< argc
; ++i
)
2060 MultiByteToWideChar( CP_ACP
, 0, *ptr
, -1, cptr
, sizes
[i
] );
2069 TCHAR
**argv
= __argv
;
2072 TCHAR
**argv
= __targv
;
2074 bool bSuccess
= true;
2076 for ( int argn
= 1; bSuccess
&& argn
< argc
; argn
++ )
2078 if ( 0 == _tcsicmp( argv
[argn
], _T("-h") ) ||
2079 0 == _tcsicmp( argv
[argn
], _T("/h") ) ||
2080 0 == _tcsicmp( argv
[argn
], _T("-?") ) ||
2081 0 == _tcsicmp( argv
[argn
], _T("/?") ) ||
2082 0 == _tcsicmp( argv
[argn
], _T("/help") ) ||
2083 0 == _tcsicmp( argv
[argn
], _T("-help") ) ||
2084 0 == _tcsicmp( argv
[argn
], _T("--help") )
2087 HINSTANCE hInstance
= GetModuleHandle(NULL
);
2088 TCHAR szUsage
[FORMATBUFSIZE
];
2089 TCHAR szProcess
[FORMATBUFSIZE
];
2090 TCHAR szProcessDescription
[FORMATBUFSIZE
];
2091 TCHAR szHelpDescription
[FORMATBUFSIZE
];
2093 LoadAndFormatString( hInstance
, IDS_MSG_CMDLINE_USAGE
, szUsage
, elementsof(szUsage
) );
2094 LoadAndFormatString( hInstance
, IDS_MSG_PARAM_PROCESSID
, szProcess
, elementsof(szProcess
) );
2095 LoadAndFormatString( hInstance
, IDS_MSG_PARAM_PROCESSID_DESCRIPTION
, szProcessDescription
, elementsof(szProcessDescription
) );
2096 LoadAndFormatString( hInstance
, IDS_MSG_PARAM_HELP_DESCRIPTION
, szHelpDescription
, elementsof(szHelpDescription
) );
2099 TEXT("\n%s: crashrep %s\n\n")
2100 TEXT("/?, -h[elp] %s\n\n")
2101 TEXT("%-20s %s\n\n"),
2102 szUsage
, szProcess
, szHelpDescription
, szProcess
, szProcessDescription
2107 else if ( 0 == _tcsicmp( argv
[argn
], _T("-p") ) ||
2108 0 == _tcsicmp( argv
[argn
], _T("/p") ) )
2110 if ( ++argn
< argc
)
2111 *pdwProcessId
= _tcstoul( argv
[argn
], NULL
, 0 );
2115 else if ( 0 == _tcsicmp( argv
[argn
], _T("-excp") ) ||
2116 0 == _tcsicmp( argv
[argn
], _T("/excp") ) )
2118 if ( ++argn
< argc
)
2119 *ppException
= (PEXCEPTION_POINTERS
)_tcstoul( argv
[argn
], NULL
, 0 );
2123 else if ( 0 == _tcsicmp( argv
[argn
], _T("-t") ) ||
2124 0 == _tcsicmp( argv
[argn
], _T("/t") ) )
2126 if ( ++argn
< argc
)
2127 *pdwThreadId
= _tcstoul( argv
[argn
], NULL
, 0 );
2131 else if ( 0 == _tcsicmp( argv
[argn
], _T("-noui") ) ||
2132 0 == _tcsicmp( argv
[argn
], _T("/noui") ) )
2134 g_bNoUserInterface
= true;
2136 else if ( 0 == _tcsicmp( argv
[argn
], _T("-send") ) ||
2137 0 == _tcsicmp( argv
[argn
], _T("/send") ) )
2139 g_bSendReport
= true;
2141 else if ( 0 == _tcsicmp( argv
[argn
], _T("-load") ) ||
2142 0 == _tcsicmp( argv
[argn
], _T("/load") ) )
2144 g_bLoadReport
= true;
2146 else // treat parameter as image path
2148 TCHAR szImagePath
[MAX_PATH
];
2151 if ( GetFullPathName( argv
[argn
], MAX_PATH
, szImagePath
, &lpImageName
) )
2153 DWORD dwProcessId
= FindProcessForImage( szImagePath
);
2156 *pdwProcessId
= dwProcessId
;
2163 if ( !*pdwProcessId
&& !g_bLoadReport
)
2165 TCHAR szImagePath
[MAX_PATH
];
2168 if ( GetFullPathName( TEXT("soffice.exe"), MAX_PATH
, szImagePath
, &lpImageName
) )
2170 DWORD dwProcessId
= FindProcessForImage( szImagePath
);
2173 *pdwProcessId
= dwProcessId
;
2182 //***************************************************************************
2184 BOOL
WriteCommentFile( LPCTSTR lpComment
)
2186 BOOL fSuccess
= FALSE
;
2187 TCHAR szTempPath
[MAX_PATH
];
2189 if ( GetTempPath( elementsof(szTempPath
), szTempPath
) )
2191 TCHAR szFileName
[MAX_PATH
];
2193 if ( GetTempFileName( szTempPath
, TEXT("CMT"), 0, szFileName
) )
2195 HANDLE hFile
= CreateFile( szFileName
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2199 DWORD dwBytesWritten
;
2201 int needed
= WideCharToMultiByte( CP_UTF8
, 0, lpComment
, -1, NULL
, 0, NULL
, NULL
);
2204 char *lpCommentUTF8
= (char *)alloca( needed
);
2205 WideCharToMultiByte( CP_UTF8
, 0, lpComment
, -1, lpCommentUTF8
, needed
, NULL
, NULL
);
2206 fSuccess
= WriteFile( hFile
, lpCommentUTF8
, strlen(lpCommentUTF8
), &dwBytesWritten
, NULL
);
2212 CloseHandle( hFile
);
2214 WideCharToMultiByte( CP_ACP
, 0, szFileName
, -1, g_szCommentFileNameA
, MAX_PATH
, NULL
, NULL
);
2218 DeleteFile( szFileName
);
2225 //***************************************************************************
2227 static int _tsetenv( const _TCHAR
*lpVar
, const _TCHAR
*lpValue
)
2232 _TCHAR
*envstr
= (TCHAR
*)alloca( (_tcslen( lpVar
) + _tcslen( lpValue
) + 2) * sizeof(_TCHAR
) );
2234 _tcscpy( envstr
, lpVar
);
2235 _tcscat( envstr
, _T("=") );
2236 _tcscat( envstr
, lpValue
);
2238 return _tputenv( envstr
);
2241 static bool read_line( FILE *fp
, string
& rLine
)
2243 char szBuffer
[1024];
2244 bool bSuccess
= false;
2249 while ( !bEOL
&& fgets( szBuffer
, sizeof(szBuffer
), fp
) )
2251 int len
= strlen(szBuffer
);
2255 while ( len
&& szBuffer
[len
- 1] == '\n' )
2257 szBuffer
[--len
] = 0;
2261 line
.append( szBuffer
);
2268 static string
get_script_string( const char *pFileName
, const char *pKeyName
)
2270 FILE *fp
= fopen( pFileName
, "rt" );
2278 while ( read_line( fp
, line
) )
2280 line
= trim_string( line
);
2283 string::size_type iEqualSign
= line
.find( '=', 0 );
2285 if ( iEqualSign
!= string::npos
)
2287 string keyname
= line
.substr( 0, iEqualSign
);
2288 keyname
= trim_string( keyname
);
2290 string value
= line
.substr( sal::static_int_cast
<string::size_type
>(iEqualSign
+ 1) );
2291 value
= trim_string( value
);
2293 if ( value
.length() && '\"' == value
[0] )
2295 value
.erase( 0, 1 );
2297 string::size_type iQuotes
= value
.find( '"', 0 );
2299 if ( iQuotes
!= string::npos
)
2300 value
.erase( iQuotes
);
2303 if ( 0 == stricmp( keyname
.c_str(), pKeyName
) )
2317 static bool ReadBootstrapParams( CrashReportParams
&rParams
)
2319 TCHAR szBuffer
[256] = TEXT("");
2320 TCHAR szModuleName
[MAX_PATH
];
2321 TCHAR szModuleVersionName
[MAX_PATH
];
2322 TCHAR szDrive
[_MAX_DRIVE
];
2323 TCHAR szDir
[_MAX_DIR
];
2324 TCHAR szFName
[_MAX_FNAME
];
2325 TCHAR szExt
[_MAX_EXT
];
2326 TCHAR szReportServer
[MAX_HOSTNAME
];
2327 TCHAR szReportPort
[256];
2328 bool bSuccess
= false;
2330 GetModuleFileName( NULL
, szModuleName
, MAX_PATH
);
2331 _tsplitpath( szModuleName
, szDrive
, szDir
, szFName
, szExt
);
2332 _tmakepath( szModuleName
, szDrive
, szDir
, _T("bootstrap"), _T(".ini") );
2333 _tmakepath( szModuleVersionName
, szDrive
, szDir
, _T("version"), _T(".ini") );
2336 GetPrivateProfileString(
2339 TEXT("OpenOffice.org"),
2341 elementsof(szBuffer
),
2345 TCHAR
*pVersion
= _tcschr( szBuffer
, ' ' );
2347 g_wstrProductKey
= szBuffer
;
2355 pVersion
= TEXT("");
2357 if ( !_tgetenv( _T("PRODUCTNAME") ) )
2359 _tsetenv( TEXT("PRODUCTNAME"), szBuffer
);
2361 if ( !_tgetenv( _T("PRODUCTVERSION") ) )
2362 _tsetenv( TEXT("PRODUCTVERSION"), pVersion
);
2365 GetPrivateProfileString(
2369 g_szBuildId
, elementsof(g_szBuildId
),
2370 szModuleVersionName
);
2372 g_strDefaultLanguage
= get_script_string( "instdb.inf", "DefaultLanguage" );
2374 if ( GetPrivateProfileString(
2375 TEXT("ErrorReport"),
2376 TEXT("ErrorReportPort"),
2378 szReportPort
, elementsof(szReportPort
),
2382 TCHAR
*endptr
= NULL
;
2384 unsigned short uReportPort
= (unsigned short)_tcstoul( szReportPort
, &endptr
, 10 );
2386 g_uReportPort
= uReportPort
;
2389 if ( GetPrivateProfileString(
2390 TEXT("ErrorReport"),
2391 TEXT("ErrorReportServer"),
2393 szReportServer
, elementsof(szReportServer
),
2397 bSuccess
= 0 != WideCharToMultiByte( CP_ACP
, 0, szReportServer
, -1, g_szReportServerA
, elementsof(g_szReportServerA
), NULL
, NULL
);
2400 LPCTSTR lpEnvString
;
2402 if ( 0 != (lpEnvString
= _tgetenv( _T("ERRORREPORT_PROXYSERVER") )) )
2403 rParams
.sProxyServer
= lpEnvString
;
2405 if ( 0 != (lpEnvString
= _tgetenv( _T("ERRORREPORT_PROXYPORT") )) )
2406 rParams
.sProxyPort
= lpEnvString
;
2408 if ( 0 != (lpEnvString
= _tgetenv( _T("ERRORREPORT_SENDERADDRESS") )) )
2409 rParams
.sEmail
= lpEnvString
;
2414 //***************************************************************************
2416 bool SendHTTPRequest(
2418 const char *pszServer
,
2419 unsigned short uPort
= 80,
2420 const char *pszProxyServer
= NULL
,
2421 unsigned short uProxyPort
= 8080 )
2423 bool success
= false;
2427 if ( pszProxyServer
)
2428 hp
= gethostbyname( pszProxyServer
);
2430 hp
= gethostbyname( pszServer
);
2434 SOCKET s
= socket( AF_INET
, SOCK_STREAM
, 0 );
2438 struct sockaddr_in address
;
2440 memcpy(&(address
.sin_addr
.s_addr
), *(hp
->h_addr_list
),sizeof(struct in_addr
));
2441 address
.sin_family
= AF_INET
;
2443 if ( pszProxyServer
)
2444 address
.sin_port
= ntohs( uProxyPort
);
2446 address
.sin_port
= ntohs( uPort
);
2448 if ( 0 == connect( s
, (struct sockaddr
*)&address
, sizeof(struct sockaddr_in
)) )
2450 fseek( fp
, 0, SEEK_END
);
2451 size_t length
= ftell( fp
);
2452 fseek( fp
, 0, SEEK_SET
);
2456 if ( pszProxyServer
)
2458 "POST http://%s:%d/soap/servlet/rpcrouter HTTP/1.0\r\n"
2459 "Content-Type: text/xml; charset=\"utf-8\"\r\n"
2460 "Content-Length: %d\r\n"
2461 "SOAPAction: \"\"\r\n\r\n",
2468 "POST /soap/servlet/rpcrouter HTTP/1.0\r\n"
2469 "Content-Type: text/xml; charset=\"utf-8\"\r\n"
2470 "Content-Length: %d\r\n"
2471 "SOAPAction: \"\"\r\n\r\n",
2475 if ( SOCKET_ERROR
!= send( s
, buffer
, strlen(buffer
), 0 ) )
2481 nBytes
= fread( buffer
, 1, sizeof(buffer
), fp
);
2484 success
= SOCKET_ERROR
!= send( s
, buffer
, nBytes
, 0 );
2485 } while( nBytes
&& success
);
2489 memset( buffer
, 0, sizeof(buffer
) );
2490 success
= SOCKET_ERROR
!= recv( s
, buffer
, sizeof(buffer
), 0 );
2493 char szHTTPSignature
[sizeof(buffer
)] = "";
2494 unsigned uHTTPReturnCode
= 0;
2496 sscanf( buffer
, "%s %d ", szHTTPSignature
, &uHTTPReturnCode
);
2497 success
= uHTTPReturnCode
== 200;
2511 //***************************************************************************
2513 static void WriteSOAPRequest( FILE *fp
)
2516 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
2517 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
2518 "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n"
2519 "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n"
2520 "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n"
2521 "xmlns:rds=\"urn:ReportDataService\"\n"
2522 "xmlns:apache=\"http://xml.apache.org/xml-soap\"\n"
2523 "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
2527 fprintf( fp
, "<rds:submitReport>\n" );
2528 fprintf( fp
, "<body xsi:type=\"xsd:string\">This is an autogenerated crash report mail.</body>\n" );
2529 fprintf( fp
, "<hash xsi:type=\"apache:Map\">\n" );
2531 FILE *fpin
= fopen( g_szReportFileNameA
, "r" );
2536 "<key xsi:type=\"xsd:string\">reportmail.xml</key>\n"
2537 "<value xsi:type=\"xsd:string\"><![CDATA[" );
2539 fprintf( fp
, "]]></value></item>\n" );
2543 fpin
= fopen( g_szCommentFileNameA
, "r" );
2548 "<key xsi:type=\"xsd:string\">description.txt</key>\n"
2549 "<value xsi:type=\"xsd:string\"><![CDATA[" );
2551 fprintf( fp
, "]]></value></item>\n" );
2556 fpin
= fopen( g_szDumpFileNameA
, "rb" );
2559 FILE *fptemp
= _tmpfile();
2563 if ( base64_encode( fpin
, fptemp
) )
2565 fseek( fptemp
, 0, SEEK_SET
);
2568 "<key xsi:type=\"xsd:string\">user.dmp</key>\n"
2569 "<value xsi:type=\"xsd:string\">" );
2570 fcopy( fptemp
, fp
);
2571 fprintf( fp
, "</value></item>\n" );
2580 "</rds:submitReport>\n"
2581 "</SOAP-ENV:Body>\n"
2582 "</SOAP-ENV:Envelope>\n"
2586 //***************************************************************************
2588 struct RequestParams
2592 const char *lpServer
;
2593 unsigned short uPort
;
2594 const char *lpProxyServer
;
2595 unsigned short uProxyPort
;
2599 void _cdecl
SendingThread( void *lpArgs
)
2601 RequestParams
*pParams
= (RequestParams
*)lpArgs
;
2603 pParams
->success
= SendHTTPRequest( pParams
->fpin
, pParams
->lpServer
, pParams
->uPort
, pParams
->lpProxyServer
, pParams
->uProxyPort
);
2605 PostMessage( pParams
->hwndStatus
, WM_COMMAND
, IDOK
, 0 );
2608 //***************************************************************************
2610 BOOL CALLBACK
SendingStatusDialogProc(
2617 static RequestParams
*pRequest
= NULL
;
2618 static HANDLE hSendingThread
= NULL
;
2624 TCHAR szBuffer
[1024] = TEXT("");
2625 HINSTANCE hInstance
= (HINSTANCE
)GetWindowLong( hwndDlg
, GWL_HINSTANCE
);
2626 //HWND hwndParent = (HWND)GetWindowLong( hwndDlg, GWL_HWNDPARENT );
2628 pRequest
= (RequestParams
*)lParam
;
2630 LoadAndFormatString( hInstance
, IDS_SENDING_REPORT_HEADER
, szBuffer
, elementsof(szBuffer
) );
2631 SetWindowText( hwndDlg
, szBuffer
);
2633 LoadAndFormatString( hInstance
, IDS_SENDING_REPORT_STATUS
, szBuffer
, elementsof(szBuffer
) );
2634 Static_SetText( GetDlgItem(hwndDlg
, IDC_SENDING_REPORT_STATUS
), szBuffer
);
2636 LoadAndFormatString( hInstance
, IDS_CANCEL_BUTTON
, szBuffer
, elementsof(szBuffer
) );
2637 Button_SetText( GetDlgItem(hwndDlg
, IDCANCEL
), szBuffer
);
2639 pRequest
->hwndStatus
= hwndDlg
;
2641 hSendingThread
= (HANDLE
)_beginthread( SendingThread
, 0, pRequest
);
2645 switch ( LOWORD(wParam
) )
2648 TerminateThread( hSendingThread
, 0 );
2650 WaitForSingleObject( hSendingThread
, INFINITE
);
2651 CloseHandle( hSendingThread
);
2652 EndDialog( hwndDlg
, wParam
);
2663 //***************************************************************************
2665 bool SendCrashReport( HWND hwndParent
, const CrashReportParams
&rParams
)
2667 bool success
= false;
2668 char szProxyServer
[1024] = "";
2669 unsigned short uProxyPort
= 8080;
2670 TCHAR
*endptr
= NULL
;
2672 switch ( rParams
.uInternetConnection
)
2676 WideCharToMultiByte(
2677 CP_ACP
, 0, rParams
.sProxyServer
.c_str(), -1,
2678 szProxyServer
, sizeof(szProxyServer
), NULL
, NULL
);
2679 uProxyPort
= (unsigned short)_tcstoul( rParams
.sProxyPort
.c_str(), &endptr
, 10 );
2684 DWORD dwProxyEnable
= 0;
2686 RegReadValue( HKEY_CURRENT_USER
,
2687 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
2688 TEXT("ProxyEnable"),
2690 sizeof(dwProxyEnable
) );
2692 if ( dwProxyEnable
)
2694 TCHAR tszProxyServers
[1024] = TEXT("");
2696 if ( ERROR_SUCCESS
== RegReadValue( HKEY_CURRENT_USER
,
2697 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"), TEXT("ProxyServer"),
2699 sizeof(tszProxyServers
) ) )
2701 TCHAR
*lpHttpStart
= _tcsstr( tszProxyServers
, TEXT("http=") );
2706 lpHttpStart
= tszProxyServers
;
2708 TCHAR
*lpHttpEnd
= _tcschr( lpHttpStart
, ';' );
2713 char szHTTPProxyServer
[1024] = "";
2714 WideCharToMultiByte( CP_ACP
, 0, lpHttpStart
, -1, szHTTPProxyServer
, sizeof(szHTTPProxyServer
), NULL
, NULL
);
2716 char *lpColon
= strchr( szHTTPProxyServer
, ':' );
2720 char *endptr
= NULL
;
2723 uProxyPort
= (unsigned short)strtoul( lpColon
+ 1, &endptr
, 10 );
2728 strcpy( szProxyServer
, szHTTPProxyServer
);
2739 FILE *fptemp
= _tmpfile();
2742 RequestParams request
;
2744 request
.success
= false;
2745 request
.fpin
= fptemp
;
2746 request
.lpServer
= REPORT_SERVER
;
2747 request
.uPort
= REPORT_PORT
;
2748 request
.lpProxyServer
= szProxyServer
[0] ? szProxyServer
: NULL
;
2749 request
.uProxyPort
= uProxyPort
;
2750 request
.hwndStatus
= NULL
;
2752 WriteSOAPRequest( fptemp
);
2753 fseek( fptemp
, 0, SEEK_SET
);
2757 int retid
= DialogBoxParam(
2758 GetModuleHandle(NULL
),
2759 MAKEINTRESOURCE(IDD_SENDING_STATUS
),
2761 SendingStatusDialogProc
,
2765 success
= request
.success
;
2767 if ( IDOK
== retid
)
2771 TCHAR szMessage
[1024];
2773 LoadAndFormatString( GetModuleHandle(NULL
), IDS_ERROR_MSG_PROXY
, szMessage
, elementsof(szMessage
) );
2775 MessageBox( hwndParent
, szMessage
, NULL
, MB_ICONERROR
| MB_OK
);
2779 TCHAR szMessage
[1024];
2780 TCHAR szTitle
[1024];
2782 LoadAndFormatString( GetModuleHandle(NULL
), IDS_SENDING_REPORT_STATUS_FINISHED
, szMessage
, elementsof(szMessage
) );
2783 LoadAndFormatString( GetModuleHandle(NULL
), IDS_SENDING_REPORT_HEADER
, szTitle
, elementsof(szTitle
) );
2785 MessageBox( hwndParent
, szMessage
, szTitle
, MB_ICONINFORMATION
| MB_OK
);
2792 HANDLE hSendingThread
= (HANDLE
)_beginthread( SendingThread
, 0, (void *)&request
);
2794 WaitForSingleObject( hSendingThread
, INFINITE
);
2796 success
= request
.success
;
2799 TCHAR szMessage
[1024];
2801 LoadAndFormatString( GetModuleHandle(NULL
), IDS_ERROR_MSG_PROXY
, szMessage
, elementsof(szMessage
) );
2802 _ftprintf( stderr
, _T("ERROR: %s\n"), szMessage
);
2806 TCHAR szMessage
[1024];
2808 LoadAndFormatString( GetModuleHandle(NULL
), IDS_SENDING_REPORT_STATUS_FINISHED
, szMessage
, elementsof(szMessage
) );
2810 _ftprintf( stderr
, _T("SUCCESS: %s\n"), szMessage
);
2817 TCHAR szMessage
[1024];
2819 LoadAndFormatString( GetModuleHandle(NULL
), IDS_ERROR_MSG_DISK_FULL
, szMessage
, elementsof(szMessage
) );
2822 MessageBox( hwndParent
, szMessage
, NULL
, MB_ICONERROR
| MB_OK
);
2824 _ftprintf( stderr
, _T("ERROR: %s\n"), szMessage
);
2830 //***************************************************************************
2833 int WINAPI
WinMain( HINSTANCE hInstance
, HINSTANCE
, LPSTR
/*lpCmdLine*/, int )
2835 int WINAPI
_tWinMain( HINSTANCE hInstance
, HINSTANCE
, LPTSTR
/*lpCmdLine*/, int )
2842 char **argv
= __argv
;
2845 char **argv
= new char *[argc
+ 1];
2847 for ( int argn
= 0; argn
< argc
; argn
++ )
2849 int nBytes
= WideCharToMultiByte( CP_ACP
, 0, __targv
[argn
], -1, NULL
, 0, NULL
, NULL
);
2850 argv
[argn
] = new char[nBytes
];
2851 WideCharToMultiByte( CP_ACP
, 0, __targv
[argn
], -1, argv
[argn
], nBytes
, NULL
, NULL
);
2855 char **argv
= __targv
;
2859 osl_setCommandArgs( argc
, argv
);
2861 PEXCEPTION_POINTERS pExceptionPointers
= NULL
;
2862 DWORD dwProcessId
= 0;
2863 DWORD dwThreadId
= 0;
2866 WORD wVersionRequested
;
2868 wVersionRequested
= MAKEWORD(1, 1);
2869 WSAStartup(wVersionRequested
, &wsaData
);
2871 CrashReportParams Params
;
2873 Params
.ReadFromRegistry();
2874 Params
.ReadFromEnvironment();
2876 if ( ReadBootstrapParams( Params
) &&
2877 ParseCommandArgs( &dwProcessId
, &pExceptionPointers
, &dwThreadId
) )
2881 if ( g_bLoadReport
)
2882 bGotDumpFile
= FindDumpFile();
2884 bGotDumpFile
= WriteDumpFile( dwProcessId
, pExceptionPointers
, dwThreadId
);
2888 hash_map
< string
, string
> aLibraries
;
2890 if ( g_bLoadReport
)
2892 g_fpStackFile
= _open_reportfile( _T(".stk"), _T("rb") );
2893 g_fpChecksumFile
= _open_reportfile( _T(".chk"), _T("rb") );
2897 if ( g_bSendReport
)
2899 g_fpStackFile
= _tmpfile();
2900 g_fpChecksumFile
= _tmpfile();
2904 g_fpStackFile
= _open_reportfile( _T(".stk"), _T("w+b") );
2905 g_fpChecksumFile
= _open_reportfile( _T(".chk"), _T("w+b") );
2907 FILE *fpUnsent
= _open_reportfile( _T(".lck"), _T("w+b") );
2910 fprintf( fpUnsent
, "Unsent\r\n" );
2915 WriteStackFile( g_fpStackFile
, aLibraries
, dwProcessId
, pExceptionPointers
);
2916 WriteChecksumFile( g_fpChecksumFile
, aLibraries
);
2917 WriteReportFile( &Params
);
2919 FILE *fpPreview
= _open_reportfile( _T(".prv"), _T("w+b") );
2923 FILE *fp
= fopen( g_szReportFileNameA
, "rb" );
2926 fcopy( fp
, fpPreview
);
2929 fclose( fpPreview
);
2933 if ( g_bSendReport
)
2935 InitCommonControls();
2937 // Actually this should never be true anymore
2938 if ( !g_bNoUserInterface
&& InitRichEdit() )
2941 INT_PTR result
= DialogBoxParam( hInstance
, MAKEINTRESOURCE(IDD_DIALOG_FRAME
), NULL
, DialogProc
, (LPARAM
)&Params
);
2951 WriteCommentFile( Params
.sComment
.c_str() );
2952 WriteReportFile( &Params
);
2953 if ( SendCrashReport( NULL
, Params
) )
2958 if ( g_szReportFileNameA
[0] )
2959 DeleteFileA( g_szReportFileNameA
);
2961 if ( g_szCommentFileNameA
[0] )
2962 DeleteFileA( g_szCommentFileNameA
);
2966 if ( g_szReportFileNameA
[0] )
2967 DeleteFileA( g_szReportFileNameA
);
2971 if ( g_szDumpFileNameA
[0] && g_bSendReport
)
2972 DeleteFileA( g_szDumpFileNameA
);
2974 if ( g_fpStackFile
)
2975 fclose( g_fpStackFile
);
2977 if ( g_fpChecksumFile
)
2978 fclose( g_fpChecksumFile
);