示例#1
0
static int wine_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
  wine_cond_detail *detail;
  int last_waiter;

  if ( !((wine_cond)cond)->cond ) wine_cond_real_init(cond);
  detail = ((wine_cond)cond)->cond;

  /* Avoid race conditions. */
  RtlEnterCriticalSection (&detail->waiters_count_lock);
  detail->waiters_count++;
  RtlLeaveCriticalSection (&detail->waiters_count_lock);

  RtlLeaveCriticalSection ( ((wine_mutex)mutex)->critsect );
  NtWaitForMultipleObjects( 1, &detail->sema, FALSE, FALSE, NULL );

  /* Reacquire lock to avoid race conditions. */
  RtlEnterCriticalSection (&detail->waiters_count_lock);

  /* We're no longer waiting... */
  detail->waiters_count--;

  /* Check to see if we're the last waiter after <pthread_cond_broadcast>. */
  last_waiter = detail->was_broadcast && detail->waiters_count == 0;

  RtlLeaveCriticalSection (&detail->waiters_count_lock);

  /*
   * If we're the last waiter thread during this particular broadcast
   * then let all the other threads proceed.
   */
  if (last_waiter) NtSetEvent( detail->waiters_done, NULL );
  RtlEnterCriticalSection (((wine_mutex)mutex)->critsect);
  return 0;
}
示例#2
0
NTSTATUS __cdecl _main(int argc,
			char *argv[],
			char *envp[],
			ULONG DebugFlag)
{
  NTSTATUS Status = STATUS_SUCCESS;
  PROCESS_BASIC_INFORMATION PBI = {0};

  /* Lookup yourself */
  Status = NtQueryInformationProcess (NtCurrentProcess(),
		    		      ProcessBasicInformation,
				      & PBI,
				      sizeof PBI,
      				      NULL);
  if(NT_SUCCESS(Status))
  {
	  SmSsProcessId = (ULONG) PBI.UniqueProcessId;
  }
  /* Initialize the system */
  Status = InitSessionManager();
  /* Watch required subsystems TODO */
#if 0
  if (!NT_SUCCESS(Status))
    {
      int i;
      for (i=0; i < (sizeof Children / sizeof Children[0]); i++)
      {
        if (Children[i])
        {
          NtTerminateProcess(Children[i],0);
        }
      }
      DPRINT1("SM: Initialization failed!\n");
      goto ByeBye;
    }

  Status = NtWaitForMultipleObjects(((LONG) sizeof(Children) / sizeof(HANDLE)),
				    Children,
				    WaitAny,
				    TRUE,	/* alertable */
				    NULL);	/* NULL for infinite */
  if (!NT_SUCCESS(Status))
    {
      DPRINT1("SM: NtWaitForMultipleObjects failed! (Status=0x%08lx)\n", Status);
    }
  else
    {
      DPRINT1("SM: Process terminated!\n");
    }

ByeBye:
  /* Raise a hard error (crash the system/BSOD) */
  NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
		   0,0,0,0,0);

