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:
-rw-r--r--overlay/lib.cpp18
-rw-r--r--overlay/overlay_exe/overlay_exe.cpp32
-rw-r--r--overlay/overlay_exe/overlay_exe.h19
-rw-r--r--src/mumble/Overlay_win.cpp32
-rw-r--r--src/mumble/Overlay_win.h1
5 files changed, 93 insertions, 9 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;
}
diff --git a/src/mumble/Overlay_win.cpp b/src/mumble/Overlay_win.cpp
index 4b5dda0bd..e401743ae 100644
--- a/src/mumble/Overlay_win.cpp
+++ b/src/mumble/Overlay_win.cpp
@@ -74,8 +74,33 @@ static bool canRun64BitPrograms() {
OverlayPrivateWin::OverlayPrivateWin(QObject *p) : OverlayPrivate(p) {
m_active = false;
+ // Acquire a handle to ourselves and duplicate it. We duplicate it because
+ // want it to be inheritable by our helper processes, and the handle returned
+ // by GetCurrentProcess is not inheritable. Duplicating it makes it inheritable.
+ // This allows our helper processes to access the handle.
+ //
+ // The helper processes need a handle to us, their parent, to be able to listen
+ // detect when our process dies.
+ //
+ // The value of the handle is passed as an argument to the helper processes via
+ // the command line as a number. The HANDLE type in Windows is typedef'd to LPVOID,
+ // but for handles that are supposed to be shared between processes (like a process
+ // handle that we are using), only the lower 32-bits of the HANDLE are considered:
+ //
+ // "When sharing a handle between 32-bit and 64-bit applications, only the lower
+ // 32 bits are significant [...]"
+ //
+ // from https://msdn.microsoft.com/en-us/library/aa384203.aspx
+ HANDLE curproc = GetCurrentProcess();
+ if (!DuplicateHandle(curproc, curproc, curproc, &m_mumble_handle,
+ 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ qFatal("OverlayPrivateWin: unable to duplicate handle to the Mumble process.");
+ return;
+ }
+
m_helper_exe_path = QString::fromLatin1("%1/mumble_ol.exe").arg(qApp->applicationDirPath());
- m_helper_exe_args = QStringList(QString::number(OVERLAY_MAGIC_NUMBER));
+ m_helper_exe_args << QString::number(OVERLAY_MAGIC_NUMBER)
+ << QString::number(reinterpret_cast<quintptr>(m_mumble_handle));
m_helper_process = new QProcess(this);
connect(m_helper_process, SIGNAL(started()),
@@ -124,6 +149,11 @@ OverlayPrivateWin::OverlayPrivateWin(QObject *p) : OverlayPrivate(p) {
OverlayPrivateWin::~OverlayPrivateWin() {
m_active = false;
+
+ if (!CloseHandle(m_mumble_handle)) {
+ qFatal("OverlayPrivateWin: unable to close Mumble process handle.");
+ return;
+ }
}
void OverlayPrivateWin::startHelper(QProcess *helper) {
diff --git a/src/mumble/Overlay_win.h b/src/mumble/Overlay_win.h
index 4fb6bd7c0..171fc32a9 100644
--- a/src/mumble/Overlay_win.h
+++ b/src/mumble/Overlay_win.h
@@ -71,6 +71,7 @@ class OverlayPrivateWin : public OverlayPrivate {
QTimer *m_helper64_restart_timer;
bool m_helper64_enabled;
+ HANDLE m_mumble_handle;
bool m_active;
void startHelper(QProcess *helper);