ReactOS  0.4.11-dev-791-gf6f1255
winsta.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Win32k subsystem
4  * PURPOSE: Window stations
5  * FILE: win32ss/user/ntuser/winsta.c
6  * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * TODO: The process window station is created on
8  * the first USER32/GDI32 call not related
9  * to window station/desktop handling
10  */
11 
12 #include <win32k.h>
13 DBG_DEFAULT_CHANNEL(UserWinsta);
14 
15 /* GLOBALS *******************************************************************/
16 
17 /*
18  * The currently active window station. This is the
19  * only one interactive window station on the system.
20  */
22 
23 /* Winlogon SAS window */
25 
26 /* Full path to WindowStations directory */
28 
29 /* INITIALIZATION FUNCTIONS ****************************************************/
30 
33 NTAPI
35 {
36  GENERIC_MAPPING IntWindowStationMapping = { WINSTA_READ,
40 
41  /* Set Winsta Object Attributes */
43  ExWindowStationObjectType->TypeInfo.GenericMapping = IntWindowStationMapping;
45 
46  return STATUS_SUCCESS;
47 }
48 
50 NTAPI
52 {
54  PPEB Peb;
56  HANDLE hWinstaDir;
57  WCHAR wstrWindowStationsDir[MAX_PATH];
58 
59  /* Create the WindowStations directory and cache its path for later use */
60  Peb = NtCurrentPeb();
61  if(Peb->SessionId == 0)
62  {
63  if (!RtlCreateUnicodeString(&gustrWindowStationsDir, WINSTA_OBJ_DIR))
64  {
66  }
67  }
68  else
69  {
70  Status = RtlStringCbPrintfW(wstrWindowStationsDir,
71  sizeof(wstrWindowStationsDir),
72  L"%ws\\%lu%ws",
74  Peb->SessionId,
76  if (!NT_SUCCESS(Status))
77  return Status;
78 
79  if (!RtlCreateUnicodeString(&gustrWindowStationsDir, wstrWindowStationsDir))
80  {
82  }
83  }
84 
85  InitializeObjectAttributes(&ObjectAttributes,
86  &gustrWindowStationsDir,
88  NULL,
89  NULL);
90  Status = ZwCreateDirectoryObject(&hWinstaDir, DIRECTORY_CREATE_OBJECT, &ObjectAttributes);
91  if (!NT_SUCCESS(Status))
92  {
93  ERR("Could not create %wZ directory (Status 0x%X)\n", &gustrWindowStationsDir, Status);
94  return Status;
95  }
96 
97  TRACE("Created directory %wZ for session %lu\n", &gustrWindowStationsDir, Peb->SessionId);
98 
99  return Status;
100 }
101 
102 /* OBJECT CALLBACKS ***********************************************************/
103 
104 NTSTATUS
105 NTAPI
108 {
109  PWIN32_DELETEMETHOD_PARAMETERS DeleteParameters = Parameters;
110  PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeleteParameters->Object;
111 
112  TRACE("Deleting window station 0x%p\n", WinSta);
113 
114  if (WinSta == InputWindowStation)
115  {
116  ERR("WARNING: Deleting the interactive window station '%wZ'!\n",
117  &(OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(InputWindowStation))->Name));
118 
119  /* Only Winlogon can close and delete the interactive window station */
121 
122  InputWindowStation = NULL;
123  }
124 
125  WinSta->Flags |= WSS_DYING;
126 
127  UserEmptyClipboardData(WinSta);
128 
130 
131  return STATUS_SUCCESS;
132 }
133 
134 NTSTATUS
135 NTAPI
138 {
139  PWIN32_PARSEMETHOD_PARAMETERS ParseParameters = Parameters;
140  PUNICODE_STRING RemainingName = ParseParameters->RemainingName;
141 
142  /* Assume we don't find anything */
143  *ParseParameters->Object = NULL;
144 
145  /* Check for an empty name */
146  if (!RemainingName->Length)
147  {
148  /* Make sure this is a window station, can't parse a desktop now */
149  if (ParseParameters->ObjectType != ExWindowStationObjectType)
150  {
151  /* Fail */
153  }
154 
155  /* Reference the window station and return */
156  ObReferenceObject(ParseParameters->ParseObject);
157  *ParseParameters->Object = ParseParameters->ParseObject;
158  return STATUS_SUCCESS;
159  }
160 
161  /* Check for leading slash */
162  if (RemainingName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
163  {
164  /* Skip it */
165  RemainingName->Buffer++;
166  RemainingName->Length -= sizeof(WCHAR);
167  RemainingName->MaximumLength -= sizeof(WCHAR);
168  }
169 
170  /* Check if there is still a slash */
171  if (wcschr(RemainingName->Buffer, OBJ_NAME_PATH_SEPARATOR))
172  {
173  /* In this case, fail */
175  }
176 
177  /*
178  * Check if we are parsing a desktop.
179  */
180  if (ParseParameters->ObjectType == ExDesktopObjectType)
181  {
182  /* Then call the desktop parse routine */
183  return IntDesktopObjectParse(ParseParameters->ParseObject,
184  ParseParameters->ObjectType,
185  ParseParameters->AccessState,
186  ParseParameters->AccessMode,
187  ParseParameters->Attributes,
188  ParseParameters->CompleteName,
189  RemainingName,
190  ParseParameters->Context,
191  ParseParameters->SecurityQos,
192  ParseParameters->Object);
193  }
194 
195  /* Should hopefully never get here */
197 }
198 
199 NTSTATUS
200 NTAPI
203 {
204  PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS OkToCloseParameters = Parameters;
205  PPROCESSINFO ppi;
206 
208 
209  if (ppi && (OkToCloseParameters->Handle == ppi->hwinsta))
210  {
211  return STATUS_ACCESS_DENIED;
212  }
213 
214  return STATUS_SUCCESS;
215 }
216 
217 /* PRIVATE FUNCTIONS **********************************************************/
218 
219 /*
220  * IntValidateWindowStationHandle
221  *
222  * Validates the window station handle.
223  *
224  * Remarks
225  * If the function succeeds, the handle remains referenced. If the
226  * fucntion fails, last error is set.
227  */
228 
231  HWINSTA WindowStation,
235  POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
236 {
238 
239  if (WindowStation == NULL)
240  {
241  ERR("Invalid window station handle\n");
243  return STATUS_INVALID_HANDLE;
244  }
245 
246  Status = ObReferenceObjectByHandle(WindowStation,
247  DesiredAccess,
249  AccessMode,
250  (PVOID*)Object,
251  pObjectHandleInfo);
252 
253  if (!NT_SUCCESS(Status))
254  SetLastNtError(Status);
255 
256  return Status;
257 }
258 
261 {
262  TEXTMETRICW tmw;
263  UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
264  PDESKTOP pdesk;
265 
267  if (NULL == ScreenDeviceContext)
268  {
270  return FALSE;
271  }
273 
274  if (! IntCreatePrimarySurface())
275  {
276  return FALSE;
277  }
278 
280 
283 
284  /* Update the SERVERINFO */
289  gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
292  {
293  gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
294  }
295  else
296  gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
297  // Font is realized and this dc was previously set to internal DC_ATTR.
298  gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
299  gpsi->tmSysFont = tmw;
300 
301  /* Put the pointer in the center of the screen */
302  gpsi->ptCursor.x = gpsi->aiSysMet[SM_CXSCREEN] / 2;
303  gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2;
304 
305  /* Attach monitor */
307 
308  /* Setup the cursor */
310 
311  /* Setup the icons */
313 
314  /* Setup Menu */
315  MenuInit();
316 
317  /* Show the desktop */
318  pdesk = IntGetActiveDesktop();
319  ASSERT(pdesk);
320  co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE);
321 
322  return TRUE;
323 }
324 
327 {
328  if (NULL != ScreenDeviceContext)
329  { // No need to allocate a new dcattr.
333  }
336 }
337 
340 {
341  return ScreenDeviceContext;
342 }
343 
346 {
348  if ( gpidLogon != PsGetCurrentProcessId() )
349  {
350  if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
351  {
352  ERR("Requires Interactive Window Station\n");
354  return FALSE;
355  }
356  if (!RtlAreAllAccessesGranted(ppi->amwinsta, DesiredAccess))
357  {
358  ERR("Access Denied\n");
360  return FALSE;
361  }
362  }
363  return TRUE;
364 }
365 
366 
367 /* PUBLIC FUNCTIONS ***********************************************************/
368 
369 /*
370  * NtUserCreateWindowStation
371  *
372  * Creates a new window station.
373  *
374  * Parameters
375  * lpszWindowStationName
376  * Pointer to a null-terminated string specifying the name of the
377  * window station to be created. Window station names are
378  * case-insensitive and cannot contain backslash characters (\).
379  * Only members of the Administrators group are allowed to specify a
380  * name.
381  *
382  * dwDesiredAccess
383  * Requested type of access
384  *
385  * lpSecurity
386  * Security descriptor
387  *
388  * Unknown3, Unknown4, Unknown5, Unknown6
389  * Unused
390  *
391  * Return Value
392  * If the function succeeds, the return value is a handle to the newly
393  * created window station. If the specified window station already
394  * exists, the function succeeds and returns a handle to the existing
395  * window station. If the function fails, the return value is NULL.
396  *
397  * Status
398  * @implemented
399  */
400 
401 NTSTATUS
402 FASTCALL
404  OUT HWINSTA* phWinSta,
407  IN KPROCESSOR_MODE OwnerMode,
408  IN ACCESS_MASK dwDesiredAccess,
409  DWORD Unknown2,
410  DWORD Unknown3,
411  DWORD Unknown4,
412  DWORD Unknown5,
413  DWORD Unknown6)
414 {
416  HWINSTA hWinSta;
417  PWINSTATION_OBJECT WindowStation;
418 
419  TRACE("IntCreateWindowStation called\n");
420 
421  ASSERT(phWinSta);
422  *phWinSta = NULL;
423 
424  Status = ObOpenObjectByName(ObjectAttributes,
426  AccessMode,
427  NULL,
428  dwDesiredAccess,
429  NULL,
430  (PVOID*)&hWinSta);
431  if (NT_SUCCESS(Status))
432  {
433  TRACE("IntCreateWindowStation opened window station '%wZ'\n",
434  ObjectAttributes->ObjectName);
435  *phWinSta = hWinSta;
436  return Status;
437  }
438 
439  /*
440  * No existing window station found, try to create a new one.
441  */
442 
443  /* Create the window station object */
444  Status = ObCreateObject(AccessMode,
446  ObjectAttributes,
447  OwnerMode,
448  NULL,
449  sizeof(WINSTATION_OBJECT),
450  0,
451  0,
452  (PVOID*)&WindowStation);
453  if (!NT_SUCCESS(Status))
454  {
455  ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
456  ObjectAttributes->ObjectName, Status);
457  SetLastNtError(Status);
458  return Status;
459  }
460 
461  /* Initialize the window station */
462  RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
463 
464  InitializeListHead(&WindowStation->DesktopListHead);
465  WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
466  Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
467  if (!NT_SUCCESS(Status))
468  {
469  ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
470  ObjectAttributes->ObjectName, Status);
471  ObDereferenceObject(WindowStation);
472  SetLastNtError(Status);
473  return Status;
474  }
475 
476  Status = ObInsertObject(WindowStation,
477  NULL,
478  dwDesiredAccess,
479  0,
480  NULL,
481  (PVOID*)&hWinSta);
482  if (!NT_SUCCESS(Status))
483  {
484  ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
485  SetLastNtError(Status);
486  return Status;
487  }
488 
489  // FIXME! TODO: Add this new window station to a linked list
490 
491  if (InputWindowStation == NULL)
492  {
493  ERR("Initializing input window station\n");
494 
495  /* Only Winlogon can create the interactive window station */
497 
498  InputWindowStation = WindowStation;
499  WindowStation->Flags &= ~WSS_NOIO;
500  InitCursorImpl();
501  }
502  else
503  {
504  WindowStation->Flags |= WSS_NOIO;
505  }
506 
507  TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
508  ObjectAttributes->ObjectName, WindowStation, hWinSta);
509 
510  *phWinSta = hWinSta;
511  return STATUS_SUCCESS;
512 }
513 
514 static VOID
516  IN OUT PUNICODE_STRING WindowStationName,
517  IN PUNICODE_STRING TebStaticUnicodeString,
518  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL,
519  IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
520 {
521  SIZE_T MemSize = 0;
522 
523  /* Try to restore the user's UserModeObjectAttributes */
524  if (UserModeObjectAttributes && LocalObjectAttributes)
525  {
526  _SEH2_TRY
527  {
528  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
529  *UserModeObjectAttributes = *LocalObjectAttributes;
530  }
532  {
533  NOTHING;
534  }
535  _SEH2_END;
536  }
537 
538  /* Free the user-mode memory */
539  if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
540  {
541  ZwFreeVirtualMemory(ZwCurrentProcess(),
542  (PVOID*)&WindowStationName,
543  &MemSize,
544  MEM_RELEASE);
545  }
546 }
547 
548 static NTSTATUS
550  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes,
551  IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes,
552  OUT PUNICODE_STRING* WindowStationName,
553  OUT PUNICODE_STRING* TebStaticUnicodeString)
554 {
556  SIZE_T MemSize;
557 
558  LUID CallerLuid;
559  PTEB Teb;
560  USHORT StrSize;
561 
562  *WindowStationName = NULL;
563  *TebStaticUnicodeString = NULL;
564 
565  /* Retrieve the current process LUID */
566  Status = GetProcessLuid(NULL, NULL, &CallerLuid);
567  if (!NT_SUCCESS(Status))
568  {
569  ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
570  return Status;
571  }
572 
573  /* Compute the needed string size */
574  MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
575  &gustrWindowStationsDir,
576  CallerLuid.HighPart,
577  CallerLuid.LowPart);
578  MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
579  if (MemSize > MAXUSHORT)
580  {
581  ERR("Window station name length is too long.\n");
582  return STATUS_NAME_TOO_LONG;
583  }
584  StrSize = (USHORT)MemSize;
585 
586  /*
587  * Check whether it's short enough so that we can use the static buffer
588  * in the TEB. Otherwise continue with virtual memory allocation.
589  */
590  Teb = NtCurrentTeb();
591  if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
592  {
593  /* We can use the TEB's static unicode string */
596 
597  /* Remember the TEB's static unicode string address for later */
598  *TebStaticUnicodeString = &Teb->StaticUnicodeString;
599 
600  *WindowStationName = *TebStaticUnicodeString;
601  (*WindowStationName)->Length = 0;
602  }
603  else
604  {
605  /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
606  MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
607 
608  /* Allocate the memory in user-mode */
609  Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
610  (PVOID*)WindowStationName,
611  0,
612  &MemSize,
613  MEM_COMMIT,
615  if (!NT_SUCCESS(Status))
616  {
617  ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
618  return Status;
619  }
620 
621  RtlInitEmptyUnicodeString(*WindowStationName,
622  (PWCHAR)((ULONG_PTR)*WindowStationName +
623  ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
624  StrSize);
625  }
626 
627  /* Build a valid window station name from the LUID */
628  Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
629  (*WindowStationName)->MaximumLength,
630  L"%wZ\\Service-0x%x-%x$",
631  &gustrWindowStationsDir,
632  CallerLuid.HighPart,
633  CallerLuid.LowPart);
634  if (!NT_SUCCESS(Status))
635  {
636  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
637  goto Quit;
638  }
639  (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
640 
641  /* Try to update the user's UserModeObjectAttributes */
642  _SEH2_TRY
643  {
644  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
645  *LocalObjectAttributes = *UserModeObjectAttributes;
646 
647  UserModeObjectAttributes->ObjectName = *WindowStationName;
648  UserModeObjectAttributes->RootDirectory = NULL;
649 
650  Status = STATUS_SUCCESS;
651  }
653  {
654  Status = _SEH2_GetExceptionCode();
655  }
656  _SEH2_END;
657 
658 Quit:
659  if (!NT_SUCCESS(Status))
660  {
661  /* Release the window station name */
662  FreeUserModeWindowStationName(*WindowStationName,
663  *TebStaticUnicodeString,
664  NULL, NULL);
665  }
666 
667  return Status;
668 }
669 
670 HWINSTA
671 APIENTRY
674  IN ACCESS_MASK dwDesiredAccess,
675  DWORD Unknown2,
676  DWORD Unknown3,
677  DWORD Unknown4,
678  DWORD Unknown5,
679  DWORD Unknown6)
680 {
682  HWINSTA hWinSta = NULL;
683  OBJECT_ATTRIBUTES LocalObjectAttributes;
684  PUNICODE_STRING WindowStationName = NULL;
685  PUNICODE_STRING TebStaticUnicodeString = NULL;
686  KPROCESSOR_MODE OwnerMode = UserMode;
687 
688  TRACE("NtUserCreateWindowStation called\n");
689 
690  /* Capture the object attributes and the window station name */
691  _SEH2_TRY
692  {
693  ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
694  LocalObjectAttributes = *ObjectAttributes;
695  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
696  {
697  ERR("Invalid ObjectAttributes length!\n");
698  Status = STATUS_INVALID_PARAMETER;
699  _SEH2_LEAVE;
700  }
701 
702  /*
703  * Check whether the caller provided a window station name together
704  * with a RootDirectory handle.
705  *
706  * If the caller did not provide a window station name, build a new one
707  * based on the logon session identifier for the calling process.
708  * The new name is allocated in user-mode, as the rest of ObjectAttributes
709  * already is, so that the validation performed by the Object Manager
710  * can be done adequately.
711  */
712  if ((LocalObjectAttributes.ObjectName == NULL ||
713  LocalObjectAttributes.ObjectName->Buffer == NULL ||
714  LocalObjectAttributes.ObjectName->Length == 0 ||
715  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
716  /* &&
717  LocalObjectAttributes.RootDirectory == NULL */)
718  {
719  /* No, build the new window station name */
720  Status = BuildUserModeWindowStationName(ObjectAttributes,
721  &LocalObjectAttributes,
722  &WindowStationName,
723  &TebStaticUnicodeString);
724  if (!NT_SUCCESS(Status))
725  {
726  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
727  _SEH2_LEAVE;
728  }
729  OwnerMode = KernelMode;
730  }
731  }
733  {
734  Status =_SEH2_GetExceptionCode();
735  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
736  }
737  _SEH2_END;
738 
739  if (!NT_SUCCESS(Status))
740  {
741  SetLastNtError(Status);
742  return NULL;
743  }
744 
745  /* Create the window station */
746  Status = IntCreateWindowStation(&hWinSta,
747  ObjectAttributes,
748  UserMode,
749  OwnerMode,
750  dwDesiredAccess,
751  Unknown2,
752  Unknown3,
753  Unknown4,
754  Unknown5,
755  Unknown6);
756  if (NT_SUCCESS(Status))
757  {
758  TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
759  ObjectAttributes->ObjectName, hWinSta);
760  }
761  else
762  {
763  ASSERT(hWinSta == NULL);
764  ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
765  ObjectAttributes->ObjectName, Status);
766  }
767 
768  /* Try to restore the user's ObjectAttributes and release the window station name */
769  FreeUserModeWindowStationName(WindowStationName,
770  TebStaticUnicodeString,
771  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
772  &LocalObjectAttributes);
773 
774  if (!NT_SUCCESS(Status))
775  {
776  ASSERT(hWinSta == NULL);
777  SetLastNtError(Status);
778  }
779 
780  return hWinSta;
781 }
782 
783 /*
784  * NtUserOpenWindowStation
785  *
786  * Opens an existing window station.
787  *
788  * Parameters
789  * lpszWindowStationName
790  * Name of the existing window station.
791  *
792  * dwDesiredAccess
793  * Requested type of access.
794  *
795  * Return Value
796  * If the function succeeds, the return value is the handle to the
797  * specified window station. If the function fails, the return value
798  * is NULL.
799  *
800  * Remarks
801  * The returned handle can be closed with NtUserCloseWindowStation.
802  *
803  * Status
804  * @implemented
805  */
806 
807 HWINSTA
808 APIENTRY
811  IN ACCESS_MASK dwDesiredAccess)
812 {
814  HWINSTA hWinSta = NULL;
815  OBJECT_ATTRIBUTES LocalObjectAttributes;
816  PUNICODE_STRING WindowStationName = NULL;
817  PUNICODE_STRING TebStaticUnicodeString = NULL;
818  KPROCESSOR_MODE OwnerMode = UserMode;
819 
820  TRACE("NtUserOpenWindowStation called\n");
821 
822  /* Capture the object attributes and the window station name */
823  _SEH2_TRY
824  {
825  ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
826  LocalObjectAttributes = *ObjectAttributes;
827  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
828  {
829  ERR("Invalid ObjectAttributes length!\n");
830  Status = STATUS_INVALID_PARAMETER;
831  _SEH2_LEAVE;
832  }
833 
834  /*
835  * Check whether the caller did not provide a window station name,
836  * or provided the special "Service-0x00000000-00000000$" name.
837  *
838  * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
839  * is used instead of an empty name (observed when API-monitoring
840  * OpenWindowStation() called with an empty window station name).
841  */
842  if ((LocalObjectAttributes.ObjectName == NULL ||
843  LocalObjectAttributes.ObjectName->Buffer == NULL ||
844  LocalObjectAttributes.ObjectName->Length == 0 ||
845  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
846  /* &&
847  LocalObjectAttributes.RootDirectory == NULL */)
848  {
849  /* No, remember that for later */
850  LocalObjectAttributes.ObjectName = NULL;
851  }
852  if (LocalObjectAttributes.ObjectName &&
853  LocalObjectAttributes.ObjectName->Length ==
854  sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
855  _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
856  L"Service-0x00000000-00000000$",
857  LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
858  {
859  /* No, remember that for later */
860  LocalObjectAttributes.ObjectName = NULL;
861  }
862 
863  /*
864  * If the caller did not provide a window station name, build a new one
865  * based on the logon session identifier for the calling process.
866  * The new name is allocated in user-mode, as the rest of ObjectAttributes
867  * already is, so that the validation performed by the Object Manager
868  * can be done adequately.
869  */
870  if (!LocalObjectAttributes.ObjectName)
871  {
872  /* No, build the new window station name */
873  Status = BuildUserModeWindowStationName(ObjectAttributes,
874  &LocalObjectAttributes,
875  &WindowStationName,
876  &TebStaticUnicodeString);
877  if (!NT_SUCCESS(Status))
878  {
879  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
880  _SEH2_LEAVE;
881  }
882  OwnerMode = KernelMode;
883  }
884  }
886  {
887  Status =_SEH2_GetExceptionCode();
888  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
889  }
890  _SEH2_END;
891 
892  if (!NT_SUCCESS(Status))
893  {
894  SetLastNtError(Status);
895  return NULL;
896  }
897 
898  /* Open the window station */
899  Status = ObOpenObjectByName(ObjectAttributes,
901  UserMode,
902  NULL,
903  dwDesiredAccess,
904  NULL,
905  (PVOID*)&hWinSta);
906  if (NT_SUCCESS(Status))
907  {
908  TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
909  ObjectAttributes->ObjectName, hWinSta);
910  }
911  else
912  {
913  ASSERT(hWinSta == NULL);
914  ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
915  ObjectAttributes->ObjectName, Status);
916  }
917 
918  /* Try to restore the user's ObjectAttributes and release the window station name */
919  FreeUserModeWindowStationName(WindowStationName,
920  TebStaticUnicodeString,
921  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
922  &LocalObjectAttributes);
923 
924  if (!NT_SUCCESS(Status))
925  {
926  ASSERT(hWinSta == NULL);
927  SetLastNtError(Status);
928  }
929 
930  return hWinSta;
931 }
932 
933 /*
934  * NtUserCloseWindowStation
935  *
936  * Closes a window station handle.
937  *
938  * Parameters
939  * hWinSta
940  * Handle to the window station.
941  *
942  * Return Value
943  * Status
944  *
945  * Remarks
946  * The window station handle can be created with NtUserCreateWindowStation
947  * or NtUserOpenWindowStation. Attempts to close a handle to the window
948  * station assigned to the calling process will fail.
949  *
950  * Status
951  * @implemented
952  */
953 
954 BOOL
955 APIENTRY
957  HWINSTA hWinSta)
958 {
961 
962  TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
963 
964  if (hWinSta == UserGetProcessWindowStation())
965  {
966  ERR("Attempted to close process window station\n");
967  return FALSE;
968  }
969 
970  Status = IntValidateWindowStationHandle(hWinSta,
971  UserMode,
972  0,
973  &Object,
974  NULL);
975  if (!NT_SUCCESS(Status))
976  {
977  ERR("Validation of window station handle (%p) failed\n", hWinSta);
978  return FALSE;
979  }
980 
981  ObDereferenceObject(Object);
982 
983  TRACE("Closing window station handle (%p)\n", hWinSta);
984 
985  Status = ObCloseHandle(hWinSta, UserMode);
986  if (!NT_SUCCESS(Status))
987  {
988  SetLastNtError(Status);
989  return FALSE;
990  }
991 
992  return TRUE;
993 }
994 
995 /*
996  * NtUserGetObjectInformation
997  *
998  * The NtUserGetObjectInformation function retrieves information about a
999  * window station or desktop object.
1000  *
1001  * Parameters
1002  * hObj
1003  * Handle to the window station or desktop object for which to
1004  * return information. This can be a handle of type HDESK or HWINSTA
1005  * (for example, a handle returned by NtUserCreateWindowStation,
1006  * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
1007  *
1008  * nIndex
1009  * Specifies the object information to be retrieved.
1010  *
1011  * pvInfo
1012  * Pointer to a buffer to receive the object information.
1013  *
1014  * nLength
1015  * Specifies the size, in bytes, of the buffer pointed to by the
1016  * pvInfo parameter.
1017  *
1018  * lpnLengthNeeded
1019  * Pointer to a variable receiving the number of bytes required to
1020  * store the requested information. If this variable's value is
1021  * greater than the value of the nLength parameter when the function
1022  * returns, the function returns FALSE, and none of the information
1023  * is copied to the pvInfo buffer. If the value of the variable pointed
1024  * to by lpnLengthNeeded is less than or equal to the value of nLength,
1025  * the entire information block is copied.
1026  *
1027  * Return Value
1028  * If the function succeeds, the return value is nonzero. If the function
1029  * fails, the return value is zero.
1030  *
1031  * Status
1032  * @unimplemented
1033  */
1034 
1035 BOOL APIENTRY
1037  HANDLE hObject,
1038  DWORD nIndex,
1039  PVOID pvInformation,
1040  DWORD nLength,
1041  PDWORD nLengthNeeded)
1042 {
1043  NTSTATUS Status;
1044  PWINSTATION_OBJECT WinStaObject = NULL;
1045  PDESKTOP DesktopObject = NULL;
1046  POBJECT_HEADER ObjectHeader;
1047  POBJECT_HEADER_NAME_INFO NameInfo;
1048  OBJECT_HANDLE_INFORMATION HandleInfo;
1049  USEROBJECTFLAGS ObjectFlags;
1050  PUNICODE_STRING pStrNameU = NULL;
1051  PVOID pvData = NULL;
1052  SIZE_T nDataSize = 0;
1053 
1054  _SEH2_TRY
1055  {
1056  if (nLengthNeeded)
1057  ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1058  ProbeForWrite(pvInformation, nLength, 1);
1059  }
1061  {
1063  return FALSE;
1064  }
1065  _SEH2_END;
1066 
1067  /* Try window station */
1068  TRACE("Trying to open window station 0x%p\n", hObject);
1069  Status = ObReferenceObjectByHandle(hObject,
1070  0,
1072  UserMode,
1073  (PVOID*)&WinStaObject,
1074  &HandleInfo);
1075 
1076  if (Status == STATUS_OBJECT_TYPE_MISMATCH)
1077  {
1078  /* Try desktop */
1079  TRACE("Trying to open desktop %p\n", hObject);
1080  WinStaObject = NULL;
1081  Status = IntValidateDesktopHandle(hObject,
1082  UserMode,
1083  0,
1084  &DesktopObject);
1085  }
1086 
1087  if (!NT_SUCCESS(Status))
1088  {
1089  ERR("Failed: 0x%x\n", Status);
1090  goto Exit;
1091  }
1092 
1093  TRACE("WinSta or Desktop opened!\n");
1094 
1095  /* Get data */
1096  switch (nIndex)
1097  {
1098  case UOI_FLAGS:
1099  {
1100  ObjectFlags.fReserved = FALSE;
1101  ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1102 
1103  ObjectFlags.dwFlags = 0;
1104  if (WinStaObject != NULL)
1105  {
1106  if (!(WinStaObject->Flags & WSS_NOIO))
1107  ObjectFlags.dwFlags |= WSF_VISIBLE;
1108  }
1109  else if (DesktopObject != NULL)
1110  {
1111  FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1112  }
1113  else
1114  {
1115  ERR("No associated WinStaObject nor DesktopObject!\n");
1116  }
1117 
1118  pvData = &ObjectFlags;
1119  nDataSize = sizeof(ObjectFlags);
1120  Status = STATUS_SUCCESS;
1121  break;
1122  }
1123 
1124  case UOI_NAME:
1125  {
1126  if (WinStaObject != NULL)
1127  {
1128  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1129  NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1130 
1131  if (NameInfo && (NameInfo->Name.Length > 0))
1132  {
1133  /* Named window station */
1134  pStrNameU = &NameInfo->Name;
1135  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1136  }
1137  else
1138  {
1139  /* Unnamed window station (should never happen!) */
1140  ASSERT(FALSE);
1141  pStrNameU = NULL;
1142  nDataSize = sizeof(UNICODE_NULL);
1143  }
1144  Status = STATUS_SUCCESS;
1145  }
1146  else if (DesktopObject != NULL)
1147  {
1148  pvData = DesktopObject->pDeskInfo->szDesktopName;
1149  nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1150  Status = STATUS_SUCCESS;
1151  }
1152  else
1153  {
1154  Status = STATUS_INVALID_PARAMETER;
1155  }
1156  break;
1157  }
1158 
1159  case UOI_TYPE:
1160  {
1161  if (WinStaObject != NULL)
1162  {
1163  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1164  pStrNameU = &ObjectHeader->Type->Name;
1165  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1166  Status = STATUS_SUCCESS;
1167  }
1168  else if (DesktopObject != NULL)
1169  {
1170  ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1171  pStrNameU = &ObjectHeader->Type->Name;
1172  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1173  Status = STATUS_SUCCESS;
1174  }
1175  else
1176  {
1177  Status = STATUS_INVALID_PARAMETER;
1178  }
1179  break;
1180  }
1181 
1182  case UOI_USER_SID:
1183  Status = STATUS_NOT_IMPLEMENTED;
1184  ERR("UOI_USER_SID unimplemented!\n");
1185  break;
1186 
1187  default:
1188  Status = STATUS_INVALID_PARAMETER;
1189  break;
1190  }
1191 
1192 Exit:
1193  if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1194  Status = STATUS_BUFFER_TOO_SMALL;
1195 
1196  _SEH2_TRY
1197  {
1198  if (nLengthNeeded)
1199  *nLengthNeeded = nDataSize;
1200 
1201  /* Try to copy data to caller */
1202  if (Status == STATUS_SUCCESS && (nDataSize > 0))
1203  {
1204  TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1205  if (pvData)
1206  {
1207  /* Copy the data */
1208  RtlCopyMemory(pvInformation, pvData, nDataSize);
1209  }
1210  else if (pStrNameU)
1211  {
1212  /* Copy and NULL-terminate the string */
1213  RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1214  ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1215  }
1216  else
1217  {
1218  /* Zero the memory */
1219  RtlZeroMemory(pvInformation, nDataSize);
1220  }
1221  }
1222  }
1224  {
1225  Status = _SEH2_GetExceptionCode();
1226  }
1227  _SEH2_END;
1228 
1229  /* Release objects */
1230  if (DesktopObject != NULL)
1231  ObDereferenceObject(DesktopObject);
1232  if (WinStaObject != NULL)
1233  ObDereferenceObject(WinStaObject);
1234 
1235  if (!NT_SUCCESS(Status))
1236  {
1237  SetLastNtError(Status);
1238  return FALSE;
1239  }
1240 
1241  return TRUE;
1242 }
1243 
1244 /*
1245  * NtUserSetObjectInformation
1246  *
1247  * The NtUserSetObjectInformation function sets information about a
1248  * window station or desktop object.
1249  *
1250  * Parameters
1251  * hObj
1252  * Handle to the window station or desktop object for which to set
1253  * object information. This value can be a handle of type HDESK or
1254  * HWINSTA.
1255  *
1256  * nIndex
1257  * Specifies the object information to be set.
1258  *
1259  * pvInfo
1260  * Pointer to a buffer containing the object information.
1261  *
1262  * nLength
1263  * Specifies the size, in bytes, of the information contained in the
1264  * buffer pointed to by pvInfo.
1265  *
1266  * Return Value
1267  * If the function succeeds, the return value is nonzero. If the function
1268  * fails the return value is zero.
1269  *
1270  * Status
1271  * @unimplemented
1272  */
1273 
1274 BOOL
1275 APIENTRY
1277  HANDLE hObject,
1278  DWORD nIndex,
1279  PVOID pvInformation,
1280  DWORD nLength)
1281 {
1282  /* FIXME: ZwQueryObject */
1283  /* FIXME: ZwSetInformationObject */
1285  return FALSE;
1286 }
1287 
1288 
1289 HWINSTA FASTCALL
1291 {
1293 
1294  return ppi->hwinsta;
1295 }
1296 
1297 
1298 /*
1299  * NtUserGetProcessWindowStation
1300  *
1301  * Returns a handle to the current process window station.
1302  *
1303  * Return Value
1304  * If the function succeeds, the return value is handle to the window
1305  * station assigned to the current process. If the function fails, the
1306  * return value is NULL.
1307  *
1308  * Status
1309  * @implemented
1310  */
1311 
1312 HWINSTA APIENTRY
1314 {
1315  return UserGetProcessWindowStation();
1316 }
1317 
1318 BOOL FASTCALL
1319 UserSetProcessWindowStation(HWINSTA hWindowStation)
1320 {
1321  NTSTATUS Status;
1322  PPROCESSINFO ppi;
1323  OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1324  PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1325  HWINSTA hCacheWinSta;
1326 
1328 
1329  /* Reference the new window station */
1330  if (hWindowStation != NULL)
1331  {
1332  Status = IntValidateWindowStationHandle(hWindowStation,
1333  UserMode,
1334  0,
1335  &NewWinSta,
1336  &ObjectHandleInfo);
1337  if (!NT_SUCCESS(Status))
1338  {
1339  TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1340  SetLastNtError(Status);
1341  return FALSE;
1342  }
1343  }
1344 
1345  OldWinSta = ppi->prpwinsta;
1346  hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1347 
1348  /* Dereference the previous window station */
1349  if (OldWinSta != NULL)
1350  {
1351  ObDereferenceObject(OldWinSta);
1352  }
1353 
1354  /*
1355  * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1356  */
1357 
1358  /* Close the cached EPROCESS window station handle if needed */
1359  if (hCacheWinSta != NULL)
1360  {
1361  /* Reference the window station */
1362  Status = ObReferenceObjectByHandle(hCacheWinSta,
1363  0,
1365  UserMode,
1366  (PVOID*)&OldWinSta,
1367  NULL);
1368  if (!NT_SUCCESS(Status))
1369  {
1370  ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1371  /* We failed, reset the cache */
1372  hCacheWinSta = NULL;
1373  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1374  }
1375  else
1376  {
1377  /*
1378  * Close the old handle and reset the cache only
1379  * if we are setting a different window station.
1380  */
1381  if (NewWinSta != OldWinSta)
1382  {
1383  ObCloseHandle(hCacheWinSta, UserMode);
1384  hCacheWinSta = NULL;
1385  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1386  }
1387 
1388  /* Dereference the window station */
1389  ObDereferenceObject(OldWinSta);
1390  }
1391  }
1392 
1393  /* Duplicate and save a new cached EPROCESS window station handle */
1394  if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1395  {
1396  Status = ZwDuplicateObject(ZwCurrentProcess(),
1397  hWindowStation,
1398  ZwCurrentProcess(),
1399  (PHANDLE)&hCacheWinSta,
1400  0,
1401  0,
1403  if (!NT_SUCCESS(Status))
1404  {
1405  ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1406  }
1407  else
1408  {
1409  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1410  }
1411  }
1412 
1413  ppi->prpwinsta = NewWinSta;
1414  ppi->hwinsta = hWindowStation;
1415  ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1416  TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1417 
1419  {
1420  ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1421  }
1422  else
1423  {
1424  ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1425  }
1426 
1427  if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1428  {
1429  ppi->W32PF_flags |= W32PF_IOWINSTA;
1430  }
1431  else /* Might be closed if the handle is NULL */
1432  {
1433  ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1434  }
1435  return TRUE;
1436 }
1437 
1438 /*
1439  * NtUserSetProcessWindowStation
1440  *
1441  * Assigns a window station to the current process.
1442  *
1443  * Parameters
1444  * hWinSta
1445  * Handle to the window station.
1446  *
1447  * Return Value
1448  * Status
1449  *
1450  * Status
1451  * @implemented
1452  */
1453 
1454 BOOL APIENTRY
1455 NtUserSetProcessWindowStation(HWINSTA hWindowStation)
1456 {
1457  BOOL ret;
1458 
1460 
1461  ret = UserSetProcessWindowStation(hWindowStation);
1462 
1463  UserLeave();
1464 
1465  return ret;
1466 }
1467 
1468 /*
1469  * NtUserLockWindowStation
1470  *
1471  * Locks switching desktops. Only the logon application is allowed to call this function.
1472  *
1473  * Status
1474  * @implemented
1475  */
1476 
1477 BOOL APIENTRY
1478 NtUserLockWindowStation(HWINSTA hWindowStation)
1479 {
1481  NTSTATUS Status;
1482 
1483  TRACE("About to set process window station with handle (%p)\n",
1484  hWindowStation);
1485 
1487  {
1488  ERR("Unauthorized process attempted to lock the window station!\n");
1490  return FALSE;
1491  }
1492 
1493  Status = IntValidateWindowStationHandle(hWindowStation,
1494  UserMode,
1495  0,
1496  &Object,
1497  NULL);
1498  if (!NT_SUCCESS(Status))
1499  {
1500  TRACE("Validation of window station handle (%p) failed\n",
1501  hWindowStation);
1502  SetLastNtError(Status);
1503  return FALSE;
1504  }
1505 
1506  Object->Flags |= WSS_LOCKED;
1507 
1508  ObDereferenceObject(Object);
1509  return TRUE;
1510 }
1511 
1512 /*
1513  * NtUserUnlockWindowStation
1514  *
1515  * Unlocks switching desktops. Only the logon application is allowed to call this function.
1516  *
1517  * Status
1518  * @implemented
1519  */
1520 
1521 BOOL APIENTRY
1522 NtUserUnlockWindowStation(HWINSTA hWindowStation)
1523 {
1525  NTSTATUS Status;
1526  BOOL Ret;
1527 
1528  TRACE("About to set process window station with handle (%p)\n",
1529  hWindowStation);
1530 
1532  {
1533  ERR("Unauthorized process attempted to unlock the window station!\n");
1535  return FALSE;
1536  }
1537 
1538  Status = IntValidateWindowStationHandle(hWindowStation,
1539  UserMode,
1540  0,
1541  &Object,
1542  NULL);
1543  if (!NT_SUCCESS(Status))
1544  {
1545  TRACE("Validation of window station handle (%p) failed\n",
1546  hWindowStation);
1547  SetLastNtError(Status);
1548  return FALSE;
1549  }
1550 
1551  Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1552  Object->Flags &= ~WSS_LOCKED;
1553 
1554  ObDereferenceObject(Object);
1555  return Ret;
1556 }
1557 
1558 static NTSTATUS FASTCALL
1560  ULONG dwSize,
1561  PVOID lpBuffer,
1562  PULONG pRequiredSize)
1563 {
1565  NTSTATUS Status;
1567  char InitialBuffer[256], *Buffer;
1569  DWORD EntryCount;
1571  WCHAR NullWchar;
1572 
1573  //
1574  // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1575  // with judicious parameters one can create window stations elsewhere
1576  // than in Windows\WindowStations directory, Win32k definitely MUST
1577  // maintain a list of window stations it has created, and not rely
1578  // on the enumeration of Windows\WindowStations !!!
1579  //
1580 
1581  /*
1582  * Try to open the directory.
1583  */
1584  InitializeObjectAttributes(&ObjectAttributes,
1585  &gustrWindowStationsDir,
1587  NULL,
1588  NULL);
1589 
1590  Status = ZwOpenDirectoryObject(&DirectoryHandle,
1592  &ObjectAttributes);
1593 
1594  if (!NT_SUCCESS(Status))
1595  {
1596  return Status;
1597  }
1598 
1599  /* First try to query the directory using a fixed-size buffer */
1600  Context = 0;
1601  Buffer = NULL;
1602  Status = ZwQueryDirectoryObject(DirectoryHandle,
1603  InitialBuffer,
1604  sizeof(InitialBuffer),
1605  FALSE,
1606  TRUE,
1607  &Context,
1608  &ReturnLength);
1609  if (NT_SUCCESS(Status))
1610  {
1611  if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1612  FALSE, &Context, NULL))
1613  {
1614  /* Our fixed-size buffer is large enough */
1615  Buffer = InitialBuffer;
1616  }
1617  }
1618 
1619  if (NULL == Buffer)
1620  {
1621  /* Need a larger buffer, check how large exactly */
1622  Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1623  &ReturnLength);
1624  if (!NT_SUCCESS(Status))
1625  {
1626  ERR("ZwQueryDirectoryObject failed\n");
1627  ZwClose(DirectoryHandle);
1628  return Status;
1629  }
1630 
1631  BufferSize = ReturnLength;
1632  Buffer = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_WINSTA);
1633  if (NULL == Buffer)
1634  {
1635  ZwClose(DirectoryHandle);
1636  return STATUS_NO_MEMORY;
1637  }
1638 
1639  /* We should have a sufficiently large buffer now */
1640  Context = 0;
1641  Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1642  FALSE, TRUE, &Context, &ReturnLength);
1643  if (! NT_SUCCESS(Status) ||
1644  STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1645  FALSE, &Context, NULL))
1646  {
1647  /* Something went wrong, maybe someone added a directory entry? Just give up. */
1648  ExFreePoolWithTag(Buffer, TAG_WINSTA);
1649  ZwClose(DirectoryHandle);
1650  return NT_SUCCESS(Status) ? STATUS_INTERNAL_ERROR : Status;
1651  }
1652  }
1653 
1654  ZwClose(DirectoryHandle);
1655 
1656  /*
1657  * Count the required size of buffer.
1658  */
1659  ReturnLength = sizeof(DWORD);
1660  EntryCount = 0;
1661  for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer;
1662  0 != DirEntry->Name.Length;
1663  DirEntry++)
1664  {
1665  ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1666  EntryCount++;
1667  }
1668  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1669  if (NULL != pRequiredSize)
1670  {
1671  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1672  if (! NT_SUCCESS(Status))
1673  {
1674  if (Buffer != InitialBuffer)
1675  {
1676  ExFreePoolWithTag(Buffer, TAG_WINSTA);
1677  }
1678  return STATUS_BUFFER_TOO_SMALL;
1679  }
1680  }
1681 
1682  /*
1683  * Check if the supplied buffer is large enough.
1684  */
1685  if (dwSize < ReturnLength)
1686  {
1687  if (Buffer != InitialBuffer)
1688  {
1689  ExFreePoolWithTag(Buffer, TAG_WINSTA);
1690  }
1691  return STATUS_BUFFER_TOO_SMALL;
1692  }
1693 
1694  /*
1695  * Generate the resulting buffer contents.
1696  */
1697  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1698  if (! NT_SUCCESS(Status))
1699  {
1700  if (Buffer != InitialBuffer)
1701  {
1702  ExFreePoolWithTag(Buffer, TAG_WINSTA);
1703  }
1704  return Status;
1705  }
1706  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1707 
1708  NullWchar = L'\0';
1709  for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer;
1710  0 != DirEntry->Name.Length;
1711  DirEntry++)
1712  {
1713  Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
1714  if (! NT_SUCCESS(Status))
1715  {
1716  if (Buffer != InitialBuffer)
1717  {
1718  ExFreePoolWithTag(Buffer, TAG_WINSTA);
1719  }
1720  return Status;
1721  }
1722  lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
1723  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1724  if (! NT_SUCCESS(Status))
1725  {
1726  if (Buffer != InitialBuffer)
1727  {
1728  ExFreePoolWithTag(Buffer, TAG_WINSTA);
1729  }
1730  return Status;
1731  }
1732  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1733  }
1734 
1735  /*
1736  * Clean up
1737  */
1738  if (Buffer != InitialBuffer)
1739  {
1740  ExFreePoolWithTag(Buffer, TAG_WINSTA);
1741  }
1742 
1743  return STATUS_SUCCESS;
1744 }
1745 
1746 static NTSTATUS FASTCALL
1748  HWINSTA hWindowStation,
1749  ULONG dwSize,
1750  PVOID lpBuffer,
1751  PULONG pRequiredSize)
1752 {
1753  NTSTATUS Status;
1754  PWINSTATION_OBJECT WindowStation;
1755  PLIST_ENTRY DesktopEntry;
1756  PDESKTOP DesktopObject;
1757  DWORD EntryCount;
1759  WCHAR NullWchar;
1760  UNICODE_STRING DesktopName;
1761 
1762  Status = IntValidateWindowStationHandle(hWindowStation,
1763  UserMode,
1764  0,
1765  &WindowStation,
1766  NULL);
1767  if (! NT_SUCCESS(Status))
1768  {
1769  return Status;
1770  }
1771 
1772  /*
1773  * Count the required size of buffer.
1774  */
1775  ReturnLength = sizeof(DWORD);
1776  EntryCount = 0;
1777  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1778  DesktopEntry != &WindowStation->DesktopListHead;
1779  DesktopEntry = DesktopEntry->Flink)
1780  {
1781  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1782  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1783  ReturnLength += DesktopName.Length + sizeof(WCHAR);
1784  EntryCount++;
1785  }
1786  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1787  if (NULL != pRequiredSize)
1788  {
1789  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1790  if (! NT_SUCCESS(Status))
1791  {
1792  ObDereferenceObject(WindowStation);
1793  return STATUS_BUFFER_TOO_SMALL;
1794  }
1795  }
1796 
1797  /*
1798  * Check if the supplied buffer is large enough.
1799  */
1800  if (dwSize < ReturnLength)
1801  {
1802  ObDereferenceObject(WindowStation);
1803  return STATUS_BUFFER_TOO_SMALL;
1804  }
1805 
1806  /*
1807  * Generate the resulting buffer contents.
1808  */
1809  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1810  if (! NT_SUCCESS(Status))
1811  {
1812  ObDereferenceObject(WindowStation);
1813  return Status;
1814  }
1815  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1816 
1817  NullWchar = L'\0';
1818  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1819  DesktopEntry != &WindowStation->DesktopListHead;
1820  DesktopEntry = DesktopEntry->Flink)
1821  {
1822  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1823  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1824  Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
1825  if (! NT_SUCCESS(Status))
1826  {
1827  ObDereferenceObject(WindowStation);
1828  return Status;
1829  }
1830  lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
1831  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1832  if (! NT_SUCCESS(Status))
1833  {
1834  ObDereferenceObject(WindowStation);
1835  return Status;
1836  }
1837  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1838  }
1839 
1840  /*
1841  * Clean up and return
1842  */
1843  ObDereferenceObject(WindowStation);
1844  return STATUS_SUCCESS;
1845 }
1846 
1847 /*
1848  * NtUserBuildNameList
1849  *
1850  * Function used for enumeration of desktops or window stations.
1851  *
1852  * Parameters
1853  * hWinSta
1854  * For enumeration of window stations this parameter must be set to
1855  * zero. Otherwise it's handle for window station.
1856  *
1857  * dwSize
1858  * Size of buffer passed by caller.
1859  *
1860  * lpBuffer
1861  * Buffer passed by caller. If the function succeeds, the buffer is
1862  * filled with window station/desktop count (in first DWORD) and
1863  * NULL-terminated window station/desktop names.
1864  *
1865  * pRequiredSize
1866  * If the function succeeds, this is the number of bytes copied.
1867  * Otherwise it's size of buffer needed for function to succeed.
1868  *
1869  * Status
1870  * @implemented
1871  */
1872 
1875  HWINSTA hWindowStation,
1876  ULONG dwSize,
1877  PVOID lpBuffer,
1878  PULONG pRequiredSize)
1879 {
1880  /* The WindowStation name list and desktop name list are build in completely
1881  different ways. Call the appropriate function */
1882  return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
1883  BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
1884 }
1885 
1886 /*
1887  * @implemented
1888  */
1889 BOOL APIENTRY
1891 {
1893  {
1894  return FALSE;
1895  }
1896 
1897  if (!IntIsWindow(hWnd))
1898  {
1899  return FALSE;
1900  }
1901 
1902  hwndSAS = hWnd;
1903 
1904  return TRUE;
1905 }
1906 
1907 BOOL
1908 APIENTRY
1910 {
1911  BOOL ret;
1913 
1915 
1916  if (pti->rpdesk == IntGetActiveDesktop())
1917  {
1919  }
1920  else
1921  {
1922  ret = FALSE;
1923  }
1924 
1925  UserLeave();
1926 
1927  return ret;
1928 }
1929 
1930 BOOL
1931 NTAPI
1933  IN HWINSTA hWindowStation,
1934  IN PLUID pluid,
1935  IN PSID psid OPTIONAL,
1936  IN DWORD size)
1937 {
1938  BOOL Ret = FALSE;
1939  NTSTATUS Status;
1940  PWINSTATION_OBJECT WindowStation = NULL;
1941  LUID luidUser;
1942 
1944 
1946  {
1948  goto Leave;
1949  }
1950 
1951  /* Validate the window station */
1952  Status = IntValidateWindowStationHandle(hWindowStation,
1953  UserMode,
1954  0,
1955  &WindowStation,
1956  NULL);
1957  if (!NT_SUCCESS(Status))
1958  {
1959  goto Leave;
1960  }
1961 
1962  /* Capture the user LUID */
1963  _SEH2_TRY
1964  {
1965  ProbeForRead(pluid, sizeof(LUID), 1);
1966  luidUser = *pluid;
1967  }
1969  {
1970  Status = _SEH2_GetExceptionCode();
1971  _SEH2_YIELD(goto Leave);
1972  }
1973  _SEH2_END;
1974 
1975  /* Reset the window station user LUID */
1976  RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
1977 
1978  /* Reset the window station user SID */
1979  if (WindowStation->psidUser)
1980  {
1981  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
1982  WindowStation->psidUser = NULL;
1983  }
1984 
1985  /* Copy the new user SID if one has been provided */
1986  if (psid)
1987  {
1988  WindowStation->psidUser = ExAllocatePoolWithTag(PagedPool, size, USERTAG_SECURITY);
1989  if (WindowStation->psidUser == NULL)
1990  {
1992  goto Leave;
1993  }
1994 
1995  Status = STATUS_SUCCESS;
1996  _SEH2_TRY
1997  {
1998  ProbeForRead(psid, size, 1);
1999  RtlCopyMemory(WindowStation->psidUser, psid, size);
2000  }
2002  {
2003  Status = _SEH2_GetExceptionCode();
2004  }
2005  _SEH2_END;
2006 
2007  if (!NT_SUCCESS(Status))
2008  {
2009  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2010  WindowStation->psidUser = NULL;
2011  goto Leave;
2012  }
2013  }
2014 
2015  /* Copy the new user LUID */
2016  WindowStation->luidUser = luidUser;
2017 
2018  Ret = TRUE;
2019 
2020 Leave:
2021  if (WindowStation)
2022  ObDereferenceObject(WindowStation);
2023 
2024  UserLeave();
2025  return Ret;
2026 }
2027 
2028 /* EOF */
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2523
DWORD *typedef PVOID
Definition: winlogon.h:61
signed char * PCHAR
Definition: retypes.h:7
#define HDC
Definition: msvc.h:22
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
BOOL MenuInit(VOID)
Definition: menu.c:361
#define WINSTA_READ
Definition: winsta.h:50
BOOL APIENTRY NtUserLockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1478
#define BITSPIXEL
Definition: wingdi.h:718
#define IN
Definition: typedefs.h:38
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1189
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:526
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1153
HWINSTA FASTCALL UserGetProcessWindowStation(VOID)
Definition: winsta.c:1290
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS APIENTRY NtUserBuildNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1874
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
PPEB Peb
Definition: dllmain.c:27
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:35
POBJECT_TYPE ExWindowStationObjectType
Definition: win32k.c:25
BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID)
Definition: winsta.c:260
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
BOOL APIENTRY NtUserLockWorkStation(VOID)
Definition: winsta.c:1909
VOID NTAPI UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
Definition: clipboard.c:339
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ZwCurrentProcess()
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS APIENTRY IntDesktopObjectParse(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
Definition: desktop.c:44
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
#define W32PF_IOWINSTA
Definition: win32.h:23
GDIINFO gdiinfo
Definition: pdevobj.h:124
PPDEVOBJ gppdevPrimary
Definition: pdevobj.c:13
#define TAG_WINSTA
Definition: tags.h:11
UNICODE_STRING gustrWindowStationsDir
Definition: winsta.c:27
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetStockObject(_In_ INT iObject)
HWINSTA APIENTRY NtUserCreateWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
Definition: winsta.c:672
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
#define UOI_USER_SID
Definition: winuser.h:1076
_In_ DWORD nLength
Definition: wincon.h:461
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
HWINSTA APIENTRY NtUserOpenWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess)
Definition: winsta.c:809
UNICODE_STRING Name
Definition: obtypes.h:433
HWND hWnd
Definition: settings.c:17
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define SESSION_DIR
Definition: dllmain.c:38
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD IN DWORD Unknown6
Definition: conport.c:35
HANDLE HWND
Definition: compat.h:13
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define WSS_DYING
Definition: winsta.h:11
#define WINSTA_OBJ_DIR
Definition: winsta.h:3
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:26
BOOL APIENTRY NtUserSetLogonNotifyWindow(HWND hWnd)
Definition: winsta.c:1890
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
KPROCESSOR_MODE AccessMode
Definition: pstypes.h:1603
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
LIST_ENTRY DesktopListHead
Definition: winsta.h:18
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSYSAPI NTSTATUS NTAPI RtlCreateAtomTable(_In_ ULONG TableSize, _Inout_ PRTL_ATOM_TABLE *AtomTable)
#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
Definition: winerror.h:940
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:257
#define WCHAR
Definition: msvc.h:43
#define RASTERCAPS
Definition: wingdi.h:743
#define FASTCALL
Definition: nt_native.h:50
#define MEM_COMMIT
Definition: nt_native.h:1313
DBG_DEFAULT_CHANNEL(UserWinsta)
#define BufferSize
Definition: acefiex.h:377
#define DWORD
Definition: msvc.h:34
struct _DESKTOP * rpdesk
Definition: win32.h:91
PSERVERINFO gpsi
Definition: main.c:27
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
DWORD DWORD
Definition: winlogon.h:84
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
NTSTATUS NTAPI UserAttachMonitor(IN HDEV hDev)
Definition: monitor.c:129
HANDLE hObject
Definition: wglext.h:924
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:52
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
NTSTATUS NTAPI IntWinStaObjectParse(_In_ PVOID Parameters)
Definition: winsta.c:136
UNICODE_STRING StaticUnicodeString
Definition: compat.h:525
NTSTATUS FASTCALL IntCreateWindowStation(OUT HWINSTA *phWinSta, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE OwnerMode, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
Definition: winsta.c:403
#define SM_CXSCREEN
Definition: winuser.h:949
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define DUPLICATE_SAME_ACCESS
ACCESS_MASK GrantedAccess
Definition: iotypes.h:158
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
BOOL FASTCALL co_IntSetWndIcons(VOID)
Definition: callback.c:1090
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
PRTL_UNICODE_STRING_BUFFER PULONG PULONG Unknown4
NTSTATUS NTAPI UserCreateWinstaDirectory(VOID)
Definition: winsta.c:51
BOOL InitCursorImpl(VOID)
Definition: cursoricon.c:64
#define WINSTA_EXECUTE
Definition: winsta.h:61
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define FIXME(fmt,...)
Definition: debug.h:110
DWORD FASTCALL IntGetCharDimensions(HDC hdc, PTEXTMETRICW ptm, PDWORD height)
Definition: font.c:326
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:163
INIT_FUNCTION NTSTATUS NTAPI InitWindowStationImpl(VOID)
Definition: winsta.c:34
NTSTATUS NTAPI IntWinStaObjectDelete(_In_ PVOID Parameters)
Definition: winsta.c:106
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL APIENTRY NtUserSetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength)
Definition: winsta.c:1276
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define WSS_NOIO
Definition: winsta.h:9
#define APIENTRY
Definition: nt_native.h:48
ULONG ulHorzRes
Definition: winddi.h:882
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3748
smooth NULL
Definition: ftsmooth.c:416
#define SYSTEM_FONT
Definition: wingdi.h:909
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:339
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1747
NTSTATUS FASTCALL IntValidateWindowStationHandle(HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
Definition: winsta.c:230
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:484
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
#define LN_LOCK_WORKSTATION
Definition: undocuser.h:116
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:243
HWND hwndSAS
Definition: winsta.c:24
__kernel_entry W32KAPI HFONT APIENTRY NtGdiSelectFont(_In_ HDC hdc, _In_ HFONT hf)
Definition: dcobjs.c:597
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define SM_CYSCREEN
Definition: winuser.h:950
#define WSF_VISIBLE
Definition: winuser.h:2406
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:259
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
LONG NTSTATUS
Definition: precomp.h:26
BOOL APIENTRY NtUserUnlockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1522
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
BOOL FASTCALL CheckWinstaAttributeAccess(ACCESS_MASK DesiredAccess)
Definition: winsta.c:345
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
HDC hSystemBM
Definition: stockobj.c:52
DWORD LowPart
static void Exit(void)
Definition: sock.c:1331
#define UOI_NAME
Definition: winuser.h:1074
BOOL APIENTRY NtUserCloseWindowStation(HWINSTA hWinSta)
Definition: winsta.c:956
DWORD dwSessionId
Definition: winsta.h:16
#define OBJ_INHERIT
Definition: winternl.h:225
#define RC_PALETTE
Definition: wingdi.h:788
#define MAX_PATH
Definition: compat.h:26
VOID NTAPI PsSetProcessWindowStation(PEPROCESS Process, PVOID WindowStation)
Definition: process.c:1314
BOOL APIENTRY co_IntLoadDefaultCursors(VOID)
Definition: callback.c:478
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
struct _WINSTATION_OBJECT * PWINSTATION_OBJECT
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:157
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
BOOL FASTCALL IntCreatePrimarySurface(VOID)
Definition: device.c:29
static IUnknown Object
Definition: main.c:512
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
struct _WINSTATION_OBJECT WINSTATION_OBJECT
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_In_ PUNICODE_STRING Name
Definition: mrx.h:218
VOID FASTCALL IntEndDesktopGraphics(VOID)
Definition: winsta.c:326
int ret
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3370
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1319
ULONG SessionId
Definition: btrfs_drv.h:1805
static const WCHAR L[]
Definition: oid.c:1087
LONG HighPart
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: pstypes.h:1608
BOOL NTAPI NtUserSetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:1932
NTSTATUS NTAPI IntWinStaOkToClose(_In_ PVOID Parameters)
Definition: winsta.c:201
#define WSS_LOCKED
Definition: winsta.h:7
static NTSTATUS FASTCALL BuildWindowStationNameList(ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1559
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
#define WM_LOGONNOTIFY
Definition: undocuser.h:37
#define NOTHING
Definition: env_spec_w32.h:461
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1562
Definition: typedefs.h:117
struct DirEntry DirEntry
Definition: storage32.h:133
PVOID NTAPI PsGetProcessWin32WindowStation(PEPROCESS Process)
Definition: process.c:1203
static __inline NTSTATUS RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1120
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
Status
Definition: gdiplustypes.h:24
int nIndex
Definition: msvc.h:77
#define ERR(fmt,...)
Definition: debug.h:109
#define _In_
Definition: no_sal2.h:204
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
ULONG_PTR SIZE_T
Definition: typedefs.h:78
Definition: compat.h:484
PRTL_ATOM_TABLE AtomTable
Definition: winsta.h:19
DWORD *typedef HANDLE
Definition: winlogon.h:61
_SEH2_END
Definition: create.c:4424
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2926
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define NtCurrentPeb()
Definition: FLS.c:19
HWINSTA hwinsta
Definition: win32.h:258
#define WINSTA_ACCESS_ALL
Definition: winsta.h:65
unsigned short USHORT
Definition: pedump.c:61
#define UOI_TYPE
Definition: winuser.h:1075
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:791
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
HDC FASTCALL IntGdiCreateDC(PUNICODE_STRING Driver, PUNICODE_STRING pustrDevice, PVOID pUMdhpdev, CONST PDEVMODEW pdmInit, BOOL CreateAsIC)
Definition: dclife.c:1032
#define W32PF_READSCREENACCESSGRANTED
Definition: win32.h:8
#define UOI_FLAGS
Definition: winuser.h:1073
BOOL NTAPI GreSetDCOwner(HDC hdc, ULONG ulOwner)
Definition: dclife.c:447
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1183
unsigned int * PULONG
Definition: retypes.h:1
static NTSTATUS BuildUserModeWindowStationName(IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes, IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes, OUT PUNICODE_STRING *WindowStationName, OUT PUNICODE_STRING *TebStaticUnicodeString)
Definition: winsta.c:549
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:279
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
DWORD * PDWORD
Definition: pedump.c:68
BOOL APIENTRY NtUserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1455
#define MAXUSHORT
Definition: typedefs.h:81
HWINSTA APIENTRY NtUserGetProcessWindowStation(VOID)
Definition: winsta.c:1313
#define MEM_RELEASE
Definition: nt_native.h:1316
BOOL APIENTRY NtUserGetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength, PDWORD nLengthNeeded)
Definition: winsta.c:1036
static VOID FreeUserModeWindowStationName(IN OUT PUNICODE_STRING WindowStationName, IN PUNICODE_STRING TebStaticUnicodeString, IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL, IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
Definition: winsta.c:515
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:954
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
PUNICODE_STRING ObjectName
Definition: umtypes.h:185
#define USERTAG_SECURITY
Definition: tags.h:274
struct tagContext Context
Definition: acpixf.h:1027
unsigned int ULONG
Definition: retypes.h:1
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
NTSYSAPI NTSTATUS NTAPI RtlDestroyAtomTable(IN PRTL_ATOM_TABLE AtomTable)
Definition: atom.c:203
#define WINSTA_WRITE
Definition: winsta.h:56
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define LOGPIXELSY
Definition: wingdi.h:717
PVOID psidUser
Definition: winsta.h:41
_Check_return_ _CRTIMP int __cdecl _scwprintf(_In_z_ _Printf_format_string_ const wchar_t *_Format,...)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1209
PUNICODE_STRING RemainingName
Definition: pstypes.h:1606
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
__kernel_entry W32KAPI INT APIENTRY NtGdiGetDeviceCaps(_In_ HDC hdc, _In_ INT i)
HDC ScreenDeviceContext
Definition: desktop.c:36
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
UNICODE_STRING Name
Definition: obtypes.h:383
#define _SEH2_LEAVE
Definition: filesup.c:20
ULONG ulVertRes
Definition: winddi.h:883
POBJECT_TYPE Type
Definition: obtypes.h:493
VOID FASTCALL IntDestroyPrimarySurface(VOID)
Definition: device.c:44
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD Unknown5
Definition: conport.c:35
return STATUS_SUCCESS
Definition: btrfs.c:2710
_Out_ PUNICODE_STRING CompleteName
Definition: pstypes.h:1605
ACCESS_MASK amwinsta
Definition: win32.h:259
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define WINSTA_READSCREEN
Definition: winuser.h:415
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
WCHAR szDesktopName[1]
Definition: ntuser.h:157
ACPI_EFI_GUID ACPI_EFI_OPEN_PROTOCOL_INFORMATION_ENTRY UINTN * EntryCount
Definition: acefiex.h:694
ULONG ACCESS_MASK
Definition: nt_native.h:40
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
HANDLE gpidLogon
Definition: simplecall.c:15
IN SCSI_ADAPTER_CONTROL_TYPE IN PVOID Parameters
Definition: srb.h:488
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1580
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define INIT_FUNCTION
Definition: ntoskrnl.h:11
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PLANES
Definition: wingdi.h:719
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
DWORD dwSize
Definition: wglext.h:734