ReactOS  0.4.15-dev-4570-g4f8bbd1
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 
31 CODE_SEG("INIT")
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  {
268  ERR("PDEVOBJ_lChangeDisplaySettings() failed.\n");
269  return FALSE;
270  }
271 
273  if (NULL == ScreenDeviceContext)
274  {
276  return FALSE;
277  }
279 
281  {
282  return FALSE;
283  }
284 
286 
289 
290  /* Update the system metrics */
291  InitMetrics();
292 
293  /* Set new size of the monitor */
295 
296  /* Update the SERVERINFO */
301  gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
304  {
305  gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
306  }
307  else
308  {
309  gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
310  }
311  // Font is realized and this dc was previously set to internal DC_ATTR.
312  gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
313  gpsi->tmSysFont = tmw;
314 
315  /* Put the pointer in the center of the screen */
316  gpsi->ptCursor.x = gpsi->aiSysMet[SM_CXSCREEN] / 2;
317  gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2;
318 
319  /* Attach monitor */
321 
322  /* Setup the cursor */
324 
325  /* Setup the icons */
327 
328  /* Setup Menu */
329  MenuInit();
330 
331  /* Show the desktop */
332  pdesk = IntGetActiveDesktop();
333  ASSERT(pdesk);
334  co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE);
335 
336  /* HACK: display wallpaper on all secondary displays */
337  {
338  PGRAPHICS_DEVICE pGraphicsDevice;
339  UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
340  UNICODE_STRING DisplayName;
341  HDC hdc;
342  ULONG iDevNum;
343 
344  for (iDevNum = 1; (pGraphicsDevice = EngpFindGraphicsDevice(NULL, iDevNum)) != NULL; iDevNum++)
345  {
346  RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
347  hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
349  }
350  }
351 
352  return TRUE;
353 }
354 
357 {
358  if (NULL != ScreenDeviceContext)
359  { // No need to allocate a new dcattr.
363  }
366 }
367 
370 {
371  return ScreenDeviceContext;
372 }
373 
376 {
378  if ( gpidLogon != PsGetCurrentProcessId() )
379  {
380  if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
381  {
382  ERR("Requires Interactive Window Station\n");
384  return FALSE;
385  }
387  {
388  ERR("Access Denied\n");
390  return FALSE;
391  }
392  }
393  return TRUE;
394 }
395 
396 
397 /* PUBLIC FUNCTIONS ***********************************************************/
398 
399 /*
400  * NtUserCreateWindowStation
401  *
402  * Creates a new window station.
403  *
404  * Parameters
405  * lpszWindowStationName
406  * Pointer to a null-terminated string specifying the name of the
407  * window station to be created. Window station names are
408  * case-insensitive and cannot contain backslash characters (\).
409  * Only members of the Administrators group are allowed to specify a
410  * name.
411  *
412  * dwDesiredAccess
413  * Requested type of access
414  *
415  * lpSecurity
416  * Security descriptor
417  *
418  * Unknown3, Unknown4, Unknown5, Unknown6
419  * Unused
420  *
421  * Return Value
422  * If the function succeeds, the return value is a handle to the newly
423  * created window station. If the specified window station already
424  * exists, the function succeeds and returns a handle to the existing
425  * window station. If the function fails, the return value is NULL.
426  *
427  * Status
428  * @implemented
429  */
430 
431 NTSTATUS
432 FASTCALL
434  OUT HWINSTA* phWinSta,
437  IN KPROCESSOR_MODE OwnerMode,
438  IN ACCESS_MASK dwDesiredAccess,
439  DWORD Unknown2,
440  DWORD Unknown3,
441  DWORD Unknown4,
442  DWORD Unknown5,
443  DWORD Unknown6)
444 {
446  HWINSTA hWinSta;
447  PWINSTATION_OBJECT WindowStation;
448 
449  TRACE("IntCreateWindowStation called\n");
450 
451  ASSERT(phWinSta);
452  *phWinSta = NULL;
453 
456  AccessMode,
457  NULL,
458  dwDesiredAccess,
459  NULL,
460  (PVOID*)&hWinSta);
461  if (NT_SUCCESS(Status))
462  {
463  TRACE("IntCreateWindowStation opened window station '%wZ'\n",
464  ObjectAttributes->ObjectName);
465  *phWinSta = hWinSta;
466  return Status;
467  }
468 
469  /*
470  * No existing window station found, try to create a new one.
471  */
472 
473  /* Create the window station object */
477  OwnerMode,
478  NULL,
479  sizeof(WINSTATION_OBJECT),
480  0,
481  0,
482  (PVOID*)&WindowStation);
483  if (!NT_SUCCESS(Status))
484  {
485  ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
486  ObjectAttributes->ObjectName, Status);
488  return Status;
489  }
490 
491  /* Initialize the window station */
492  RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
493 
494  InitializeListHead(&WindowStation->DesktopListHead);
495  WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
496  Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
497  if (!NT_SUCCESS(Status))
498  {
499  ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
500  ObjectAttributes->ObjectName, Status);
501  ObDereferenceObject(WindowStation);
503  return Status;
504  }
505 
506  Status = ObInsertObject(WindowStation,
507  NULL,
508  dwDesiredAccess,
509  0,
510  NULL,
511  (PVOID*)&hWinSta);
512  if (!NT_SUCCESS(Status))
513  {
514  ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
516  return Status;
517  }
518 
519  // FIXME! TODO: Add this new window station to a linked list
520 
521  if (InputWindowStation == NULL)
522  {
523  ERR("Initializing input window station\n");
524 
525  /* Only Winlogon can create the interactive window station */
527 
528  InputWindowStation = WindowStation;
529  WindowStation->Flags &= ~WSS_NOIO;
530 
531  InitCursorImpl();
532 
535 
536  /* Desktop functions require the desktop thread running so wait for it to initialize */
537  UserLeaveCo();
539  UserRequest,
540  UserMode,
541  FALSE,
542  NULL);
543  UserEnterCo();
544  }
545  else
546  {
547  WindowStation->Flags |= WSS_NOIO;
548  }
549 
550  TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
551  ObjectAttributes->ObjectName, WindowStation, hWinSta);
552 
553  *phWinSta = hWinSta;
555 
556  return STATUS_SUCCESS;
557 }
558 
559 static VOID
561  IN OUT PUNICODE_STRING WindowStationName,
562  IN PUNICODE_STRING TebStaticUnicodeString,
563  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL,
564  IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
565 {
566  SIZE_T MemSize = 0;
567 
568  /* Try to restore the user's UserModeObjectAttributes */
569  if (UserModeObjectAttributes && LocalObjectAttributes)
570  {
571  _SEH2_TRY
572  {
573  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
574  *UserModeObjectAttributes = *LocalObjectAttributes;
575  }
577  {
578  NOTHING;
579  }
580  _SEH2_END;
581  }
582 
583  /* Free the user-mode memory */
584  if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
585  {
586  ZwFreeVirtualMemory(ZwCurrentProcess(),
587  (PVOID*)&WindowStationName,
588  &MemSize,
589  MEM_RELEASE);
590  }
591 }
592 
593 static NTSTATUS
595  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes,
596  IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes,
597  OUT PUNICODE_STRING* WindowStationName,
598  OUT PUNICODE_STRING* TebStaticUnicodeString)
599 {
601  SIZE_T MemSize;
602 
603  LUID CallerLuid;
604  PTEB Teb;
605  USHORT StrSize;
606 
607  *WindowStationName = NULL;
608  *TebStaticUnicodeString = NULL;
609 
610  /* Retrieve the current process LUID */
611  Status = GetProcessLuid(NULL, NULL, &CallerLuid);
612  if (!NT_SUCCESS(Status))
613  {
614  ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
615  return Status;
616  }
617 
618  /* Compute the needed string size */
619  MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
621  CallerLuid.HighPart,
622  CallerLuid.LowPart);
623  MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
624  if (MemSize > MAXUSHORT)
625  {
626  ERR("Window station name length is too long.\n");
627  return STATUS_NAME_TOO_LONG;
628  }
629  StrSize = (USHORT)MemSize;
630 
631  /*
632  * Check whether it's short enough so that we can use the static buffer
633  * in the TEB. Otherwise continue with virtual memory allocation.
634  */
635  Teb = NtCurrentTeb();
636  if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
637  {
638  /* We can use the TEB's static unicode string */
641 
642  /* Remember the TEB's static unicode string address for later */
643  *TebStaticUnicodeString = &Teb->StaticUnicodeString;
644 
645  *WindowStationName = *TebStaticUnicodeString;
646  (*WindowStationName)->Length = 0;
647  }
648  else
649  {
650  /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
651  MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
652 
653  /* Allocate the memory in user-mode */
654  Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
655  (PVOID*)WindowStationName,
656  0,
657  &MemSize,
658  MEM_COMMIT,
660  if (!NT_SUCCESS(Status))
661  {
662  ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
663  return Status;
664  }
665 
666  RtlInitEmptyUnicodeString(*WindowStationName,
667  (PWCHAR)((ULONG_PTR)*WindowStationName +
668  ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
669  StrSize);
670  }
671 
672  /* Build a valid window station name from the LUID */
673  Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
674  (*WindowStationName)->MaximumLength,
675  L"%wZ\\Service-0x%x-%x$",
677  CallerLuid.HighPart,
678  CallerLuid.LowPart);
679  if (!NT_SUCCESS(Status))
680  {
681  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
682  goto Quit;
683  }
684  (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
685 
686  /* Try to update the user's UserModeObjectAttributes */
687  _SEH2_TRY
688  {
689  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
690  *LocalObjectAttributes = *UserModeObjectAttributes;
691 
692  UserModeObjectAttributes->ObjectName = *WindowStationName;
693  UserModeObjectAttributes->RootDirectory = NULL;
694 
696  }
698  {
700  }
701  _SEH2_END;
702 
703 Quit:
704  if (!NT_SUCCESS(Status))
705  {
706  /* Release the window station name */
707  FreeUserModeWindowStationName(*WindowStationName,
708  *TebStaticUnicodeString,
709  NULL, NULL);
710  }
711 
712  return Status;
713 }
714 
715 HWINSTA
716 APIENTRY
719  IN ACCESS_MASK dwDesiredAccess,
720  DWORD Unknown2,
721  DWORD Unknown3,
722  DWORD Unknown4,
723  DWORD Unknown5,
724  DWORD Unknown6)
725 {
727  HWINSTA hWinSta = NULL;
728  OBJECT_ATTRIBUTES LocalObjectAttributes;
729  PUNICODE_STRING WindowStationName = NULL;
730  PUNICODE_STRING TebStaticUnicodeString = NULL;
731  KPROCESSOR_MODE OwnerMode = UserMode;
732 
733  TRACE("NtUserCreateWindowStation called\n");
734 
735  /* Capture the object attributes and the window station name */
736  _SEH2_TRY
737  {
739  LocalObjectAttributes = *ObjectAttributes;
740  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
741  {
742  ERR("Invalid ObjectAttributes length!\n");
744  _SEH2_LEAVE;
745  }
746 
747  /*
748  * Check whether the caller provided a window station name together
749  * with a RootDirectory handle.
750  *
751  * If the caller did not provide a window station name, build a new one
752  * based on the logon session identifier for the calling process.
753  * The new name is allocated in user-mode, as the rest of ObjectAttributes
754  * already is, so that the validation performed by the Object Manager
755  * can be done adequately.
756  */
757  if ((LocalObjectAttributes.ObjectName == NULL ||
758  LocalObjectAttributes.ObjectName->Buffer == NULL ||
759  LocalObjectAttributes.ObjectName->Length == 0 ||
760  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
761  /* &&
762  LocalObjectAttributes.RootDirectory == NULL */)
763  {
764  /* No, build the new window station name */
766  &LocalObjectAttributes,
767  &WindowStationName,
768  &TebStaticUnicodeString);
769  if (!NT_SUCCESS(Status))
770  {
771  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
772  _SEH2_LEAVE;
773  }
774  OwnerMode = KernelMode;
775  }
776  }
778  {
780  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
781  }
782  _SEH2_END;
783 
784  if (!NT_SUCCESS(Status))
785  {
787  return NULL;
788  }
789 
791 
792  /* Create the window station */
793  Status = IntCreateWindowStation(&hWinSta,
795  UserMode,
796  OwnerMode,
797  dwDesiredAccess,
798  Unknown2,
799  Unknown3,
800  Unknown4,
801  Unknown5,
802  Unknown6);
803  UserLeave();
804 
805  if (NT_SUCCESS(Status))
806  {
807  TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
808  ObjectAttributes->ObjectName, hWinSta);
809  }
810  else
811  {
812  ASSERT(hWinSta == NULL);
813  ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
814  ObjectAttributes->ObjectName, Status);
815  }
816 
817  /* Try to restore the user's ObjectAttributes and release the window station name */
818  FreeUserModeWindowStationName(WindowStationName,
819  TebStaticUnicodeString,
820  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
821  &LocalObjectAttributes);
822 
823  if (!NT_SUCCESS(Status))
824  {
825  ASSERT(hWinSta == NULL);
827  }
828 
829  return hWinSta;
830 }
831 
832 /*
833  * NtUserOpenWindowStation
834  *
835  * Opens an existing window station.
836  *
837  * Parameters
838  * lpszWindowStationName
839  * Name of the existing window station.
840  *
841  * dwDesiredAccess
842  * Requested type of access.
843  *
844  * Return Value
845  * If the function succeeds, the return value is the handle to the
846  * specified window station. If the function fails, the return value
847  * is NULL.
848  *
849  * Remarks
850  * The returned handle can be closed with NtUserCloseWindowStation.
851  *
852  * Status
853  * @implemented
854  */
855 
856 HWINSTA
857 APIENTRY
860  IN ACCESS_MASK dwDesiredAccess)
861 {
863  HWINSTA hWinSta = NULL;
864  OBJECT_ATTRIBUTES LocalObjectAttributes;
865  PUNICODE_STRING WindowStationName = NULL;
866  PUNICODE_STRING TebStaticUnicodeString = NULL;
867  KPROCESSOR_MODE OwnerMode = UserMode;
868 
869  TRACE("NtUserOpenWindowStation called\n");
870 
871  /* Capture the object attributes and the window station name */
872  _SEH2_TRY
873  {
875  LocalObjectAttributes = *ObjectAttributes;
876  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
877  {
878  ERR("Invalid ObjectAttributes length!\n");
880  _SEH2_LEAVE;
881  }
882 
883  /*
884  * Check whether the caller did not provide a window station name,
885  * or provided the special "Service-0x00000000-00000000$" name.
886  *
887  * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
888  * is used instead of an empty name (observed when API-monitoring
889  * OpenWindowStation() called with an empty window station name).
890  */
891  if ((LocalObjectAttributes.ObjectName == NULL ||
892  LocalObjectAttributes.ObjectName->Buffer == NULL ||
893  LocalObjectAttributes.ObjectName->Length == 0 ||
894  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
895  /* &&
896  LocalObjectAttributes.RootDirectory == NULL */)
897  {
898  /* No, remember that for later */
899  LocalObjectAttributes.ObjectName = NULL;
900  }
901  if (LocalObjectAttributes.ObjectName &&
902  LocalObjectAttributes.ObjectName->Length ==
903  sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
904  _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
905  L"Service-0x00000000-00000000$",
906  LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
907  {
908  /* No, remember that for later */
909  LocalObjectAttributes.ObjectName = NULL;
910  }
911 
912  /*
913  * If the caller did not provide a window station name, build a new one
914  * based on the logon session identifier for the calling process.
915  * The new name is allocated in user-mode, as the rest of ObjectAttributes
916  * already is, so that the validation performed by the Object Manager
917  * can be done adequately.
918  */
919  if (!LocalObjectAttributes.ObjectName)
920  {
921  /* No, build the new window station name */
923  &LocalObjectAttributes,
924  &WindowStationName,
925  &TebStaticUnicodeString);
926  if (!NT_SUCCESS(Status))
927  {
928  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
929  _SEH2_LEAVE;
930  }
931  OwnerMode = KernelMode;
932  }
933  }
935  {
937  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
938  }
939  _SEH2_END;
940 
941  if (!NT_SUCCESS(Status))
942  {
944  return NULL;
945  }
946 
947  /* Open the window station */
950  UserMode,
951  NULL,
952  dwDesiredAccess,
953  NULL,
954  (PVOID*)&hWinSta);
955  if (NT_SUCCESS(Status))
956  {
957  TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
958  ObjectAttributes->ObjectName, hWinSta);
959  }
960  else
961  {
962  ASSERT(hWinSta == NULL);
963  ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
964  ObjectAttributes->ObjectName, Status);
965  }
966 
967  /* Try to restore the user's ObjectAttributes and release the window station name */
968  FreeUserModeWindowStationName(WindowStationName,
969  TebStaticUnicodeString,
970  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
971  &LocalObjectAttributes);
972 
973  if (!NT_SUCCESS(Status))
974  {
975  ASSERT(hWinSta == NULL);
977  }
978 
979  return hWinSta;
980 }
981 
982 /*
983  * NtUserCloseWindowStation
984  *
985  * Closes a window station handle.
986  *
987  * Parameters
988  * hWinSta
989  * Handle to the window station.
990  *
991  * Return Value
992  * Status
993  *
994  * Remarks
995  * The window station handle can be created with NtUserCreateWindowStation
996  * or NtUserOpenWindowStation. Attempts to close a handle to the window
997  * station assigned to the calling process will fail.
998  *
999  * Status
1000  * @implemented
1001  */
1002 
1003 BOOL
1004 APIENTRY
1006  HWINSTA hWinSta)
1007 {
1009  NTSTATUS Status;
1010 
1011  TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
1012 
1013  if (hWinSta == UserGetProcessWindowStation())
1014  {
1015  ERR("Attempted to close process window station\n");
1016  return FALSE;
1017  }
1018 
1020  UserMode,
1021  0,
1022  &Object,
1023  NULL);
1024  if (!NT_SUCCESS(Status))
1025  {
1026  ERR("Validation of window station handle (%p) failed\n", hWinSta);
1027  return FALSE;
1028  }
1029 
1031 
1032  TRACE("Closing window station handle (%p)\n", hWinSta);
1033 
1034  Status = ObCloseHandle(hWinSta, UserMode);
1035  if (!NT_SUCCESS(Status))
1036  {
1038  return FALSE;
1039  }
1040 
1041  return TRUE;
1042 }
1043 
1044 /*
1045  * NtUserGetObjectInformation
1046  *
1047  * The NtUserGetObjectInformation function retrieves information about a
1048  * window station or desktop object.
1049  *
1050  * Parameters
1051  * hObj
1052  * Handle to the window station or desktop object for which to
1053  * return information. This can be a handle of type HDESK or HWINSTA
1054  * (for example, a handle returned by NtUserCreateWindowStation,
1055  * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
1056  *
1057  * nIndex
1058  * Specifies the object information to be retrieved.
1059  *
1060  * pvInfo
1061  * Pointer to a buffer to receive the object information.
1062  *
1063  * nLength
1064  * Specifies the size, in bytes, of the buffer pointed to by the
1065  * pvInfo parameter.
1066  *
1067  * lpnLengthNeeded
1068  * Pointer to a variable receiving the number of bytes required to
1069  * store the requested information. If this variable's value is
1070  * greater than the value of the nLength parameter when the function
1071  * returns, the function returns FALSE, and none of the information
1072  * is copied to the pvInfo buffer. If the value of the variable pointed
1073  * to by lpnLengthNeeded is less than or equal to the value of nLength,
1074  * the entire information block is copied.
1075  *
1076  * Return Value
1077  * If the function succeeds, the return value is nonzero. If the function
1078  * fails, the return value is zero.
1079  *
1080  * Status
1081  * @unimplemented
1082  */
1083 
1084 BOOL APIENTRY
1086  HANDLE hObject,
1087  DWORD nIndex,
1088  PVOID pvInformation,
1089  DWORD nLength,
1090  PDWORD nLengthNeeded)
1091 {
1092  NTSTATUS Status;
1093  PWINSTATION_OBJECT WinStaObject = NULL;
1094  PDESKTOP DesktopObject = NULL;
1095  POBJECT_HEADER ObjectHeader;
1096  POBJECT_HEADER_NAME_INFO NameInfo;
1097  OBJECT_HANDLE_INFORMATION HandleInfo;
1098  USEROBJECTFLAGS ObjectFlags;
1099  PUNICODE_STRING pStrNameU = NULL;
1100  PVOID pvData = NULL;
1101  SIZE_T nDataSize = 0;
1102 
1103  _SEH2_TRY
1104  {
1105  if (nLengthNeeded)
1106  ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1107  ProbeForWrite(pvInformation, nLength, 1);
1108  }
1110  {
1112  return FALSE;
1113  }
1114  _SEH2_END;
1115 
1116  /* Try window station */
1117  TRACE("Trying to open window station 0x%p\n", hObject);
1119  0,
1121  UserMode,
1122  (PVOID*)&WinStaObject,
1123  &HandleInfo);
1124 
1126  {
1127  /* Try desktop */
1128  TRACE("Trying to open desktop %p\n", hObject);
1129  WinStaObject = NULL;
1130  Status = IntValidateDesktopHandle(hObject,
1131  UserMode,
1132  0,
1133  &DesktopObject);
1134  }
1135 
1136  if (!NT_SUCCESS(Status))
1137  {
1138  ERR("Failed: 0x%x\n", Status);
1139  goto Exit;
1140  }
1141 
1142  TRACE("WinSta or Desktop opened!\n");
1143 
1144  /* Get data */
1145  switch (nIndex)
1146  {
1147  case UOI_FLAGS:
1148  {
1149  ObjectFlags.fReserved = FALSE;
1150  ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1151 
1152  ObjectFlags.dwFlags = 0;
1153  if (WinStaObject != NULL)
1154  {
1155  if (!(WinStaObject->Flags & WSS_NOIO))
1156  ObjectFlags.dwFlags |= WSF_VISIBLE;
1157  }
1158  else if (DesktopObject != NULL)
1159  {
1160  FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1161  }
1162  else
1163  {
1164  ERR("No associated WinStaObject nor DesktopObject!\n");
1165  }
1166 
1167  pvData = &ObjectFlags;
1168  nDataSize = sizeof(ObjectFlags);
1170  break;
1171  }
1172 
1173  case UOI_NAME:
1174  {
1175  if (WinStaObject != NULL)
1176  {
1177  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1178  NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1179 
1180  if (NameInfo && (NameInfo->Name.Length > 0))
1181  {
1182  /* Named window station */
1183  pStrNameU = &NameInfo->Name;
1184  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1185  }
1186  else
1187  {
1188  /* Unnamed window station (should never happen!) */
1189  ASSERT(FALSE);
1190  pStrNameU = NULL;
1191  nDataSize = sizeof(UNICODE_NULL);
1192  }
1194  }
1195  else if (DesktopObject != NULL)
1196  {
1197  pvData = DesktopObject->pDeskInfo->szDesktopName;
1198  nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1200  }
1201  else
1202  {
1204  }
1205  break;
1206  }
1207 
1208  case UOI_TYPE:
1209  {
1210  if (WinStaObject != NULL)
1211  {
1212  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1213  pStrNameU = &ObjectHeader->Type->Name;
1214  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1216  }
1217  else if (DesktopObject != NULL)
1218  {
1219  ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1220  pStrNameU = &ObjectHeader->Type->Name;
1221  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1223  }
1224  else
1225  {
1227  }
1228  break;
1229  }
1230 
1231  case UOI_USER_SID:
1233  ERR("UOI_USER_SID unimplemented!\n");
1234  break;
1235 
1236  default:
1238  break;
1239  }
1240 
1241 Exit:
1242  if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1244 
1245  _SEH2_TRY
1246  {
1247  if (nLengthNeeded)
1248  *nLengthNeeded = nDataSize;
1249 
1250  /* Try to copy data to caller */
1251  if (Status == STATUS_SUCCESS && (nDataSize > 0))
1252  {
1253  TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1254  if (pvData)
1255  {
1256  /* Copy the data */
1257  RtlCopyMemory(pvInformation, pvData, nDataSize);
1258  }
1259  else if (pStrNameU)
1260  {
1261  /* Copy and NULL-terminate the string */
1262  RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1263  ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1264  }
1265  else
1266  {
1267  /* Zero the memory */
1268  RtlZeroMemory(pvInformation, nDataSize);
1269  }
1270  }
1271  }
1273  {
1275  }
1276  _SEH2_END;
1277 
1278  /* Release objects */
1279  if (DesktopObject != NULL)
1280  ObDereferenceObject(DesktopObject);
1281  if (WinStaObject != NULL)
1282  ObDereferenceObject(WinStaObject);
1283 
1284  if (!NT_SUCCESS(Status))
1285  {
1287  return FALSE;
1288  }
1289 
1290  return TRUE;
1291 }
1292 
1293 /*
1294  * NtUserSetObjectInformation
1295  *
1296  * The NtUserSetObjectInformation function sets information about a
1297  * window station or desktop object.
1298  *
1299  * Parameters
1300  * hObj
1301  * Handle to the window station or desktop object for which to set
1302  * object information. This value can be a handle of type HDESK or
1303  * HWINSTA.
1304  *
1305  * nIndex
1306  * Specifies the object information to be set.
1307  *
1308  * pvInfo
1309  * Pointer to a buffer containing the object information.
1310  *
1311  * nLength
1312  * Specifies the size, in bytes, of the information contained in the
1313  * buffer pointed to by pvInfo.
1314  *
1315  * Return Value
1316  * If the function succeeds, the return value is nonzero. If the function
1317  * fails the return value is zero.
1318  *
1319  * Status
1320  * @unimplemented
1321  */
1322 
1323 BOOL
1324 APIENTRY
1326  HANDLE hObject,
1327  DWORD nIndex,
1328  PVOID pvInformation,
1329  DWORD nLength)
1330 {
1331  /* FIXME: ZwQueryObject */
1332  /* FIXME: ZwSetInformationObject */
1334  return FALSE;
1335 }
1336 
1337 
1338 HWINSTA FASTCALL
1340 {
1342 
1343  return ppi->hwinsta;
1344 }
1345 
1346 
1347 /*
1348  * NtUserGetProcessWindowStation
1349  *
1350  * Returns a handle to the current process window station.
1351  *
1352  * Return Value
1353  * If the function succeeds, the return value is handle to the window
1354  * station assigned to the current process. If the function fails, the
1355  * return value is NULL.
1356  *
1357  * Status
1358  * @implemented
1359  */
1360 
1361 HWINSTA APIENTRY
1363 {
1364  return UserGetProcessWindowStation();
1365 }
1366 
1367 BOOL FASTCALL
1368 UserSetProcessWindowStation(HWINSTA hWindowStation)
1369 {
1370  NTSTATUS Status;
1371  PPROCESSINFO ppi;
1372  OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1373  PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1374  HWINSTA hCacheWinSta;
1375 
1377 
1378  /* Reference the new window station */
1379  if (hWindowStation != NULL)
1380  {
1381  Status = IntValidateWindowStationHandle(hWindowStation,
1382  UserMode,
1383  0,
1384  &NewWinSta,
1385  &ObjectHandleInfo);
1386  if (!NT_SUCCESS(Status))
1387  {
1388  TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1390  return FALSE;
1391  }
1392  }
1393 
1394  OldWinSta = ppi->prpwinsta;
1395  hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1396 
1397  /* Dereference the previous window station */
1398  if (OldWinSta != NULL)
1399  {
1400  ObDereferenceObject(OldWinSta);
1401  }
1402 
1403  /*
1404  * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1405  */
1406 
1407  /* Close the cached EPROCESS window station handle if needed */
1408  if (hCacheWinSta != NULL)
1409  {
1410  /* Reference the window station */
1411  Status = ObReferenceObjectByHandle(hCacheWinSta,
1412  0,
1414  UserMode,
1415  (PVOID*)&OldWinSta,
1416  NULL);
1417  if (!NT_SUCCESS(Status))
1418  {
1419  ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1420  /* We failed, reset the cache */
1421  hCacheWinSta = NULL;
1422  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1423  }
1424  else
1425  {
1426  /*
1427  * Close the old handle and reset the cache only
1428  * if we are setting a different window station.
1429  */
1430  if (NewWinSta != OldWinSta)
1431  {
1432  ObCloseHandle(hCacheWinSta, UserMode);
1433  hCacheWinSta = NULL;
1434  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1435  }
1436 
1437  /* Dereference the window station */
1438  ObDereferenceObject(OldWinSta);
1439  }
1440  }
1441 
1442  /* Duplicate and save a new cached EPROCESS window station handle */
1443  if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1444  {
1445  Status = ZwDuplicateObject(ZwCurrentProcess(),
1446  hWindowStation,
1447  ZwCurrentProcess(),
1448  (PHANDLE)&hCacheWinSta,
1449  0,
1450  0,
1452  if (!NT_SUCCESS(Status))
1453  {
1454  ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1455  }
1456  else
1457  {
1458  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1459  }
1460  }
1461 
1462  ppi->prpwinsta = NewWinSta;
1463  ppi->hwinsta = hWindowStation;
1464  ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1465  TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1466 
1468  {
1469  ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1470  }
1471  else
1472  {
1473  ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1474  }
1475 
1476  if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1477  {
1478  ppi->W32PF_flags |= W32PF_IOWINSTA;
1479  }
1480  else /* Might be closed if the handle is NULL */
1481  {
1482  ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1483  }
1484  return TRUE;
1485 }
1486 
1487 /*
1488  * NtUserSetProcessWindowStation
1489  *
1490  * Assigns a window station to the current process.
1491  *
1492  * Parameters
1493  * hWinSta
1494  * Handle to the window station.
1495  *
1496  * Return Value
1497  * Status
1498  *
1499  * Status
1500  * @implemented
1501  */
1502 
1503 BOOL APIENTRY
1504 NtUserSetProcessWindowStation(HWINSTA hWindowStation)
1505 {
1506  BOOL ret;
1507 
1509 
1510  ret = UserSetProcessWindowStation(hWindowStation);
1511 
1512  UserLeave();
1513 
1514  return ret;
1515 }
1516 
1517 /*
1518  * NtUserLockWindowStation
1519  *
1520  * Locks switching desktops. Only the logon application is allowed to call this function.
1521  *
1522  * Status
1523  * @implemented
1524  */
1525 
1526 BOOL APIENTRY
1527 NtUserLockWindowStation(HWINSTA hWindowStation)
1528 {
1530  NTSTATUS Status;
1531 
1532  TRACE("About to set process window station with handle (%p)\n",
1533  hWindowStation);
1534 
1536  {
1537  ERR("Unauthorized process attempted to lock the window station!\n");
1539  return FALSE;
1540  }
1541 
1542  Status = IntValidateWindowStationHandle(hWindowStation,
1543  UserMode,
1544  0,
1545  &Object,
1546  NULL);
1547  if (!NT_SUCCESS(Status))
1548  {
1549  TRACE("Validation of window station handle (%p) failed\n",
1550  hWindowStation);
1552  return FALSE;
1553  }
1554 
1555  Object->Flags |= WSS_LOCKED;
1556 
1558  return TRUE;
1559 }
1560 
1561 /*
1562  * NtUserUnlockWindowStation
1563  *
1564  * Unlocks switching desktops. Only the logon application is allowed to call this function.
1565  *
1566  * Status
1567  * @implemented
1568  */
1569 
1570 BOOL APIENTRY
1571 NtUserUnlockWindowStation(HWINSTA hWindowStation)
1572 {
1574  NTSTATUS Status;
1575  BOOL Ret;
1576 
1577  TRACE("About to set process window station with handle (%p)\n",
1578  hWindowStation);
1579 
1581  {
1582  ERR("Unauthorized process attempted to unlock the window station!\n");
1584  return FALSE;
1585  }
1586 
1587  Status = IntValidateWindowStationHandle(hWindowStation,
1588  UserMode,
1589  0,
1590  &Object,
1591  NULL);
1592  if (!NT_SUCCESS(Status))
1593  {
1594  TRACE("Validation of window station handle (%p) failed\n",
1595  hWindowStation);
1597  return FALSE;
1598  }
1599 
1600  Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1601  Object->Flags &= ~WSS_LOCKED;
1602 
1604  return Ret;
1605 }
1606 
1607 static NTSTATUS FASTCALL
1609  ULONG dwSize,
1610  PVOID lpBuffer,
1611  PULONG pRequiredSize)
1612 {
1614  NTSTATUS Status;
1616  char InitialBuffer[256], *Buffer;
1618  DWORD EntryCount;
1620  WCHAR NullWchar;
1621 
1622  //
1623  // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1624  // with judicious parameters one can create window stations elsewhere
1625  // than in Windows\WindowStations directory, Win32k definitely MUST
1626  // maintain a list of window stations it has created, and not rely
1627  // on the enumeration of Windows\WindowStations !!!
1628  //
1629 
1630  /*
1631  * Try to open the directory.
1632  */
1636  NULL,
1637  NULL);
1638 
1641  &ObjectAttributes);
1642 
1643  if (!NT_SUCCESS(Status))
1644  {
1645  return Status;
1646  }
1647 
1648  /* First try to query the directory using a fixed-size buffer */
1649  Context = 0;
1650  Buffer = NULL;
1651  Status = ZwQueryDirectoryObject(DirectoryHandle,
1652  InitialBuffer,
1653  sizeof(InitialBuffer),
1654  FALSE,
1655  TRUE,
1656  &Context,
1657  &ReturnLength);
1658  if (NT_SUCCESS(Status))
1659  {
1660  if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1661  FALSE, &Context, NULL))
1662  {
1663  /* Our fixed-size buffer is large enough */
1664  Buffer = InitialBuffer;
1665  }
1666  }
1667 
1668  if (NULL == Buffer)
1669  {
1670  /* Need a larger buffer, check how large exactly */
1671  Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1672  &ReturnLength);
1673  if (!NT_SUCCESS(Status))
1674  {
1675  ERR("ZwQueryDirectoryObject failed\n");
1677  return Status;
1678  }
1679 
1682  if (NULL == Buffer)
1683  {
1685  return STATUS_NO_MEMORY;
1686  }
1687 
1688  /* We should have a sufficiently large buffer now */
1689  Context = 0;
1690  Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1692  if (! NT_SUCCESS(Status) ||
1693  STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1694  FALSE, &Context, NULL))
1695  {
1696  /* Something went wrong, maybe someone added a directory entry? Just give up. */
1700  }
1701  }
1702 
1704 
1705  /*
1706  * Count the required size of buffer.
1707  */
1708  ReturnLength = sizeof(DWORD);
1709  EntryCount = 0;
1711  0 != DirEntry->Name.Length;
1712  DirEntry++)
1713  {
1714  ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1715  EntryCount++;
1716  }
1717  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1718  if (NULL != pRequiredSize)
1719  {
1720  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1721  if (! NT_SUCCESS(Status))
1722  {
1723  if (Buffer != InitialBuffer)
1724  {
1726  }
1727  return STATUS_BUFFER_TOO_SMALL;
1728  }
1729  }
1730 
1731  /*
1732  * Check if the supplied buffer is large enough.
1733  */
1734  if (dwSize < ReturnLength)
1735  {
1736  if (Buffer != InitialBuffer)
1737  {
1739  }
1740  return STATUS_BUFFER_TOO_SMALL;
1741  }
1742 
1743  /*
1744  * Generate the resulting buffer contents.
1745  */
1746  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1747  if (! NT_SUCCESS(Status))
1748  {
1749  if (Buffer != InitialBuffer)
1750  {
1752  }
1753  return Status;
1754  }
1755  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1756 
1757  NullWchar = L'\0';
1759  0 != DirEntry->Name.Length;
1760  DirEntry++)
1761  {
1762  Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
1763  if (! NT_SUCCESS(Status))
1764  {
1765  if (Buffer != InitialBuffer)
1766  {
1768  }
1769  return Status;
1770  }
1771  lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
1772  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1773  if (! NT_SUCCESS(Status))
1774  {
1775  if (Buffer != InitialBuffer)
1776  {
1778  }
1779  return Status;
1780  }
1781  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1782  }
1783 
1784  /*
1785  * Clean up
1786  */
1787  if (Buffer != InitialBuffer)
1788  {
1790  }
1791 
1792  return STATUS_SUCCESS;
1793 }
1794 
1795 static NTSTATUS FASTCALL
1797  HWINSTA hWindowStation,
1798  ULONG dwSize,
1799  PVOID lpBuffer,
1800  PULONG pRequiredSize)
1801 {
1802  NTSTATUS Status;
1803  PWINSTATION_OBJECT WindowStation;
1804  PLIST_ENTRY DesktopEntry;
1805  PDESKTOP DesktopObject;
1806  DWORD EntryCount;
1808  WCHAR NullWchar;
1809  UNICODE_STRING DesktopName;
1810 
1811  Status = IntValidateWindowStationHandle(hWindowStation,
1812  UserMode,
1813  0,
1814  &WindowStation,
1815  NULL);
1816  if (! NT_SUCCESS(Status))
1817  {
1818  return Status;
1819  }
1820 
1821  /*
1822  * Count the required size of buffer.
1823  */
1824  ReturnLength = sizeof(DWORD);
1825  EntryCount = 0;
1826  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1827  DesktopEntry != &WindowStation->DesktopListHead;
1828  DesktopEntry = DesktopEntry->Flink)
1829  {
1830  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1831  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1832  ReturnLength += DesktopName.Length + sizeof(WCHAR);
1833  EntryCount++;
1834  }
1835  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1836  if (NULL != pRequiredSize)
1837  {
1838  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1839  if (! NT_SUCCESS(Status))
1840  {
1841  ObDereferenceObject(WindowStation);
1842  return STATUS_BUFFER_TOO_SMALL;
1843  }
1844  }
1845 
1846  /*
1847  * Check if the supplied buffer is large enough.
1848  */
1849  if (dwSize < ReturnLength)
1850  {
1851  ObDereferenceObject(WindowStation);
1852  return STATUS_BUFFER_TOO_SMALL;
1853  }
1854 
1855  /*
1856  * Generate the resulting buffer contents.
1857  */
1858  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1859  if (! NT_SUCCESS(Status))
1860  {
1861  ObDereferenceObject(WindowStation);
1862  return Status;
1863  }
1864  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1865 
1866  NullWchar = L'\0';
1867  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1868  DesktopEntry != &WindowStation->DesktopListHead;
1869  DesktopEntry = DesktopEntry->Flink)
1870  {
1871  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1872  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1873  Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
1874  if (! NT_SUCCESS(Status))
1875  {
1876  ObDereferenceObject(WindowStation);
1877  return Status;
1878  }
1879  lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
1880  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1881  if (! NT_SUCCESS(Status))
1882  {
1883  ObDereferenceObject(WindowStation);
1884  return Status;
1885  }
1886  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1887  }
1888 
1889  /*
1890  * Clean up and return
1891  */
1892  ObDereferenceObject(WindowStation);
1893  return STATUS_SUCCESS;
1894 }
1895 
1896 /*
1897  * NtUserBuildNameList
1898  *
1899  * Function used for enumeration of desktops or window stations.
1900  *
1901  * Parameters
1902  * hWinSta
1903  * For enumeration of window stations this parameter must be set to
1904  * zero. Otherwise it's handle for window station.
1905  *
1906  * dwSize
1907  * Size of buffer passed by caller.
1908  *
1909  * lpBuffer
1910  * Buffer passed by caller. If the function succeeds, the buffer is
1911  * filled with window station/desktop count (in first DWORD) and
1912  * NULL-terminated window station/desktop names.
1913  *
1914  * pRequiredSize
1915  * If the function succeeds, this is the number of bytes copied.
1916  * Otherwise it's size of buffer needed for function to succeed.
1917  *
1918  * Status
1919  * @implemented
1920  */
1921 
1924  HWINSTA hWindowStation,
1925  ULONG dwSize,
1926  PVOID lpBuffer,
1927  PULONG pRequiredSize)
1928 {
1929  /* The WindowStation name list and desktop name list are build in completely
1930  different ways. Call the appropriate function */
1931  return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
1932  BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
1933 }
1934 
1935 /*
1936  * @implemented
1937  */
1938 BOOL APIENTRY
1940 {
1942  {
1943  return FALSE;
1944  }
1945 
1946  if (!IntIsWindow(hWnd))
1947  {
1948  return FALSE;
1949  }
1950 
1951  hwndSAS = hWnd;
1952 
1953  return TRUE;
1954 }
1955 
1956 BOOL
1957 APIENTRY
1959 {
1960  BOOL ret;
1962 
1964 
1965  if (pti->rpdesk == IntGetActiveDesktop())
1966  {
1968  }
1969  else
1970  {
1971  ret = FALSE;
1972  }
1973 
1974  UserLeave();
1975 
1976  return ret;
1977 }
1978 
1979 BOOL
1980 NTAPI
1982  IN HWINSTA hWindowStation,
1983  IN PLUID pluid,
1984  IN PSID psid OPTIONAL,
1985  IN DWORD size)
1986 {
1987  BOOL Ret = FALSE;
1988  NTSTATUS Status;
1989  PWINSTATION_OBJECT WindowStation = NULL;
1990  LUID luidUser;
1991 
1993 
1995  {
1997  goto Leave;
1998  }
1999 
2000  /* Validate the window station */
2001  Status = IntValidateWindowStationHandle(hWindowStation,
2002  UserMode,
2003  0,
2004  &WindowStation,
2005  NULL);
2006  if (!NT_SUCCESS(Status))
2007  {
2008  goto Leave;
2009  }
2010 
2011  /* Capture the user LUID */
2012  _SEH2_TRY
2013  {
2014  ProbeForRead(pluid, sizeof(LUID), 1);
2015  luidUser = *pluid;
2016  }
2018  {
2020  _SEH2_YIELD(goto Leave);
2021  }
2022  _SEH2_END;
2023 
2024  /* Reset the window station user LUID */
2025  RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
2026 
2027  /* Reset the window station user SID */
2028  if (WindowStation->psidUser)
2029  {
2030  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2031  WindowStation->psidUser = NULL;
2032  }
2033 
2034  /* Copy the new user SID if one has been provided */
2035  if (psid)
2036  {
2038  if (WindowStation->psidUser == NULL)
2039  {
2041  goto Leave;
2042  }
2043 
2045  _SEH2_TRY
2046  {
2047  ProbeForRead(psid, size, 1);
2048  RtlCopyMemory(WindowStation->psidUser, psid, size);
2049  }
2051  {
2053  }
2054  _SEH2_END;
2055 
2056  if (!NT_SUCCESS(Status))
2057  {
2058  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2059  WindowStation->psidUser = NULL;
2060  goto Leave;
2061  }
2062  }
2063 
2064  /* Copy the new user LUID */
2065  WindowStation->luidUser = luidUser;
2066 
2067  Ret = TRUE;
2068 
2069 Leave:
2070  if (WindowStation)
2071  ObDereferenceObject(WindowStation);
2072 
2073  UserLeave();
2074  return Ret;
2075 }
2076 
2077 /* 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:2531
signed char * PCHAR
Definition: retypes.h:7
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define WINSTA_WRITE
Definition: security.h:48
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
BOOL MenuInit(VOID)
Definition: menu.c:359
BOOL APIENTRY NtUserLockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1527
#define BITSPIXEL
Definition: wingdi.h:720
#define IN
Definition: typedefs.h:39
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1346
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2654
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:736
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
HWINSTA FASTCALL UserGetProcessWindowStation(VOID)
Definition: winsta.c:1339
NTSTATUS APIENTRY NtUserBuildNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1923
#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:21
BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID)
Definition: winsta.c:260
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define ERROR_SUCCESS
Definition: deptool.c:10
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
NTSTATUS NTAPI UserUpdateMonitorSize(IN HDEV hDev)
Definition: monitor.c:225
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
BOOL APIENTRY NtUserLockWorkStation(VOID)
Definition: winsta.c:1958
VOID NTAPI UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
Definition: clipboard.c:354
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
WCHAR szWinDeviceName[CCHDEVICENAME/2]
Definition: pdevobj.h:60
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define ZwCurrentProcess()
#define WINSTA_EXECUTE
Definition: security.h:53
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:45
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
#define W32PF_IOWINSTA
Definition: win32.h:23
GDIINFO gdiinfo
Definition: pdevobj.h:123
#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:717
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
LONG NTSTATUS
Definition: precomp.h:26
#define UOI_USER_SID
Definition: winuser.h:1080
static HDC
Definition: imagelist.c:92
_In_ DWORD nLength
Definition: wincon.h:473
PSERVERINFO gpsi
Definition: imm.c:17
_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:858
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:22
BOOL APIENTRY NtUserSetLogonNotifyWindow(HWND hWnd)
Definition: winsta.c:1939
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
KPROCESSOR_MODE AccessMode
Definition: pstypes.h:1672
LIST_ENTRY DesktopListHead
Definition: winsta.h:18
uint16_t * PWCHAR
Definition: typedefs.h:56
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:262
#define RASTERCAPS
Definition: wingdi.h:745
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
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
DBG_DEFAULT_CHANNEL(UserWinsta)
struct _DESKTOP * rpdesk
Definition: win32.h:93
#define DWORD
Definition: nt_native.h:44
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
NTSTATUS NTAPI UserAttachMonitor(IN HDEV hDev)
Definition: monitor.c:129
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
NTSTATUS NTAPI IntWinStaObjectParse(_In_ PVOID Parameters)
Definition: winsta.c:136
UNICODE_STRING StaticUnicodeString
Definition: compat.h:735
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:433
return STATUS_NOT_IMPLEMENTED
#define SM_CXSCREEN
Definition: winuser.h:953
#define L(x)
Definition: ntvdm.h:50
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:494
#define DUPLICATE_SAME_ACCESS
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
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:97
BOOL FASTCALL co_IntSetWndIcons(VOID)
Definition: callback.c:1101
unsigned int BOOL
Definition: ntddk_ex.h:94
#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 UserLeaveCo
Definition: ntuser.h:10
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#define FIXME(fmt,...)
Definition: debug.h:111
#define WINSTA_READ
Definition: security.h:42
DWORD FASTCALL IntGetCharDimensions(HDC hdc, PTEXTMETRICW ptm, PDWORD height)
Definition: font.c:329
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
NTSTATUS NTAPI IntWinStaObjectDelete(_In_ PVOID Parameters)
Definition: winsta.c:106
BOOL APIENTRY NtUserSetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength)
Definition: winsta.c:1325
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
#define _In_
Definition: ms_sal.h:308
#define SYSTEM_FONT
Definition: wingdi.h:911
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:369
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1830
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1796
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:498
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:951
#define LN_LOCK_WORKSTATION
Definition: undocuser.h:117
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
Status
Definition: gdiplustypes.h:24
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:121
#define SM_CYSCREEN
Definition: winuser.h:954
#define WSF_VISIBLE
Definition: winuser.h:2432
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
BOOL APIENTRY NtUserUnlockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1571
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define ASSERT(a)
Definition: mode.c:44
BOOL FASTCALL CheckWinstaAttributeAccess(ACCESS_MASK DesiredAccess)
Definition: winsta.c:375
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HDC hSystemBM
Definition: stockobj.c:52
DWORD LowPart
NTSTRSAFEVAPI 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:1173
#define OBJ_INHERIT
Definition: winternl.h:225
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static void Exit(void)
Definition: sock.c:1331
#define UOI_NAME
Definition: winuser.h:1078
BOOL APIENTRY NtUserCloseWindowStation(HWINSTA hWinSta)
Definition: winsta.c:1005
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:39
#define RC_PALETTE
Definition: wingdi.h:790
BOOL NTAPI InitMetrics(VOID)
Definition: metric.c:33
#define MAX_PATH
Definition: compat.h:34
#define ObDereferenceObject
Definition: obfuncs.h:203
#define DISP_CHANGE_SUCCESSFUL
Definition: winuser.h:190
VOID NTAPI PsSetProcessWindowStation(PEPROCESS Process, PVOID WindowStation)
Definition: process.c:1314
BOOL APIENTRY co_IntLoadDefaultCursors(VOID)
Definition: callback.c:471
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:180
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
BOOL FASTCALL IntCreatePrimarySurface(VOID)
Definition: device.c:29
#define UserEnterCo
Definition: ntuser.h:9
struct _WINSTATION_OBJECT WINSTATION_OBJECT
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS NTAPI InitWindowStationImpl(VOID)
Definition: winsta.c:34
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID FASTCALL IntEndDesktopGraphics(VOID)
Definition: winsta.c:356
int ret
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3378
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:1368
ULONG SessionId
Definition: btrfs_drv.h:1909
LONG HighPart
HDC hdc
Definition: main.c:9
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: pstypes.h:1677
PGRAPHICS_DEVICE NTAPI EngpFindGraphicsDevice(_In_opt_ PUNICODE_STRING pustrDevice, _In_ ULONG iDevNum)
Definition: device.c:338
BOOL NTAPI NtUserSetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:1981
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:1608
#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:1620
Definition: typedefs.h:119
struct DirEntry DirEntry
Definition: storage32.h:133
PVOID NTAPI PsGetProcessWin32WindowStation(PEPROCESS Process)
Definition: process.c:1203
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
#define ST_RIT
Definition: csr.h:35
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:37
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
ULONG_PTR SIZE_T
Definition: typedefs.h:80
Definition: compat.h:694
PRTL_ATOM_TABLE AtomTable
Definition: winsta.h:19
_SEH2_END
Definition: create.c:4400
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:2934
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define WINSTA_ACCESS_ALL
Definition: security.h:57
#define NtCurrentPeb()
Definition: FLS.c:22
HWINSTA hwinsta
Definition: win32.h:263
unsigned short USHORT
Definition: pedump.c:61
#define UOI_TYPE
Definition: winuser.h:1079
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:809
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PPDEVOBJ ppdevGlobal
Definition: mdevobj.h:16
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
HDC FASTCALL IntGdiCreateDC(PUNICODE_STRING Driver, PUNICODE_STRING pustrDevice, PVOID pUMdhpdev, CONST PDEVMODEW pdmInit, BOOL CreateAsIC)
Definition: dclife.c:1040
#define W32PF_READSCREENACCESSGRANTED
Definition: win32.h:8
#define UOI_FLAGS
Definition: winuser.h:1077
PMDEVOBJ gpmdev
Definition: mdevobj.c:14
BOOL NTAPI GreSetDCOwner(HDC hdc, ULONG ulOwner)
Definition: dclife.c:455
#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:1240
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:594
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define NULL
Definition: types.h:112
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
DWORD * PDWORD
Definition: pedump.c:68
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
BOOL APIENTRY NtUserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1504
#define MAXUSHORT
Definition: typedefs.h:83
HWINSTA APIENTRY NtUserGetProcessWindowStation(VOID)
Definition: winsta.c:1362
#define MEM_RELEASE
Definition: nt_native.h:1316
BOOL APIENTRY NtUserGetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength, PDWORD nLengthNeeded)
Definition: winsta.c:1085
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:560
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:972
struct tagContext Context
Definition: acpixf.h:1034
#define OUT
Definition: typedefs.h:40
#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:275
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
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define LOGPIXELSY
Definition: wingdi.h:719
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
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:40
#define STATUS_SUCCESS
Definition: shellext.h:65
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1265
PUNICODE_STRING RemainingName
Definition: pstypes.h:1675
__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:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
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
LONG PDEVOBJ_lChangeDisplaySettings(_In_opt_ PUNICODE_STRING pustrDeviceName, _In_opt_ PDEVMODEW RequestedMode, _In_opt_ PMDEVOBJ pmdevOld, _Out_ PMDEVOBJ *ppmdevNew, _In_ BOOL bSearchClosestMode)
Definition: pdevobj.c:776
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD Unknown5
Definition: conport.c:35
_Out_ PUNICODE_STRING CompleteName
Definition: pstypes.h:1674
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
ACCESS_MASK amwinsta
Definition: win32.h:264
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
#define WINSTA_READSCREEN
Definition: winuser.h:415
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
WCHAR szDesktopName[1]
Definition: ntuser.h:154
ULONG ACCESS_MASK
Definition: nt_native.h:40
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
HANDLE gpidLogon
Definition: simplecall.c:15
#define APIENTRY
Definition: api.h:79
#define BufferSize
Definition: mmc.h:75
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1638
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PLANES
Definition: wingdi.h:721
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:801
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68