Private Const ERROR_ALREADY_EXISTS = 183&
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Sub Form_Load()
Dim sTemp As String, hMutex As Long
sTemp = "MyMutex"
hMutex = CreateMutex(ByVal 0&, 1, sTemp)
If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then Unload Me
End Sub
The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.
Только если у кого-то остался незакрытым хэндл мьютекса. Родителя мьютекса документированными способами узнать не получится, хотя должен сохраняться в заголовке соответствующего объекта в ядре.Важно, останется ли мьютекс в памяти после некорректного завершения моего exe-шника.
Twister писал(а):Только если у кого-то остался незакрытым хэндл мьютекса. Родителя мьютекса документированными способами узнать не получится, хотя должен сохраняться в заголовке соответствующего объекта в ядре.Важно, останется ли мьютекс в памяти после некорректного завершения моего exe-шника.
А откуда уверенность, что таки-сохраняется?
typedef struct _KMUTANT {
DISPATCHER_HEADER Header;
LIST_ENTRY MutantListEntry;
struct _KTHREAD *OwnerThread;
BOOLEAN Abandoned;
UCHAR ApcDisable;
} KMUTANT, *PKMUTANT, *PRKMUTANT, KMUTEX, *PKMUTEX, *PRKMUTEX;
VOID
KeInitializeMutant (
__out PRKMUTANT Mutant,
__in BOOLEAN InitialOwner
)
/*++
Routine Description:
This function initializes a kernel mutant object.
Arguments:
Mutant - Supplies a pointer to a dispatcher object of type mutant.
InitialOwner - Supplies a boolean value that determines whether the
current thread is to be the initial owner of the mutant object.
Return Value:
None.
--*/
{
PLIST_ENTRY ListEntry;
KIRQL OldIrql;
PRKTHREAD Thread;
//
// Initialize standard dispatcher object header, set the owner thread to
// NULL, set the abandoned state to FALSE, and set the APC disable count
// to zero (this is the only thing that distinguishes a mutex from a mutant).
//
Mutant->Header.Type = MutantObject;
Mutant->Header.Size = sizeof(KMUTANT) / sizeof(LONG);
if (InitialOwner == TRUE) {
Thread = KeGetCurrentThread();
Mutant->Header.SignalState = 0;
Mutant->OwnerThread = Thread;
KiLockDispatcherDatabase(&OldIrql);
ListEntry = Thread->MutantListHead.Blink;
InsertHeadList(ListEntry, &Mutant->MutantListEntry);
KiUnlockDispatcherDatabase(OldIrql);
} else {
Mutant->Header.SignalState = 1;
Mutant->OwnerThread = (PKTHREAD)NULL;
}
InitializeListHead(&Mutant->Header.WaitListHead);
Mutant->Abandoned = FALSE;
Mutant->ApcDisable = 0;
return;
}
Сейчас этот форум просматривают: Yandex-бот и гости: 56