//   NtTerminateProcess(NtCurrentProcess(), 0);
#endif
	return NtTerminateThread(NtCurrentThread(), Status);
}
    HOOKFUNC NTSTATUS NTAPI MyNtWaitForMultipleObjects(ULONG ObjectCount, PHANDLE ObjectsArray, DWORD WaitType, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
    {
        DWORD dwMilliseconds = Timeout ? Timeout->LowPart : ~0;
        ENTER(dwMilliseconds);

        {
            return NtWaitForMultipleObjects(ObjectCount, ObjectsArray, WaitType, Alertable, Timeout);
        }
    }
示例#4
0
HOOKFUNC NTSTATUS NTAPI MyNtWaitForMultipleObjects(ULONG ObjectCount, PHANDLE ObjectsArray, DWORD WaitType, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
{
    DWORD dwMilliseconds = Timeout ? Timeout->LowPart : ~0;
    debuglog(LCF_WAIT|LCF_FREQUENT|LCF_DESYNC, __FUNCTION__ "(%d)\n", dwMilliseconds);

    {
        return NtWaitForMultipleObjects(ObjectCount, ObjectsArray, WaitType, Alertable, Timeout);
    }
}
示例#5
0
文件: push.c 项目: Volkanite/Push
DWORD __stdcall MonitorThread(VOID* Parameter)
{
    HANDLE processEvent;
    HANDLE d3dImageEvent;
    VOID *handles[2];

    processEvent = OpenEvent(L"Global\\" PUSH_PROCESS_EVENT_NAME);
    d3dImageEvent = OpenEvent(L"Global\\" PUSH_IMAGE_EVENT_NAME);

    handles[0] = processEvent;
    handles[1] = d3dImageEvent;

    while (processEvent)
    {
        NTSTATUS result;
        HANDLE threadHandle;

        result = NtWaitForMultipleObjects(2, &handles[0], WaitAny, FALSE, NULL);

        if (processEvent && handles[result - STATUS_WAIT_0] == processEvent)
        {
            NtCreateThreadEx(
                &threadHandle,
                THREAD_ALL_ACCESS,
                NULL,
                NtCurrentProcess(),
                &RetrieveProcessEvent,
                NULL,
                NoThreadFlags,
                0, 0, 0,
                NULL
                );
        }
        else if (handles[result - STATUS_WAIT_0] == d3dImageEvent)
        {
            NtCreateThreadEx(
                &threadHandle,
                THREAD_ALL_ACCESS,
                NULL,
                NtCurrentProcess(),
                &RetrieveImageEvent,
                NULL,
                NoThreadFlags,
                0, 0, 0,
                NULL
                );
        }
    }

    return 0;
}
示例#6
0
static NTSTATUS PhpWfmoThreadStart(
    _In_ PVOID Parameter
    )
{
    HANDLE eventHandle;
    LARGE_INTEGER timeout;

    eventHandle = Parameter;

    timeout.QuadPart = -(LONGLONG)UInt32x32To64(5, PH_TIMEOUT_SEC);
    NtWaitForMultipleObjects(1, &eventHandle, WaitAll, FALSE, &timeout);

    return STATUS_SUCCESS;
}
示例#7
0
static int wine_pthread_cond_broadcast(pthread_cond_t *cond)
{
  int have_waiters = 0;
  wine_cond_detail *detail;

  if ( !((wine_cond)cond)->cond ) wine_cond_real_init(cond);
  detail = ((wine_cond)cond)->cond;

  /*
   * This is needed to ensure that <waiters_count> and <was_broadcast> are
   * consistent relative to each other.
   */
  RtlEnterCriticalSection (&detail->waiters_count_lock);

  if (detail->waiters_count > 0) {
    /*
     * We are broadcasting, even if there is just one waiter...
     * Record that we are broadcasting, which helps optimize
     * <pthread_cond_wait> for the non-broadcast case.
     */
    detail->was_broadcast = 1;
    have_waiters = 1;
  }

  if (have_waiters) {
    /* Wake up all the waiters atomically. */
    NtReleaseSemaphore(detail->sema, detail->waiters_count, NULL);

    RtlLeaveCriticalSection (&detail->waiters_count_lock);

    /* Wait for all the awakened threads to acquire the counting semaphore. */
    NtWaitForMultipleObjects( 1, &detail->waiters_done, FALSE, FALSE, NULL );

    /*
     * This assignment is okay, even without the <waiters_count_lock> held
     * because no other waiter threads can wake up to access it.
     */
    detail->was_broadcast = 0;
  }
  else
    RtlLeaveCriticalSection (&detail->waiters_count_lock);
  return 0;
}
示例#8
0
static int wine_pthread_join(pthread_t thread, void **value_ptr)
{
  THREAD_BASIC_INFORMATION info;
  CLIENT_ID cid;
  NTSTATUS status;
  HANDLE handle;

  cid.UniqueProcess = 0;
  cid.UniqueThread = (HANDLE)thread;
  status = NtOpenThread( &handle, THREAD_QUERY_INFORMATION|SYNCHRONIZE, NULL, &cid );
  if (!status)
  {
    NtWaitForMultipleObjects( 1, &handle, FALSE, FALSE, NULL );
    status = NtQueryInformationThread( handle, ThreadBasicInformation, &info, sizeof(info), NULL );
    NtClose( handle );
    if (!status) *value_ptr = UlongToPtr(info.ExitStatus);
  }
  if (status) return EINVAL; /* FIXME: make this more correctly match windows errors */
  return 0;
}
示例#9
0
static int wine_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
                                       const struct timespec *abstime)
{
  LARGE_INTEGER time;
  int last_waiter;
  wine_cond_detail *detail;

  if ( !((wine_cond)cond)->cond ) wine_cond_real_init(cond);
  detail = ((wine_cond)cond)->cond;

  /* Avoid race conditions. */
  RtlEnterCriticalSection (&detail->waiters_count_lock);
  detail->waiters_count++;
  RtlLeaveCriticalSection (&detail->waiters_count_lock);

  RtlLeaveCriticalSection (((wine_mutex)mutex)->critsect);

  time.QuadPart = (ULONGLONG)abstime->tv_sec * 10000000 + abstime->tv_nsec / 100;
  time.QuadPart = -time.QuadPart;
  NtWaitForMultipleObjects( 1, &detail->sema, FALSE, FALSE, &time );

  /* Reacquire lock to avoid race conditions. */
  RtlEnterCriticalSection (&detail->waiters_count_lock);

  /* We're no longer waiting... */
  detail->waiters_count--;

  /* Check to see if we're the last waiter after <pthread_cond_broadcast>. */
  last_waiter = detail->was_broadcast && detail->waiters_count == 0;

  RtlLeaveCriticalSection (&detail->waiters_count_lock);

  /*
   * If we're the last waiter thread during this particular broadcast
   * then let all the other threads proceed.
   */
  if (last_waiter) NtSetEvent( detail->waiters_done, NULL );
  RtlEnterCriticalSection (((wine_mutex)mutex)->critsect);
  return 0;
}
示例#10
0
文件: smss.c 项目: rmallof/reactos
NTSTATUS
_main(IN INT argc,
      IN PCHAR argv[],
      IN PCHAR envp[],
      IN ULONG DebugFlag)
{
    NTSTATUS Status;
    KPRIORITY SetBasePriority;
    ULONG_PTR Parameters[4];
    HANDLE Handles[2];
    PVOID State;
    ULONG Flags;
    PROCESS_BASIC_INFORMATION ProcessInfo;
    UNICODE_STRING DbgString, InitialCommand;

    /* Make us critical */
    RtlSetProcessIsCritical(TRUE, NULL, FALSE);
    RtlSetThreadIsCritical(TRUE, NULL, FALSE);

    /* Raise our priority */
    SetBasePriority = 11;
    Status = NtSetInformationProcess(NtCurrentProcess(),
                                     ProcessBasePriority,
                                     (PVOID)&SetBasePriority,
                                     sizeof(SetBasePriority));
    ASSERT(NT_SUCCESS(Status));

    /* Save the debug flag if it was passed */
    if (DebugFlag) SmpDebug = DebugFlag != 0;

    /* Build the hard error parameters */
    Parameters[0] = (ULONG_PTR)&DbgString;
    Parameters[1] = Parameters[2] = Parameters[3] = 0;

    /* Enter SEH so we can terminate correctly if anything goes wrong */
    _SEH2_TRY
    {
        /* Initialize SMSS */
        Status = SmpInit(&InitialCommand, Handles);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("SMSS: SmpInit return failure - Status == %x\n", Status);
            RtlInitUnicodeString(&DbgString, L"Session Manager Initialization");
            Parameters[1] = Status;
            _SEH2_LEAVE;
        }

        /* Get the global flags */
        Status = NtQuerySystemInformation(SystemFlagsInformation,
                                          &Flags,
                                          sizeof(Flags),
                                          NULL);
        ASSERT(NT_SUCCESS(Status));

        /* Before executing the initial command check if the debug flag is on */
        if (Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX))
        {
            /* SMSS should launch ntsd with a few parameters at this point */
            DPRINT1("Global Flags Set to SMSS Debugging: Not yet supported\n");
        }

        /* Execute the initial command (Winlogon.exe) */
        Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], NULL);
        if (!NT_SUCCESS(Status))
        {
            /* Fail and raise a hard error */
            DPRINT1("SMSS: Execute Initial Command failed\n");
            RtlInitUnicodeString(&DbgString,
                                 L"Session Manager ExecuteInitialCommand");
            Parameters[1] = Status;
            _SEH2_LEAVE;
        }

        /*  Check if we're already attached to a session */
        Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State);
        if (AttachedSessionId != -1)
        {
            /* Detach from it, we should be in no session right now */
            Status = NtSetSystemInformation(SystemSessionDetach,
                                            &AttachedSessionId,
                                            sizeof(AttachedSessionId));
            ASSERT(NT_SUCCESS(Status));
            AttachedSessionId = -1;
        }
        SmpReleasePrivilege(State);

        /* Wait on either CSRSS or Winlogon to die */
        Status = NtWaitForMultipleObjects(RTL_NUMBER_OF(Handles),
                                          Handles,
                                          WaitAny,
                                          FALSE,
                                          NULL);
        if (Status == STATUS_WAIT_0)
        {
            /* CSRSS is dead, get exit code and prepare for the hard error */
            RtlInitUnicodeString(&DbgString, L"Windows SubSystem");
            Status = NtQueryInformationProcess(Handles[0],
                                               ProcessBasicInformation,
                                               &ProcessInfo,
                                               sizeof(ProcessInfo),
                                               NULL);
            DPRINT1("SMSS: Windows subsystem terminated when it wasn't supposed to.\n");
        }
        else
        {
            /* The initial command is dead or we have another failure */
            RtlInitUnicodeString(&DbgString, L"Windows Logon Process");
            if (Status == STATUS_WAIT_1)
            {
                /* Winlogon.exe got terminated, get its exit code */
                Status = NtQueryInformationProcess(Handles[1],
                                                   ProcessBasicInformation,
                                                   &ProcessInfo,
                                                   sizeof(ProcessInfo),
                                                   NULL);
            }
            else
            {
                /* Something else satisfied our wait, so set the wait status */
                ProcessInfo.ExitStatus = Status;
                Status = STATUS_SUCCESS;
            }
            DPRINT1("SMSS: Initial command '%wZ' terminated when it wasn't supposed to.\n",
                    &InitialCommand);
        }

        /* Check if NtQueryInformationProcess was successful */
        if (NT_SUCCESS(Status))
        {
            /* Then we must have a valid exit status in the structure, use it */
            Parameters[1] = ProcessInfo.ExitStatus;
        }
        else
        {
            /* We really don't know what happened, so set a generic error */
            Parameters[1] = STATUS_UNSUCCESSFUL;
        }
    }
    _SEH2_EXCEPT(SmpUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
    {
        /* The filter should never return here */
        ASSERT(FALSE);
    }
    _SEH2_END;

    /* Something in the init loop failed, terminate SMSS */
    return SmpTerminate(Parameters, 1, RTL_NUMBER_OF(Parameters));
}
示例#11
0
/*
 * @implemented
 */
