mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
a2b376af96
Now it can be called from places other than Pageant's WinMain(). In particular, the attempt to make a security descriptor in lock_interprocess_mutex() is gated on it. In return, however, I've tightened up the semantics. In normal PuTTY builds that aren't trying to support pre-NT systems, the function *unconditionally* returns true, on the grounds that we don't expect to target any system that doesn't support the security APIs, and if someone manages to contrive one anyway - or, more likely, if we some day introduce a bug in our loading of the security API functions - then this safety catch should make Pageant less likely to accidentally fall back to 'never mind, just run in insecure mode'.
49 lines
1.1 KiB
C
49 lines
1.1 KiB
C
/*
|
|
* 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);
|
|
}
|