Win32app.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. #include "pch.h"
  2. #include "regkey.h"
  3. //////////////////////////////////////////////////////////////////////////////
  4. //
  5. // Some assertion functions
  6. //
  7. //////////////////////////////////////////////////////////////////////////////
  8. Win32App *g_papp;
  9. //////////////////////////////////////////////////////////////////////////////
  10. //
  11. // Some assertion functions
  12. //
  13. //////////////////////////////////////////////////////////////////////////////
  14. void ZAssertImpl(bool bSucceeded, const char* psz, const char* pszFile, int line, const char* pszModule)
  15. {
  16. if (!bSucceeded) {
  17. //
  18. // Just in case this was a Win32 error get the last error
  19. //
  20. DWORD dwError = GetLastError();
  21. if (!g_papp) {
  22. __asm int 3; // (debug break)
  23. } else if (g_papp->OnAssert(psz, pszFile, line, pszModule)) {
  24. g_papp->OnAssertBreak();
  25. }
  26. }
  27. }
  28. void ZDebugOutputImpl(const char *psz)
  29. {
  30. if (g_papp)
  31. g_papp->DebugOutput(psz);
  32. else
  33. ::OutputDebugStringA(psz);
  34. }
  35. HANDLE g_logfile = NULL;
  36. void retailf(const char* format, ...)
  37. {
  38. if (g_bOutput)
  39. {
  40. #ifndef DREAMCAST
  41. const size_t size = 256;
  42. char bfr[size];
  43. va_list vl;
  44. va_start(vl, format);
  45. _vsnprintf(bfr, size, format, vl);
  46. va_end(vl);
  47. ZDebugOutputImpl(bfr);
  48. #else
  49. ZDebugOutputImpl(format);
  50. #endif
  51. }
  52. }
  53. extern bool g_bOutput = true;
  54. #ifdef _DEBUG
  55. void ZWarningImpl(bool bSucceeded, const char* psz, const char* pszFile, int line, const char* pszModule)
  56. {
  57. if (!bSucceeded) {
  58. debugf("%s(%d) : ShouldBe failed: '%s'\n", pszFile, line, psz);
  59. }
  60. }
  61. bool ZFailedImpl(HRESULT hr, const char* pszFile, int line, const char* pszModule)
  62. {
  63. bool bFailed = FAILED(hr);
  64. ZAssertImpl(!bFailed, "Function Failed", pszFile, line, pszModule);
  65. return bFailed;
  66. }
  67. bool ZSucceededImpl(HRESULT hr, const char* pszFile, int line, const char* pszModule)
  68. {
  69. bool bSucceeded = SUCCEEDED(hr);
  70. ZAssertImpl(bSucceeded, "Function Failed", pszFile, line, pszModule);
  71. return bSucceeded;
  72. }
  73. #ifdef _TRACE
  74. bool g_bEnableTrace = false;
  75. ZString g_strSpaces;
  76. int g_indent = 0;
  77. int g_line = 0;
  78. void SetStrSpaces()
  79. {
  80. g_strSpaces =
  81. " "
  82. + ZString((float)g_indent, 2, 0)
  83. + ZString(' ', g_indent * 2 + 1);
  84. }
  85. void ZTraceImpl(const char* pcc)
  86. {
  87. if (g_bEnableTrace) {
  88. ZDebugOutput(ZString((float)g_line, 4, 0) + g_strSpaces + ZString(pcc) + "\n");
  89. }
  90. g_line++;
  91. }
  92. void ZEnterImpl(const char* pcc)
  93. {
  94. ZTraceImpl("enter " + ZString(pcc));
  95. g_indent += 1;
  96. SetStrSpaces();
  97. }
  98. void ZExitImpl(const char* pcc)
  99. {
  100. g_indent -= 1;
  101. SetStrSpaces();
  102. ZTraceImpl("exit " + ZString(pcc));
  103. }
  104. void ZStartTraceImpl(const char* pcc)
  105. {
  106. g_indent = 0;
  107. g_line = 0;
  108. SetStrSpaces();
  109. ZTraceImpl(pcc);
  110. }
  111. #endif
  112. void debugf(const char* format, ...)
  113. {
  114. if (g_bOutput)
  115. {
  116. #ifndef DREAMCAST
  117. const size_t size = 256;
  118. char bfr[size];
  119. va_list vl;
  120. va_start(vl, format);
  121. _vsnprintf(bfr, size, format, vl);
  122. va_end(vl);
  123. ZDebugOutputImpl(bfr);
  124. #else
  125. ZDebugOutputImpl(format);
  126. #endif
  127. }
  128. }
  129. void InitializeDebugf()
  130. {
  131. #ifndef DREAMCAST
  132. HKEY hKey;
  133. DWORD dwType;
  134. char szValue[20];
  135. DWORD cbValue = sizeof(szValue);
  136. bool bLogToFile = false;
  137. if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, ALLEGIANCE_REGISTRY_KEY_ROOT, 0, KEY_READ, &hKey))
  138. {
  139. ::RegQueryValueEx(hKey, "LogToFile", NULL, &dwType, (unsigned char*)&szValue, &cbValue);
  140. ::RegCloseKey(hKey);
  141. bLogToFile = (strcmp(szValue, "1") == 0);
  142. }
  143. if (bLogToFile)
  144. {
  145. time_t longTime;
  146. time(&longTime);
  147. tm* t = localtime(&longTime);
  148. char logFileName[MAX_PATH + 16];
  149. GetModuleFileName(NULL, logFileName, MAX_PATH);
  150. char* p = strrchr(logFileName, '\\');
  151. if (!p)
  152. p = logFileName;
  153. else
  154. p++;
  155. const char* months[] = {"jan", "feb", "mar", "apr",
  156. "may", "jun", "jul", "aug",
  157. "sep", "oct", "nov", "dec"};
  158. strcpy(p, months[t->tm_mon]);
  159. sprintf(p + 3, "%02d%02d%02d%02d.txt",
  160. t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
  161. g_logfile =
  162. CreateFile(
  163. logFileName,
  164. GENERIC_WRITE,
  165. 0,
  166. NULL,
  167. OPEN_ALWAYS,
  168. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
  169. NULL
  170. );
  171. }
  172. #endif
  173. }
  174. void TerminateDebugf()
  175. {
  176. #ifndef DREAMCAST
  177. if (g_logfile) {
  178. CloseHandle(g_logfile);
  179. g_logfile = NULL;
  180. }
  181. #endif
  182. }
  183. #endif
  184. //////////////////////////////////////////////////////////////////////////////
  185. //
  186. // Win32 Application
  187. //
  188. //////////////////////////////////////////////////////////////////////////////
  189. Win32App::Win32App()
  190. {
  191. g_papp = this;
  192. }
  193. Win32App::~Win32App()
  194. {
  195. }
  196. HRESULT Win32App::Initialize(const ZString& strCommandLine)
  197. {
  198. return S_OK;
  199. }
  200. void Win32App::Terminate()
  201. {
  202. }
  203. void Win32App::Exit(int value)
  204. {
  205. _CrtSetDbgFlag(0);
  206. _exit(value);
  207. }
  208. int Win32App::OnException(DWORD code, ExceptionData* pdata)
  209. {
  210. return EXCEPTION_CONTINUE_SEARCH;
  211. }
  212. #ifdef MemoryOutput
  213. TList<ZString> g_listOutput;
  214. #endif
  215. void Win32App::DebugOutput(const char *psz)
  216. {
  217. #ifdef MemoryOutput
  218. g_listOutput.PushFront(ZString(psz));
  219. if (g_listOutput.GetCount() > 100) {
  220. g_listOutput.PopEnd();
  221. }
  222. #else
  223. ::OutputDebugStringA(psz);
  224. if (g_logfile) {
  225. DWORD nBytes;
  226. ::WriteFile(g_logfile, psz, strlen(psz), &nBytes, NULL);
  227. }
  228. #endif
  229. }
  230. bool Win32App::OnAssert(const char* psz, const char* pszFile, int line, const char* pszModule)
  231. {
  232. ZDebugOutput(
  233. ZString("assertion failed: '")
  234. + psz
  235. + "' ("
  236. + pszFile
  237. + ":"
  238. + ZString(line)
  239. + ")\n"
  240. );
  241. //return _CrtDbgReport(_CRT_ASSERT, pszFile, line, pszModule, psz) == 1;
  242. return true;
  243. }
  244. void Win32App::OnAssertBreak()
  245. {
  246. #ifdef MemoryOutput
  247. ZString str;
  248. TList<ZString>::Iterator iter(g_listOutput);
  249. while (!iter.End()) {
  250. str = iter.Value() + str;
  251. iter.Next();
  252. }
  253. #endif
  254. //
  255. // Cause an exception
  256. //
  257. (*(int*)0) = 0;
  258. }
  259. //////////////////////////////////////////////////////////////////////////////
  260. //
  261. // Win Main
  262. //
  263. //////////////////////////////////////////////////////////////////////////////
  264. __declspec(dllexport) int WINAPI Win32Main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
  265. {
  266. HRESULT hr;
  267. // seed the random number generator with the current time
  268. // (GetTickCount may be semi-predictable on server startup, so we add the
  269. // clock time to shake things up a bit)
  270. srand(GetTickCount() + time(NULL));
  271. // shift the stack locals and the heap by a random amount.
  272. char* pzSpacer = new char[4 * (int)random(21, 256)];
  273. pzSpacer[0] = *(char*)_alloca(4 * (int)random(1, 256));
  274. __try {
  275. do {
  276. #ifdef _DEBUG
  277. InitializeDebugf();
  278. #endif
  279. BreakOnError(hr = Window::StaticInitialize());
  280. BreakOnError(hr = g_papp->Initialize(lpszCmdLine));
  281. //
  282. // Win32App::Initialize() return S_FALSE if this is a command line app and
  283. // we shouldn't run the message loop
  284. //
  285. if (SUCCEEDED(hr) && S_FALSE != hr) {
  286. Window::MessageLoop();
  287. }
  288. g_papp->Terminate();
  289. Window::StaticTerminate();
  290. #ifdef _DEBUG
  291. TerminateDebugf();
  292. #endif
  293. } while (false);
  294. } __except (g_papp->OnException(_exception_code(), (ExceptionData*)_exception_info())){
  295. }
  296. delete pzSpacer;
  297. return 0;
  298. }