Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikkel Krautz <mikkel@krautz.dk>2015-02-27 20:34:44 +0300
committerMikkel Krautz <mikkel@krautz.dk>2015-04-22 22:03:53 +0300
commit6c446e4ead44a66b5706a95b410f5429e7890b9f (patch)
treef429fc5a3d33bbe7c57e5b608148dc143f499623 /overlay
parentb1880294df43d16ff03e927fba1572a027dac6aa (diff)
Ensure overlay helpers exit when the Mumble process terminates.
Normally, Mumble itself will terminate the helper processes. But if Mumble crashes, or is manually killed by the user, it will not be able to terminate the helper processes itself. In order to fix this, we create a way for the helpers to know when their parent process has terminated. This is implemented by creating an inheritable process handle in Mumble, and passing its value to the helpers. The helpers then WaitForSingleObject() on the parent handle, and exits with status code 0 if it the WaitForSingleObject() call returns successfully.
Diffstat (limited to 'overlay')
-rw-r--r--overlay/lib.cpp18
-rw-r--r--overlay/overlay_exe/overlay_exe.cpp32
-rw-r--r--overlay/overlay_exe/overlay_exe.h19
3 files changed, 61 insertions, 8 deletions
diff --git a/overlay/lib.cpp b/overlay/lib.cpp
index e9eeb4370..9358212c0 100644
--- a/overlay/lib.cpp
+++ b/overlay/lib.cpp
@@ -448,13 +448,29 @@ extern "C" __declspec(dllexport) void __cdecl PrepareD3D9();
// Via dxgi.cpp
extern "C" __declspec(dllexport) void __cdecl PrepareDXGI();
-extern "C" __declspec(dllexport) int __cdecl OverlayHelperProcessMain(unsigned int magic) {
+void __stdcall OverlayHelperProcessParentDeathThread(void *udata) {
+ HANDLE parent = reinterpret_cast<HANDLE>(udata);
+ DWORD status = WaitForSingleObject(parent, INFINITE);
+ if (status != WAIT_OBJECT_0) {
+ ExitProcess(OVERLAY_HELPER_ERROR_DLL_PDEATH_WAIT_FAIL);
+ }
+
+ ExitProcess(0);
+}
+
+extern "C" __declspec(dllexport) int __cdecl OverlayHelperProcessMain(unsigned int magic, HANDLE parent) {
int retval = 0;
if (GetOverlayMagicVersion() != magic) {
return OVERLAY_HELPER_ERROR_DLL_MAGIC_MISMATCH;
}
+ HANDLE pcheckHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OverlayHelperProcessParentDeathThread,
+ reinterpret_cast<void *>(parent), 0, NULL);
+ if (pcheckHandle == 0) {
+ return OVERLAY_HELPER_ERROR_DLL_PDEATH_THREAD_ERROR;
+ }
+
PrepareD3D9();
PrepareDXGI();
diff --git a/overlay/overlay_exe/overlay_exe.cpp b/overlay/overlay_exe/overlay_exe.cpp
index be9dbc653..bee53bdf7 100644
--- a/overlay/overlay_exe/overlay_exe.cpp
+++ b/overlay/overlay_exe/overlay_exe.cpp
@@ -40,7 +40,7 @@
#define UNUSED(x) ((void)x)
-typedef int (*OverlayHelperProcessMain)(unsigned int magic);
+typedef int (*OverlayHelperProcessMain)(unsigned int magic, HANDLE parent);
// Signal to the overlay DLL that it should not inject
// into this process.
@@ -116,6 +116,7 @@ int main(int argc, char **argv) {
// display a nice alert dialog directing users to
// 'mumble.exe' instead.
unsigned int magic = 0;
+ HANDLE parent = 0;
{
std::wstring commandLine(GetCommandLine());
@@ -123,21 +124,40 @@ int main(int argc, char **argv) {
// if the program was passed any arguments. If we don't
// find them, it probably means that a user has double-clicked
// the executable. Tell them to run 'mumble.exe' instead.
- size_t sep = commandLine.find(std::wstring(L" "));
+ std::wstring doubleSpace = std::wstring(L" ");
+ size_t sep = commandLine.find(doubleSpace);
if (sep == std::string::npos) {
Alert(L"Mumble Overlay", L"This program is not meant to be run by itself. Run 'mumble.exe' instead.");
return OVERLAY_HELPER_ERROR_EXE_MISSING_MAGIC_ARGUMENT;
}
- // We expect that the Mumble process passes the overlay
- // magic number that it is built with to us.
- std::wstring magicNumberStr = commandLine.substr(sep);
+ // 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) {
+ 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);
+
try {
unsigned long passedInMagic = std::stoul(magicNumberStr);
magic = static_cast<unsigned int>(passedInMagic);
} catch (std::exception &) {
return OVERLAY_HELPER_ERROR_EXE_INVALID_MAGIC_ARGUMENT;
}
+
+ try {
+ unsigned long passedInHandle = std::stoul(handleStr);
+ parent = reinterpret_cast<HANDLE>(passedInHandle & 0xFFFFFFFFUL);
+ } catch(std::exception &) {
+ return OVERLAY_HELPER_ERROR_EXE_INVALID_HANDLE_ARGUMENT;
+ }
}
if (magic != OVERLAY_MAGIC_NUMBER) {
@@ -163,7 +183,7 @@ int main(int argc, char **argv) {
return OVERLAY_HELPER_ERROR_EXE_LOOKUP_ENTRY_POINT;
}
- return entryPoint(magic);
+ return entryPoint(magic, parent);
}
int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, wchar_t *cmdArg, int cmdShow) {
diff --git a/overlay/overlay_exe/overlay_exe.h b/overlay/overlay_exe/overlay_exe.h
index bbd9d2e20..e950aeed9 100644
--- a/overlay/overlay_exe/overlay_exe.h
+++ b/overlay/overlay_exe/overlay_exe.h
@@ -64,14 +64,27 @@ enum OverlayHelperError {
/// the 'OverlayHelperProcessMain' entry point in the
/// overlay DLL.
OVERLAY_HELPER_ERROR_EXE_LOOKUP_ENTRY_POINT = -7,
+ /// The overlay helper process was uanble to parse
+ /// the commandline arguments it was passed.
+ /// The helper process exepcts two arguments, and this
+ /// error occurs if it only finds one.
+ OVERLAY_HELPER_ERROR_TOO_FEW_ARGUMENTS = -8,
+ /// The magic number on the command line of the overlay
+ /// helper process could not be converted to a HANDLE.
+ OVERLAY_HELPER_ERROR_EXE_INVALID_HANDLE_ARGUMENT = -9,
- /// The magic number passed to the overlay DLL's
+ /// The magic number passed to the overlay DLL's
/// OverlayHelperProcessMain function did not match
/// the overlay DLL's built-in magic number.
OVERLAY_HELPER_ERROR_DLL_MAGIC_MISMATCH = -1000,
/// The overlay helper process exited due to an error
/// in the Windows message loop.
OVERLAY_HELPER_ERROR_DLL_MESSAGE_LOOP = -1001,
+ /// The parent death thread could not be created.
+ OVERLAY_HELPER_ERROR_DLL_PDEATH_THREAD_ERROR = -1002,
+ /// The helper's WaitForSingleObject call on its parent
+ /// process failed unexpectedly.
+ OVERLAY_HELPER_ERROR_DLL_PDEATH_WAIT_FAIL = -1003,
};
/// OverlayHelperErrorToString converts an OverlayHelperError value
@@ -86,8 +99,12 @@ static inline const char *OverlayHelperErrorToString(OverlayHelperError err) {
OHE(OVERLAY_HELPER_ERROR_EXE_GET_DLL_PATH);
OHE(OVERLAY_HELPER_ERROR_EXE_LOAD_DLL);
OHE(OVERLAY_HELPER_ERROR_EXE_LOOKUP_ENTRY_POINT);
+ OHE(OVERLAY_HELPER_ERROR_TOO_FEW_ARGUMENTS);
+ OHE(OVERLAY_HELPER_ERROR_EXE_INVALID_HANDLE_ARGUMENT);
OHE(OVERLAY_HELPER_ERROR_DLL_MAGIC_MISMATCH);
OHE(OVERLAY_HELPER_ERROR_DLL_MESSAGE_LOOP);
+ OHE(OVERLAY_HELPER_ERROR_DLL_PDEATH_THREAD_ERROR);
+ OHE(OVERLAY_HELPER_ERROR_DLL_PDEATH_WAIT_FAIL);
}
return NULL;
}