Пример #1
0
NTSTATUS NTAPI
UserCreateThreadInfo(struct _ETHREAD *Thread)
{
    struct _EPROCESS *Process;
    PCLIENTINFO pci;
    PTHREADINFO ptiCurrent;
    int i;
    NTSTATUS Status = STATUS_SUCCESS;
    PTEB pTeb;
    LARGE_INTEGER LargeTickCount;

    Process = Thread->ThreadsProcess;

    pTeb = NtCurrentTeb();

    ASSERT(pTeb);

    ptiCurrent = ExAllocatePoolWithTag(NonPagedPool,
                                       sizeof(THREADINFO),
                                       USERTAG_THREADINFO);
    if (ptiCurrent == NULL)
    {
        ERR_CH(UserThread, "Failed to allocate pti for TID %p\n", Thread->Cid.UniqueThread);
        return STATUS_NO_MEMORY;
    }

    TRACE_CH(UserThread,"Create pti 0x%p eThread 0x%p\n", ptiCurrent, Thread);

    RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));

    /* Initialize the THREADINFO */

    PsSetThreadWin32Thread(Thread, ptiCurrent, NULL);
    IntReferenceThreadInfo(ptiCurrent);
    ptiCurrent->pEThread = Thread;
    ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
    pTeb->Win32ThreadInfo = ptiCurrent;
    ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;

    TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);

    InitializeListHead(&ptiCurrent->WindowListHead);
    InitializeListHead(&ptiCurrent->W32CallbackListHead);
    InitializeListHead(&ptiCurrent->PostedMessagesListHead);
    InitializeListHead(&ptiCurrent->SentMessagesListHead);
    InitializeListHead(&ptiCurrent->DispatchingMessagesHead);
    InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead);
    InitializeListHead(&ptiCurrent->PtiLink);
    for (i = 0; i < NB_HOOKS; i++)
    {
        InitializeListHead(&ptiCurrent->aphkStart[i]);
    }
    ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
    ptiCurrent->ppi->ptiList = ptiCurrent;
    ptiCurrent->ppi->cThreads++;

    ptiCurrent->hEventQueueClient = NULL;
    Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS,
                           NULL, SynchronizationEvent, FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto error;
    }
    Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
                                       *ExEventObjectType, KernelMode,
                                       (PVOID*)&ptiCurrent->pEventQueueServer, NULL);
    if (!NT_SUCCESS(Status))
    {
        ZwClose(ptiCurrent->hEventQueueClient);
        ptiCurrent->hEventQueueClient = NULL;
        goto error;
    }

    KeQueryTickCount(&LargeTickCount);
    ptiCurrent->timeLast = LargeTickCount.u.LowPart;

    ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
    if(ptiCurrent->MessageQueue == NULL)
    {
        ERR_CH(UserThread,"Failed to allocate message loop\n");
        Status = STATUS_NO_MEMORY;
        goto error;
    }
    ptiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
    if (ptiCurrent->KeyboardLayout)
        UserReferenceObject(ptiCurrent->KeyboardLayout);
    ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
    if (Process == gpepCSRSS) /* If this thread is owned by CSRSS, mark it as such */
        ptiCurrent->TIF_flags |= TIF_CSRSSTHREAD;
    ptiCurrent->pcti = &ptiCurrent->cti;

    /* Initialize the CLIENTINFO */
    pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
    RtlZeroMemory(pci, sizeof(CLIENTINFO));
    pci->ppi = ptiCurrent->ppi;
    pci->fsHooks = ptiCurrent->fsHooks;
    pci->dwTIFlags = ptiCurrent->TIF_flags;
    if (ptiCurrent->KeyboardLayout)
    {
        pci->hKL = ptiCurrent->KeyboardLayout->hkl;
        pci->CodePage = ptiCurrent->KeyboardLayout->CodePage;
    }

    /* Assign a default window station and desktop to the process */
    /* Do not try to open a desktop or window station before winlogon initializes */
    if(ptiCurrent->ppi->hdeskStartup == NULL && LogonProcess != NULL)
    {
        HWINSTA hWinSta = NULL;
        HDESK hDesk = NULL;
        UNICODE_STRING DesktopPath;
        PDESKTOP pdesk;
        PRTL_USER_PROCESS_PARAMETERS ProcessParams;

        /*
         * inherit the thread desktop and process window station (if not yet inherited) from the process startup
         * info structure. See documentation of CreateProcess()
         */
        ProcessParams = pTeb->ProcessEnvironmentBlock->ProcessParameters;

        Status = STATUS_UNSUCCESSFUL;
        if(ProcessParams && ProcessParams->DesktopInfo.Length > 0)
        {
            Status = IntSafeCopyUnicodeStringTerminateNULL(&DesktopPath, &ProcessParams->DesktopInfo);
        }
        if(!NT_SUCCESS(Status))
        {
            RtlInitUnicodeString(&DesktopPath, NULL);
        }

        Status = IntParseDesktopPath(Process,
                                     &DesktopPath,
                                     &hWinSta,
                                     &hDesk);

        if (DesktopPath.Buffer)
            ExFreePoolWithTag(DesktopPath.Buffer, TAG_STRING);

        if(!NT_SUCCESS(Status))
        {
            ERR_CH(UserThread, "Failed to assign default dekstop and winsta to process\n");
            goto error;
        }

        if(!UserSetProcessWindowStation(hWinSta))
        {
            Status = STATUS_UNSUCCESSFUL;
            ERR_CH(UserThread,"Failed to set initial process winsta\n");
            goto error;
        }

        /* Validate the new desktop. */
        Status = IntValidateDesktopHandle(hDesk, UserMode, 0, &pdesk);
        if(!NT_SUCCESS(Status))
        {
            ERR_CH(UserThread,"Failed to validate initial desktop handle\n");
            goto error;
        }

        /* Store the parsed desktop as the initial desktop */
        ptiCurrent->ppi->hdeskStartup = hDesk;
        ptiCurrent->ppi->rpdeskStartup = pdesk;
    }

    if (ptiCurrent->ppi->hdeskStartup != NULL)
    {
        if (!IntSetThreadDesktop(ptiCurrent->ppi->hdeskStartup, FALSE))
        {
            ERR_CH(UserThread,"Failed to set thread desktop\n");
            Status = STATUS_UNSUCCESSFUL;
            goto error;
        }
    }

    /* mark the thread as fully initialized */
    ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED;

    if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) &&
            (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi ))
    {
        ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
    }
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
    TRACE_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent);
    return STATUS_SUCCESS;

