From 9a18c77da1a933e0916e62de8c2a5c57c76ffc01 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Wed, 22 Apr 2015 21:00:52 +0200 Subject: Re-work command line parsing in the Windows overlay helper executable. The old parsing was error-prone and hard to read. We introduce the GetCommandLineArgs() function that returns he program's arguments as a vector of strings. Using this function makes the code that processes the arguments much simpler and easier to understand. --- overlay/overlay_exe/overlay_exe-shared.pro | 2 +- overlay/overlay_exe/overlay_exe.cpp | 55 +++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 17 deletions(-) (limited to 'overlay') diff --git a/overlay/overlay_exe/overlay_exe-shared.pro b/overlay/overlay_exe/overlay_exe-shared.pro index acba31004..99d2fa647 100644 --- a/overlay/overlay_exe/overlay_exe-shared.pro +++ b/overlay/overlay_exe/overlay_exe-shared.pro @@ -8,7 +8,7 @@ TARGET = mumble_ol win32 { DEFINES += WIN32 _WIN32 RC_FILE = overlay_exe.rc - LIBS *= -luser32 -lshlwapi + LIBS *= -luser32 -lshlwapi -lshell32 CONFIG(release, debug|release) { QMAKE_CXXFLAGS_RELEASE -= -MD diff --git a/overlay/overlay_exe/overlay_exe.cpp b/overlay/overlay_exe/overlay_exe.cpp index bfc5c5399..9fc999399 100644 --- a/overlay/overlay_exe/overlay_exe.cpp +++ b/overlay/overlay_exe/overlay_exe.cpp @@ -32,8 +32,10 @@ #include #include #include +#include #include +#include #include "../overlay.h" #include "overlay_exe.h" @@ -95,6 +97,31 @@ static std::wstring GetAbsoluteMumbleOverlayDllPath() { return absDLLPath; } +// GetCommandLineArgs returns the command line arguments +// passed to the process. +// If the returned vector has a length of 0, an unknown +// error occurred. +static std::vector GetCommandLineArgs() { + std::vector args; + + LPWSTR cmdLine = GetCommandLine(); + if (cmdLine == NULL) { + return args; + } + + int argc = 0; + LPWSTR *argv = CommandLineToArgvW(cmdLine, &argc); + if (argv == NULL) { + return args; + } + + for (int i = 0; i < argc; i++) { + args.push_back(std::wstring(argv[0])); + } + + return args; +} + int main(int argc, char **argv) { UNUSED(argc); UNUSED(argv); @@ -118,32 +145,28 @@ int main(int argc, char **argv) { unsigned int magic = 0; HANDLE parent = 0; { - std::wstring commandLine(GetCommandLine()); + std::vector args = GetCommandLineArgs(); - // The command line will contain two consecutive spaces - // if the program was passed any arguments. If we don't - // find them, it probably means that a user has double-clicked + // If there is only a single argument, it's the program name. + // That probably means that a user has double-clicked // the executable. Tell them to run 'mumble.exe' instead. - std::wstring doubleSpace = std::wstring(L" "); - size_t sep = commandLine.find(doubleSpace); - if (sep == std::string::npos) { + // + // This also handles the case where GetCommandLineArgs returns + // an empty vector (the error case). + if (args.size() <= 1) { Alert(L"Mumble Overlay", L"This program is not meant to be run by itself. Run 'mumble.exe' instead."); return OVERLAY_HELPER_ERROR_EXE_NO_ARGUMENTS; } // The Mumble process passes the overlay magic number, // and a HANDLE in numeric form as its only two arguments. - // Let's try to parse the command line to extract them... - std::wstring args = commandLine.substr(sep + doubleSpace.length()); - sep = args.find(std::wstring(L" ")); - if (sep == std::string::npos) { + // We must have both of them to continue. + if (args.size() < 3) { return OVERLAY_HELPER_ERROR_TOO_FEW_ARGUMENTS; } - if (args.length() <= sep + 1) { - return OVERLAY_HELPER_ERROR_TOO_FEW_ARGUMENTS; - } - std::wstring magicNumberStr = args.substr(0, sep); - std::wstring handleStr = args.substr(sep+1); + + std::wstring magicNumberStr = args[1]; + std::wstring handleStr = args[2]; try { unsigned long passedInMagic = std::stoul(magicNumberStr); -- cgit v1.2.3