aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCrystalP <crystalp@kodi.tv>2023-11-28 13:10:54 -0500
committerGitHub <noreply@github.com>2023-11-28 13:10:54 -0500
commit4a41a5e42e5bfd32031ba85e4692b9c7894d368f (patch)
tree57630a2c0bf4984be5c87f354a984711db2d8235
parentb4ae12fe3bdf428ed40ca7d6a55f204e23dd83e7 (diff)
parent3d7f34a9df40ccdc8ab80992a3dfa6d94d9493cc (diff)
Merge pull request #24149 from CrystalP/winmain-intellisense
[Windows] address recommendations of VS code analysis tools for WinMain
-rw-r--r--xbmc/platform/win32/WinMain.cpp96
1 files changed, 74 insertions, 22 deletions
diff --git a/xbmc/platform/win32/WinMain.cpp b/xbmc/platform/win32/WinMain.cpp
index c9ee17d950..87dde67ce9 100644
--- a/xbmc/platform/win32/WinMain.cpp
+++ b/xbmc/platform/win32/WinMain.cpp
@@ -33,16 +33,39 @@ LONG WINAPI CreateMiniDump(EXCEPTION_POINTERS* pEp)
return pEp->ExceptionRecord->ExceptionCode;
}
-//-----------------------------------------------------------------------------
-// Name: WinMain()
-// Desc: The application's entry point
-//-----------------------------------------------------------------------------
-INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT)
+static bool isConsoleAttached{false};
+
+/*!
+ * \brief Basic error reporting before the log subsystem is initialized
+ *
+ * The message is formatted using printf and output to debugger and cmd.exe, as applicable.
+ *
+ * \param[in] format printf-style format string
+ * \param[in] ... optional parameters for the format string.
+ */
+template<typename... Args>
+static void LogError(const wchar_t* format, Args&&... args)
+{
+ const int count = _snwprintf(nullptr, 0, format, args...);
+ // terminating null character not included in count
+ auto buf = std::make_unique<wchar_t[]>(count + 1);
+ swprintf(buf.get(), format, args...);
+
+ OutputDebugString(buf.get());
+
+ if (!isConsoleAttached && AttachConsole(ATTACH_PARENT_PROCESS))
+ {
+ (void)freopen("CONOUT$", "w", stdout);
+ wprintf(L"\n");
+ isConsoleAttached = true;
+ }
+ wprintf(buf.get());
+}
+
+static std::shared_ptr<CAppParams> ParseCommandLine()
{
- // parse command line parameters
int argc = 0;
LPWSTR* argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
-
char** argv = new char*[argc];
for (int i = 0; i < argc; ++i)
@@ -58,7 +81,21 @@ INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT)
CAppParamParser appParamParser;
appParamParser.Parse(argv, argc);
- const auto params = appParamParser.GetAppParams();
+ for (int i = 0; i < argc; ++i)
+ delete[] argv[i];
+ delete[] argv;
+
+ return appParamParser.GetAppParams();
+}
+
+//-----------------------------------------------------------------------------
+// Name: WinMain()
+// Desc: The application's entry point
+//-----------------------------------------------------------------------------
+_Use_decl_annotations_ INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
+{
+ // parse command line parameters
+ const auto params = ParseCommandLine();
// this fixes crash if OPENSSL_CONF is set to existed openssl.cfg
// need to set it as soon as possible
@@ -80,11 +117,16 @@ INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT)
SetUnhandledExceptionFilter(CreateMiniDump);
}
+ int status{0};
+ HRESULT hrCOM{E_FAIL};
+ int rcWinsock{WSANOTINITIALISED};
+ WSADATA wd{};
+
// check if Kodi is already running
using KODI::PLATFORM::WINDOWS::ToW;
std::string appName = CCompileInfo::GetAppName();
HANDLE appRunningMutex = CreateMutex(nullptr, FALSE, ToW(appName + " Media Center").c_str());
- if (GetLastError() == ERROR_ALREADY_EXISTS)
+ if (appRunningMutex != nullptr && GetLastError() == ERROR_ALREADY_EXISTS)
{
auto appNameW = ToW(appName);
HWND hwnd = FindWindow(appNameW.c_str(), appNameW.c_str());
@@ -94,16 +136,25 @@ INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT)
ShowWindow(hwnd, SW_RESTORE);
SetForegroundWindow(hwnd);
}
- ReleaseMutex(appRunningMutex);
- return 0;
+ status = 0;
+ goto cleanup;
}
//Initialize COM
- CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+ if ((hrCOM = CoInitializeEx(nullptr, COINIT_MULTITHREADED)) != S_OK)
+ {
+ LogError(L"unable to initialize COM, error %ld\n", hrCOM);
+ status = -2;
+ goto cleanup;
+ }
// Initialise Winsock
- WSADATA wd;
- WSAStartup(MAKEWORD(2, 2), &wd);
+ if ((rcWinsock = WSAStartup(MAKEWORD(2, 2), &wd)) != 0)
+ {
+ LogError(L"unable to initialize Windows Sockets, error %i\n", rcWinsock);
+ status = -3;
+ goto cleanup;
+ }
// use 1 ms timer precision - like SDL initialization used to do
timeBeginPeriod(1);
@@ -116,20 +167,21 @@ INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT)
CAppEnvironment::SetUp(params);
// Create and run the app
- int status = XBMC_Run(true);
+ status = XBMC_Run(true);
CAppEnvironment::TearDown();
- for (int i = 0; i < argc; ++i)
- delete[] argv[i];
- delete[] argv;
-
// clear previously set timer resolution
timeEndPeriod(1);
- WSACleanup();
- CoUninitialize();
- ReleaseMutex(appRunningMutex);
+cleanup:
+
+ if (rcWinsock == 0)
+ WSACleanup();
+ if (hrCOM == S_OK)
+ CoUninitialize();
+ if (appRunningMutex)
+ CloseHandle(appRunningMutex);
return status;
}