{*******************************************************} { } { Tocsg.Win32 } { } { Copyright (C) 2022 kkuzil } { } {*******************************************************} unit Tocsg.Win32; interface uses Tocsg.Obj, System.Classes, Winapi.Windows; type TMutexState = (msUnknown, msCreateOk, msAlreadyExist, msFail); TTgMutex = class(TTgObject) private sName_: String; hMutex_: THandle; MutexState_: TMutexState; public Constructor Create(const sName: String); Destructor Destroy; override; property MutexName: String read sName_; property MutexState: TMutexState read MutexState_; property LastError; end; function MutexExists(const sMutex: String): Boolean; implementation function MutexExists(const sMutex: String): Boolean; var h: THandle; begin Result := false; // h := OpenMutex(MUTEX_ALL_ACCESS, true, PChar(sMutex)); h := OpenMutex(SYNCHRONIZE, false, PChar(sMutex)); if h <> 0 then begin CloseHandle(h); Result := true; end; end; { TTgMutex } Constructor TTgMutex.Create(const sName: String); procedure InitCreateMutex; var sd: SECURITY_DESCRIPTOR; sa: SECURITY_ATTRIBUTES; begin InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@sd, true, nil, false); ZeroMemory(@sa, sizeof(SECURITY_ATTRIBUTES)); sa.nLength := sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor := @sd; sa.bInheritHandle := false; hMutex_ := CreateMutex(@sa, false, PChar(sName_)); nLastError_ := GetLastError; if hMutex_ > 0 then begin if nLastError_ = ERROR_ALREADY_EXISTS then MutexState_ := msAlreadyExist else MutexState_ := msCreateOk; end else MutexState_ := msFail; end; begin Inherited Create; ASSERT(sName <> '', 'no mutex name..'); hMutex_ := 0; sName_ := sName; MutexState_ := msUnknown; InitCreateMutex; end; Destructor TTgMutex.Destroy; begin if hMutex_ > 0 then CloseHandle(hMutex_); Inherited; end; end.