2 * Copyright (C) 2005-2013 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, see
17 * <http://www.gnu.org/licenses/>.
21 #include "AppParamParser.h"
22 #include "settings/AdvancedSettings.h"
23 #include "utils/CharsetConverter.h"
24 #include "utils/log.h"
25 #include "threads/platform/win/Win32Exception.h"
28 #include "XBDateTime.h"
29 #include "threads/Thread.h"
30 #include "Application.h"
31 #include "XbmcContext.h"
32 #include "GUIInfoManager.h"
33 #include "utils/StringUtils.h"
34 #include "utils/CPUInfo.h"
37 #define XBMC_TRACK_EXCEPTIONS
40 // Minidump creation function
41 LONG WINAPI CreateMiniDump( EXCEPTION_POINTERS* pEp )
43 win32_exception::write_stacktrace(pEp);
44 win32_exception::write_minidump(pEp);
45 return pEp->ExceptionRecord->ExceptionCode;;
48 //-----------------------------------------------------------------------------
50 // Desc: The application's entry point
51 //-----------------------------------------------------------------------------
52 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT )
54 // set up some xbmc specific relationships
55 XBMC::Context context;
57 //this can't be set from CAdvancedSettings::Initialize() because it will overwrite
58 //the loglevel set with the --debug flag
60 g_advancedSettings.m_logLevel = LOG_LEVEL_DEBUG;
61 g_advancedSettings.m_logLevelHint = LOG_LEVEL_DEBUG;
63 g_advancedSettings.m_logLevel = LOG_LEVEL_NORMAL;
64 g_advancedSettings.m_logLevelHint = LOG_LEVEL_NORMAL;
66 CLog::SetLogLevel(g_advancedSettings.m_logLevel);
68 // Initializes CreateMiniDump to handle exceptions.
69 win32_exception::set_version(g_infoManager.GetVersion());
70 SetUnhandledExceptionFilter( CreateMiniDump );
72 // check if XBMC is already running
73 CreateMutex(NULL, FALSE, "XBMC Media Center");
74 if(GetLastError() == ERROR_ALREADY_EXISTS)
76 HWND m_hwnd = FindWindow("XBMC","XBMC");
79 // switch to the running instance
80 ShowWindow(m_hwnd,SW_RESTORE);
81 SetForegroundWindow(m_hwnd);
87 if(CWIN32Util::GetDesktopColorDepth() < 32)
89 //FIXME: replace it by a SDL window for all ports
90 MessageBox(NULL, "Desktop Color Depth isn't 32Bit", "XBMC: Fatal Error", MB_OK|MB_ICONERROR);
95 if((g_cpuInfo.GetCPUFeatures() & CPU_FEATURE_SSE2) == 0)
97 MessageBox(NULL, "No SSE2 support detected", "XBMC: Fatal Error", MB_OK|MB_ICONERROR);
102 CoInitializeEx(NULL, COINIT_MULTITHREADED);
104 // Handle numeric values using the default/POSIX standard
105 setlocale(LC_NUMERIC, "C");
107 // If the command line passed to WinMain, commandLine, is not "" we need
108 // to process the command line arguments.
109 // Note that commandLine does not include the program name and can be
110 // equal to "" if no arguments were supplied. By contrast GetCommandLineW()
111 // does include the program name and is never equal to "".
112 g_advancedSettings.Initialize();
113 if (strlen(commandLine) != 0)
116 LPWSTR* argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
118 std::vector<std::string> strargvA;
119 strargvA.resize(argc);
120 const char** argv = (const char**) LocalAlloc(LMEM_FIXED, argc*sizeof(char*));
121 for (int i = 0; i < argc; i++)
123 g_charsetConverter.wToUTF8(argvW[i], strargvA[i]);
124 argv[i] = strargvA[i].c_str();
127 // Parse the arguments
128 CAppParamParser appParamParser;
129 appParamParser.Parse(argv, argc);
131 // Clean up the storage we've used
136 // Initialise Winsock
138 WSAStartup(MAKEWORD(2,2), &wd);
140 // use 1 ms timer precision - like SDL initialization used to do
143 #ifdef XBMC_TRACK_EXCEPTIONS
147 // Create and run the app
148 if(!g_application.Create())
150 MessageBox(NULL, "ERROR: Unable to create application. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
153 #ifdef XBMC_TRACK_EXCEPTIONS
155 catch (const XbmcCommons::UncheckedException &e)
157 e.LogThrowMessage("CApplication::Create()");
158 MessageBox(NULL, "ERROR: Unable to create application. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
163 CLog::Log(LOGERROR, "exception in CApplication::Create()");
164 MessageBox(NULL, "ERROR: Unable to create application. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
170 // we don't want to see the "no disc in drive" windows message box
171 SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
174 #ifdef XBMC_TRACK_EXCEPTIONS
178 if (!g_application.CreateGUI())
180 MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
183 #ifdef XBMC_TRACK_EXCEPTIONS
185 catch (const XbmcCommons::UncheckedException &e)
187 e.LogThrowMessage("CApplication::CreateGUI()");
188 MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
193 CLog::Log(LOGERROR, "exception in CApplication::CreateGUI()");
194 MessageBox(NULL, "ERROR: Unable to create GUI. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
199 #ifdef XBMC_TRACK_EXCEPTIONS
203 if (!g_application.Initialize())
205 MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
208 #ifdef XBMC_TRACK_EXCEPTIONS
210 catch (const XbmcCommons::UncheckedException &e)
212 e.LogThrowMessage("CApplication::Initialize()");
213 MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
218 CLog::Log(LOGERROR, "exception in CApplication::Initialize()");
219 MessageBox(NULL, "ERROR: Unable to Initialize. Exiting.", "XBMC: Error", MB_OK|MB_ICONERROR);
226 // clear previously set timer resolution