main.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #ifndef main_H
  2. #define main_H
  3. #ifdef _DEBUG
  4. # include <iostream>
  5. # include <sstream>
  6. # include <vector>
  7. # ifndef _LTMDB
  8. # define _CRTDBG_MAP_ALLOC
  9. # include <crtdbg.h>
  10. # include <stdlib.h>
  11. # define DEBUG_CLIENTBLOCK new (_CLIENT_BLOCK, __FILE__, __LINE__)
  12. # define new DEBUG_CLIENTBLOCK
  13. # define _LTMDB
  14. # endif
  15. #endif
  16. #define WIN32_LEAN_AND_MEAN
  17. #include <Windows.h>
  18. #pragma warning(push)
  19. #pragma warning(disable : 4091)
  20. #include <DbgHelp.h>
  21. #pragma warning(pop)
  22. #define KSGStart __stdcall
  23. #include "Globals.h"
  24. namespace Framework
  25. {
  26. //! Speichert die dem Programm vom Betriebssystem beim Start übergebenen
  27. //! Parameter
  28. struct Startparam
  29. {
  30. HINSTANCE hinst, hpinst;
  31. LPSTR cmd;
  32. int show;
  33. };
  34. //! Überschreibe diese Funktion. Sie wird vom Framework automatisch beim
  35. //! Start des Programmes aufgerufen \param p Die Parameter, die dem Programm
  36. //! beim Start vom Betriebssystem übergeben wurden
  37. int KSGStart Start(Startparam p);
  38. } // namespace Framework
  39. typedef BOOL(__stdcall* MINIDUMPWRITEDUMP)(HANDLE hProcess,
  40. DWORD dwPid,
  41. HANDLE hFile,
  42. MINIDUMP_TYPE DumpType,
  43. CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
  44. CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
  45. CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
  46. void createMinidump(struct _EXCEPTION_POINTERS* apExceptionInfo)
  47. {
  48. HMODULE mhLib = ::LoadLibrary("dbghelp.dll");
  49. MINIDUMPWRITEDUMP pDump = mhLib ? (MINIDUMPWRITEDUMP)::GetProcAddress(
  50. mhLib, "MiniDumpWriteDump")
  51. : 0;
  52. HANDLE hFile = ::CreateFile("error_core_memory_dump.dmp",
  53. GENERIC_WRITE,
  54. FILE_SHARE_WRITE,
  55. NULL,
  56. CREATE_ALWAYS,
  57. FILE_ATTRIBUTE_NORMAL,
  58. NULL);
  59. _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
  60. ExInfo.ThreadId = ::GetCurrentThreadId();
  61. ExInfo.ExceptionPointers = apExceptionInfo;
  62. ExInfo.ClientPointers = FALSE;
  63. if (pDump)
  64. pDump(GetCurrentProcess(),
  65. GetCurrentProcessId(),
  66. hFile,
  67. MiniDumpNormal,
  68. &ExInfo,
  69. NULL,
  70. NULL);
  71. ::CloseHandle(hFile);
  72. }
  73. LONG WINAPI unhandledHandler(struct _EXCEPTION_POINTERS* apExceptionInfo)
  74. {
  75. createMinidump(apExceptionInfo);
  76. return EXCEPTION_CONTINUE_SEARCH;
  77. }
  78. #ifdef _DEBUG
  79. template<typename TChar, typename TTraits> class OutputDebugStringBuf
  80. : public std::basic_stringbuf<TChar, TTraits>
  81. {
  82. public:
  83. explicit OutputDebugStringBuf()
  84. : _buffer(1)
  85. {
  86. __super::setg(nullptr, nullptr, nullptr);
  87. __super::setp(
  88. _buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
  89. }
  90. ~OutputDebugStringBuf() {}
  91. static_assert(
  92. std::is_same<TChar, char>::value || std::is_same<TChar, wchar_t>::value,
  93. "OutputDebugStringBuf only supports char and wchar_t types");
  94. int sync()
  95. try
  96. {
  97. MessageOutputer<TChar, TTraits>()(__super::pbase(), __super::pptr());
  98. __super::setp(
  99. _buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
  100. return 0;
  101. } catch (...)
  102. {
  103. return -1;
  104. }
  105. int overflow(int c = TTraits::eof())
  106. {
  107. auto syncRet = sync();
  108. if (c != TTraits::eof())
  109. {
  110. _buffer[0] = c;
  111. __super::setp(_buffer.data(),
  112. _buffer.data() + 1,
  113. _buffer.data() + _buffer.size());
  114. }
  115. return syncRet == -1 ? TTraits::eof() : 0;
  116. }
  117. private:
  118. std::vector<TChar> _buffer;
  119. template<typename TChar, typename TTraits> struct MessageOutputer;
  120. template<> struct MessageOutputer<char, std::char_traits<char>>
  121. {
  122. template<typename TIterator>
  123. void operator()(TIterator begin, TIterator end) const
  124. {
  125. std::string s(begin, end);
  126. OutputDebugStringA(s.c_str());
  127. }
  128. };
  129. template<> struct MessageOutputer<wchar_t, std::char_traits<wchar_t>>
  130. {
  131. template<typename TIterator>
  132. void operator()(TIterator begin, TIterator end) const
  133. {
  134. std::wstring s(begin, end);
  135. OutputDebugStringW(s.c_str());
  136. }
  137. };
  138. };
  139. #endif
  140. #ifndef NO_MAIN
  141. int WINAPI WinMain(_In_ HINSTANCE hinst,
  142. _In_opt_ HINSTANCE hpinst,
  143. _In_ LPSTR cmd,
  144. int _In_ show)
  145. {
  146. # ifdef _DEBUG
  147. _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  148. OutputDebugStringBuf<char, std::char_traits<char>> charDebugOutput;
  149. std::streambuf* buf = std::cout.rdbuf();
  150. std::cout.rdbuf(&charDebugOutput);
  151. # endif
  152. SetUnhandledExceptionFilter(unhandledHandler);
  153. Framework::initFramework(hinst);
  154. Framework::Startparam stp;
  155. stp.hinst = hinst;
  156. stp.hpinst = hpinst;
  157. stp.cmd = cmd;
  158. stp.show = show;
  159. int ret = Framework::Start(stp);
  160. Framework::releaseFramework();
  161. # ifdef _DEBUG
  162. std::cout.rdbuf(buf);
  163. # endif
  164. return ret;
  165. }
  166. #endif
  167. #endif