NTSTATUS NtSetEvent ( IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL ) /*++ Routine Description: This function sets an event object to a Signaled state and attempts to satisfy as many waits as possible. Arguments: EventHandle - Supplies a handle to an event object. PreviousState - Supplies an optional pointer to a variable that will receive the previous state of the event object. Return Value: TBS --*/ { PVOID Event; KPROCESSOR_MODE PreviousMode; LONG State; NTSTATUS Status; // // Establish an exception handler, probe the previous state address if // specified, reference the event object, and set the event object. If // the probe fails, then return the exception code as the service status. // Otherwise return the status value returned by the reference object by // handle routine. // try { // // Get previous processor mode and probe previous state address // if necessary. // PreviousMode = KeGetPreviousMode(); if ((PreviousMode != KernelMode) && (ARGUMENT_PRESENT(PreviousState))) { ProbeForWriteLong(PreviousState); } // // Reference event object by handle. // Status = ObReferenceObjectByHandle(EventHandle, EVENT_MODIFY_STATE, ExEventObjectType, PreviousMode, &Event, NULL); // // If the reference was successful, then set the event object to the // Signaled state, dereference event object, and write the previous // state value if specified. If the write of the previous state fails, // then do not report an error. When the caller attempts to access the // previous state value, an access violation will occur. // if (NT_SUCCESS(Status)) { State = KeSetEvent((PKEVENT)Event, ExpEventBoost, FALSE); ObDereferenceObject(Event); if (ARGUMENT_PRESENT(PreviousState)) { try { *PreviousState = State; } except(ExSystemExceptionFilter()) { } } } // // If an exception occurs during the probe of the previous state, then // always handle the exception and return the exception code as the status // value. // } except(ExSystemExceptionFilter()) { return GetExceptionCode(); } // // Return service status. // return Status; }
NTSTATUS NtReleaseMutant ( IN HANDLE MutantHandle, OUT PLONG PreviousCount OPTIONAL ) /*++ Routine Description: This function releases a mutant object. Arguments: Mutant - Supplies a handle to a mutant object. PreviousCount - Supplies an optional pointer to a variable that will receive the previous mutant count. Return Value: TBS --*/ { LONG Count; PVOID Mutant; KPROCESSOR_MODE PreviousMode; NTSTATUS Status; // // Establish an exception handler, probe the previous count address if // specified, reference the mutant object, and release the mutant object. // If the probe fails, then return the exception code as the service // status. Otherwise return the status value returned by the reference // object by handle routine. // try { // // Get previous processor mode and probe previous count address // if necessary. // PreviousMode = KeGetPreviousMode(); if ((PreviousMode != KernelMode) && (ARGUMENT_PRESENT(PreviousCount))) { ProbeForWriteLong(PreviousCount); } // // Reference mutant object by handle. // // Note that the desired access is specified as zero since only the // owner can release a mutant object. // Status = ObReferenceObjectByHandle(MutantHandle, 0, ExMutantObjectType, PreviousMode, &Mutant, NULL); // // If the reference was successful, then release the mutant object. If // an exception occurs because the caller is not the owner of the mutant // object, then dereference mutant object and return the exception code // as the service status. Otherise write the previous count value if // specified. If the write of the previous count fails, then do not // report an error. When the caller attempts to access the previous // count value, an access violation will occur. // if (NT_SUCCESS(Status)) { try { Count = KeReleaseMutant((PKMUTANT)Mutant, MUTANT_INCREMENT, FALSE, FALSE); ObDereferenceObject(Mutant); if (ARGUMENT_PRESENT(PreviousCount)) { try { *PreviousCount = Count; } except(ExSystemExceptionFilter()) { } } // // If an exception occurs because the caller is not the owner of // the mutant object, then always handle the exception, dereference // the mutant object, and return the exception code as the status // value. // } except(ExSystemExceptionFilter()) { ObDereferenceObject(Mutant); return GetExceptionCode(); } } // // If an exception occurs during the probe of the previous count, then // always handle the exception and return the exception code as the status // value. // } except(ExSystemExceptionFilter()) { return GetExceptionCode(); } // // Return service status. // return Status; }