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

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'windows/utils/interprocess_mutex.c')
-rw-r--r--windows/utils/interprocess_mutex.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/windows/utils/interprocess_mutex.c b/windows/utils/interprocess_mutex.c
new file mode 100644
index 00000000..8612a298
--- /dev/null
+++ b/windows/utils/interprocess_mutex.c
@@ -0,0 +1,48 @@
+/*
+ * Lock and unlock a mutex with a globally visible name. Used to
+ * synchronise between unrelated processes, such as two
+ * connection-sharing PuTTYs deciding which will be the upstream.
+ */
+
+#include "putty.h"
+#include "security-api.h"
+
+HANDLE lock_interprocess_mutex(const char *mutexname, char **error)
+{
+ PSECURITY_DESCRIPTOR psd = NULL;
+ PACL acl = NULL;
+ HANDLE mutex = NULL;
+
+ if (should_have_security() && !make_private_security_descriptor(
+ MUTEX_ALL_ACCESS, &psd, &acl, error))
+ goto out;
+
+ SECURITY_ATTRIBUTES sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = psd;
+ sa.bInheritHandle = false;
+
+ mutex = CreateMutex(&sa, false, mutexname);
+ if (!mutex) {
+ *error = dupprintf("CreateMutex(\"%s\") failed: %s",
+ mutexname, win_strerror(GetLastError()));
+ goto out;
+ }
+
+ WaitForSingleObject(mutex, INFINITE);
+
+ out:
+ if (psd)
+ LocalFree(psd);
+ if (acl)
+ LocalFree(acl);
+
+ return mutex;
+}
+
+void unlock_interprocess_mutex(HANDLE mutex)
+{
+ ReleaseMutex(mutex);
+ CloseHandle(mutex);
+}