ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

NTSTATUS NTAPI NtSignalAndWaitForSingleObject ( IN HANDLE  ObjectHandleToSignal,
IN HANDLE  WaitableObjectHandle,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER TimeOut  OPTIONAL 
)

Definition at line 450 of file obwait.c.

{
    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
    POBJECT_TYPE Type;
    PVOID SignalObj, WaitObj, WaitableObject;
    LARGE_INTEGER SafeTimeOut;
    OBJECT_HANDLE_INFORMATION HandleInfo;
    NTSTATUS Status;

    /* Check if we came with a timeout from user mode */
    if ((TimeOut) && (PreviousMode != KernelMode))
    {
        /* Enter SEH for probing */
        _SEH2_TRY
        {
            /* Make a copy on the stack */
            SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
            TimeOut = &SafeTimeOut;
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Return the exception code */
            _SEH2_YIELD(return _SEH2_GetExceptionCode());
        }
        _SEH2_END;
    }

    /* Start by getting the signal object*/
    Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
                                       0,
                                       NULL,
                                       PreviousMode,
                                       &SignalObj,
                                       &HandleInfo);
    if (!NT_SUCCESS(Status)) return Status;

    /* Now get the wait object */
    Status = ObReferenceObjectByHandle(WaitableObjectHandle,
                                       SYNCHRONIZE,
                                       NULL,
                                       PreviousMode,
                                       &WaitObj,
                                       NULL);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to reference the wait object */
        ObDereferenceObject(SignalObj);
        return Status;
    }

    /* Get the real waitable object */
    WaitableObject = OBJECT_TO_OBJECT_HEADER(WaitObj)->Type->DefaultObject;

    /* Handle internal offset */
    if (IsPointerOffset(WaitableObject))
    {
        /* Get real pointer */
        WaitableObject = (PVOID)((ULONG_PTR)WaitObj +
                                 (ULONG_PTR)WaitableObject);
    }

    /* Check Signal Object Type */
    Type = OBJECT_TO_OBJECT_HEADER(SignalObj)->Type;
    if (Type == ExEventObjectType)
    {
        /* Check if we came from user-mode without the right access */
        if ((PreviousMode != KernelMode) &&
            !(HandleInfo.GrantedAccess & EVENT_MODIFY_STATE))
        {
            /* Fail: lack of rights */
            Status = STATUS_ACCESS_DENIED;
            goto Quickie;
        }

        /* Set the Event */
        KeSetEvent(SignalObj, EVENT_INCREMENT, TRUE);
    }
    else if (Type == ExMutantObjectType)
    {
        /* This can raise an exception */
        _SEH2_TRY
        {
            /* Release the mutant */
            KeReleaseMutant(SignalObj, MUTANT_INCREMENT, FALSE, TRUE);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Get the exception code */
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END;
    }
    else if (Type == ExSemaphoreObjectType)
    {
        /* Check if we came from user-mode without the right access */
        if ((PreviousMode != KernelMode) &&
            !(HandleInfo.GrantedAccess & SEMAPHORE_MODIFY_STATE))
        {
            /* Fail: lack of rights */
            Status = STATUS_ACCESS_DENIED;
            goto Quickie;
        }

        /* This can raise an exception*/
        _SEH2_TRY
        {
            /* Release the semaphore */
            KeReleaseSemaphore(SignalObj, SEMAPHORE_INCREMENT, 1, TRUE);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Get the exception code */
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END;
    }
    else
    {
        /* This isn't a valid object to be waiting on */
        Status = STATUS_OBJECT_TYPE_MISMATCH;
    }

    /* Make sure we didn't fail */
    if (NT_SUCCESS(Status))
    {
        /* SEH this since it can also raise an exception */
        _SEH2_TRY
        {
            /* Perform the wait now */
            Status = KeWaitForSingleObject(WaitableObject,
                                           UserRequest,
                                           PreviousMode,
                                           Alertable,
                                           TimeOut);
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            /* Get the exception code */
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END;
    }

    /* We're done here, dereference both objects */
Quickie:
    ObDereferenceObject(SignalObj);
    ObDereferenceObject(WaitObj);
    return Status;
}

Generated on Sun May 27 2012 06:08:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.