* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Window stations
- * FILE: subsystems/win32/win32k/ntuser/winsta.c
+ * FILE: win32ss/user/ntuser/winsta.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* TODO: The process window station is created on
* the first USER32/GDI32 call not related
NTSTATUS
NTAPI
-UserCreateWinstaDirectory()
+UserCreateWinstaDirectory(VOID)
{
PPEB Peb;
NTSTATUS Status;
TRACE("Deleting window station (0x%p)\n", WinSta);
+ WinSta->Flags |= WSS_DYING;
+
UserEmptyClipboardData(WinSta);
RtlDestroyAtomTable(WinSta->AtomTable);
HWINSTA WindowStation,
KPROCESSOR_MODE AccessMode,
ACCESS_MASK DesiredAccess,
- PWINSTATION_OBJECT *Object)
+ PWINSTATION_OBJECT *Object,
+ POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
{
NTSTATUS Status;
ExWindowStationObjectType,
AccessMode,
(PVOID*)Object,
- NULL);
+ pObjectHandleInfo);
if (!NT_SUCCESS(Status))
SetLastNtError(Status);
/* Setup the cursor */
co_IntLoadDefaultCursors();
+ /* Setup the icons */
+ co_IntSetWndIcons();
+
+ /* Setup Menu */
+ MenuInit();
+
/* Show the desktop */
pdesk = IntGetActiveDesktop();
ASSERT(pdesk);
return ScreenDeviceContext;
}
+BOOL FASTCALL
+CheckWinstaAttributeAccess(ACCESS_MASK DesiredAccess)
+{
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+ if ( gpidLogon != PsGetCurrentProcessId() )
+ {
+ if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
+ {
+ ERR("Requires Interactive Window Station\n");
+ EngSetLastError(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION);
+ return FALSE;
+ }
+ if (!RtlAreAllAccessesGranted(ppi->amwinsta, DesiredAccess))
+ {
+ ERR("Access Denied\n");
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*
if (InputWindowStation == NULL)
{
- TRACE("Initializeing input window station\n");
+ ERR("Initializing input window station\n");
InputWindowStation = WindowStationObject;
+ WindowStationObject->Flags &= ~WSS_NOIO;
+
InitCursorImpl();
}
+ else
+ {
+ WindowStationObject->Flags |= WSS_NOIO;
+ }
TRACE("NtUserCreateWindowStation created object %p with name %wZ handle %p\n",
WindowStation, &WindowStationObject->Name, WindowStation);
hWinSta,
KernelMode,
0,
- &Object);
+ &Object,
+ 0);
if (!NT_SUCCESS(Status))
{
DWORD nLength,
PDWORD nLengthNeeded)
{
- PWINSTATION_OBJECT WinStaObject = NULL;
+ PWINSTATION_OBJECT WinStaObject;
PDESKTOP DesktopObject = NULL;
NTSTATUS Status;
PVOID pvData = NULL;
{
/* try desktop */
TRACE("Trying to open desktop %p\n", hObject);
+ WinStaObject = NULL;
Status = IntValidateDesktopHandle(
hObject,
UserMode,
PPROCESSINFO ppi;
NTSTATUS Status;
HWINSTA hwinstaOld;
+ OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
ppi = PsGetCurrentProcessWin32Process();
Status = IntValidateWindowStationHandle( hWindowStation,
KernelMode,
0,
- &NewWinSta);
+ &NewWinSta,
+ &ObjectHandleInfo);
if (!NT_SUCCESS(Status))
{
TRACE("Validation of window station handle (%p) failed\n",
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;
}
hWindowStation,
KernelMode,
0,
- &Object);
+ &Object,
+ 0);
if (!NT_SUCCESS(Status))
{
TRACE("Validation of window station handle (%p) failed\n",
hWindowStation,
KernelMode,
0,
- &Object);
+ &Object,
+ 0);
if (!NT_SUCCESS(Status))
{
TRACE("Validation of window station handle (%p) failed\n",
InitializeObjectAttributes(
&ObjectAttributes,
&gustrWindowStationsDir,
- OBJ_CASE_INSENSITIVE,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
/* Need a larger buffer, check how large exactly */
Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
&ReturnLength);
- if (STATUS_BUFFER_TOO_SMALL == Status)
+ if (!NT_SUCCESS(Status))
{
- ObDereferenceObject(DirectoryHandle);
- return STATUS_NO_MEMORY;
+ ERR("ZwQueryDirectoryObject failed\n");
+ ZwClose(DirectoryHandle);
+ return Status;
}
BufferSize = ReturnLength;
Buffer = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_WINSTA);
if (NULL == Buffer)
{
- ObDereferenceObject(DirectoryHandle);
+ ZwClose(DirectoryHandle);
return STATUS_NO_MEMORY;
}
{
/* Something went wrong, maybe someone added a directory entry? Just give up. */
ExFreePoolWithTag(Buffer, TAG_WINSTA);
- ObDereferenceObject(DirectoryHandle);
+ ZwClose(DirectoryHandle);
return NT_SUCCESS(Status) ? STATUS_INTERNAL_ERROR : Status;
}
}
Status = IntValidateWindowStationHandle(hWindowStation,
KernelMode,
0,
- &WindowStation);
+ &WindowStation,
+ 0);
if (! NT_SUCCESS(Status))
{
return Status;
* Size of buffer passed by caller.
*
* lpBuffer
- * Buffer passed by caller. If the function succedes, the buffer is
+ * Buffer passed by caller. If the function succeeds, the buffer is
* filled with window station/desktop count (in first DWORD) and
* NULL-terminated window station/desktop names.
*
* pRequiredSize
- * If the function suceedes, this is the number of bytes copied.
+ * If the function succeeds, this is the number of bytes copied.
* Otherwise it's size of buffer needed for function to succeed.
*
* Status
return ret;
}
+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,
+ KernelMode,
+ 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;
+}
+
+
/* EOF */