ReactOS  0.4.15-dev-2947-g59e1b78
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  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  /* HACK: display wallpaper on all secondary displays */
331  {
332  PGRAPHICS_DEVICE pGraphicsDevice;
333  UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
334  UNICODE_STRING DisplayName;
335  HDC hdc;
336  ULONG iDevNum;
337 
338  for (iDevNum = 1; (pGraphicsDevice = EngpFindGraphicsDevice(NULL, iDevNum, 0)) != NULL; iDevNum++)
339  {
340  RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
341  hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
343  }
344  }
345 
346  return TRUE;
347 }
348 
351 {
352  if (NULL != ScreenDeviceContext)
353  { // No need to allocate a new dcattr.
357  }
360 }
361 
364 {
365  return ScreenDeviceContext;
366 }
367 
370 {
372  if ( gpidLogon != PsGetCurrentProcessId() )
373  {
374  if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
375  {
376  ERR("Requires Interactive Window Station\n");
378  return FALSE;
379  }
381  {
382  ERR("Access Denied\n");
384  return FALSE;
385  }
386  }
387  return TRUE;
388 }
389 
390 
391 /* PUBLIC FUNCTIONS ***********************************************************/
392 
393 /*
394  * NtUserCreateWindowStation
395  *
396  * Creates a new window station.
397  *
398  * Parameters
399  * lpszWindowStationName
400  * Pointer to a null-terminated string specifying the name of the
401  * window station to be created. Window station names are
402  * case-insensitive and cannot contain backslash characters (\).
403  * Only members of the Administrators group are allowed to specify a
404  * name.
405  *
406  * dwDesiredAccess
407  * Requested type of access
408  *
409  * lpSecurity
410  * Security descriptor
411  *
412  * Unknown3, Unknown4, Unknown5, Unknown6
413  * Unused
414  *
415  * Return Value
416  * If the function succeeds, the return value is a handle to the newly
417  * created window station. If the specified window station already
418  * exists, the function succeeds and returns a handle to the existing
419  * window station. If the function fails, the return value is NULL.
420  *
421  * Status
422  * @implemented
423  */
424 
425 NTSTATUS
426 FASTCALL
428  OUT HWINSTA* phWinSta,
431  IN KPROCESSOR_MODE OwnerMode,
432  IN ACCESS_MASK dwDesiredAccess,
433  DWORD Unknown2,
434  DWORD Unknown3,
435  DWORD Unknown4,
436  DWORD Unknown5,
437  DWORD Unknown6)
438 {
440  HWINSTA hWinSta;
441  PWINSTATION_OBJECT WindowStation;
442 
443  TRACE("IntCreateWindowStation called\n");
444 
445  ASSERT(phWinSta);
446  *phWinSta = NULL;
447 
450  AccessMode,
451  NULL,
452  dwDesiredAccess,
453  NULL,
454  (PVOID*)&hWinSta);
455  if (NT_SUCCESS(Status))
456  {
457  TRACE("IntCreateWindowStation opened window station '%wZ'\n",
458  ObjectAttributes->ObjectName);
459  *phWinSta = hWinSta;
460  return Status;
461  }
462 
463  /*
464  * No existing window station found, try to create a new one.
465  */
466 
467  /* Create the window station object */
471  OwnerMode,
472  NULL,
473  sizeof(WINSTATION_OBJECT),
474  0,
475  0,
476  (PVOID*)&WindowStation);
477  if (!NT_SUCCESS(Status))
478  {
479  ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
480  ObjectAttributes->ObjectName, Status);
482  return Status;
483  }
484 
485  /* Initialize the window station */
486  RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
487 
488  InitializeListHead(&WindowStation->DesktopListHead);
489  WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
490  Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
491  if (!NT_SUCCESS(Status))
492  {
493  ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
494  ObjectAttributes->ObjectName, Status);
495  ObDereferenceObject(WindowStation);
497  return Status;
498  }
499 
500  Status = ObInsertObject(WindowStation,
501  NULL,
502  dwDesiredAccess,
503  0,
504  NULL,
505  (PVOID*)&hWinSta);
506  if (!NT_SUCCESS(Status))
507  {
508  ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
510  return Status;
511  }
512 
513  // FIXME! TODO: Add this new window station to a linked list
514 
515  if (InputWindowStation == NULL)
516  {
517  ERR("Initializing input window station\n");
518 
519  /* Only Winlogon can create the interactive window station */
521 
522  InputWindowStation = WindowStation;
523  WindowStation->Flags &= ~WSS_NOIO;
524 
525  InitCursorImpl();
526 
529 
530  /* Desktop functions require the desktop thread running so wait for it to initialize */
531  UserLeaveCo();
533  UserRequest,
534  UserMode,
535  FALSE,
536  NULL);
537  UserEnterCo();
538  }
539  else
540  {
541  WindowStation->Flags |= WSS_NOIO;
542  }
543 
544  TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
545  ObjectAttributes->ObjectName, WindowStation, hWinSta);
546 
547  *phWinSta = hWinSta;
549 
550  return STATUS_SUCCESS;
551 }
552 
553 static VOID
555  IN OUT PUNICODE_STRING WindowStationName,
556  IN PUNICODE_STRING TebStaticUnicodeString,
557  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL,
558  IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
559 {
560  SIZE_T MemSize = 0;
561 
562  /* Try to restore the user's UserModeObjectAttributes */
563  if (UserModeObjectAttributes && LocalObjectAttributes)
564  {
565  _SEH2_TRY
566  {
567  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
568  *UserModeObjectAttributes = *LocalObjectAttributes;
569  }
571  {
572  NOTHING;
573  }
574  _SEH2_END;
575  }
576 
577  /* Free the user-mode memory */
578  if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
579  {
580  ZwFreeVirtualMemory(ZwCurrentProcess(),
581  (PVOID*)&WindowStationName,
582  &MemSize,
583  MEM_RELEASE);
584  }
585 }
586 
587 static NTSTATUS
589  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes,
590  IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes,
591  OUT PUNICODE_STRING* WindowStationName,
592  OUT PUNICODE_STRING* TebStaticUnicodeString)
593 {
595  SIZE_T MemSize;
596 
597  LUID CallerLuid;
598  PTEB Teb;
599  USHORT StrSize;
600 
601  *WindowStationName = NULL;
602  *TebStaticUnicodeString = NULL;
603 
604  /* Retrieve the current process LUID */
605  Status = GetProcessLuid(NULL, NULL, &CallerLuid);
606  if (!NT_SUCCESS(Status))
607  {
608  ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
609  return Status;
610  }
611 
612  /* Compute the needed string size */
613  MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
615  CallerLuid.HighPart,
616  CallerLuid.LowPart);
617  MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
618  if (MemSize > MAXUSHORT)
619  {
620  ERR("Window station name length is too long.\n");
621  return STATUS_NAME_TOO_LONG;
622  }
623  StrSize = (USHORT)MemSize;
624 
625  /*
626  * Check whether it's short enough so that we can use the static buffer
627  * in the TEB. Otherwise continue with virtual memory allocation.
628  */
629  Teb = NtCurrentTeb();
630  if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
631  {
632  /* We can use the TEB's static unicode string */
635 
636  /* Remember the TEB's static unicode string address for later */
637  *TebStaticUnicodeString = &Teb->StaticUnicodeString;
638 
639  *WindowStationName = *TebStaticUnicodeString;
640  (*WindowStationName)->Length = 0;
641  }
642  else
643  {
644  /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
645  MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
646 
647  /* Allocate the memory in user-mode */
648  Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
649  (PVOID*)WindowStationName,
650  0,
651  &MemSize,
652  MEM_COMMIT,
654  if (!NT_SUCCESS(Status))
655  {
656  ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
657  return Status;
658  }
659 
660  RtlInitEmptyUnicodeString(*WindowStationName,
661  (PWCHAR)((ULONG_PTR)*WindowStationName +
662  ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
663  StrSize);
664  }
665 
666  /* Build a valid window station name from the LUID */
667  Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
668  (*WindowStationName)->MaximumLength,
669  L"%wZ\\Service-0x%x-%x$",
671  CallerLuid.HighPart,
672  CallerLuid.LowPart);
673  if (!NT_SUCCESS(Status))
674  {
675  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
676  goto Quit;
677  }
678  (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
679 
680  /* Try to update the user's UserModeObjectAttributes */
681  _SEH2_TRY
682  {
683  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
684  *LocalObjectAttributes = *UserModeObjectAttributes;
685 
686  UserModeObjectAttributes->ObjectName = *WindowStationName;
687  UserModeObjectAttributes->RootDirectory = NULL;
688 
690  }
692  {
694  }
695  _SEH2_END;
696 
697 Quit:
698  if (!NT_SUCCESS(Status))
699  {
700  /* Release the window station name */
701  FreeUserModeWindowStationName(*WindowStationName,
702  *TebStaticUnicodeString,
703  NULL, NULL);
704  }
705 
706  return Status;
707 }
708 
709 HWINSTA
710 APIENTRY
713  IN ACCESS_MASK dwDesiredAccess,
714  DWORD Unknown2,
715  DWORD Unknown3,
716  DWORD Unknown4,
717  DWORD Unknown5,
718  DWORD Unknown6)
719 {
721  HWINSTA hWinSta = NULL;
722  OBJECT_ATTRIBUTES LocalObjectAttributes;
723  PUNICODE_STRING WindowStationName = NULL;
724  PUNICODE_STRING TebStaticUnicodeString = NULL;
725  KPROCESSOR_MODE OwnerMode = UserMode;
726 
727  TRACE("NtUserCreateWindowStation called\n");
728 
729  /* Capture the object attributes and the window station name */
730  _SEH2_TRY
731  {
733  LocalObjectAttributes = *ObjectAttributes;
734  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
735  {
736  ERR("Invalid ObjectAttributes length!\n");
738  _SEH2_LEAVE;
739  }
740 
741  /*
742  * Check whether the caller provided a window station name together
743  * with a RootDirectory handle.
744  *
745  * If the caller did not provide a window station name, build a new one
746  * based on the logon session identifier for the calling process.
747  * The new name is allocated in user-mode, as the rest of ObjectAttributes
748  * already is, so that the validation performed by the Object Manager
749  * can be done adequately.
750  */
751  if ((LocalObjectAttributes.ObjectName == NULL ||
752  LocalObjectAttributes.ObjectName->Buffer == NULL ||
753  LocalObjectAttributes.ObjectName->Length == 0 ||
754  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
755  /* &&
756  LocalObjectAttributes.RootDirectory == NULL */)
757  {
758  /* No, build the new window station name */
760  &LocalObjectAttributes,
761  &WindowStationName,
762  &TebStaticUnicodeString);
763  if (!NT_SUCCESS(Status))
764  {
765  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
766  _SEH2_LEAVE;
767  }
768  OwnerMode = KernelMode;
769  }
770  }
772  {
774  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
775  }
776  _SEH2_END;
777 
778  if (!NT_SUCCESS(Status))
779  {
781  return NULL;
782  }
783 
785 
786  /* Create the window station */
787  Status = IntCreateWindowStation(&hWinSta,
789  UserMode,
790  OwnerMode,
791  dwDesiredAccess,
792  Unknown2,
793  Unknown3,
794  Unknown4,
795  Unknown5,
796  Unknown6);
797  UserLeave();
798 
799  if (NT_SUCCESS(Status))
800  {
801  TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
802  ObjectAttributes->ObjectName, hWinSta);
803  }
804  else
805  {
806  ASSERT(hWinSta == NULL);
807  ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
808  ObjectAttributes->ObjectName, Status);
809  }
810 
811  /* Try to restore the user's ObjectAttributes and release the window station name */
812  FreeUserModeWindowStationName(WindowStationName,
813  TebStaticUnicodeString,
814  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
815  &LocalObjectAttributes);
816 
817  if (!NT_SUCCESS(Status))
818  {
819  ASSERT(hWinSta == NULL);
821  }
822 
823  return hWinSta;
824 }
825 
826 /*
827  * NtUserOpenWindowStation
828  *
829  * Opens an existing window station.
830  *
831  * Parameters
832  * lpszWindowStationName
833  * Name of the existing window station.
834  *
835  * dwDesiredAccess
836  * Requested type of access.
837  *
838  * Return Value
839  * If the function succeeds, the return value is the handle to the
840  * specified window station. If the function fails, the return value
841  * is NULL.
842  *
843  * Remarks
844  * The returned handle can be closed with NtUserCloseWindowStation.
845  *
846  * Status
847  * @implemented
848  */
849 
850 HWINSTA
851 APIENTRY
854  IN ACCESS_MASK dwDesiredAccess)
855 {
857  HWINSTA hWinSta = NULL;
858  OBJECT_ATTRIBUTES LocalObjectAttributes;
859  PUNICODE_STRING WindowStationName = NULL;
860  PUNICODE_STRING TebStaticUnicodeString = NULL;
861  KPROCESSOR_MODE OwnerMode = UserMode;
862 
863  TRACE("NtUserOpenWindowStation called\n");
864 
865  /* Capture the object attributes and the window station name */
866  _SEH2_TRY
867  {
869  LocalObjectAttributes = *ObjectAttributes;
870  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
871  {
872  ERR("Invalid ObjectAttributes length!\n");
874  _SEH2_LEAVE;
875  }
876 
877  /*
878  * Check whether the caller did not provide a window station name,
879  * or provided the special "Service-0x00000000-00000000$" name.
880  *
881  * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
882  * is used instead of an empty name (observed when API-monitoring
883  * OpenWindowStation() called with an empty window station name).
884  */
885  if ((LocalObjectAttributes.ObjectName == NULL ||
886  LocalObjectAttributes.ObjectName->Buffer == NULL ||
887  LocalObjectAttributes.ObjectName->Length == 0 ||
888  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
889  /* &&
890  LocalObjectAttributes.RootDirectory == NULL */)
891  {
892  /* No, remember that for later */
893  LocalObjectAttributes.ObjectName = NULL;
894  }
895  if (LocalObjectAttributes.ObjectName &&
896  LocalObjectAttributes.ObjectName->Length ==
897  sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
898  _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
899  L"Service-0x00000000-00000000$",
900  LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
901  {
902  /* No, remember that for later */
903  LocalObjectAttributes.ObjectName = NULL;
904  }
905 
906  /*
907  * If the caller did not provide a window station name, build a new one
908  * based on the logon session identifier for the calling process.
909  * The new name is allocated in user-mode, as the rest of ObjectAttributes
910  * already is, so that the validation performed by the Object Manager
911  * can be done adequately.
912  */
913  if (!LocalObjectAttributes.ObjectName)
914  {
915  /* No, build the new window station name */
917  &LocalObjectAttributes,
918  &WindowStationName,
919  &TebStaticUnicodeString);
920  if (!NT_SUCCESS(Status))
921  {
922  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
923  _SEH2_LEAVE;
924  }
925  OwnerMode = KernelMode;
926  }
927  }
929  {
931  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
932  }
933  _SEH2_END;
934 
935  if (!NT_SUCCESS(Status))
936  {
938  return NULL;
939  }
940 
941  /* Open the window station */
944  UserMode,
945  NULL,
946  dwDesiredAccess,
947  NULL,
948  (PVOID*)&hWinSta);
949  if (NT_SUCCESS(Status))
950  {
951  TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
952  ObjectAttributes->ObjectName, hWinSta);
953  }
954  else
955  {
956  ASSERT(hWinSta == NULL);
957  ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
958  ObjectAttributes->ObjectName, Status);
959  }
960 
961  /* Try to restore the user's ObjectAttributes and release the window station name */
962  FreeUserModeWindowStationName(WindowStationName,
963  TebStaticUnicodeString,
964  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
965  &LocalObjectAttributes);
966 
967  if (!NT_SUCCESS(Status))
968  {
969  ASSERT(hWinSta == NULL);
971  }
972 
973  return hWinSta;
974 }
975 
976 /*
977  * NtUserCloseWindowStation
978  *
979  * Closes a window station handle.
980  *
981  * Parameters
982  * hWinSta
983  * Handle to the window station.
984  *
985  * Return Value
986  * Status
987  *
988  * Remarks
989  * The window station handle can be created with NtUserCreateWindowStation
990  * or NtUserOpenWindowStation. Attempts to close a handle to the window
991  * station assigned to the calling process will fail.
992  *
993  * Status
994  * @implemented
995  */
996 
997 BOOL
998 APIENTRY
1000  HWINSTA hWinSta)
1001 {
1003  NTSTATUS Status;
1004 
1005  TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
1006 
1007  if (hWinSta == UserGetProcessWindowStation())
1008  {
1009  ERR("Attempted to close process window station\n");
1010  return FALSE;
1011  }
1012 
1014  UserMode,
1015  0,
1016  &Object,
1017  NULL);
1018  if (!NT_SUCCESS(Status))
1019  {
1020  ERR("Validation of window station handle (%p) failed\n", hWinSta);
1021  return FALSE;
1022  }
1023 
1025 
1026  TRACE("Closing window station handle (%p)\n", hWinSta);
1027 
1028  Status = ObCloseHandle(hWinSta, UserMode);
1029  if (!NT_SUCCESS(Status))
1030  {
1032  return FALSE;
1033  }
1034 
1035  return TRUE;
1036 }
1037 
1038 /*
1039  * NtUserGetObjectInformation
1040  *
1041  * The NtUserGetObjectInformation function retrieves information about a
1042  * window station or desktop object.
1043  *
1044  * Parameters
1045  * hObj
1046  * Handle to the window station or desktop object for which to
1047  * return information. This can be a handle of type HDESK or HWINSTA
1048  * (for example, a handle returned by NtUserCreateWindowStation,
1049  * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
1050  *
1051  * nIndex
1052  * Specifies the object information to be retrieved.
1053  *
1054  * pvInfo
1055  * Pointer to a buffer to receive the object information.
1056  *
1057  * nLength
1058  * Specifies the size, in bytes, of the buffer pointed to by the
1059  * pvInfo parameter.
1060  *
1061  * lpnLengthNeeded
1062  * Pointer to a variable receiving the number of bytes required to
1063  * store the requested information. If this variable's value is
1064  * greater than the value of the nLength parameter when the function
1065  * returns, the function returns FALSE, and none of the information
1066  * is copied to the pvInfo buffer. If the value of the variable pointed
1067  * to by lpnLengthNeeded is less than or equal to the value of nLength,
1068  * the entire information block is copied.
1069  *
1070  * Return Value
1071  * If the function succeeds, the return value is nonzero. If the function
1072  * fails, the return value is zero.
1073  *
1074  * Status
1075  * @unimplemented
1076  */
1077 
1078 BOOL APIENTRY
1080  HANDLE hObject,
1081  DWORD nIndex,
1082  PVOID pvInformation,
1083  DWORD nLength,
1084  PDWORD nLengthNeeded)
1085 {
1086  NTSTATUS Status;
1087  PWINSTATION_OBJECT WinStaObject = NULL;
1088  PDESKTOP DesktopObject = NULL;
1089  POBJECT_HEADER ObjectHeader;
1090  POBJECT_HEADER_NAME_INFO NameInfo;
1091  OBJECT_HANDLE_INFORMATION HandleInfo;
1092  USEROBJECTFLAGS ObjectFlags;
1093  PUNICODE_STRING pStrNameU = NULL;
1094  PVOID pvData = NULL;
1095  SIZE_T nDataSize = 0;
1096 
1097  _SEH2_TRY
1098  {
1099  if (nLengthNeeded)
1100  ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1101  ProbeForWrite(pvInformation, nLength, 1);
1102  }
1104  {
1106  return FALSE;
1107  }
1108  _SEH2_END;
1109 
1110  /* Try window station */
1111  TRACE("Trying to open window station 0x%p\n", hObject);
1113  0,
1115  UserMode,
1116  (PVOID*)&WinStaObject,
1117  &HandleInfo);
1118 
1120  {
1121  /* Try desktop */
1122  TRACE("Trying to open desktop %p\n", hObject);
1123  WinStaObject = NULL;
1124  Status = IntValidateDesktopHandle(hObject,
1125  UserMode,
1126  0,
1127  &DesktopObject);
1128  }
1129 
1130  if (!NT_SUCCESS(Status))
1131  {
1132  ERR("Failed: 0x%x\n", Status);
1133  goto Exit;
1134  }
1135 
1136  TRACE("WinSta or Desktop opened!\n");
1137 
1138  /* Get data */
1139  switch (nIndex)
1140  {
1141  case UOI_FLAGS:
1142  {
1143  ObjectFlags.fReserved = FALSE;
1144  ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1145 
1146  ObjectFlags.dwFlags = 0;
1147  if (WinStaObject != NULL)
1148  {
1149  if (!(WinStaObject->Flags & WSS_NOIO))
1150  ObjectFlags.dwFlags |= WSF_VISIBLE;
1151  }
1152  else if (DesktopObject != NULL)
1153  {
1154  FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1155  }
1156  else
1157  {
1158  ERR("No associated WinStaObject nor DesktopObject!\n");
1159  }
1160 
1161  pvData = &ObjectFlags;
1162  nDataSize = sizeof(ObjectFlags);
1164  break;
1165  }
1166 
1167  case UOI_NAME:
1168  {
1169  if (WinStaObject != NULL)
1170  {
1171  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1172  NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1173 
1174  if (NameInfo && (NameInfo->Name.Length > 0))
1175  {
1176  /* Named window station */
1177  pStrNameU = &NameInfo->Name;
1178  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1179  }
1180  else
1181  {
1182  /* Unnamed window station (should never happen!) */
1183  ASSERT(FALSE);
1184  pStrNameU = NULL;
1185  nDataSize = sizeof(UNICODE_NULL);
1186  }
1188  }
1189  else if (DesktopObject != NULL)
1190  {
1191  pvData = DesktopObject->pDeskInfo->szDesktopName;
1192  nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1194  }
1195  else
1196  {
1198  }
1199  break;
1200  }
1201 
1202  case UOI_TYPE:
1203  {
1204  if (WinStaObject != NULL)
1205  {
1206  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1207  pStrNameU = &ObjectHeader->Type->Name;
1208  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1210  }
1211  else if (DesktopObject != NULL)
1212  {
1213  ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1214  pStrNameU = &ObjectHeader->Type->Name;
1215  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1217  }
1218  else
1219  {
1221  }
1222  break;
1223  }
1224 
1225  case UOI_USER_SID:
1227  ERR("UOI_USER_SID unimplemented!\n");
1228  break;
1229 
1230  default:
1232  break;
1233  }
1234 
1235 Exit:
1236  if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1238 
1239  _SEH2_TRY
1240  {
1241  if (nLengthNeeded)
1242  *nLengthNeeded = nDataSize;
1243 
1244  /* Try to copy data to caller */
1245  if (Status == STATUS_SUCCESS && (nDataSize > 0))
1246  {
1247  TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1248  if (pvData)
1249  {
1250  /* Copy the data */
1251  RtlCopyMemory(pvInformation, pvData, nDataSize);
1252  }
1253  else if (pStrNameU)
1254  {
1255  /* Copy and NULL-terminate the string */
1256  RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1257  ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1258  }
1259  else
1260  {
1261  /* Zero the memory */
1262  RtlZeroMemory(pvInformation, nDataSize);
1263  }
1264  }
1265  }
1267  {
1269  }
1270  _SEH2_END;
1271 
1272  /* Release objects */
1273  if (DesktopObject != NULL)
1274  ObDereferenceObject(DesktopObject);
1275  if (WinStaObject != NULL)
1276  ObDereferenceObject(WinStaObject);
1277 
1278  if (!NT_SUCCESS(Status))
1279  {
1281  return FALSE;
1282  }
1283 
1284  return TRUE;
1285 }
1286 
1287 /*
1288  * NtUserSetObjectInformation
1289  *
1290  * The NtUserSetObjectInformation function sets information about a
1291  * window station or desktop object.
1292  *
1293  * Parameters
1294  * hObj
1295  * Handle to the window station or desktop object for which to set
1296  * object information. This value can be a handle of type HDESK or
1297  * HWINSTA.
1298  *
1299  * nIndex
1300  * Specifies the object information to be set.
1301  *
1302  * pvInfo
1303  * Pointer to a buffer containing the object information.
1304  *
1305  * nLength
1306  * Specifies the size, in bytes, of the information contained in the
1307  * buffer pointed to by pvInfo.
1308  *
1309  * Return Value
1310  * If the function succeeds, the return value is nonzero. If the function
1311  * fails the return value is zero.
1312  *
1313  * Status
1314  * @unimplemented
1315  */
1316 
1317 BOOL
1318 APIENTRY
1320  HANDLE hObject,
1321  DWORD nIndex,
1322  PVOID pvInformation,
1323  DWORD nLength)
1324 {
1325  /* FIXME: ZwQueryObject */
1326  /* FIXME: ZwSetInformationObject */
1328  return FALSE;
1329 }
1330 
1331 
1332 HWINSTA FASTCALL
1334 {
1336 
1337  return ppi->hwinsta;
1338 }
1339 
1340 
1341 /*
1342  * NtUserGetProcessWindowStation
1343  *
1344  * Returns a handle to the current process window station.
1345  *
1346  * Return Value
1347  * If the function succeeds, the return value is handle to the window
1348  * station assigned to the current process. If the function fails, the
1349  * return value is NULL.
1350  *
1351  * Status
1352  * @implemented
1353  */
1354 
1355 HWINSTA APIENTRY
1357 {
1358  return UserGetProcessWindowStation();
1359 }
1360 
1361 BOOL FASTCALL
1362 UserSetProcessWindowStation(HWINSTA hWindowStation)
1363 {
1364  NTSTATUS Status;
1365  PPROCESSINFO ppi;
1366  OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1367  PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1368  HWINSTA hCacheWinSta;
1369 
1371 
1372  /* Reference the new window station */
1373  if (hWindowStation != NULL)
1374  {
1375  Status = IntValidateWindowStationHandle(hWindowStation,
1376  UserMode,
1377  0,
1378  &NewWinSta,
1379  &ObjectHandleInfo);
1380  if (!NT_SUCCESS(Status))
1381  {
1382  TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1384  return FALSE;
1385  }
1386  }
1387 
1388  OldWinSta = ppi->prpwinsta;
1389  hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1390 
1391  /* Dereference the previous window station */
1392  if (OldWinSta != NULL)
1393  {
1394  ObDereferenceObject(OldWinSta);
1395  }
1396 
1397  /*
1398  * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1399  */
1400 
1401  /* Close the cached EPROCESS window station handle if needed */
1402  if (hCacheWinSta != NULL)
1403  {
1404  /* Reference the window station */
1405  Status = ObReferenceObjectByHandle(hCacheWinSta,
1406  0,
1408  UserMode,
1409  (PVOID*)&OldWinSta,
1410  NULL);
1411  if (!NT_SUCCESS(Status))
1412  {
1413  ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1414  /* We failed, reset the cache */
1415  hCacheWinSta = NULL;
1416  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1417  }
1418  else
1419  {
1420  /*
1421  * Close the old handle and reset the cache only
1422  * if we are setting a different window station.
1423  */
1424  if (NewWinSta != OldWinSta)
1425  {
1426  ObCloseHandle(hCacheWinSta, UserMode);
1427  hCacheWinSta = NULL;
1428  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1429  }
1430 
1431  /* Dereference the window station */
1432  ObDereferenceObject(OldWinSta);
1433  }
1434  }
1435 
1436  /* Duplicate and save a new cached EPROCESS window station handle */
1437  if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1438  {
1439  Status = ZwDuplicateObject(ZwCurrentProcess(),
1440  hWindowStation,
1441  ZwCurrentProcess(),
1442  (PHANDLE)&hCacheWinSta,
1443  0,
1444  0,
1446  if (!NT_SUCCESS(Status))
1447  {
1448  ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1449  }
1450  else
1451  {
1452  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1453  }
1454  }
1455 
1456  ppi->prpwinsta = NewWinSta;
1457  ppi->hwinsta = hWindowStation;
1458  ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1459  TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1460 
1462  {
1463  ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1464  }
1465  else
1466  {
1467  ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1468  }
1469 
1470  if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1471  {
1472  ppi->W32PF_flags |= W32PF_IOWINSTA;
1473  }
1474  else /* Might be closed if the handle is NULL */
1475  {
1476  ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1477  }
1478  return TRUE;
1479 }
1480 
1481 /*
1482  * NtUserSetProcessWindowStation
1483  *
1484  * Assigns a window station to the current process.
1485  *
1486  * Parameters
1487  * hWinSta
1488  * Handle to the window station.
1489  *
1490  * Return Value
1491  * Status
1492  *
1493  * Status
1494  * @implemented
1495  */
1496 
1497 BOOL APIENTRY
1498 NtUserSetProcessWindowStation(HWINSTA hWindowStation)
1499 {
1500  BOOL ret;
1501 
1503 
1504  ret = UserSetProcessWindowStation(hWindowStation);
1505 
1506  UserLeave();
1507 
1508  return ret;
1509 }
1510 
1511 /*
1512  * NtUserLockWindowStation
1513  *
1514  * Locks switching desktops. Only the logon application is allowed to call this function.
1515  *
1516  * Status
1517  * @implemented
1518  */
1519 
1520 BOOL APIENTRY
1521 NtUserLockWindowStation(HWINSTA hWindowStation)
1522 {
1524  NTSTATUS Status;
1525 
1526  TRACE("About to set process window station with handle (%p)\n",
1527  hWindowStation);
1528 
1530  {
1531  ERR("Unauthorized process attempted to lock the window station!\n");
1533  return FALSE;
1534  }
1535 
1536  Status = IntValidateWindowStationHandle(hWindowStation,
1537  UserMode,
1538  0,
1539  &Object,
1540  NULL);
1541  if (!NT_SUCCESS(Status))
1542  {
1543  TRACE("Validation of window station handle (%p) failed\n",
1544  hWindowStation);
1546  return FALSE;
1547  }
1548 
1549  Object->Flags |= WSS_LOCKED;
1550 
1552  return TRUE;
1553 }
1554 
1555 /*
1556  * NtUserUnlockWindowStation
1557  *
1558  * Unlocks switching desktops. Only the logon application is allowed to call this function.
1559  *
1560  * Status
1561  * @implemented
1562  */
1563 
1564 BOOL APIENTRY
1565 NtUserUnlockWindowStation(HWINSTA hWindowStation)
1566 {
1568  NTSTATUS Status;
1569  BOOL Ret;
1570 
1571  TRACE("About to set process window station with handle (%p)\n",
1572  hWindowStation);
1573 
1575  {
1576  ERR("Unauthorized process attempted to unlock the window station!\n");
1578  return FALSE;
1579  }
1580 
1581  Status = IntValidateWindowStationHandle(hWindowStation,
1582  UserMode,
1583  0,
1584  &Object,
1585  NULL);
1586  if (!NT_SUCCESS(Status))
1587  {
1588  TRACE("Validation of window station handle (%p) failed\n",
1589  hWindowStation);
1591  return FALSE;
1592  }
1593 
1594  Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1595  Object->Flags &= ~WSS_LOCKED;
1596 
1598  return Ret;
1599 }
1600 
1601 static NTSTATUS FASTCALL
1603  ULONG dwSize,
1604  PVOID lpBuffer,
1605  PULONG pRequiredSize)
1606 {
1608  NTSTATUS Status;
1610  char InitialBuffer[256], *Buffer;
1612  DWORD EntryCount;
1614  WCHAR NullWchar;
1615 
1616  //
1617  // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1618  // with judicious parameters one can create window stations elsewhere
1619  // than in Windows\WindowStations directory, Win32k definitely MUST
1620  // maintain a list of window stations it has created, and not rely
1621  // on the enumeration of Windows\WindowStations !!!
1622  //
1623 
1624  /*
1625  * Try to open the directory.
1626  */
1630  NULL,
1631  NULL);
1632 
1635  &ObjectAttributes);
1636 
1637  if (!NT_SUCCESS(Status))
1638  {
1639  return Status;
1640  }
1641 
1642  /* First try to query the directory using a fixed-size buffer */
1643  Context = 0;
1644  Buffer = NULL;
1645  Status = ZwQueryDirectoryObject(DirectoryHandle,
1646  InitialBuffer,
1647  sizeof(InitialBuffer),
1648  FALSE,
1649  TRUE,
1650  &Context,
1651  &ReturnLength);
1652  if (NT_SUCCESS(Status))
1653  {
1654  if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1655  FALSE, &Context, NULL))
1656  {
1657  /* Our fixed-size buffer is large enough */
1658  Buffer = InitialBuffer;
1659  }
1660  }
1661 
1662  if (NULL == Buffer)
1663  {
1664  /* Need a larger buffer, check how large exactly */
1665  Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1666  &ReturnLength);
1667  if (!NT_SUCCESS(Status))
1668  {
1669  ERR("ZwQueryDirectoryObject failed\n");
1671  return Status;
1672  }
1673 
1676  if (NULL == Buffer)
1677  {
1679  return STATUS_NO_MEMORY;
1680  }
1681 
1682  /* We should have a sufficiently large buffer now */
1683  Context = 0;
1684  Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1686  if (! NT_SUCCESS(Status) ||
1687  STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1688  FALSE, &Context, NULL))
1689  {
1690  /* Something went wrong, maybe someone added a directory entry? Just give up. */
1694  }
1695  }
1696 
1698 
1699  /*
1700  * Count the required size of buffer.
1701  */
1702  ReturnLength = sizeof(DWORD);
1703  EntryCount = 0;
1705  0 != DirEntry->Name.Length;
1706  DirEntry++)
1707  {
1708  ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1709  EntryCount++;
1710  }
1711  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1712  if (NULL != pRequiredSize)
1713  {
1714  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1715  if (! NT_SUCCESS(Status))
1716  {
1717  if (Buffer != InitialBuffer)
1718  {
1720  }
1721  return STATUS_BUFFER_TOO_SMALL;
1722  }
1723  }
1724 
1725  /*
1726  * Check if the supplied buffer is large enough.
1727  */
1728  if (dwSize < ReturnLength)
1729  {
1730  if (Buffer != InitialBuffer)
1731  {
1733  }
1734  return STATUS_BUFFER_TOO_SMALL;
1735  }
1736 
1737  /*
1738  * Generate the resulting buffer contents.
1739  */
1740  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1741  if (! NT_SUCCESS(Status))
1742  {
1743  if (Buffer != InitialBuffer)
1744  {
1746  }
1747  return Status;
1748  }
1749  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1750 
1751  NullWchar = L'\0';
1753  0 != DirEntry->Name.Length;
1754  DirEntry++)
1755  {
1756  Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
1757  if (! NT_SUCCESS(Status))
1758  {
1759  if (Buffer != InitialBuffer)
1760  {
1762  }
1763  return Status;
1764  }
1765  lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
1766  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1767  if (! NT_SUCCESS(Status))
1768  {
1769  if (Buffer != InitialBuffer)
1770  {
1772  }
1773  return Status;
1774  }
1775  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1776  }
1777 
1778  /*
1779  * Clean up
1780  */
1781  if (Buffer != InitialBuffer)
1782  {
1784  }
1785 
1786  return STATUS_SUCCESS;
1787 }
1788 
1789 static NTSTATUS FASTCALL
1791  HWINSTA hWindowStation,
1792  ULONG dwSize,
1793  PVOID lpBuffer,
1794  PULONG pRequiredSize)
1795 {
1796  NTSTATUS Status;
1797  PWINSTATION_OBJECT WindowStation;
1798  PLIST_ENTRY DesktopEntry;
1799  PDESKTOP DesktopObject;
1800  DWORD EntryCount;
1802  WCHAR NullWchar;
1803  UNICODE_STRING DesktopName;
1804 
1805  Status = IntValidateWindowStationHandle(hWindowStation,
1806  UserMode,
1807  0,
1808  &WindowStation,
1809  NULL);
1810  if (! NT_SUCCESS(Status))
1811  {
1812  return Status;
1813  }
1814 
1815  /*
1816  * Count the required size of buffer.
1817  */
1818  ReturnLength = sizeof(DWORD);
1819  EntryCount = 0;
1820  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1821  DesktopEntry != &WindowStation->DesktopListHead;
1822  DesktopEntry = DesktopEntry->Flink)
1823  {
1824  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1825  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1826  ReturnLength += DesktopName.Length + sizeof(WCHAR);
1827  EntryCount++;
1828  }
1829  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1830  if (NULL != pRequiredSize)
1831  {
1832  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1833  if (! NT_SUCCESS(Status))
1834  {
1835  ObDereferenceObject(WindowStation);
1836  return STATUS_BUFFER_TOO_SMALL;
1837  }
1838  }
1839 
1840  /*
1841  * Check if the supplied buffer is large enough.
1842  */
1843  if (dwSize < ReturnLength)
1844  {
1845  ObDereferenceObject(WindowStation);
1846  return STATUS_BUFFER_TOO_SMALL;
1847  }
1848 
1849  /*
1850  * Generate the resulting buffer contents.
1851  */
1852  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1853  if (! NT_SUCCESS(Status))
1854  {
1855  ObDereferenceObject(WindowStation);
1856  return Status;
1857  }
1858  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1859 
1860  NullWchar = L'\0';
1861  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1862  DesktopEntry != &WindowStation->DesktopListHead;
1863  DesktopEntry = DesktopEntry->Flink)
1864  {
1865  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1866  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1867  Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
1868  if (! NT_SUCCESS(Status))
1869  {
1870  ObDereferenceObject(WindowStation);
1871  return Status;
1872  }
1873  lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
1874  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1875  if (! NT_SUCCESS(Status))
1876  {
1877  ObDereferenceObject(WindowStation);
1878  return Status;
1879  }
1880  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1881  }
1882 
1883  /*
1884  * Clean up and return
1885  */
1886  ObDereferenceObject(WindowStation);
1887  return STATUS_SUCCESS;
1888 }
1889 
1890 /*
1891  * NtUserBuildNameList
1892  *
1893  * Function used for enumeration of desktops or window stations.
1894  *
1895  * Parameters
1896  * hWinSta
1897  * For enumeration of window stations this parameter must be set to
1898  * zero. Otherwise it's handle for window station.
1899  *
1900  * dwSize
1901  * Size of buffer passed by caller.
1902  *
1903  * lpBuffer
1904  * Buffer passed by caller. If the function succeeds, the buffer is
1905  * filled with window station/desktop count (in first DWORD) and
1906  * NULL-terminated window station/desktop names.
1907  *
1908  * pRequiredSize
1909  * If the function succeeds, this is the number of bytes copied.
1910  * Otherwise it's size of buffer needed for function to succeed.
1911  *
1912  * Status
1913  * @implemented
1914  */
1915 
1918  HWINSTA hWindowStation,
1919  ULONG dwSize,
1920  PVOID lpBuffer,
1921  PULONG pRequiredSize)
1922 {
1923  /* The WindowStation name list and desktop name list are build in completely
1924  different ways. Call the appropriate function */
1925  return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
1926  BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
1927 }
1928 
1929 /*
1930  * @implemented
1931  */
1932 BOOL APIENTRY
1934 {
1936  {
1937  return FALSE;
1938  }
1939 
1940  if (!IntIsWindow(hWnd))
1941  {
1942  return FALSE;
1943  }
1944 
1945  hwndSAS = hWnd;
1946 
1947  return TRUE;
1948 }
1949 
1950 BOOL
1951 APIENTRY
1953 {
1954  BOOL ret;
1956 
1958 
1959  if (pti->rpdesk == IntGetActiveDesktop())
1960  {
1962  }
1963  else
1964  {
1965  ret = FALSE;
1966  }
1967 
1968  UserLeave();
1969 
1970  return ret;
1971 }
1972 
1973 BOOL
1974 NTAPI
1976  IN HWINSTA hWindowStation,
1977  IN PLUID pluid,
1978  IN PSID psid OPTIONAL,
1979  IN DWORD size)
1980 {
1981  BOOL Ret = FALSE;
1982  NTSTATUS Status;
1983  PWINSTATION_OBJECT WindowStation = NULL;
1984  LUID luidUser;
1985 
1987 
1989  {
1991  goto Leave;
1992  }
1993 
1994  /* Validate the window station */
1995  Status = IntValidateWindowStationHandle(hWindowStation,
1996  UserMode,
1997  0,
1998  &WindowStation,
1999  NULL);
2000  if (!NT_SUCCESS(Status))
2001  {
2002  goto Leave;
2003  }
2004 
2005  /* Capture the user LUID */
2006  _SEH2_TRY
2007  {
2008  ProbeForRead(pluid, sizeof(LUID), 1);
2009  luidUser = *pluid;
2010  }
2012  {
2014  _SEH2_YIELD(goto Leave);
2015  }
2016  _SEH2_END;
2017 
2018  /* Reset the window station user LUID */
2019  RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
2020 
2021  /* Reset the window station user SID */
2022  if (WindowStation->psidUser)
2023  {
2024  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2025  WindowStation->psidUser = NULL;
2026  }
2027 
2028  /* Copy the new user SID if one has been provided */
2029  if (psid)
2030  {
2032  if (WindowStation->psidUser == NULL)
2033  {
2035  goto Leave;
2036  }
2037 
2039  _SEH2_TRY
2040  {
2041  ProbeForRead(psid, size, 1);
2042  RtlCopyMemory(WindowStation->psidUser, psid, size);
2043  }
2045  {
2047  }
2048  _SEH2_END;
2049 
2050  if (!NT_SUCCESS(Status))
2051  {
2052  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2053  WindowStation->psidUser = NULL;
2054  goto Leave;
2055  }
2056  }
2057 
2058  /* Copy the new user LUID */
2059  WindowStation->luidUser = luidUser;
2060 
2061  Ret = TRUE;
2062 
2063 Leave:
2064  if (WindowStation)
2065  ObDereferenceObject(WindowStation);
2066 
2067  UserLeave();
2068  return Ret;
2069 }
2070 
2071 /* 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:2528
signed char * PCHAR
Definition: retypes.h:7
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:359
#define WINSTA_READ
Definition: winsta.h:50
BOOL APIENTRY NtUserLockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1521
#define BITSPIXEL
Definition: wingdi.h:719
#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:1333
NTSTATUS APIENTRY NtUserBuildNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1917
#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:1952
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()
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: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:711
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:1076
static HDC
Definition: imagelist.c:92
_In_ DWORD nLength
Definition: wincon.h:473
_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:852
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:1933
#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:258
#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
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
DBG_DEFAULT_CHANNEL(UserWinsta)
struct _DESKTOP * rpdesk
Definition: win32.h:91
#define DWORD
Definition: nt_native.h:44
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: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:427
return STATUS_NOT_IMPLEMENTED
#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:494
#define DUPLICATE_SAME_ACCESS
PGRAPHICS_DEVICE NTAPI EngpFindGraphicsDevice(_In_opt_ PUNICODE_STRING pustrDevice, _In_ ULONG iDevNum, _In_ DWORD dwFlags)
Definition: device.c:469
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 WINSTA_EXECUTE
Definition: winsta.h:61
#define UserLeaveCo
Definition: ntuser.h:10
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#define FIXME(fmt,...)
Definition: debug.h:111
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:1319
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:910
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:363
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1791
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1790
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:952
#define LN_LOCK_WORKSTATION
Definition: undocuser.h:116
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
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:950
#define WSF_VISIBLE
Definition: winuser.h:2427
#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:1565
_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:369
__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:1074
BOOL APIENTRY NtUserCloseWindowStation(HWINSTA hWinSta)
Definition: winsta.c:999
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:34
#define ObDereferenceObject
Definition: obfuncs.h:203
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:157
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:350
int ret
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3375
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:1362
ULONG SessionId
Definition: btrfs_drv.h:1965
static const WCHAR L[]
Definition: oid.c:1250
LONG HighPart
HDC hdc
Definition: main.c:9
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: pstypes.h:1677
BOOL NTAPI NtUserSetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:1975
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:1602
#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: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:36
__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:255
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:2931
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define NtCurrentPeb()
Definition: FLS.c:22
HWINSTA hwinsta
Definition: win32.h:259
#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:790
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#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:1073
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: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:588
#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:1498
#define MAXUSHORT
Definition: typedefs.h:83
HWINSTA APIENTRY NtUserGetProcessWindowStation(VOID)
Definition: winsta.c:1356
#define MEM_RELEASE
Definition: nt_native.h:1316
BOOL APIENTRY NtUserGetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength, PDWORD nLengthNeeded)
Definition: winsta.c:1079
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:554
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:956
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:274
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:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define LOGPIXELSY
Definition: wingdi.h:718
#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:1226
PUNICODE_STRING RemainingName
Definition: pstypes.h:1675
#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: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
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
ACCESS_MASK amwinsta
Definition: win32.h:260
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:157
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:27
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:1599
_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:720
_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