DWORD
WINAPI
WaitForMultipleObjectsEx(IN DWORD nCount,
                         IN CONST HANDLE *lpHandles,
                         IN BOOL bWaitAll,
                         IN DWORD dwMilliseconds,
                         IN BOOL bAlertable)
{
    PLARGE_INTEGER TimePtr;
    LARGE_INTEGER Time;
    PHANDLE HandleBuffer;
    HANDLE Handle[8];
    DWORD i;
    NTSTATUS Status;
    RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx;

    /* APCs must execute with the default activation context */
    if (bAlertable)
    {
        /* Setup the frame */
        RtlZeroMemory(&ActCtx, sizeof(ActCtx));
        ActCtx.Size = sizeof(ActCtx);
        ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER;
        RtlActivateActivationContextUnsafeFast(&ActCtx, NULL);
    }

    /* Check if we have more handles then we locally optimize */
    if (nCount > 8)
    {
        /* Allocate a buffer for them */
        HandleBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
                                       0,
                                       nCount * sizeof(HANDLE));
        if (!HandleBuffer)
        {
            /* No buffer, fail the wait */
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx);
            return WAIT_FAILED;
        }
    }
    else
    {
        /* Otherwise, use our local buffer */
        HandleBuffer = Handle;
    }

    /* Copy the handles into our buffer and loop them all */
    RtlCopyMemory(HandleBuffer, (LPVOID)lpHandles, nCount * sizeof(HANDLE));
    for (i = 0; i < nCount; i++)
    {
        /* Check what kind of handle this is */
        HandleBuffer[i] = TranslateStdHandle(HandleBuffer[i]);

        /* Check for console handle */
        if ((IsConsoleHandle(HandleBuffer[i])) &&
            (VerifyConsoleIoHandle(HandleBuffer[i])))
        {
            /* Get the real wait handle */
            HandleBuffer[i] = GetConsoleInputWaitHandle();
        }
    }

    /* Convert the timeout */
    TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);

    /* Start wait loop */
    do
    {
        /* Do the wait */
        Status = NtWaitForMultipleObjects(nCount,
                                          HandleBuffer,
                                          bWaitAll ? WaitAll : WaitAny,
                                          (BOOLEAN)bAlertable,
                                          TimePtr);
        if (!NT_SUCCESS(Status))
        {
            /* Wait failed */
            BaseSetLastNTError(Status);
            Status = WAIT_FAILED;
        }
    } while ((Status == STATUS_ALERTED) && (bAlertable));

    /* Check if we didn't use our local buffer */
    if (HandleBuffer != Handle)
    {
        /* Free the allocated one */
        RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer);
    }

    /* Cleanup the activation context */
    if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx);

    /* Return wait status */
    return Status;
}
示例#12
0
文件: tob.c 项目: Gaikokujin/WinNT4
BOOLEAN
obtest( void )
{
    ULONG i;
    HANDLE Handles[ 2 ];
    NTSTATUS Status;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectTypeAName, "ObjectTypeA" );
    RtlInitString( &ObjectTypeBName, "ObjectTypeB" );

    RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
    ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
    ObjectTypeInitializer.ValidAccessMask = -1;

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = TRUE;
    ObjectTypeInitializer.DumpProcedure = DumpAProc;
    ObjectTypeInitializer.OpenProcedure = OpenAProc;
    ObjectTypeInitializer.CloseProcedure = CloseAProc;
    ObjectTypeInitializer.DeleteProcedure = DeleteAProc;
    ObjectTypeInitializer.ParseProcedure = ParseAProc;
    ObCreateObjectType(
        &ObjectTypeAName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeA
        );

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = FALSE;
    ObjectTypeInitializer.GenericMapping = MyGenericMapping;
    ObjectTypeInitializer.DumpProcedure = DumpBProc;
    ObjectTypeInitializer.OpenProcedure = NULL;
    ObjectTypeInitializer.CloseProcedure = NULL;
    ObjectTypeInitializer.DeleteProcedure = DeleteBProc;
    ObjectTypeInitializer.ParseProcedure = NULL;
    ObCreateObjectType(
        &ObjectTypeBName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeB
        );

    ObpDumpTypes( NULL );

    RtlInitString( &DirectoryName, "\\MyObjects" );
    InitializeObjectAttributes( &DirectoryObjA,
                                &DirectoryName,
                                OBJ_PERMANENT |
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    NtCreateDirectoryObject( &DirectoryHandle,
                             0,
                             &DirectoryObjA
                           );
    NtClose( DirectoryHandle );

    RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" );
    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA
        );

    ObjectA = (POBJECTTYPEA)ObjectBodyA;
    ObjectA->TypeALength = sizeof( *ObjectA );
    for (i=0; i<4; i++) {
        ObjectA->Stuff[i] = i+1;
        }
    KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeB,
        &ObjectBObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEB ),
        0L,
        0L,
        (PVOID *)&ObjectBodyB
        );

    ObjectB = (POBJECTTYPEB)ObjectBodyB;
    ObjectB->TypeBLength = sizeof( *ObjectB );
    for (i=0; i<16; i++) {
        ObjectB->Stuff[i] = i+1;
        }
    KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L );

    Status = ObInsertObject(
        ObjectBodyA,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA,
        &ObjectHandleA1
        );

    DbgPrint( "Status: %lx  ObjectBodyA: %lx  ObjectHandleA1: %lx\n",
             Status, ObjectBodyA, ObjectHandleA1
           );

    Status = ObInsertObject(
        ObjectBodyB,
        SYNCHRONIZE | 0x1,
        NULL,
        1,
        &ObjectBodyB,
        &ObjectHandleB1
        );

    DbgPrint( "Status: %lx  ObjectBodyB: %lx  ObjectHandleB1: %lx\n",
             Status, ObjectBodyB, ObjectHandleB1
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_OPENIF,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA1
        );


    Status = ObInsertObject(
        ObjectBodyA1,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA2,
        &ObjectHandleA2
        );

    DbgPrint( "Status: %lx  ObjectBodyA1: %lx  ObjectBodyA2: %lx  ObjectHandleA2: %lx\n",
             Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );
    NtClose( ObjectHandleA2 );
    ObDereferenceObject( ObjectBodyA2 );    // ObInsertObject,ObjectPointerBias

    NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL );
    Handles[ 0 ] = ObjectHandleA1;
    Handles[ 1 ] = ObjectHandleB1;
    NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByPointer(
        ObjectBodyA,
        0L,
        ObjectTypeA,
        KernelMode
        );

    ObReferenceObjectByPointer(
        ObjectBodyB,
        0L,
        ObjectTypeB,
        KernelMode
        );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" );
    RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" );
    ObReferenceObjectByName(
        &ObjectAPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectBodyA
        );

    ObReferenceObjectByName(
        &ObjectBPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectBodyB
        );

    DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectBodyA );

    DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObInsertObject,ObjectPointerBias
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByPointer
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByName
    ObDereferenceObject( ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectAObjA,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectHandleA2
        );

    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectBObjA,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectHandleB2
        );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectHandleA2 );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA2,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB2,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObOpenObjectByPointer(
        ObjectBodyA,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        &ObjectHandleA1
        );

    ObOpenObjectByPointer(
        ObjectBodyB,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        &ObjectHandleB1
        );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA,
            ObjectHandleA1 );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB,
            ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    NtClose( ObjectHandleA2 );
    NtClose( ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    TestFunction = NULL;

    return( TRUE );
}
示例#13
0
VOID NotificationThread(
    PVOID pJunk)
{
    INT         nEvents = ID_MEDIACHANGE;
    INT         nMediaEvents = 0;
    KPRIORITY   Priority;
    NTSTATUS    Status;
    HANDLE      hEvent[ MAXIMUM_WAIT_OBJECTS ];

    try {

        /*
         * Set the priority of the RIT to 3.
         */
        Priority = LOW_PRIORITY + 3;
        NtSetInformationThread(hThreadNotification, ThreadPriority, &Priority,
                sizeof(KPRIORITY));

        /*
         * Setup the NLS event
         */
        NtCreateEvent(&ghNlsEvent, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE);
        UserAssert( ghNlsEvent != NULL );
        hEvent[ID_NLS] = ghNlsEvent;

        /*
         * Setup the MediaChangeEvent
         */
        RtlZeroMemory(wcDriveCache, sizeof(wcDriveCache));
        Status = NtUserGetMediaChangeEvents(MAXIMUM_WAIT_OBJECTS - ID_MEDIACHANGE,
                                            &hEvent[ID_MEDIACHANGE],
                                            &nMediaEvents);
        if (NT_SUCCESS(Status)) {
            nEvents += nMediaEvents;
        }
#ifdef DEBUG
        else {
            KdPrint(("NotificationThread: NtUserGetMediaChangeEvents failed 0x08X\n", Status));
        }
#endif

        StartRegReadRead();

        /*
         * Sit and wait forever.
         */
        while (TRUE) {
            Status = NtWaitForMultipleObjects(nEvents,
                                              hEvent,
                                              WaitAny,
                                              TRUE,
                                              NULL);


            if (Status == ID_NLS + WAIT_OBJECT_0) {

                /*
                 * Handle the NLS event
                 */
                if (gfLogon) {
                    gfLogon = FALSE;
                    BaseSrvNlsUpdateRegistryCache(NULL, NULL);
                }

            }
            else if (Status >= ID_MEDIACHANGE + WAIT_OBJECT_0 &&
                     Status < (ID_MEDIACHANGE + nMediaEvents + WAIT_OBJECT_0)) {
                /*
                 * Handle the CD-ROM \Device\MediaChangeEventX event
                 */

                NtResetEvent( hEvent[Status - WAIT_OBJECT_0], NULL );
                HandleMediaChangeEvent( Status - WAIT_OBJECT_0 - ID_MEDIACHANGE );
            }

        } // While (TRUE)

    } except (CsrUnhandledExceptionFilter(GetExceptionInformation())) {
        KdPrint(("Registry notification thread is dead, sorry.\n"));
    }
}
示例#14
0
文件: synch.c 项目: shuowen/OpenNT
DWORD
APIENTRY
WaitForMultipleObjectsEx(
    DWORD nCount,
    CONST HANDLE *lpHandles,
    BOOL bWaitAll,
    DWORD dwMilliseconds,
    BOOL bAlertable
)

