Exemplo n.º 1
0
BOOL APIENTRY
NtUserLockWindowStation(HWINSTA hWindowStation)
{
    PWINSTATION_OBJECT Object;
    NTSTATUS Status;

    TRACE("About to set process window station with handle (%p)\n",
          hWindowStation);

    if (gpidLogon != PsGetCurrentProcessId())
    {
        ERR("Unauthorized process attempted to lock the window station!\n");
        EngSetLastError(ERROR_ACCESS_DENIED);
        return FALSE;
    }

    Status = IntValidateWindowStationHandle(hWindowStation,
                                            UserMode,
                                            0,
                                            &Object,
                                            0);
    if (!NT_SUCCESS(Status))
    {
        TRACE("Validation of window station handle (%p) failed\n",
              hWindowStation);
        SetLastNtError(Status);
        return FALSE;
    }

    Object->Flags |= WSS_LOCKED;

    ObDereferenceObject(Object);
    return TRUE;
}
Exemplo n.º 2
0
BOOL FASTCALL
UserSetProcessWindowStation(HWINSTA hWindowStation)
{
    PPROCESSINFO ppi;
    NTSTATUS Status;
    HWINSTA hwinstaOld;
    PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;

    ppi = PsGetCurrentProcessWin32Process();

    /* Reference the new window station */
    if(hWindowStation !=NULL)
    {
        Status = IntValidateWindowStationHandle( hWindowStation,
                                                 KernelMode,
                                                 0,
                                                 &NewWinSta);
       if (!NT_SUCCESS(Status))
       {
          TRACE("Validation of window station handle (0x%X) failed\n",
                 hWindowStation);
          SetLastNtError(Status);
          return FALSE;
       }
    }

   OldWinSta = ppi->prpwinsta;
   hwinstaOld = PsGetProcessWin32WindowStation(ppi->peProcess);

   /* Dereference the previous window station */
   if(OldWinSta != NULL)
   {
       ObDereferenceObject(OldWinSta);
   }

   /* Check if we have a stale handle (it should happen for console apps) */
   if(hwinstaOld != ppi->hwinsta)
   {
       ObCloseHandle(hwinstaOld, UserMode);
   }

   /*
    * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects.
    */

   PsSetProcessWindowStation(ppi->peProcess, hWindowStation);

   ppi->prpwinsta = NewWinSta;
   ppi->hwinsta = hWindowStation;

   return TRUE;
}
Exemplo n.º 3
0
static PWINSTATION_OBJECT FASTCALL
IntGetWinStaForCbAccess(VOID)
{
    HWINSTA hWinSta;
    PWINSTATION_OBJECT pWinStaObj;
    NTSTATUS Status;

    hWinSta = UserGetProcessWindowStation();
    Status = IntValidateWindowStationHandle(hWinSta, KernelMode, WINSTA_ACCESSCLIPBOARD, &pWinStaObj, 0);
    if (!NT_SUCCESS(Status))
    {
        ERR("Cannot open winsta\n");
        SetLastNtError(Status);
        return NULL;
    }

    return pWinStaObj;
}
Exemplo n.º 4
0
BOOL
APIENTRY
NtUserCloseWindowStation(
    HWINSTA hWinSta)
{
    PWINSTATION_OBJECT Object;
    NTSTATUS Status;

    TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);

    if (hWinSta == UserGetProcessWindowStation())
    {
        ERR("Attempted to close process window station\n");
        return FALSE;
    }

    Status = IntValidateWindowStationHandle(hWinSta,
                                            UserMode,
                                            0,
                                            &Object,
                                            0);

    if (!NT_SUCCESS(Status))
    {
        ERR("Validation of window station handle (%p) failed\n", hWinSta);
        return FALSE;
    }

    ObDereferenceObject(Object);

    TRACE("Closing window station handle (%p)\n", hWinSta);

    Status = ObCloseHandle(hWinSta, UserMode);
    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 5
