ReactOS  0.4.12-dev-396-g37af787
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  {
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 
88  NULL,
89  NULL);
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",
118 
119  /* Only Winlogon can close and delete the interactive window station */
121 
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 */
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,
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,
249  AccessMode,
250  (PVOID*)Object,
251  pObjectHandleInfo);
252 
253  if (!NT_SUCCESS(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 
275  {
276  return FALSE;
277  }
278 
280 
283 
284  /* Update the system metrics */
285  InitMetrics();
286 
287  /* Set new size of the monitor */
289 
290  /* Update the SERVERINFO */
295  gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
298  {
299  gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
300  }
301  else
302  {
303  gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
304  }
305  // Font is realized and this dc was previously set to internal DC_ATTR.
306  gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
307  gpsi->tmSysFont = tmw;
308 
309  /* Put the pointer in the center of the screen */
310  gpsi->ptCursor.x = gpsi->aiSysMet[SM_CXSCREEN] / 2;
311  gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2;
312 
313  /* Attach monitor */
315 
316  /* Setup the cursor */
318 
319  /* Setup the icons */
321 
322  /* Setup Menu */
323  MenuInit();
324 
325  /* Show the desktop */
326  pdesk = IntGetActiveDesktop();
327  ASSERT(pdesk);
328  co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE);
329 
330  return TRUE;
331 }
332 
335 {
336  if (NULL != ScreenDeviceContext)
337  { // No need to allocate a new dcattr.
341  }
344 }
345 
348 {
349  return ScreenDeviceContext;
350 }
351 
354 {
356  if ( gpidLogon != PsGetCurrentProcessId() )
357  {
358  if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
359  {
360  ERR("Requires Interactive Window Station\n");
362  return FALSE;
363  }
365  {
366  ERR("Access Denied\n");
368  return FALSE;
369  }
370  }
371  return TRUE;
372 }
373 
374 
375 /* PUBLIC FUNCTIONS ***********************************************************/
376 
377 /*
378  * NtUserCreateWindowStation
379  *
380  * Creates a new window station.
381  *
382  * Parameters
383  * lpszWindowStationName
384  * Pointer to a null-terminated string specifying the name of the
385  * window station to be created. Window station names are
386  * case-insensitive and cannot contain backslash characters (\).
387  * Only members of the Administrators group are allowed to specify a
388  * name.
389  *
390  * dwDesiredAccess
391  * Requested type of access
392  *
393  * lpSecurity
394  * Security descriptor
395  *
396  * Unknown3, Unknown4, Unknown5, Unknown6
397  * Unused
398  *
399  * Return Value
400  * If the function succeeds, the return value is a handle to the newly
401  * created window station. If the specified window station already
402  * exists, the function succeeds and returns a handle to the existing
403  * window station. If the function fails, the return value is NULL.
404  *
405  * Status
406  * @implemented
407  */
408 
409 NTSTATUS
410 FASTCALL
412  OUT HWINSTA* phWinSta,
415  IN KPROCESSOR_MODE OwnerMode,
416  IN ACCESS_MASK dwDesiredAccess,
417  DWORD Unknown2,
418  DWORD Unknown3,
419  DWORD Unknown4,
420  DWORD Unknown5,
421  DWORD Unknown6)
422 {
424  HWINSTA hWinSta;
425  PWINSTATION_OBJECT WindowStation;
426 
427  TRACE("IntCreateWindowStation called\n");
428 
429  ASSERT(phWinSta);
430  *phWinSta = NULL;
431 
434  AccessMode,
435  NULL,
436  dwDesiredAccess,
437  NULL,
438  (PVOID*)&hWinSta);
439  if (NT_SUCCESS(Status))
440  {
441  TRACE("IntCreateWindowStation opened window station '%wZ'\n",
442  ObjectAttributes->ObjectName);
443  *phWinSta = hWinSta;
444  return Status;
445  }
446 
447  /*
448  * No existing window station found, try to create a new one.
449  */
450 
451  /* Create the window station object */
455  OwnerMode,
456  NULL,
457  sizeof(WINSTATION_OBJECT),
458  0,
459  0,
460  (PVOID*)&WindowStation);
461  if (!NT_SUCCESS(Status))
462  {
463  ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
464  ObjectAttributes->ObjectName, Status);
466  return Status;
467  }
468 
469  /* Initialize the window station */
470  RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
471 
472  InitializeListHead(&WindowStation->DesktopListHead);
473  WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
474  Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
475  if (!NT_SUCCESS(Status))
476  {
477  ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
478  ObjectAttributes->ObjectName, Status);
479  ObDereferenceObject(WindowStation);
481  return Status;
482  }
483 
484  Status = ObInsertObject(WindowStation,
485  NULL,
486  dwDesiredAccess,
487  0,
488  NULL,
489  (PVOID*)&hWinSta);
490  if (!NT_SUCCESS(Status))
491  {
492  ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
494  return Status;
495  }
496 
497  // FIXME! TODO: Add this new window station to a linked list
498 
499  if (InputWindowStation == NULL)
500  {
501  ERR("Initializing input window station\n");
502 
503  /* Only Winlogon can create the interactive window station */
505 
506  InputWindowStation = WindowStation;
507  WindowStation->Flags &= ~WSS_NOIO;
508 
509  InitCursorImpl();
510 
513 
514  /* Desktop functions require the desktop thread running so wait for it to initialize */
515  UserLeaveCo();
517  UserRequest,
518  UserMode,
519  FALSE,
520  NULL);
521  UserEnterCo();
522  }
523  else
524  {
525  WindowStation->Flags |= WSS_NOIO;
526  }
527 
528  TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
529  ObjectAttributes->ObjectName, WindowStation, hWinSta);
530 
531  *phWinSta = hWinSta;
533 
534  return STATUS_SUCCESS;
535 }
536 
537 static VOID
539  IN OUT PUNICODE_STRING WindowStationName,
540  IN PUNICODE_STRING TebStaticUnicodeString,
541  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL,
542  IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
543 {
544  SIZE_T MemSize = 0;
545 
546  /* Try to restore the user's UserModeObjectAttributes */
547  if (UserModeObjectAttributes && LocalObjectAttributes)
548  {
549  _SEH2_TRY
550  {
551  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
552  *UserModeObjectAttributes = *LocalObjectAttributes;
553  }
555  {
556  NOTHING;
557  }
558  _SEH2_END;
559  }
560 
561  /* Free the user-mode memory */
562  if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
563  {
564  ZwFreeVirtualMemory(ZwCurrentProcess(),
565  (PVOID*)&WindowStationName,
566  &MemSize,
567  MEM_RELEASE);
568  }
569 }
570 
571 static NTSTATUS
573  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes,
574  IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes,
575  OUT PUNICODE_STRING* WindowStationName,
576  OUT PUNICODE_STRING* TebStaticUnicodeString)
577 {
579  SIZE_T MemSize;
580 
581  LUID CallerLuid;
582  PTEB Teb;
583  USHORT StrSize;
584 
585  *WindowStationName = NULL;
586  *TebStaticUnicodeString = NULL;
587 
588  /* Retrieve the current process LUID */
589  Status = GetProcessLuid(NULL, NULL, &CallerLuid);
590  if (!NT_SUCCESS(Status))
591  {
592  ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
593  return Status;
594  }
595 
596  /* Compute the needed string size */
597  MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
599  CallerLuid.HighPart,
600  CallerLuid.LowPart);
601  MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
602  if (MemSize > MAXUSHORT)
603  {
604  ERR("Window station name length is too long.\n");
605  return STATUS_NAME_TOO_LONG;
606  }
607  StrSize = (USHORT)MemSize;
608 
609  /*
610  * Check whether it's short enough so that we can use the static buffer
611  * in the TEB. Otherwise continue with virtual memory allocation.
612  */
613  Teb = NtCurrentTeb();
614  if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
615  {
616  /* We can use the TEB's static unicode string */
619 
620  /* Remember the TEB's static unicode string address for later */
621  *TebStaticUnicodeString = &Teb->StaticUnicodeString;
622 
623  *WindowStationName = *TebStaticUnicodeString;
624  (*WindowStationName)->Length = 0;
625  }
626  else
627  {
628  /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
629  MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
630 
631  /* Allocate the memory in user-mode */
632  Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
633  (PVOID*)WindowStationName,
634  0,
635  &MemSize,
636  MEM_COMMIT,
638  if (!NT_SUCCESS(Status))
639  {
640  ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
641  return Status;
642  }
643 
644  RtlInitEmptyUnicodeString(*WindowStationName,
645  (PWCHAR)((ULONG_PTR)*WindowStationName +
646  ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
647  StrSize);
648  }
649 
650  /* Build a valid window station name from the LUID */
651  Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
652  (*WindowStationName)->MaximumLength,
653  L"%wZ\\Service-0x%x-%x$",
655  CallerLuid.HighPart,
656  CallerLuid.LowPart);
657  if (!NT_SUCCESS(Status))
658  {
659  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
660  goto Quit;
661  }
662  (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
663 
664  /* Try to update the user's UserModeObjectAttributes */
665  _SEH2_TRY
666  {
667  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
668  *LocalObjectAttributes = *UserModeObjectAttributes;
669 
670  UserModeObjectAttributes->ObjectName = *WindowStationName;
671  UserModeObjectAttributes->RootDirectory = NULL;
672 
674  }
676  {
678  }
679  _SEH2_END;
680 
681 Quit:
682  if (!NT_SUCCESS(Status))
683  {
684  /* Release the window station name */
685  FreeUserModeWindowStationName(*WindowStationName,
686  *TebStaticUnicodeString,
687  NULL, NULL);
688  }
689 
690  return Status;
691 }
692 
693 HWINSTA
694 APIENTRY
697  IN ACCESS_MASK dwDesiredAccess,
698  DWORD Unknown2,
699  DWORD Unknown3,
700  DWORD Unknown4,
701  DWORD Unknown5,
702  DWORD Unknown6)
703 {
705  HWINSTA hWinSta = NULL;
706  OBJECT_ATTRIBUTES LocalObjectAttributes;
707  PUNICODE_STRING WindowStationName = NULL;
708  PUNICODE_STRING TebStaticUnicodeString = NULL;
709  KPROCESSOR_MODE OwnerMode = UserMode;
710 
711  TRACE("NtUserCreateWindowStation called\n");
712 
713  /* Capture the object attributes and the window station name */
714  _SEH2_TRY
715  {
717  LocalObjectAttributes = *ObjectAttributes;
718  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
719  {
720  ERR("Invalid ObjectAttributes length!\n");
722  _SEH2_LEAVE;
723  }
724 
725  /*
726  * Check whether the caller provided a window station name together
727  * with a RootDirectory handle.
728  *
729  * If the caller did not provide a window station name, build a new one
730  * based on the logon session identifier for the calling process.
731  * The new name is allocated in user-mode, as the rest of ObjectAttributes
732  * already is, so that the validation performed by the Object Manager
733  * can be done adequately.
734  */
735  if ((LocalObjectAttributes.ObjectName == NULL ||
736  LocalObjectAttributes.ObjectName->Buffer == NULL ||
737  LocalObjectAttributes.ObjectName->Length == 0 ||
738  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
739  /* &&
740  LocalObjectAttributes.RootDirectory == NULL */)
741  {
742  /* No, build the new window station name */
744  &LocalObjectAttributes,
745  &WindowStationName,
746  &TebStaticUnicodeString);
747  if (!NT_SUCCESS(Status))
748  {
749  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
750  _SEH2_LEAVE;
751  }
752  OwnerMode = KernelMode;
753  }
754  }
756  {
758  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
759  }
760  _SEH2_END;
761 
762  if (!NT_SUCCESS(Status))
763  {
765  return NULL;
766  }
767 
769 
770  /* Create the window station */
771  Status = IntCreateWindowStation(&hWinSta,
773  UserMode,
774  OwnerMode,
775  dwDesiredAccess,
776  Unknown2,
777  Unknown3,
778  Unknown4,
779  Unknown5,
780  Unknown6);
781  UserLeave();
782 
783  if (NT_SUCCESS(Status))
784  {
785  TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
786  ObjectAttributes->ObjectName, hWinSta);
787  }
788  else
789  {
790  ASSERT(hWinSta == NULL);
791  ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
792  ObjectAttributes->ObjectName, Status);
793  }
794 
795  /* Try to restore the user's ObjectAttributes and release the window station name */
796  FreeUserModeWindowStationName(WindowStationName,
797  TebStaticUnicodeString,
798  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
799  &LocalObjectAttributes);
800 
801  if (!NT_SUCCESS(Status))
802  {
803  ASSERT(hWinSta == NULL);
805  }
806 
807  return hWinSta;
808 }
809 
810 /*
811  * NtUserOpenWindowStation
812  *
813  * Opens an existing window station.
814  *
815  * Parameters
816  * lpszWindowStationName
817  * Name of the existing window station.
818  *
819  * dwDesiredAccess
820  * Requested type of access.
821  *
822  * Return Value
823  * If the function succeeds, the return value is the handle to the
824  * specified window station. If the function fails, the return value
825  * is NULL.
826  *
827  * Remarks
828  * The returned handle can be closed with NtUserCloseWindowStation.
829  *
830  * Status
831  * @implemented
832  */
833 
834 HWINSTA
835 APIENTRY
838  IN ACCESS_MASK dwDesiredAccess)
839 {
841  HWINSTA hWinSta = NULL;
842  OBJECT_ATTRIBUTES LocalObjectAttributes;
843  PUNICODE_STRING WindowStationName = NULL;
844  PUNICODE_STRING TebStaticUnicodeString = NULL;
845  KPROCESSOR_MODE OwnerMode = UserMode;
846 
847  TRACE("NtUserOpenWindowStation called\n");
848 
849  /* Capture the object attributes and the window station name */
850  _SEH2_TRY
851  {
853  LocalObjectAttributes = *ObjectAttributes;
854  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
855  {
856  ERR("Invalid ObjectAttributes length!\n");
858  _SEH2_LEAVE;
859  }
860 
861  /*
862  * Check whether the caller did not provide a window station name,
863  * or provided the special "Service-0x00000000-00000000$" name.
864  *
865  * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
866  * is used instead of an empty name (observed when API-monitoring
867  * OpenWindowStation() called with an empty window station name).
868  */
869  if ((LocalObjectAttributes.ObjectName == NULL ||
870  LocalObjectAttributes.ObjectName->Buffer == NULL ||
871  LocalObjectAttributes.ObjectName->Length == 0 ||
872  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
873  /* &&
874  LocalObjectAttributes.RootDirectory == NULL */)
875  {
876  /* No, remember that for later */
877  LocalObjectAttributes.ObjectName = NULL;
878  }
879  if (LocalObjectAttributes.ObjectName &&
880  LocalObjectAttributes.ObjectName->Length ==
881  sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
882  _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
883  L"Service-0x00000000-00000000$",
884  LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
885  {
886  /* No, remember that for later */
887  LocalObjectAttributes.ObjectName = NULL;
888  }
889 
890  /*
891  * If the caller did not provide a window station name, build a new one
892  * based on the logon session identifier for the calling process.
893  * The new name is allocated in user-mode, as the rest of ObjectAttributes
894  * already is, so that the validation performed by the Object Manager
895  * can be done adequately.
896  */
897  if (!LocalObjectAttributes.ObjectName)
898  {
899  /* No, build the new window station name */
901  &LocalObjectAttributes,
902  &WindowStationName,
903  &TebStaticUnicodeString);
904  if (!NT_SUCCESS(Status))
905  {
906  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
907  _SEH2_LEAVE;
908  }
909  OwnerMode = KernelMode;
910  }
911  }
913  {
915  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
916  }
917  _SEH2_END;
918 
919  if (!NT_SUCCESS(Status))
920  {
922  return NULL;
923  }
924 
925  /* Open the window station */
928  UserMode,
929  NULL,
930  dwDesiredAccess,
931  NULL,
932  (PVOID*)&hWinSta);
933  if (NT_SUCCESS(Status))
934  {
935  TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
936  ObjectAttributes->ObjectName, hWinSta);
937  }
938  else
939  {
940  ASSERT(hWinSta == NULL);
941  ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
942  ObjectAttributes->ObjectName, Status);
943  }
944 
945  /* Try to restore the user's ObjectAttributes and release the window station name */
946  FreeUserModeWindowStationName(WindowStationName,
947  TebStaticUnicodeString,
948  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
949  &LocalObjectAttributes);
950 
951  if (!NT_SUCCESS(Status))
952  {
953  ASSERT(hWinSta == NULL);
955  }
956 
957  return hWinSta;
958 }
959 
960 /*
961  * NtUserCloseWindowStation
962  *
963  * Closes a window station handle.
964  *
965  * Parameters
966  * hWinSta
967  * Handle to the window station.
968  *
969  * Return Value
970  * Status
971  *
972  * Remarks
973  * The window station handle can be created with NtUserCreateWindowStation
974  * or NtUserOpenWindowStation. Attempts to close a handle to the window
975  * station assigned to the calling process will fail.
976  *
977  * Status
978  * @implemented
979  */
980 
981 BOOL
982 APIENTRY
984  HWINSTA hWinSta)
985 {
988 
989  TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
990 
991  if (hWinSta == UserGetProcessWindowStation())
992  {
993  ERR("Attempted to close process window station\n");
994  return FALSE;
995  }
996 
998  UserMode,
999  0,
1000  &Object,
1001  NULL);
1002  if (!NT_SUCCESS(Status))
1003  {
1004  ERR("Validation of window station handle (%p) failed\n", hWinSta);
1005  return FALSE;
1006  }
1007 
1009 
1010  TRACE("Closing window station handle (%p)\n", hWinSta);
1011 
1012  Status = ObCloseHandle(hWinSta, UserMode);
1013  if (!NT_SUCCESS(Status))
1014  {
1016  return FALSE;
1017  }
1018 
1019  return TRUE;
1020 }
1021 
1022 /*
1023  * NtUserGetObjectInformation
1024  *
1025  * The NtUserGetObjectInformation function retrieves information about a
1026  * window station or desktop object.
1027  *
1028  * Parameters
1029  * hObj
1030  * Handle to the window station or desktop object for which to
1031  * return information. This can be a handle of type HDESK or HWINSTA
1032  * (for example, a handle returned by NtUserCreateWindowStation,
1033  * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
1034  *
1035  * nIndex
1036  * Specifies the object information to be retrieved.
1037  *
1038  * pvInfo
1039  * Pointer to a buffer to receive the object information.
1040  *
1041  * nLength
1042  * Specifies the size, in bytes, of the buffer pointed to by the
1043  * pvInfo parameter.
1044  *
1045  * lpnLengthNeeded
1046  * Pointer to a variable receiving the number of bytes required to
1047  * store the requested information. If this variable's value is
1048  * greater than the value of the nLength parameter when the function
1049  * returns, the function returns FALSE, and none of the information
1050  * is copied to the pvInfo buffer. If the value of the variable pointed
1051  * to by lpnLengthNeeded is less than or equal to the value of nLength,
1052  * the entire information block is copied.
1053  *
1054  * Return Value
1055  * If the function succeeds, the return value is nonzero. If the function
1056  * fails, the return value is zero.
1057  *
1058  * Status
1059  * @unimplemented
1060  */
1061 
1062 BOOL APIENTRY
1064  HANDLE hObject,
1065  DWORD nIndex,
1066  PVOID pvInformation,
1067  DWORD nLength,
1068  PDWORD nLengthNeeded)
1069 {
1070  NTSTATUS Status;
1071  PWINSTATION_OBJECT WinStaObject = NULL;
1072  PDESKTOP DesktopObject = NULL;
1073  POBJECT_HEADER ObjectHeader;
1074  POBJECT_HEADER_NAME_INFO NameInfo;
1075  OBJECT_HANDLE_INFORMATION HandleInfo;
1076  USEROBJECTFLAGS ObjectFlags;
1077  PUNICODE_STRING pStrNameU = NULL;
1078  PVOID pvData = NULL;
1079  SIZE_T nDataSize = 0;
1080 
1081  _SEH2_TRY
1082  {
1083  if (nLengthNeeded)
1084  ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1085  ProbeForWrite(pvInformation, nLength, 1);
1086  }
1088  {
1090  return FALSE;
1091  }
1092  _SEH2_END;
1093 
1094  /* Try window station */
1095  TRACE("Trying to open window station 0x%p\n", hObject);
1097  0,
1099  UserMode,
1100  (PVOID*)&WinStaObject,
1101  &HandleInfo);
1102 
1104  {
1105  /* Try desktop */
1106  TRACE("Trying to open desktop %p\n", hObject);
1107  WinStaObject = NULL;
1108  Status = IntValidateDesktopHandle(hObject,
1109  UserMode,
1110  0,
1111  &DesktopObject);
1112  }
1113 
1114  if (!NT_SUCCESS(Status))
1115  {
1116  ERR("Failed: 0x%x\n", Status);
1117  goto Exit;
1118  }
1119 
1120  TRACE("WinSta or Desktop opened!\n");
1121 
1122  /* Get data */
1123  switch (nIndex)
1124  {
1125  case UOI_FLAGS:
1126  {
1127  ObjectFlags.fReserved = FALSE;
1128  ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1129 
1130  ObjectFlags.dwFlags = 0;
1131  if (WinStaObject != NULL)
1132  {
1133  if (!(WinStaObject->Flags & WSS_NOIO))
1134  ObjectFlags.dwFlags |= WSF_VISIBLE;
1135  }
1136  else if (DesktopObject != NULL)
1137  {
1138  FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1139  }
1140  else
1141  {
1142  ERR("No associated WinStaObject nor DesktopObject!\n");
1143  }
1144 
1145  pvData = &ObjectFlags;
1146  nDataSize = sizeof(ObjectFlags);
1148  break;
1149  }
1150 
1151  case UOI_NAME:
1152  {
1153  if (WinStaObject != NULL)
1154  {
1155  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1156  NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1157 
1158  if (NameInfo && (NameInfo->Name.Length > 0))
1159  {
1160  /* Named window station */
1161  pStrNameU = &NameInfo->Name;
1162  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1163  }
1164  else
1165  {
1166  /* Unnamed window station (should never happen!) */
1167  ASSERT(FALSE);
1168  pStrNameU = NULL;
1169  nDataSize = sizeof(UNICODE_NULL);
1170  }
1172  }
1173  else if (DesktopObject != NULL)
1174  {
1175  pvData = DesktopObject->pDeskInfo->szDesktopName;
1176  nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1178  }
1179  else
1180  {
1182  }
1183  break;
1184  }
1185 
1186  case UOI_TYPE:
1187  {
1188  if (WinStaObject != NULL)
1189  {
1190  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1191  pStrNameU = &ObjectHeader->Type->Name;
1192  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1194  }
1195  else if (DesktopObject != NULL)
1196  {
1197  ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1198  pStrNameU = &ObjectHeader->Type->Name;
1199  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1201  }
1202  else
1203  {
1205  }
1206  break;
1207  }
1208 
1209  case UOI_USER_SID:
1211  ERR("UOI_USER_SID unimplemented!\n");
1212  break;
1213 
1214  default:
1216  break;
1217  }
1218 
1219 Exit:
1220  if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1222 
1223  _SEH2_TRY
1224  {
1225  if (nLengthNeeded)
1226  *nLengthNeeded = nDataSize;
1227 
1228  /* Try to copy data to caller */
1229  if (Status == STATUS_SUCCESS && (nDataSize > 0))
1230  {
1231  TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1232  if (pvData)
1233  {
1234  /* Copy the data */
1235  RtlCopyMemory(pvInformation, pvData, nDataSize);
1236  }
1237  else if (pStrNameU)
1238  {
1239  /* Copy and NULL-terminate the string */
1240  RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1241  ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1242  }
1243  else
1244  {
1245  /* Zero the memory */
1246  RtlZeroMemory(pvInformation, nDataSize);
1247  }
1248  }
1249  }
1251  {
1253  }
1254  _SEH2_END;
1255 
1256  /* Release objects */
1257  if (DesktopObject != NULL)
1258  ObDereferenceObject(DesktopObject);
1259  if (WinStaObject != NULL)
1260  ObDereferenceObject(WinStaObject);
1261 
1262  if (!NT_SUCCESS(Status))
1263  {
1265  return FALSE;
1266  }
1267 
1268  return TRUE;
1269 }
1270 
1271 /*
1272  * NtUserSetObjectInformation
1273  *
1274  * The NtUserSetObjectInformation function sets information about a
1275  * window station or desktop object.
1276  *
1277  * Parameters
1278  * hObj
1279  * Handle to the window station or desktop object for which to set
1280  * object information. This value can be a handle of type HDESK or
1281  * HWINSTA.
1282  *
1283  * nIndex
1284  * Specifies the object information to be set.
1285  *
1286  * pvInfo
1287  * Pointer to a buffer containing the object information.
1288  *
1289  * nLength
1290  * Specifies the size, in bytes, of the information contained in the
1291  * buffer pointed to by pvInfo.
1292  *
1293  * Return Value
1294  * If the function succeeds, the return value is nonzero. If the function
1295  * fails the return value is zero.
1296  *
1297  * Status
1298  * @unimplemented
1299  */
1300 
1301 BOOL
1302 APIENTRY
1304  HANDLE hObject,
1305  DWORD nIndex,
1306  PVOID pvInformation,
1307  DWORD nLength)
1308 {
1309  /* FIXME: ZwQueryObject */
1310  /* FIXME: ZwSetInformationObject */
1312  return FALSE;
1313 }
1314 
1315 
1316 HWINSTA FASTCALL
1318 {
1320 
1321  return ppi->hwinsta;
1322 }
1323 
1324 
1325 /*
1326  * NtUserGetProcessWindowStation
1327  *
1328  * Returns a handle to the current process window station.
1329  *
1330  * Return Value
1331  * If the function succeeds, the return value is handle to the window
1332  * station assigned to the current process. If the function fails, the
1333  * return value is NULL.
1334  *
1335  * Status
1336  * @implemented
1337  */
1338 
1339 HWINSTA APIENTRY
1341 {
1342  return UserGetProcessWindowStation();
1343 }
1344 
1345 BOOL FASTCALL
1346 UserSetProcessWindowStation(HWINSTA hWindowStation)
1347 {
1348  NTSTATUS Status;
1349  PPROCESSINFO ppi;
1350  OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1351  PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1352  HWINSTA hCacheWinSta;
1353 
1355 
1356  /* Reference the new window station */
1357  if (hWindowStation != NULL)
1358  {
1359  Status = IntValidateWindowStationHandle(hWindowStation,
1360  UserMode,
1361  0,
1362  &NewWinSta,
1363  &ObjectHandleInfo);
1364  if (!NT_SUCCESS(Status))
1365  {
1366  TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1368  return FALSE;
1369  }
1370  }
1371 
1372  OldWinSta = ppi->prpwinsta;
1373  hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1374 
1375  /* Dereference the previous window station */
1376  if (OldWinSta != NULL)
1377  {
1378  ObDereferenceObject(OldWinSta);
1379  }
1380 
1381  /*
1382  * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1383  */
1384 
1385  /* Close the cached EPROCESS window station handle if needed */
1386  if (hCacheWinSta != NULL)
1387  {
1388  /* Reference the window station */
1389  Status = ObReferenceObjectByHandle(hCacheWinSta,
1390  0,
1392  UserMode,
1393  (PVOID*)&OldWinSta,
1394  NULL);
1395  if (!NT_SUCCESS(Status))
1396  {
1397  ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1398  /* We failed, reset the cache */
1399  hCacheWinSta = NULL;
1400  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1401  }
1402  else
1403  {
1404  /*
1405  * Close the old handle and reset the cache only
1406  * if we are setting a different window station.
1407  */
1408  if (NewWinSta != OldWinSta)
1409  {
1410  ObCloseHandle(hCacheWinSta, UserMode);
1411  hCacheWinSta = NULL;
1412  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1413  }
1414 
1415  /* Dereference the window station */
1416  ObDereferenceObject(OldWinSta);
1417  }
1418  }
1419 
1420  /* Duplicate and save a new cached EPROCESS window station handle */
1421  if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1422  {
1423  Status = ZwDuplicateObject(ZwCurrentProcess(),
1424  hWindowStation,
1425  ZwCurrentProcess(),
1426  (PHANDLE)&hCacheWinSta,
1427  0,
1428  0,
1430  if (!NT_SUCCESS(Status))
1431  {
1432  ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1433  }
1434  else
1435  {
1436  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1437  }
1438  }
1439 
1440  ppi->prpwinsta = NewWinSta;
1441  ppi->hwinsta = hWindowStation;
1442  ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1443  TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1444 
1446  {
1447  ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1448  }
1449  else
1450  {
1451  ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1452  }
1453 
1454  if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1455  {
1456  ppi->W32PF_flags |= W32PF_IOWINSTA;
1457  }
1458  else /* Might be closed if the handle is NULL */
1459  {
1460  ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1461  }
1462  return TRUE;
1463 }
1464 
1465 /*
1466  * NtUserSetProcessWindowStation
1467  *
1468  * Assigns a window station to the current process.
1469  *
1470  * Parameters
1471  * hWinSta
1472  * Handle to the window station.
1473  *
1474  * Return Value
1475  * Status
1476  *
1477  * Status
1478  * @implemented
1479  */
1480 
1481 BOOL APIENTRY
1482 NtUserSetProcessWindowStation(HWINSTA hWindowStation)
1483 {
1484  BOOL ret;
1485 
1487 
1488  ret = UserSetProcessWindowStation(hWindowStation);
1489 
1490  UserLeave();
1491 
1492  return ret;
1493 }
1494 
1495 /*
1496  * NtUserLockWindowStation
1497  *
1498  * Locks switching desktops. Only the logon application is allowed to call this function.
1499  *
1500  * Status
1501  * @implemented
1502  */
1503 
1504 BOOL APIENTRY
1505 NtUserLockWindowStation(HWINSTA hWindowStation)
1506 {
1508  NTSTATUS Status;
1509 
1510  TRACE("About to set process window station with handle (%p)\n",
1511  hWindowStation);
1512 
1514  {
1515  ERR("Unauthorized process attempted to lock the window station!\n");
1517  return FALSE;
1518  }
1519 
1520  Status = IntValidateWindowStationHandle(hWindowStation,
1521  UserMode,
1522  0,
1523  &Object,
1524  NULL);
1525  if (!NT_SUCCESS(Status))
1526  {
1527  TRACE("Validation of window station handle (%p) failed\n",
1528  hWindowStation);
1530  return FALSE;
1531  }
1532 
1533  Object->Flags |= WSS_LOCKED;
1534 
1536  return TRUE;
1537 }
1538 
1539 /*
1540  * NtUserUnlockWindowStation
1541  *
1542  * Unlocks switching desktops. Only the logon application is allowed to call this function.
1543  *
1544  * Status
1545  * @implemented
1546  */
1547 
1548 BOOL APIENTRY
1549 NtUserUnlockWindowStation(HWINSTA hWindowStation)
1550 {
1552  NTSTATUS Status;
1553  BOOL Ret;
1554 
1555  TRACE("About to set process window station with handle (%p)\n",
1556  hWindowStation);
1557 
1559  {
1560  ERR("Unauthorized process attempted to unlock the window station!\n");
1562  return FALSE;
1563  }
1564 
1565  Status = IntValidateWindowStationHandle(hWindowStation,
1566  UserMode,
1567  0,
1568  &Object,
1569  NULL);
1570  if (!NT_SUCCESS(Status))
1571  {
1572  TRACE("Validation of window station handle (%p) failed\n",
1573  hWindowStation);
1575  return FALSE;
1576  }
1577 
1578  Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1579  Object->Flags &= ~WSS_LOCKED;
1580 
1582  return Ret;
1583 }
1584 
1585 static NTSTATUS FASTCALL
1587  ULONG dwSize,
1588  PVOID lpBuffer,
1589  PULONG pRequiredSize)
1590 {
1592  NTSTATUS Status;
1594  char InitialBuffer[256], *Buffer;
1596  DWORD EntryCount;
1598  WCHAR NullWchar;
1599 
1600  //
1601  // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1602  // with judicious parameters one can create window stations elsewhere
1603  // than in Windows\WindowStations directory, Win32k definitely MUST
1604  // maintain a list of window stations it has created, and not rely
1605  // on the enumeration of Windows\WindowStations !!!
1606  //
1607 
1608  /*
1609  * Try to open the directory.
1610  */
1614  NULL,
1615  NULL);
1616 
1619  &ObjectAttributes);
1620 
1621  if (!NT_SUCCESS(Status))
1622  {
1623  return Status;
1624  }
1625 
1626  /* First try to query the directory using a fixed-size buffer */
1627  Context = 0;
1628  Buffer = NULL;
1629  Status = ZwQueryDirectoryObject(DirectoryHandle,
1630  InitialBuffer,
1631  sizeof(InitialBuffer),
1632  FALSE,
1633  TRUE,
1634  &Context,
1635  &ReturnLength);
1636  if (NT_SUCCESS(Status))
1637  {
1638  if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1639  FALSE, &Context, NULL))
1640  {
1641  /* Our fixed-size buffer is large enough */
1642  Buffer = InitialBuffer;
1643  }
1644  }
1645 
1646  if (NULL == Buffer)
1647  {
1648  /* Need a larger buffer, check how large exactly */
1649  Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1650  &ReturnLength);
1651  if (!NT_SUCCESS(Status))
1652  {
1653  ERR("ZwQueryDirectoryObject failed\n");
1655  return Status;
1656  }
1657 
1660  if (NULL == Buffer)
1661  {
1663  return STATUS_NO_MEMORY;
1664  }
1665 
1666  /* We should have a sufficiently large buffer now */
1667  Context = 0;
1668  Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1670  if (! NT_SUCCESS(Status) ||
1671  STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1672  FALSE, &Context, NULL))
1673  {
1674  /* Something went wrong, maybe someone added a directory entry? Just give up. */
1678  }
1679  }
1680 
1682 
1683  /*
1684  * Count the required size of buffer.
1685  */
1686  ReturnLength = sizeof(DWORD);
1687  EntryCount = 0;
1689  0 != DirEntry->Name.Length;
1690  DirEntry++)
1691  {
1692  ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1693  EntryCount++;
1694  }
1695  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1696  if (NULL != pRequiredSize)
1697  {
1698  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1699  if (! NT_SUCCESS(Status))
1700  {
1701  if (Buffer != InitialBuffer)
1702  {
1704  }
1705  return STATUS_BUFFER_TOO_SMALL;
1706  }
1707  }
1708 
1709  /*
1710  * Check if the supplied buffer is large enough.
1711  */
1712  if (dwSize < ReturnLength)
1713  {
1714  if (Buffer != InitialBuffer)
1715  {
1717  }
1718  return STATUS_BUFFER_TOO_SMALL;
1719  }
1720 
1721  /*
1722  * Generate the resulting buffer contents.
1723  */
1724  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1725  if (! NT_SUCCESS(Status))
1726  {
1727  if (Buffer != InitialBuffer)
1728  {
1730  }
1731  return Status;
1732  }
1733  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1734 
1735  NullWchar = L'\0';
1737  0 != DirEntry->Name.Length;
1738  DirEntry++)
1739  {
1740  Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
1741  if (! NT_SUCCESS(Status))
1742  {
1743  if (Buffer != InitialBuffer)
1744  {
1746  }
1747  return Status;
1748  }
1749  lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
1750  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1751  if (! NT_SUCCESS(Status))
1752  {
1753  if (Buffer != InitialBuffer)
1754  {
1756  }
1757  return Status;
1758  }
1759  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1760  }
1761 
1762  /*
1763  * Clean up
1764  */
1765  if (Buffer != InitialBuffer)
1766  {
1768  }
1769 
1770  return STATUS_SUCCESS;
1771 }
1772 
1773 static NTSTATUS FASTCALL
1775  HWINSTA hWindowStation,
1776  ULONG dwSize,
1777  PVOID lpBuffer,
1778  PULONG pRequiredSize)
1779 {
1780  NTSTATUS Status;
1781  PWINSTATION_OBJECT WindowStation;
1782  PLIST_ENTRY DesktopEntry;
1783  PDESKTOP DesktopObject;
1784  DWORD EntryCount;
1786  WCHAR NullWchar;
1787  UNICODE_STRING DesktopName;
1788 
1789  Status = IntValidateWindowStationHandle(hWindowStation,
1790  UserMode,
1791  0,
1792  &WindowStation,
1793  NULL);
1794  if (! NT_SUCCESS(Status))
1795  {
1796  return Status;
1797  }
1798 
1799  /*
1800  * Count the required size of buffer.
1801  */
1802  ReturnLength = sizeof(DWORD);
1803  EntryCount = 0;
1804  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1805  DesktopEntry != &WindowStation->DesktopListHead;
1806  DesktopEntry = DesktopEntry->Flink)
1807  {
1808  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1809  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1810  ReturnLength += DesktopName.Length + sizeof(WCHAR);
1811  EntryCount++;
1812  }
1813  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1814  if (NULL != pRequiredSize)
1815  {
1816  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1817  if (! NT_SUCCESS(Status))
1818  {
1819  ObDereferenceObject(WindowStation);
1820  return STATUS_BUFFER_TOO_SMALL;
1821  }
1822  }
1823 
1824  /*
1825  * Check if the supplied buffer is large enough.
1826  */
1827  if (dwSize < ReturnLength)
1828  {
1829  ObDereferenceObject(WindowStation);
1830  return STATUS_BUFFER_TOO_SMALL;
1831  }
1832 
1833  /*
1834  * Generate the resulting buffer contents.
1835  */
1836  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1837  if (! NT_SUCCESS(Status))
1838  {
1839  ObDereferenceObject(WindowStation);
1840  return Status;
1841  }
1842  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1843 
1844  NullWchar = L'\0';
1845  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1846  DesktopEntry != &WindowStation->DesktopListHead;
1847  DesktopEntry = DesktopEntry->Flink)
1848  {
1849  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1850  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1851  Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
1852  if (! NT_SUCCESS(Status))
1853  {
1854  ObDereferenceObject(WindowStation);
1855  return Status;
1856  }
1857  lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
1858  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1859  if (! NT_SUCCESS(Status))
1860  {
1861  ObDereferenceObject(WindowStation);
1862  return Status;
1863  }
1864  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1865  }
1866 
1867  /*
1868  * Clean up and return
1869  */
1870  ObDereferenceObject(WindowStation);
1871  return STATUS_SUCCESS;
1872 }
1873 
1874 /*
1875  * NtUserBuildNameList
1876  *
1877  * Function used for enumeration of desktops or window stations.
1878  *
1879  * Parameters
1880  * hWinSta
1881  * For enumeration of window stations this parameter must be set to
1882  * zero. Otherwise it's handle for window station.
1883  *
1884  * dwSize
1885  * Size of buffer passed by caller.
1886  *
1887  * lpBuffer
1888  * Buffer passed by caller. If the function succeeds, the buffer is
1889  * filled with window station/desktop count (in first DWORD) and
1890  * NULL-terminated window station/desktop names.
1891  *
1892  * pRequiredSize
1893  * If the function succeeds, this is the number of bytes copied.
1894  * Otherwise it's size of buffer needed for function to succeed.
1895  *
1896  * Status
1897  * @implemented
1898  */
1899 
1902  HWINSTA hWindowStation,
1903  ULONG dwSize,
1904  PVOID lpBuffer,
1905  PULONG pRequiredSize)
1906 {
1907  /* The WindowStation name list and desktop name list are build in completely
1908  different ways. Call the appropriate function */
1909  return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
1910  BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
1911 }
1912 
1913 /*
1914  * @implemented
1915  */
1916 BOOL APIENTRY
1918 {
1920  {
1921  return FALSE;
1922  }
1923 
1924  if (!IntIsWindow(hWnd))
1925  {
1926  return FALSE;
1927  }
1928 
1929  hwndSAS = hWnd;
1930 
1931  return TRUE;
1932 }
1933 
1934 BOOL
1935 APIENTRY
1937 {
1938  BOOL ret;
1940 
1942 
1943  if (pti->rpdesk == IntGetActiveDesktop())
1944  {
1946  }
1947  else
1948  {
1949  ret = FALSE;
1950  }
1951 
1952  UserLeave();
1953 
1954  return ret;
1955 }
1956 
1957 BOOL
1958 NTAPI
1960  IN HWINSTA hWindowStation,
1961  IN PLUID pluid,
1962  IN PSID psid OPTIONAL,
1963  IN DWORD size)
1964 {
1965  BOOL Ret = FALSE;
1966  NTSTATUS Status;
1967  PWINSTATION_OBJECT WindowStation = NULL;
1968  LUID luidUser;
1969 
1971 
1973  {
1975  goto Leave;
1976  }
1977 
1978  /* Validate the window station */
1979  Status = IntValidateWindowStationHandle(hWindowStation,
1980  UserMode,
1981  0,
1982  &WindowStation,
1983  NULL);
1984  if (!NT_SUCCESS(Status))
1985  {
1986  goto Leave;
1987  }
1988 
1989  /* Capture the user LUID */
1990  _SEH2_TRY
1991  {
1992  ProbeForRead(pluid, sizeof(LUID), 1);
1993  luidUser = *pluid;
1994  }
1996  {
1998  _SEH2_YIELD(goto Leave);
1999  }
2000  _SEH2_END;
2001 
2002  /* Reset the window station user LUID */
2003  RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
2004 
2005  /* Reset the window station user SID */
2006  if (WindowStation->psidUser)
2007  {
2008  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2009  WindowStation->psidUser = NULL;
2010  }
2011 
2012  /* Copy the new user SID if one has been provided */
2013  if (psid)
2014  {
2016  if (WindowStation->psidUser == NULL)
2017  {
2019  goto Leave;
2020  }
2021 
2023  _SEH2_TRY
2024  {
2025  ProbeForRead(psid, size, 1);
2026  RtlCopyMemory(WindowStation->psidUser, psid, size);
2027  }
2029  {
2031  }
2032  _SEH2_END;
2033 
2034  if (!NT_SUCCESS(Status))
2035  {
2036  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2037  WindowStation->psidUser = NULL;
2038  goto Leave;
2039  }
2040  }
2041 
2042  /* Copy the new user LUID */
2043  WindowStation->luidUser = luidUser;
2044 
2045  Ret = TRUE;
2046 
2047 Leave:
2048  if (WindowStation)
2049  ObDereferenceObject(WindowStation);
2050 
2051  UserLeave();
2052  return Ret;
2053 }
2054 
2055 /* 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
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:363
#define WINSTA_READ
Definition: winsta.h:50
BOOL APIENTRY NtUserLockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1505
#define BITSPIXEL
Definition: wingdi.h:719
#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:1317
#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:1901
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
BOOL UserCreateSystemThread(DWORD Type)
Definition: csr.c:247
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 ERROR_SUCCESS
Definition: deptool.c:10
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
NTSTATUS NTAPI UserUpdateMonitorSize(IN HDEV hDev)
Definition: monitor.c:225
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
BOOL APIENTRY NtUserLockWorkStation(VOID)
Definition: winsta.c:1936
VOID NTAPI UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
Definition: clipboard.c:339
#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)
#define DWORD
Definition: msvc.h:34
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:45
#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:695
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
LONG NTSTATUS
Definition: precomp.h:26
#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:836
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
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:1917
#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:744
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
#define MEM_COMMIT
Definition: nt_native.h:1313
DBG_DEFAULT_CHANNEL(UserWinsta)
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
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
NTSTATUS NTAPI UserAttachMonitor(IN HDEV hDev)
Definition: monitor.c:129
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_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:411
#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 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
#define UserLeaveCo
Definition: ntuser.h:10
_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:329
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:1303
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define WSS_NOIO
Definition: winsta.h:9
ULONG ulHorzRes
Definition: winddi.h:882
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3748
smooth NULL
Definition: ftsmooth.c:416
#define INIT_FUNCTION
Definition: dfs.h:10
#define SYSTEM_FONT
Definition: wingdi.h:910
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:347
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1774
NTSTATUS FASTCALL IntValidateWindowStationHandle(HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
Definition: winsta.c:230
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
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
BOOL APIENTRY NtUserUnlockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1549
_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:353
#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:983
#define OBJ_INHERIT
Definition: winternl.h:225
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:39
#define RC_PALETTE
Definition: wingdi.h:789
BOOL NTAPI InitMetrics(VOID)
Definition: metric.c:19
#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 BufferSize
Definition: classpnp.h:419
unsigned long DWORD
Definition: ntddk_ex.h:95
#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
#define UserEnterCo
Definition: ntuser.h:9
static IUnknown Object
Definition: main.c:512
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
struct _WINSTATION_OBJECT WINSTATION_OBJECT
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID FASTCALL IntEndDesktopGraphics(VOID)
Definition: winsta.c:334
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:1346
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:871
ULONG SessionId
Definition: btrfs_drv.h:1844
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:1959
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:1586
#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:1581
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
#define ST_RIT
Definition: csr.h:35
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
_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:1200
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:572
#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:1482
#define MAXUSHORT
Definition: typedefs.h:81
HWINSTA APIENTRY NtUserGetProcessWindowStation(VOID)
Definition: winsta.c:1340
#define MEM_RELEASE
Definition: nt_native.h:1316
BOOL APIENTRY NtUserGetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength, PDWORD nLengthNeeded)
Definition: winsta.c:1063
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:538
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:954
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
#define ST_DESKTOP_THREAD
Definition: csr.h:36
PUNICODE_STRING ObjectName
Definition: umtypes.h:185
#define USERTAG_SECURITY
Definition: tags.h:274
struct tagContext Context
Definition: acpixf.h:1020
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:718
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:1226
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 BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD Unknown5
Definition: conport.c:35
return STATUS_SUCCESS
Definition: btrfs.c:2725
_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
WCHAR szDesktopName[1]
Definition: ntuser.h:157
ULONG ACCESS_MASK
Definition: nt_native.h:40
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
HANDLE gpidLogon
Definition: simplecall.c:15
#define APIENTRY
Definition: api.h:79
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1599
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PLANES
Definition: wingdi.h:720
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68