1 // Copyright 2014 Idol Software, Inc.
3 // This file is part of Doctor Dump SDK.
5 // Doctor Dump SDK is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "DumpWriter.h"
26 DumpWriter::DumpWriter(Log
& log
)
29 , m_pfnMiniDumpWriteDump(NULL
)
33 DumpWriter::~DumpWriter()
35 m_pfnMiniDumpWriteDump
= NULL
;
38 FreeLibrary(m_hDbgHelp
);
43 void DumpWriter::Init(LPCWSTR dbgHelpPath
)
46 m_dbgHelpPath
= dbgHelpPath
;
47 m_hDbgHelp
= LoadLibraryW(m_dbgHelpPath
);
50 m_hDbgHelp
= LoadLibrary(_T("dbghelp.dll"));
52 throw runtime_error("failed to load dbghelp.dll");
55 #define GetProc(func)\
56 m_pfn##func = (fn##func) GetProcAddress(m_hDbgHelp, #func);\
58 throw runtime_error("failed to get " #func);
60 GetProc(MiniDumpWriteDump
);
64 bool DumpWriter::WriteMiniDump(
67 MINIDUMP_EXCEPTION_INFORMATION
* pExceptInfo
,
69 MINIDUMP_TYPE DumpType
,
70 MINIDUMP_CALLBACK_INFORMATION
* pCallback
)
72 if (!m_pfnMiniDumpWriteDump
)
75 HANDLE hFile
= CreateFile(pszFileName
,
80 FILE_ATTRIBUTE_NORMAL
,
83 if (hFile
== INVALID_HANDLE_VALUE
)
86 bool result
= m_pfnMiniDumpWriteDump(hProcess
, dwProcessId
,
87 hFile
, DumpType
, pExceptInfo
, NULL
, pCallback
) != FALSE
;
89 DWORD err
= GetLastError();
93 DWORD dwFileSize
= GetFileSize(hFile
, NULL
);
94 result
= dwFileSize
!= INVALID_FILE_SIZE
&& dwFileSize
> 1024;
96 err
= ERROR_INVALID_DATA
;
100 m_log
.Error(_T("MiniDumpWriteDump failed, 0x%08x"), err
);
110 DumpFilter::DumpFilter(bool& cancel
, DWORD saveOnlyThisThreadID
)
111 : m_saveOnlyThisThreadID(saveOnlyThisThreadID
), m_cancel(cancel
)
113 m_callback
.CallbackRoutine
= _MinidumpCallback
;
114 m_callback
.CallbackParam
= this;
117 BOOL
DumpFilter::MinidumpCallback(const PMINIDUMP_CALLBACK_INPUT CallbackInput
, PMINIDUMP_CALLBACK_OUTPUT CallbackOutput
)
122 switch (CallbackInput
->CallbackType
)
125 CallbackOutput
->CheckCancel
= TRUE
;
127 CallbackOutput
->Cancel
= TRUE
;
129 case IncludeThreadCallback
:
130 if (m_saveOnlyThisThreadID
!= 0 && CallbackInput
->IncludeThread
.ThreadId
!= m_saveOnlyThisThreadID
)
132 CallbackOutput
->ThreadWriteFlags
= 0;
137 if (m_saveOnlyThisThreadID
!= 0 && CallbackInput
->Thread
.ThreadId
!= m_saveOnlyThisThreadID
)
138 CallbackOutput
->ThreadWriteFlags
= 0;
145 BOOL CALLBACK
DumpFilter::_MinidumpCallback(PVOID CallbackParam
, const PMINIDUMP_CALLBACK_INPUT CallbackInput
, PMINIDUMP_CALLBACK_OUTPUT CallbackOutput
)
147 return static_cast<DumpFilter
*>(CallbackParam
)->MinidumpCallback(CallbackInput
, CallbackOutput
);