2 * Copyright (C) 2005-2008 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
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 General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "settings/AdvancedSettings.h"
23 #include "utils/log.h"
24 #include "WIN32Util.h"
28 #include "threads/Thread.h"
29 #include "Application.h"
31 typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
32 CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
33 CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
34 CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
37 // Minidump creation function
38 LONG WINAPI CreateMiniDump( EXCEPTION_POINTERS* pEp )
40 // Create the dump file where the xbmc.exe resides
43 CDateTime now(CDateTime::GetCurrentDateTime());
44 dumpFile.Format("%s\\XBMC\\xbmc_crashlog-%04i%02i%02i-%02i%02i%02i.dmp", CWIN32Util::GetProfilePath().c_str(), now.GetYear(), now.GetMonth(), now.GetDay(), now.GetHour(), now.GetMinute(), now.GetSecond());
45 HANDLE hFile = CreateFile(dumpFile.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
47 // Call MiniDumpWriteDump api with the dump file
48 if ( hFile && ( hFile != INVALID_HANDLE_VALUE ) )
50 // Load the DBGHELP DLL
51 HMODULE hDbgHelpDll = ::LoadLibrary("DBGHELP.DLL");
54 MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDbgHelpDll, "MiniDumpWriteDump");
57 // Initialize minidump structure
58 MINIDUMP_EXCEPTION_INFORMATION mdei;
59 mdei.ThreadId = CThread::GetCurrentThreadId();
60 mdei.ExceptionPointers = pEp;
61 mdei.ClientPointers = FALSE;
63 // Call the minidump api with normal dumping
64 // We can get more detail information by using other minidump types but the dump file will be
66 BOOL rv = pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, 0, NULL);
69 errorMsg.Format("MiniDumpWriteDump failed with error id %d", GetLastError());
70 MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR);
75 errorMsg.Format("MiniDumpWriteDump failed to load with error id %d", GetLastError());
76 MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR);
80 FreeLibrary(hDbgHelpDll);
84 errorMsg.Format("LoadLibrary 'DBGHELP.DLL' failed with error id %d", GetLastError());
85 MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR);
93 errorMsg.Format("CreateFile '%s' failed with error id %d", dumpFile.c_str(), GetLastError());
94 MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR);
97 return pEp->ExceptionRecord->ExceptionCode;;
100 //-----------------------------------------------------------------------------
102 // Desc: The application's entry point
103 //-----------------------------------------------------------------------------
104 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT )
106 //this can't be set from CAdvancedSettings::Initialize() because it will overwrite
107 //the loglevel set with the --debug flag
109 g_advancedSettings.m_logLevel = LOG_LEVEL_DEBUG;
110 g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG;
112 g_advancedSettings.m_logLevel = LOG_LEVEL_NORMAL;
113 g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL;
115 CLog::SetLogLevel(g_advancedSettings.m_logLevel);
117 // Initializes CreateMiniDump to handle exceptions.
118 SetUnhandledExceptionFilter( CreateMiniDump );
120 // check if XBMC is already running
121 CreateMutex(NULL, FALSE, "XBMC Media Center");
122 if(GetLastError() == ERROR_ALREADY_EXISTS)
124 HWND m_hwnd = FindWindow("XBMC","XBMC");
127 // switch to the running instance
128 ShowWindow(m_hwnd,SW_RESTORE);
129 SetForegroundWindow(m_hwnd);
135 if(CWIN32Util::GetDesktopColorDepth() < 32)
137 //FIXME: replace it by a SDL window for all ports
138 MessageBox(NULL, "Desktop Color Depth isn't 32Bit", "XBMC: Fatal Error", MB_OK|MB_ICONERROR);
144 CoInitializeEx(NULL, COINIT_MULTITHREADED);
146 // parse the command line
147 CStdStringW strcl(commandLine);
151 setlocale(LC_NUMERIC, "C");
152 g_advancedSettings.Initialize();
153 szArglist = CommandLineToArgvW(strcl.c_str(), &nArgs);
154 if(szArglist != NULL)
156 for(int i=0;i<nArgs;i++)
158 CStdStringW strArgW(szArglist[i]);
159 if(strArgW.Equals(L"-fs"))
160 g_advancedSettings.m_startFullScreen = true;
161 else if(strArgW.Equals(L"-p") || strArgW.Equals(L"--portable"))
162 g_application.EnablePlatformDirectories(false);
163 else if(strArgW.Equals(L"-d"))
167 int iSleep = _wtoi(szArglist[i]);
168 if(iSleep > 0 && iSleep < 360)
174 else if(strArgW.Equals(L"--debug"))
176 g_advancedSettings.m_logLevel = LOG_LEVEL_DEBUG;
177 g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG;
178 CLog::SetLogLevel(g_advancedSettings.m_logLevel);
181 LocalFree(szArglist);
185 WSAStartup(MAKEWORD(2,2), &wd);
187 // Create and run the app
188 if(!g_application.Create())
191 errorMsg.Format("CApplication::Create() failed - check log file and that it is writable");
192 MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR);
197 // we don't want to see the "no disc in drive" windows message box
198 SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
203 // put everything in CApplication::Cleanup() since this point is never reached