/* * 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); }