[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / platform / win32 / WinMain.cpp
blob87dde67ce9cf3dedf5e1921637ebc7fefc0258bd
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "CompileInfo.h"
10 #include "ServiceBroker.h"
11 #include "application/AppEnvironment.h"
12 #include "application/AppParamParser.h"
13 #include "application/AppParams.h"
14 #include "platform/Environment.h"
15 #include "platform/xbmc.h"
16 #include "threads/Thread.h"
17 #include "utils/CharsetConverter.h" // Required to initialize converters before usage
19 #include "platform/win32/CharsetConverter.h"
20 #include "platform/win32/threads/Win32Exception.h"
22 #include <Objbase.h>
23 #include <WinSock2.h>
24 #include <dbghelp.h>
25 #include <mmsystem.h>
26 #include <shellapi.h>
28 // Minidump creation function
29 LONG WINAPI CreateMiniDump(EXCEPTION_POINTERS* pEp)
31 win32_exception::write_stacktrace(pEp);
32 win32_exception::write_minidump(pEp);
33 return pEp->ExceptionRecord->ExceptionCode;
36 static bool isConsoleAttached{false};
38 /*!
39 * \brief Basic error reporting before the log subsystem is initialized
41 * The message is formatted using printf and output to debugger and cmd.exe, as applicable.
43 * \param[in] format printf-style format string
44 * \param[in] ... optional parameters for the format string.
46 template<typename... Args>
47 static void LogError(const wchar_t* format, Args&&... args)
49 const int count = _snwprintf(nullptr, 0, format, args...);
50 // terminating null character not included in count
51 auto buf = std::make_unique<wchar_t[]>(count + 1);
52 swprintf(buf.get(), format, args...);
54 OutputDebugString(buf.get());
56 if (!isConsoleAttached && AttachConsole(ATTACH_PARENT_PROCESS))
58 (void)freopen("CONOUT$", "w", stdout);
59 wprintf(L"\n");
60 isConsoleAttached = true;
62 wprintf(buf.get());
65 static std::shared_ptr<CAppParams> ParseCommandLine()
67 int argc = 0;
68 LPWSTR* argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
69 char** argv = new char*[argc];
71 for (int i = 0; i < argc; ++i)
73 int size = WideCharToMultiByte(CP_UTF8, 0, argvW[i], -1, nullptr, 0, nullptr, nullptr);
74 if (size > 0)
76 argv[i] = new char[size];
77 WideCharToMultiByte(CP_UTF8, 0, argvW[i], -1, argv[i], size, nullptr, nullptr);
81 CAppParamParser appParamParser;
82 appParamParser.Parse(argv, argc);
84 for (int i = 0; i < argc; ++i)
85 delete[] argv[i];
86 delete[] argv;
88 return appParamParser.GetAppParams();
91 //-----------------------------------------------------------------------------
92 // Name: WinMain()
93 // Desc: The application's entry point
94 //-----------------------------------------------------------------------------
95 _Use_decl_annotations_ INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
97 // parse command line parameters
98 const auto params = ParseCommandLine();
100 // this fixes crash if OPENSSL_CONF is set to existed openssl.cfg
101 // need to set it as soon as possible
102 CEnvironment::unsetenv("OPENSSL_CONF");
104 // Initializes CreateMiniDump to handle exceptions.
105 char ver[100];
106 if (strlen(CCompileInfo::GetSuffix()) > 0)
107 sprintf_s(ver, "%d.%d-%s Git:%s", CCompileInfo::GetMajor(),
108 CCompileInfo::GetMinor(), CCompileInfo::GetSuffix(), CCompileInfo::GetSCMID());
109 else
110 sprintf_s(ver, "%d.%d Git:%s", CCompileInfo::GetMajor(),
111 CCompileInfo::GetMinor(), CCompileInfo::GetSCMID());
113 if (win32_exception::ShouldHook())
115 win32_exception::set_version(std::string(ver));
116 win32_exception::set_platformDirectories(params->HasPlatformDirectories());
117 SetUnhandledExceptionFilter(CreateMiniDump);
120 int status{0};
121 HRESULT hrCOM{E_FAIL};
122 int rcWinsock{WSANOTINITIALISED};
123 WSADATA wd{};
125 // check if Kodi is already running
126 using KODI::PLATFORM::WINDOWS::ToW;
127 std::string appName = CCompileInfo::GetAppName();
128 HANDLE appRunningMutex = CreateMutex(nullptr, FALSE, ToW(appName + " Media Center").c_str());
129 if (appRunningMutex != nullptr && GetLastError() == ERROR_ALREADY_EXISTS)
131 auto appNameW = ToW(appName);
132 HWND hwnd = FindWindow(appNameW.c_str(), appNameW.c_str());
133 if (hwnd != nullptr)
135 // switch to the running instance
136 ShowWindow(hwnd, SW_RESTORE);
137 SetForegroundWindow(hwnd);
139 status = 0;
140 goto cleanup;
143 //Initialize COM
144 if ((hrCOM = CoInitializeEx(nullptr, COINIT_MULTITHREADED)) != S_OK)
146 LogError(L"unable to initialize COM, error %ld\n", hrCOM);
147 status = -2;
148 goto cleanup;
151 // Initialise Winsock
152 if ((rcWinsock = WSAStartup(MAKEWORD(2, 2), &wd)) != 0)
154 LogError(L"unable to initialize Windows Sockets, error %i\n", rcWinsock);
155 status = -3;
156 goto cleanup;
159 // use 1 ms timer precision - like SDL initialization used to do
160 timeBeginPeriod(1);
162 #ifndef _DEBUG
163 // we don't want to see the "no disc in drive" windows message box
164 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
165 #endif
167 CAppEnvironment::SetUp(params);
169 // Create and run the app
170 status = XBMC_Run(true);
172 CAppEnvironment::TearDown();
174 // clear previously set timer resolution
175 timeEndPeriod(1);
177 cleanup:
179 if (rcWinsock == 0)
180 WSACleanup();
181 if (hrCOM == S_OK)
182 CoUninitialize();
183 if (appRunningMutex)
184 CloseHandle(appRunningMutex);
186 return status;