/*++

Routine Description:

    A wait operation on multiple waitable objects (up to
    MAXIMUM_WAIT_OBJECTS) is accomplished with the
    WaitForMultipleObjects function.

    This API can be used to wait on any of the specified objects to
    enter the signaled state, or all of the objects to enter the
    signaled state.

    If the bAlertable parameter is FALSE, the only way the wait
    terminates is because the specified timeout period expires, or
    because the specified objects entered the signaled state.  If the
    bAlertable parameter is TRUE, then the wait can return due to any one of
    the above wait termination conditions, or because an I/O completion
    callback terminated the wait early (return value of
    WAIT_IO_COMPLETION).

Arguments:

    nCount - A count of the number of objects that are to be waited on.

    lpHandles - An array of object handles.  Each handle must have
        SYNCHRONIZE access to the associated object.

    bWaitAll - A flag that supplies the wait type.  A value of TRUE
        indicates a "wait all".  A value of false indicates a "wait
        any".

    dwMilliseconds - A time-out value that specifies the relative time,
        in milliseconds, over which the wait is to be completed.  A
        timeout value of 0 specified that the wait is to timeout
        immediately.  This allows an application to test an object to
        determine if it is in the signaled state.  A timeout value of
        0xffffffff specifies an infinite timeout period.

    bAlertable - Supplies a flag that controls whether or not the
        wait may terminate early due to an I/O completion callback.
        A value of TRUE allows this API to complete early due to an I/O
        completion callback.  A value of FALSE will not allow I/O
        completion callbacks to terminate this call early.

Return Value:

    WAIT_TIME_OUT - indicates that the wait was terminated due to the
        TimeOut conditions.

    0 to MAXIMUM_WAIT_OBJECTS-1, indicates, in the case of wait for any
        object, the object number which satisfied the wait.  In the case
        of wait for all objects, the value only indicates that the wait
        was completed successfully.

    0xffffffff - The wait terminated due to an error. GetLastError may be
        used to get additional error information.

    WAIT_ABANDONED_0 to (WAIT_ABANDONED_0)+(MAXIMUM_WAIT_OBJECTS - 1),
        indicates, in the case of wait for any object, the object number
        which satisfied the event, and that the object which satisfied
        the event was abandoned.  In the case of wait for all objects,
        the value indicates that the wait was completed successfully and
        at least one of the objects was abandoned.

    WAIT_IO_COMPLETION - The wait terminated due to one or more I/O
        completion callbacks.

--*/
{
    NTSTATUS Status;
    LARGE_INTEGER TimeOut;
    PLARGE_INTEGER pTimeOut;
    DWORD i;
    LPHANDLE HandleArray;
    HANDLE Handles[ 8 ];
    PPEB Peb;

    if (nCount > 8) {
        HandleArray = (LPHANDLE) RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ), nCount*sizeof(HANDLE));
        if (HandleArray == NULL) {
            BaseSetLastNTError(STATUS_NO_MEMORY);
            return 0xffffffff;
        }
    } else {
        HandleArray = Handles;
    }
    RtlCopyMemory(HandleArray,(LPVOID)lpHandles,nCount*sizeof(HANDLE));

    Peb = NtCurrentPeb();
    for (i=0; i<nCount; i++) {
        switch( (DWORD)HandleArray[i] ) {
        case STD_INPUT_HANDLE:
            HandleArray[i] = Peb->ProcessParameters->StandardInput;
            break;
        case STD_OUTPUT_HANDLE:
            HandleArray[i] = Peb->ProcessParameters->StandardOutput;
            break;
        case STD_ERROR_HANDLE:
            HandleArray[i] = Peb->ProcessParameters->StandardError;
            break;
        }

        if (CONSOLE_HANDLE(HandleArray[i]) && VerifyConsoleIoHandle(HandleArray[i])) {
            HandleArray[i] = GetConsoleInputWaitHandle();
        }
    }

    pTimeOut = BaseFormatTimeOut(&TimeOut,dwMilliseconds);
rewait:
    Status = NtWaitForMultipleObjects(
                 (CHAR)nCount,
                 HandleArray,
                 bWaitAll ? WaitAll : WaitAny,
                 (BOOLEAN)bAlertable,
                 pTimeOut
             );
    if ( !NT_SUCCESS(Status) ) {
        BaseSetLastNTError(Status);
        Status = (NTSTATUS)0xffffffff;
    }
    else {
        if ( bAlertable && Status == STATUS_ALERTED ) {
            goto rewait;
        }
    }

    if (HandleArray != Handles) {
        RtlFreeHeap(RtlProcessHeap(), 0, HandleArray);
    }

    return (DWORD)Status;
}