0
BOOL APIENTRY
NtUserUnlockWindowStation(HWINSTA hWindowStation)
{
   PWINSTATION_OBJECT Object;
   NTSTATUS Status;
   BOOL Ret;

   TRACE("About to set process window station with handle (0x%X)\n",
          hWindowStation);

   if(PsGetCurrentProcessWin32Process() != LogonProcess)
   {
      ERR("Unauthorized process attempted to unlock the window station!\n");
      EngSetLastError(ERROR_ACCESS_DENIED);
      return FALSE;
   }

   Status = IntValidateWindowStationHandle(
               hWindowStation,
               KernelMode,
               0,
               &Object);
   if (!NT_SUCCESS(Status))
   {
      TRACE("Validation of window station handle (0x%X) failed\n",
             hWindowStation);
      SetLastNtError(Status);
      return FALSE;
   }

   Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
   Object->Flags &= ~WSS_LOCKED;

   ObDereferenceObject(Object);
   return Ret;
}
Exemplo n.º 6
0
BOOL FASTCALL
UserSetProcessWindowStation(HWINSTA hWindowStation)
{
    PPROCESSINFO ppi;
    NTSTATUS Status;
    HWINSTA hwinstaOld;
    OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
    PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;

    ppi = PsGetCurrentProcessWin32Process();

    /* Reference the new window station */
    if(hWindowStation !=NULL)
    {
        Status = IntValidateWindowStationHandle(hWindowStation,
                                                UserMode,
                                                0,
                                                &NewWinSta,
                                                &ObjectHandleInfo);
        if (!NT_SUCCESS(Status))
        {
            TRACE("Validation of window station handle (%p) failed\n",
                  hWindowStation);
            SetLastNtError(Status);
            return FALSE;
        }
    }

    OldWinSta = ppi->prpwinsta;
    hwinstaOld = PsGetProcessWin32WindowStation(ppi->peProcess);

    /* Dereference the previous window station */
    if(OldWinSta != NULL)
    {
        ObDereferenceObject(OldWinSta);
    }

    /* Check if we have a stale handle (it should happen for console apps) */
    if(hwinstaOld != ppi->hwinsta)
    {
        ObCloseHandle(hwinstaOld, UserMode);
    }

    /*
     * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects.
     */

    PsSetProcessWindowStation(ppi->peProcess, hWindowStation);

    ppi->prpwinsta = NewWinSta;
    ppi->hwinsta = hWindowStation;
    ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
    TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);

    if (RtlAreAllAccessesGranted(ppi->amwinsta, WINSTA_READSCREEN))
    {
        ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
    }
    else
    {
        ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
    }

    if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO) )
    {
        ppi->W32PF_flags |= W32PF_IOWINSTA;
    }
    else // Might be closed if the handle is null.
    {
        ppi->W32PF_flags &= ~W32PF_IOWINSTA;
    }
    return TRUE;
}
Exemplo n.º 7
0
BOOL APIENTRY
NtUserSetWindowStationUser(
    HWINSTA hWindowStation,
    PLUID pluid,
    PSID psid,
    DWORD size)
{
    NTSTATUS Status;
    PWINSTATION_OBJECT WindowStation = NULL;
    BOOL Ret = FALSE;

    UserEnterExclusive();

    if (gpidLogon != PsGetCurrentProcessId())
    {
        EngSetLastError(ERROR_ACCESS_DENIED);
        goto Leave;
    }

    Status = IntValidateWindowStationHandle(hWindowStation,
                                            UserMode,
                                            0,
                                            &WindowStation,
                                            0);
    if (!NT_SUCCESS(Status))
    {
        goto Leave;
    }

    if (WindowStation->psidUser)
    {
        ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
    }

    WindowStation->psidUser = ExAllocatePoolWithTag(PagedPool, size, USERTAG_SECURITY);
    if (WindowStation->psidUser == NULL)
    {
        EngSetLastError(ERROR_OUTOFMEMORY);
        goto Leave;
    }

    _SEH2_TRY
    {
        ProbeForRead( psid, size, 1);
        ProbeForRead( pluid, sizeof(LUID), 1);

        RtlCopyMemory(WindowStation->psidUser, psid, size);
        WindowStation->luidUser = *pluid;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    if (!NT_SUCCESS(Status))
    {
        ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
        WindowStation->psidUser = 0;
        goto Leave;
    }

    Ret = TRUE;

Leave:
    if (WindowStation) ObDereferenceObject(WindowStation);
    UserLeave();
    return Ret;
}
Exemplo n.º 8
0
static NTSTATUS FASTCALL
BuildDesktopNameList(
    HWINSTA hWindowStation,
    ULONG dwSize,
    PVOID lpBuffer,
    PULONG pRequiredSize)
{
    NTSTATUS Status;
    PWINSTATION_OBJECT WindowStation;
    PLIST_ENTRY DesktopEntry;
    PDESKTOP DesktopObject;
    DWORD EntryCount;
    ULONG ReturnLength;
    WCHAR NullWchar;
    UNICODE_STRING DesktopName;

    Status = IntValidateWindowStationHandle(hWindowStation,
                                            UserMode,
                                            0,
                                            &WindowStation,
                                            0);
    if (! NT_SUCCESS(Status))
    {
        return Status;
    }

    /*
     * Count the required size of buffer.
     */
    ReturnLength = sizeof(DWORD);
    EntryCount = 0;
    for (DesktopEntry = WindowStation->DesktopListHead.Flink;
         DesktopEntry != &WindowStation->DesktopListHead;
         DesktopEntry = DesktopEntry->Flink)
    {
        DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
        RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
        ReturnLength += DesktopName.Length + sizeof(WCHAR);
        EntryCount++;
    }
    TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
    if (NULL != pRequiredSize)
    {
        Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
        if (! NT_SUCCESS(Status))
        {
            ObDereferenceObject(WindowStation);
            return STATUS_BUFFER_TOO_SMALL;
        }
    }

    /*
     * Check if the supplied buffer is large enough.
     */
    if (dwSize < ReturnLength)
    {
        ObDereferenceObject(WindowStation);
        return STATUS_BUFFER_TOO_SMALL;
    }

    /*
     * Generate the resulting buffer contents.
     */
    Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
    if (! NT_SUCCESS(Status))
    {
        ObDereferenceObject(WindowStation);
        return Status;
    }
    lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));

    NullWchar = L'\0';
    for (DesktopEntry = WindowStation->DesktopListHead.Flink;
         DesktopEntry != &WindowStation->DesktopListHead;
         DesktopEntry = DesktopEntry->Flink)
    {
        DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
        RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
        Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
        if (! NT_SUCCESS(Status))
        {
            ObDereferenceObject(WindowStation);
            return Status;
        }
        lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
        Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
        if (! NT_SUCCESS(Status))
        {
            ObDereferenceObject(WindowStation);
            return Status;
        }
        lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
    }

    /*
     * Clean up and return
     */
    ObDereferenceObject(WindowStation);
    return STATUS_SUCCESS;
}
Exemplo n.º 9
0
static NTSTATUS FASTCALL
BuildDesktopNameList(
   HWINSTA hWindowStation,
   ULONG dwSize,
   PVOID lpBuffer,
   PULONG pRequiredSize)
{
   NTSTATUS Status;
   PWINSTATION_OBJECT WindowStation;
   KIRQL OldLevel;
   PLIST_ENTRY DesktopEntry;
   PDESKTOP DesktopObject;
   DWORD EntryCount;
   ULONG ReturnLength;
   WCHAR NullWchar;
   PUNICODE_STRING DesktopName;

   Status = IntValidateWindowStationHandle(hWindowStation,
                                           KernelMode,
                                           0,
                                           &WindowStation);
   if (! NT_SUCCESS(Status))
   {
      return Status;
   }

   KeAcquireSpinLock(&WindowStation->Lock, &OldLevel);

   /*
    * Count the required size of buffer.
    */
   ReturnLength = sizeof(DWORD);
   EntryCount = 0;
   for (DesktopEntry = WindowStation->DesktopListHead.Flink;
         DesktopEntry != &WindowStation->DesktopListHead;
         DesktopEntry = DesktopEntry->Flink)
   {
      DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
      DesktopName = GET_DESKTOP_NAME(DesktopObject);
      if (DesktopName) ReturnLength += DesktopName->Length + sizeof(WCHAR);
      EntryCount++;
   }
   TRACE("Required size: %d Entry count: %d\n", ReturnLength, EntryCount);
   if (NULL != pRequiredSize)
   {
      Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
      if (! NT_SUCCESS(Status))
      {
         KeReleaseSpinLock(&WindowStation->Lock, OldLevel);
         ObDereferenceObject(WindowStation);
         return STATUS_BUFFER_TOO_SMALL;
      }
   }

   /*
    * Check if the supplied buffer is large enough.
    */
   if (dwSize < ReturnLength)
   {
      KeReleaseSpinLock(&WindowStation->Lock, OldLevel);
      ObDereferenceObject(WindowStation);
      return STATUS_BUFFER_TOO_SMALL;
   }

   /*
    * Generate the resulting buffer contents.
    */
   Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
   if (! NT_SUCCESS(Status))
   {
      KeReleaseSpinLock(&WindowStation->Lock, OldLevel);
      ObDereferenceObject(WindowStation);
      return Status;
   }
   lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));

   NullWchar = L'\0';
   for (DesktopEntry = WindowStation->DesktopListHead.Flink;
         DesktopEntry != &WindowStation->DesktopListHead;
         DesktopEntry = DesktopEntry->Flink)
   {
      DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
      _PRAGMA_WARNING_SUPPRESS(__WARNING_DEREF_NULL_PTR)
      DesktopName = GET_DESKTOP_NAME(DesktopObject);/// @todo Don't mess around with the object headers!
      if (!DesktopName) continue;

      Status = MmCopyToCaller(lpBuffer, DesktopName->Buffer, DesktopName->Length);
      if (! NT_SUCCESS(Status))
      {
         KeReleaseSpinLock(&WindowStation->Lock, OldLevel);
         ObDereferenceObject(WindowStation);
         return Status;
      }
      lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName->Length);
      Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
      if (! NT_SUCCESS(Status))
      {
         KeReleaseSpinLock(&WindowStation->Lock, OldLevel);
         ObDereferenceObject(WindowStation);
         return Status;
      }
      lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
   }

   /*
    * Clean up
    */
   KeReleaseSpinLock(&WindowStation->Lock, OldLevel);
   ObDereferenceObject(WindowStation);

   return STATUS_SUCCESS;
}