From 7c6cb34cd14d58b9078d572dadafe3b13a401471 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 19 Jan 2014 14:27:41 -0500 Subject: [PATCH 1/4] Don't eat calls in hsAssert. ShellExecuteW != NOOP. Let's get it right. --- Sources/Plasma/Apps/plUruLauncher/winmain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Plasma/Apps/plUruLauncher/winmain.cpp b/Sources/Plasma/Apps/plUruLauncher/winmain.cpp index 571c5dee..b0499756 100644 --- a/Sources/Plasma/Apps/plUruLauncher/winmain.cpp +++ b/Sources/Plasma/Apps/plUruLauncher/winmain.cpp @@ -270,7 +270,7 @@ static HANDLE ICreateProcess(const plFileName& exe, const plString& args) info.lpFile = file.GetData(); info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC; info.lpParameters = args.ToWchar(); - hsAssert(ShellExecuteExW(&info), "ShellExecuteExW phailed"); + ShellExecuteExW(&info); return info.hProcess; } else { @@ -312,7 +312,7 @@ static bool IInstallRedist(const plFileName& exe) // Get the exit code so we can indicate success/failure to the redist thread DWORD code = PLASMA_OK; - hsAssert(GetExitCodeProcess(process, &code), "failed to get redist exit code"); + GetExitCodeProcess(process, &code); CloseHandle(process); return code != PLASMA_PHAILURE; From d7aa9ac17c809bcc64af82ee0a3cb73c0cb22636 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 19 Jan 2014 14:39:52 -0500 Subject: [PATCH 2/4] Handle smart pointers... This fixes a few HANDLE leaks. They aren't a big deal in the grand scheme of things, but it's good to be correct. --- Sources/Plasma/Apps/plUruLauncher/winmain.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/Sources/Plasma/Apps/plUruLauncher/winmain.cpp b/Sources/Plasma/Apps/plUruLauncher/winmain.cpp index b0499756..10cd64e1 100644 --- a/Sources/Plasma/Apps/plUruLauncher/winmain.cpp +++ b/Sources/Plasma/Apps/plUruLauncher/winmain.cpp @@ -66,26 +66,29 @@ static plClientLauncher s_launcher; static UINT s_taskbarCreated = RegisterWindowMessageW(L"TaskbarButtonCreated"); static ITaskbarList3* s_taskbar = nullptr; +typedef std::unique_ptr> handleptr_t; + // =================================================== /** Create a global patcher mutex that is backwards compatible with eap's */ -static HANDLE CreatePatcherMutex() +static handleptr_t CreatePatcherMutex() { - return CreateMutexW(nullptr, FALSE, plManifest::PatcherExecutable().AsString().ToWchar()); + return handleptr_t(CreateMutexW(nullptr, TRUE, plManifest::PatcherExecutable().AsString().ToWchar()), + CloseHandle); } static bool IsPatcherRunning() { - HANDLE mut = CreatePatcherMutex(); - return WaitForSingleObject(mut, 0) != WAIT_OBJECT_0; + handleptr_t mut = CreatePatcherMutex(); + return WaitForSingleObject(mut.get(), 0) != WAIT_OBJECT_0; } static void WaitForOldPatcher() { - HANDLE mut = CreatePatcherMutex(); - DWORD wait = WaitForSingleObject(mut, 0); + handleptr_t mut = CreatePatcherMutex(); + DWORD wait = WaitForSingleObject(mut.get(), 0); while (wait != WAIT_OBJECT_0) // :( :( :( - wait = WaitForSingleObject(mut, 100); + wait = WaitForSingleObject(mut.get(), 100); Sleep(1000); // :( } @@ -231,7 +234,7 @@ static void ISetDownloadStatus(const plString& status) } -static HANDLE ICreateProcess(const plFileName& exe, const plString& args) +static handleptr_t ICreateProcess(const plFileName& exe, const plString& args) { STARTUPINFOW si; PROCESS_INFORMATION pi; @@ -262,7 +265,7 @@ static HANDLE ICreateProcess(const plFileName& exe, const plString& args) // So maybe it needs elevation... Or maybe everything arseploded. if (result != FALSE) { CloseHandle(pi.hThread); - return pi.hProcess; + return handleptr_t(pi.hProcess, CloseHandle); } else if (GetLastError() == ERROR_ELEVATION_REQUIRED) { SHELLEXECUTEINFOW info; memset(&info, 0, sizeof(info)); @@ -272,7 +275,7 @@ static HANDLE ICreateProcess(const plFileName& exe, const plString& args) info.lpParameters = args.ToWchar(); ShellExecuteExW(&info); - return info.hProcess; + return handleptr_t(info.hProcess, CloseHandle); } else { wchar_t* msg = nullptr; FormatMessageW( @@ -306,14 +309,13 @@ static bool IInstallRedist(const plFileName& exe) ss << " /norestart"; // I don't want to image the accusations of viruses and hacking if this happened... // Now fire up the process... - HANDLE process = ICreateProcess(exe, ss.GetString()); + handleptr_t process = ICreateProcess(exe, ss.GetString()); if (process) { - WaitForSingleObject(process, INFINITE); + WaitForSingleObject(process.get(), INFINITE); // Get the exit code so we can indicate success/failure to the redist thread DWORD code = PLASMA_OK; - GetExitCodeProcess(process, &code); - CloseHandle(process); + GetExitCodeProcess(process.get(), &code); return code != PLASMA_PHAILURE; } @@ -329,17 +331,14 @@ static void ILaunchClientExecutable(const plFileName& exe, const plString& args) // Only launch a client executable if we're given one. If not, that's probably a cue that we're // done with some service operation and need to go away. if (!exe.AsString().IsEmpty()) { - HANDLE hEvent = CreateEventW(nullptr, TRUE, FALSE, L"UruPatcherEvent"); - HANDLE process = ICreateProcess(exe, args); + handleptr_t hEvent = handleptr_t(CreateEventW(nullptr, TRUE, FALSE, L"UruPatcherEvent"), CloseHandle); + handleptr_t process = ICreateProcess(exe, args); // if this is the real game client, then we need to make sure it gets this event... if (plManifest::ClientExecutable().AsString().CompareI(exe.AsString()) == 0) { - WaitForInputIdle(process, 1000); - WaitForSingleObject(hEvent, INFINITE); + WaitForInputIdle(process.get(), 1000); + WaitForSingleObject(hEvent.get(), INFINITE); } - - CloseHandle(process); - CloseHandle(hEvent); } // time to hara-kiri... @@ -399,7 +398,7 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL IShowErrorDialog(text.ToWchar()); return PLASMA_OK; } - HANDLE _onePatcherMut = CreatePatcherMutex(); + HANDLE _onePatcherMut = CreatePatcherMutex().release(); // Initialize the network core s_launcher.InitializeNetCore(); From 5021438dd7eac748aa32dd4d46c18f2b0b3a8396 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 19 Jan 2014 14:45:05 -0500 Subject: [PATCH 3/4] SkipLoginDialog -- forgot to implement this one --- Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp | 9 +++++++-- Sources/Plasma/Apps/plUruLauncher/plClientLauncher.h | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp index 9a077c81..45ff9f9a 100644 --- a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp +++ b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp @@ -234,6 +234,8 @@ plString plClientLauncher::GetAppArgs() const ss << " -Image"; if (hsCheckBits(fFlags, kPatchOnly)) ss << " -PatchOnly"; + if (hsCheckBits(fFlags, kSkipLoginDialog)) + ss << " -SkipLoginDialog"; return ss.GetString(); } @@ -429,13 +431,15 @@ void plClientLauncher::ParseArguments() if (cmdParser.GetBool(arg)) \ fFlags |= flag; - enum { kArgServerIni, kArgNoSelfPatch, kArgImage, kArgRepairGame, kArgPatchOnly }; + enum { kArgServerIni, kArgNoSelfPatch, kArgImage, kArgRepairGame, kArgPatchOnly, + kArgSkipLoginDialog }; const CmdArgDef cmdLineArgs[] = { { kCmdArgFlagged | kCmdTypeString, L"ServerIni", kArgServerIni }, { kCmdArgFlagged | kCmdTypeBool, L"NoSelfPatch", kArgNoSelfPatch }, { kCmdArgFlagged | kCmdTypeBool, L"Image", kArgImage }, { kCmdArgFlagged | kCmdTypeBool, L"Repair", kArgRepairGame }, - { kCmdArgFlagged | kCmdTypeBool, L"PatchOnly", kArgPatchOnly } + { kCmdArgFlagged | kCmdTypeBool, L"PatchOnly", kArgPatchOnly }, + { kCmdArgFlagged | kCmdTypeBool, L"SkipLoginDialog", kArgSkipLoginDialog } }; CCmdParser cmdParser(cmdLineArgs, arrsize(cmdLineArgs)); @@ -448,6 +452,7 @@ void plClientLauncher::ParseArguments() APPLY_FLAG(kArgImage, kClientImage); APPLY_FLAG(kArgRepairGame, kRepairGame); APPLY_FLAG(kArgPatchOnly, kPatchOnly); + APPLY_FLAG(kArgSkipLoginDialog, kSkipLoginDialog); // last chance setup if (hsCheckBits(fFlags, kPatchOnly)) diff --git a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.h b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.h index c67b9816..308abdcc 100644 --- a/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.h +++ b/Sources/Plasma/Apps/plUruLauncher/plClientLauncher.h @@ -63,8 +63,9 @@ private: { kHaveSelfPatched = 1<<0, kClientImage = 1<<1, - kGameDataOnly = (1<<2), + kGameDataOnly = 1<<2, kPatchOnly = 1<<3, + kSkipLoginDialog = 1<<4, kRepairGame = kHaveSelfPatched | kClientImage | kGameDataOnly, }; From 625319f99d15f524368fc0565121033cb21404ab Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 19 Jan 2014 14:48:04 -0500 Subject: [PATCH 4/4] NT6-proof PhysX_Setup.exe launch CreateProcessW on PhysX_Setup.exe will probably cause ERROR_ELEVATION_REQUIRED. That is NOT my idea of a successful install. --- Sources/Plasma/Apps/plClient/winmain.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/winmain.cpp b/Sources/Plasma/Apps/plClient/winmain.cpp index cb179d5b..7a2e08b5 100644 --- a/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/Sources/Plasma/Apps/plClient/winmain.cpp @@ -497,22 +497,18 @@ bool InitPhysX() return false; // launch the PhysX installer - STARTUPINFOW startupInfo; - PROCESS_INFORMATION processInfo; - memset(&startupInfo, 0, sizeof(startupInfo)); - memset(&processInfo, 0, sizeof(processInfo)); - startupInfo.cb = sizeof(startupInfo); - if(!CreateProcessW(NULL, s_physXSetupExeName, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) - { - hsMessageBox("Failed to launch PhysX installer.\nPlease re-run URU to ensure you have the latest version.", "Error", hsMessageBoxNormal); - return false; - } + SHELLEXECUTEINFOW info; + memset(&info, 0, sizeof(info)); + info.cbSize = sizeof(info); + info.lpFile = s_physXSetupExeName; + info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC; + ShellExecuteExW(&info); // let the user know what's going on HWND waitingDialog = ::CreateDialog(gHInst, MAKEINTRESOURCE(IDD_LOADING), NULL, WaitingForPhysXDialogProc); // run a loop to wait for it to quit, pumping the windows message queue intermittently - DWORD waitRet = WaitForSingleObject(processInfo.hProcess, 100); + DWORD waitRet = WaitForSingleObject(info.hProcess, 100); MSG msg; while (waitRet == WAIT_TIMEOUT) { @@ -521,12 +517,11 @@ bool InitPhysX() TranslateMessage(&msg); DispatchMessage(&msg); } - waitRet = WaitForSingleObject(processInfo.hProcess, 100); + waitRet = WaitForSingleObject(info.hProcess, 100); } // cleanup - CloseHandle(processInfo.hThread); - CloseHandle(processInfo.hProcess); + CloseHandle(info.hProcess); ::DestroyWindow(waitingDialog); } else