error:
    ERR_CH(UserThread,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
    UserDestroyThreadInfo(Thread);
    return Status;
}
Пример #2
0
BOOL APIENTRY
NtUserGetObjectInformation(
    HANDLE hObject,
    DWORD nIndex,
    PVOID pvInformation,
    DWORD nLength,
    PDWORD nLengthNeeded)
{
    PWINSTATION_OBJECT WinStaObject;
    PDESKTOP DesktopObject = NULL;
    NTSTATUS Status;
    PVOID pvData = NULL;
    DWORD nDataSize = 0;

    _SEH2_TRY
    {
        if (nLengthNeeded)
            ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
        ProbeForWrite(pvInformation, nLength, 1);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        SetLastNtError(_SEH2_GetExceptionCode());
        return FALSE;
    }
    _SEH2_END;

    /* try windowstation */
    TRACE("Trying to open window station %p\n", hObject);
    Status = ObReferenceObjectByHandle(hObject,
                                       0,
                                       ExWindowStationObjectType,
                                       UserMode,
                                       (PVOID*)&WinStaObject,
                                       NULL);

    if (Status == STATUS_OBJECT_TYPE_MISMATCH)
    {
        /* try desktop */
        TRACE("Trying to open desktop %p\n", hObject);
        WinStaObject = NULL;
        Status = IntValidateDesktopHandle(hObject,
                                          UserMode,
                                          0,
                                          &DesktopObject);
    }

    if (!NT_SUCCESS(Status))
    {
        ERR("Failed: 0x%x\n", Status);
        goto Exit;
    }

    TRACE("WinSta or Desktop opened!!\n");

    /* get data */
    switch (nIndex)
    {
        case UOI_FLAGS:
            nDataSize = sizeof(USEROBJECTFLAGS);
            if (nLength >= nDataSize)
            {
                PUSEROBJECTFLAGS ObjectFlags = pvInformation;

                ObjectFlags->fInherit = 0;
                ObjectFlags->fReserved = 0;
                ObjectFlags->dwFlags = 0;

                Status = STATUS_SUCCESS;
            }
            else
            {
                Status = STATUS_BUFFER_TOO_SMALL;
            }
            ERR("UOI_FLAGS unimplemented!\n");
            break;

        case UOI_NAME:
            if (WinStaObject != NULL)
            {
                pvData = WinStaObject->Name.Buffer;
                nDataSize = WinStaObject->Name.Length + sizeof(WCHAR);
                Status = STATUS_SUCCESS;
            }
            else if (DesktopObject != NULL)
            {
                pvData = DesktopObject->pDeskInfo->szDesktopName;
                nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
                Status = STATUS_SUCCESS;
            }
            else
                Status = STATUS_INVALID_PARAMETER;
            break;

        case UOI_TYPE:
            if (WinStaObject != NULL)
            {
                pvData = L"WindowStation";
                nDataSize = sizeof(L"WindowStation");
                Status = STATUS_SUCCESS;
            }
            else if (DesktopObject != NULL)
            {
                pvData = L"Desktop";
                nDataSize = sizeof(L"Desktop");
                Status = STATUS_SUCCESS;
            }
            else
                Status = STATUS_INVALID_PARAMETER;
            break;

        case UOI_USER_SID:
            Status = STATUS_NOT_IMPLEMENTED;
            ERR("UOI_USER_SID unimplemented!\n");
            break;

        default:
            Status = STATUS_INVALID_PARAMETER;
            break;
    }

Exit:
    if (Status == STATUS_SUCCESS && nLength < nDataSize)
        Status = STATUS_BUFFER_TOO_SMALL;

    _SEH2_TRY
    {
        if (nLengthNeeded)
            *nLengthNeeded = nDataSize;

        /* try to copy data to caller */
        if (Status == STATUS_SUCCESS)
        {
            TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
            RtlCopyMemory(pvInformation, pvData, nDataSize);
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    /* release objects */
    if (WinStaObject != NULL)
        ObDereferenceObject(WinStaObject);
    if (DesktopObject != NULL)
        ObDereferenceObject(DesktopObject);

    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        return FALSE;
    }

    return TRUE;
}
Пример #3
0
BOOL APIENTRY
NtUserGetObjectInformation(
   HANDLE hObject,
   DWORD nIndex,
   PVOID pvInformation,
   DWORD nLength,
   PDWORD nLengthNeeded)
{
   PWINSTATION_OBJECT WinStaObject = NULL;
   PDESKTOP DesktopObject = NULL;
   NTSTATUS Status;
   PVOID pvData = NULL;
   DWORD nDataSize = 0;

   /* try windowstation */
   TRACE("Trying to open window station 0x%x\n", hObject);
   Status = ObReferenceObjectByHandle(
               hObject,
               0,
               ExWindowStationObjectType,
               UserMode,
               (PVOID*)&WinStaObject,
               NULL);

   if (Status == STATUS_OBJECT_TYPE_MISMATCH)
   {
      /* try desktop */
      TRACE("Trying to open desktop 0x%x\n", hObject);
      Status = IntValidateDesktopHandle(
                  hObject,
                  UserMode,
                  0,
                  &DesktopObject);
   }

   if (!NT_SUCCESS(Status))
   {
      ERR("Failed: 0x%x\n", Status);
      SetLastNtError(Status);
      return FALSE;
   }

   TRACE("WinSta or Desktop opened!!\n");

   /* get data */
   switch (nIndex)
   {
      case UOI_FLAGS:
         Status = STATUS_NOT_IMPLEMENTED;
         ERR("UOI_FLAGS unimplemented!\n");
         break;

      case UOI_NAME:
         if (WinStaObject != NULL)
         {
             pvData = WinStaObject->Name.Buffer;
             nDataSize = WinStaObject->Name.Length + sizeof(WCHAR);
            Status = STATUS_SUCCESS;
         }
         else if (DesktopObject != NULL)
         {
             pvData = DesktopObject->pDeskInfo->szDesktopName;
            nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
            Status = STATUS_SUCCESS;
         }
         else
            Status = STATUS_INVALID_PARAMETER;
         break;

      case UOI_TYPE:
         if (WinStaObject != NULL)
         {
            pvData = L"WindowStation";
            nDataSize = sizeof(L"WindowStation");
            Status = STATUS_SUCCESS;
         }
         else if (DesktopObject != NULL)
         {
            pvData = L"Desktop";
            nDataSize = sizeof(L"Desktop");
            Status = STATUS_SUCCESS;
         }
         else
            Status = STATUS_INVALID_PARAMETER;
         break;

      case UOI_USER_SID:
         Status = STATUS_NOT_IMPLEMENTED;
         ERR("UOI_USER_SID unimplemented!\n");
         break;

      default:
         Status = STATUS_INVALID_PARAMETER;
         break;
   }

   /* try to copy data to caller */
   if (Status == STATUS_SUCCESS)
   {
      TRACE("Trying to copy data to caller (len = %d, len needed = %d)\n", nLength, nDataSize);
      *nLengthNeeded = nDataSize;
      if (nLength >= nDataSize)
         Status = MmCopyToCaller(pvInformation, pvData, nDataSize);
      else
         Status = STATUS_BUFFER_TOO_SMALL;
   }

   /* release objects */
   if (WinStaObject != NULL)
      ObDereferenceObject(WinStaObject);
   if (DesktopObject != NULL)
      ObDereferenceObject(DesktopObject);

   if (!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      return FALSE;
   }

   return TRUE;
}