Pain Posted June 25, 2009 Share Posted June 25, 2009 expandcollapse popup#RequireAdmin Global Const $MUTEX_ALL_ACCESS = 0x1F0001 Global $hMutexGlobal $name = "SciTE-UniqueInstanceMutex-Default" ConsoleWrite("Mutex Exists: " & (_MutexExists($name) = 1) & @CRLF) $hMutexGlobal = _MutexOpen($name) ConsoleWrite("Mutex Handle: " & $hMutexGlobal & @CRLF) ConsoleWrite("Mutex Released: " & (_ReleaseMutex($hMutexGlobal) = 1) & @CRLF) ConsoleWrite("Mutex Exists: " & (_MutexExists($name) = 1) & @CRLF) Func _MutexOpen($szMutexName) Local $hMutex = DllCall("kernel32.dll", "hwnd", "OpenMutex", "int", $MUTEX_ALL_ACCESS, "int", 0, "str", $szMutexName) If IsArray($hMutex) And $hMutex[0] Then Return $hMutex[0] EndIf Return 0 EndFunc Func _MutexExists($szMutexName) Local $hMutex = DllCall("Kernel32.dll", "hwnd", "OpenMutex", "int", 0x1F0001, "int", 1, "str", $szMutexName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($hMutex) And $hMutex[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hMutex[0]) EndIf If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc ;==>_MutexExists Func _ReleaseMutex($hMutex) Local $aRM = DllCall("kernel32.dll", "int", "ReleaseMutex", "hwnd", $hMutex) Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hMutex) If (IsArray($aRM) And $aRM[0] > 0) And (IsArray($aCH) And $aCH[0] > 0) Then Return 1 Return 0 EndFunc ;==>ExitScriptI guess most have Scite so to make it easier to test I'm using the Scite mutex.This is my output:Mutex Exists: TrueMutex Handle: 0x000006FCMutex Released: FalseMutex Exists: TrueIt appears to me that the problem is either in _MutexOpen or _ReleaseMutex. Most likely because the current thread doesn't own the mutex. So my question is how do I make the thread to have ownership of the mutex?OpenMutex: http://msdn.microsoft.com/en-us/library/ms684315(VS.85).aspxReleaseMutex: http://msdn.microsoft.com/en-us/library/ms685066(VS.85).aspx Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 25, 2009 Share Posted June 25, 2009 It appears to me that the problem is either in _MutexOpen or _ReleaseMutex. Most likely because the current thread doesn't own the mutex. So my question is how do I make the thread to have ownership of the mutex?I don't think you can "Take Ownership" of the mutex unless the current owner releases it. You are just in the que to get ownership when available. Since you are using SciTE's mutex, that would mean closing SciTE. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
trancexx Posted June 25, 2009 Share Posted June 25, 2009 PsaltyDS is right of course. Run this to see (run and then close SciTE):expandcollapse popup#RequireAdmin HotKeySet("{ESC}", "_Escape"); ESC to exit #include <WinAPI.au3> Global Const $MUTEX_ALL_ACCESS = 0x1F0001 Global $hMutexGlobal $name = "SciTE-UniqueInstanceMutex-Default" While 1 ConsoleWrite("Mutex Exists: " & (_MutexExists($name) = 1) & @CRLF) $hMutexGlobal = _MutexOpen($name) ConsoleWrite("Mutex Handle: " & $hMutexGlobal & @CRLF) If _ReleaseMutex($hMutexGlobal) = 1 Then MsgBox(0, '', "Mutex Released!" & @CRLF & "Mutex Exists: " & (_MutexExists($name) = 1)) Else ConsoleWrite("Mutex Released: False" & @CRLF) ConsoleWrite("Mutex Exists: " & (_MutexExists($name) = 1) & @CRLF) EndIf Sleep(1000) WEnd Func _MutexOpen($szMutexName) Local $tSECURITY_ATTRIBUTES = DllStructCreate("dword Length;" & _ "ptr SecurityDescriptor;" & _ "int InheritHandle") DllStructSetData($tSECURITY_ATTRIBUTES, "Length", DllStructGetSize($tSECURITY_ATTRIBUTES)) DllStructSetData($tSECURITY_ATTRIBUTES, "InheritHandle", 1); inherit the handle;<- THIS!!! Local $hMutex = DllCall("kernel32.dll", "hwnd", "CreateMutex", _ "ptr", DllStructGetPtr($tSECURITY_ATTRIBUTES), _ "int", 1, _ "str", $szMutexName) If @error Or Not $hMutex[0] Then Return 0 EndIf Return $hMutex[0] EndFunc ;==>_MutexOpen Func _MutexOpen_($szMutexName) Local $hMutex = DllCall("kernel32.dll", "hwnd", "OpenMutex", "int", $MUTEX_ALL_ACCESS, "int", 0, "str", $szMutexName) If IsArray($hMutex) And $hMutex[0] Then Return $hMutex[0] EndIf Return 0 EndFunc ;==>_MutexOpen_ Func _MutexExists($szMutexName) Local $hMutex = DllCall("Kernel32.dll", "hwnd", "OpenMutex", "int", 0x1F0001, "int", 1, "str", $szMutexName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($hMutex) And $hMutex[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hMutex[0]) EndIf If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc ;==>_MutexExists Func _ReleaseMutex($hMutex) Local $aRM = DllCall("kernel32.dll", "int", "ReleaseMutex", "hwnd", $hMutex) ConsoleWrite("!!!!" & _WinAPI_GetLastErrorMessage()) ;ConsoleWrite("!!!!" & $aRM[0] & @CRLF) Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hMutex) If (IsArray($aRM) And $aRM[0] > 0) And (IsArray($aCH) And $aCH[0] > 0) Then Return 1 Return 0 EndFunc ;==>_ReleaseMutex Func _Escape() Exit EndFunc ;==>_EscapeI changed _MutexOpen() and added _WinAPI_GetLastErrorMessage().ESC to exit ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 25, 2009 Share Posted June 25, 2009 Do it like this and you can run it from SciTE, then close SciTE to see what happens: expandcollapse popup#RequireAdmin HotKeySet("{ESC}", "_Escape"); ESC to exit #include <WinAPI.au3> Global Const $MUTEX_ALL_ACCESS = 0x1F0001 Global $hMutexGlobal Global $name = "SciTE-UniqueInstanceMutex-Default" Global $hGUI = GUICreate("Mutex Test", 400, 600) Global $ctrlEdit = GUICtrlCreateEdit("Start...", 10, 10, 380, 580) GUISetState() While 1 _EditWrite("Mutex Exists: " & (_MutexExists($name) = 1) & @CRLF) $hMutexGlobal = _MutexOpen($name) _EditWrite("Mutex Handle: " & $hMutexGlobal & @CRLF) If _ReleaseMutex($hMutexGlobal) = 1 Then _EditWrite("Mutex Released!" & @CRLF & "Mutex Exists: " & (_MutexExists($name) = 1) & @CRLF & @CRLF) Else _EditWrite("Mutex Released: False" & @CRLF) _EditWrite("Mutex Exists: " & (_MutexExists($name) = 1) & @CRLF & @CRLF) EndIf Sleep(1000) WEnd Func _MutexOpen($szMutexName) Local $tSECURITY_ATTRIBUTES = DllStructCreate("dword Length;" & _ "ptr SecurityDescriptor;" & _ "int InheritHandle") DllStructSetData($tSECURITY_ATTRIBUTES, "Length", DllStructGetSize($tSECURITY_ATTRIBUTES)) DllStructSetData($tSECURITY_ATTRIBUTES, "InheritHandle", 1); inherit the handle;<- THIS!!! Local $hMutex = DllCall("kernel32.dll", "hwnd", "CreateMutex", _ "ptr", DllStructGetPtr($tSECURITY_ATTRIBUTES), _ "int", 1, _ "str", $szMutexName) If @error Or Not $hMutex[0] Then Return 0 EndIf Return $hMutex[0] EndFunc ;==>_MutexOpen Func _MutexOpen_($szMutexName) Local $hMutex = DllCall("kernel32.dll", "hwnd", "OpenMutex", "int", $MUTEX_ALL_ACCESS, "int", 0, "str", $szMutexName) If IsArray($hMutex) And $hMutex[0] Then Return $hMutex[0] EndIf Return 0 EndFunc ;==>_MutexOpen_ Func _MutexExists($szMutexName) Local $hMutex = DllCall("Kernel32.dll", "hwnd", "OpenMutex", "int", 0x1F0001, "int", 1, "str", $szMutexName) Local $aGLE = DllCall("Kernel32.dll", "int", "GetLastError") If IsArray($hMutex) And $hMutex[0] Then DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hMutex[0]) EndIf If IsArray($aGLE) And $aGLE[0] = 127 Then Return 1 Return 0 EndFunc ;==>_MutexExists Func _ReleaseMutex($hMutex) Local $aRM = DllCall("kernel32.dll", "int", "ReleaseMutex", "hwnd", $hMutex) _EditWrite("!!!!" & _WinAPI_GetLastErrorMessage()) ;_EditWrite("!!!!" & $aRM[0] & @CRLF) Local $aCH = DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hMutex) If (IsArray($aRM) And $aRM[0] > 0) And (IsArray($aCH) And $aCH[0] > 0) Then Return 1 Return 0 EndFunc ;==>_ReleaseMutex Func _EditWrite($sString) ControlSetText($hGUI, "", $ctrlEdit, ControlGetText($hGUI, "", $ctrlEdit) & $sString) EndFunc ;==>_EditWrite Func _Escape() Sleep(5000) Exit EndFunc ;==>_Escape Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Pain Posted June 25, 2009 Author Share Posted June 25, 2009 So, how is Process Explorer working where you can close the mutex without the the program have to be closed?If more than one thread is waiting on a mutex, a waiting thread is selected. Do not assume a first-in, first-out (FIFO) order. External events such as kernel-mode APCs can change the wait order.http://msdn.microsoft.com/en-us/library/ms684266(VS.85).aspxI guess this refers to NtQueueApcThread. Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 25, 2009 Share Posted June 25, 2009 So, how is Process Explorer working where you can close the mutex without the the program have to be closed?http://msdn.microsoft.com/en-us/library/ms684266(VS.85).aspxI guess this refers to NtQueueApcThread.Time for my daily stupid question: How did you get to the mutex via Process Explorer? What view do you see SciTE's mutex in? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Pain Posted June 25, 2009 Author Share Posted June 25, 2009 (edited) Show Lower Pane, Lower Pane View > Handle and click on Scite and you'll see it. I think you already know that mutant = mutex but I'll tell it anyways. Right click on the mutex and close it and you will see that Scite didn't close but the mutex has been closed. Edited June 25, 2009 by Pain Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 25, 2009 Share Posted June 25, 2009 Show Lower Pane, Lower Pane View > Handle and click on Scite and you'll see it.I think you already know that mutant = mutex but I'll tell it anyways.Right click on the mutex and close it and you will see that Scite didn't close but the mutex has been closed.Sho'nuf! I ran my version of the demo above and closing the handle to the mutex in Process Explorer is clearly visible to the script, while SciTE is still running.Thanks for the tip. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Pain Posted June 25, 2009 Author Share Posted June 25, 2009 So the question still remains, how is it done? Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 25, 2009 Share Posted June 25, 2009 (edited) So the question still remains, how is it done?No clue here. But those tools come from Mark Russinovich, which means much deeper JuJu is available if required. I don't know it's the case, but the API used may not be documented for us mere mortals. Edit: After consulting with the deep JuJu (herewasplato and Valik) I eventually got from here: Close Mutex of another processTo here: 5. Need a CloseHandleEx? (Remote Handle Closing) (last post by "Matts_User_Name", numbered item 5. in his list).What you are doing is duplicating the handle with a flag set to close the original ( $DUPLICATE_CLOSE_SOURCE = 0x1 ). Then you close your duplicate. So you call DuplicateHandle() with $DUPLICATE_CLOSE_SOURCE, and then call CloseHandle() on your returned duplicate handle.Hope that helps! It was at least educational for me. Edited June 25, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
simon387 Posted May 16, 2010 Share Posted May 16, 2010 @ #10: I need it Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now