ReactOS  0.4.15-dev-5109-g2469ce2
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  UserAssignmentUnlock((PVOID*)&WinSta->spklList);
132 
133  return STATUS_SUCCESS;
134 }
135 
136 NTSTATUS
137 NTAPI
140 {
141  PWIN32_PARSEMETHOD_PARAMETERS ParseParameters = Parameters;
142  PUNICODE_STRING RemainingName = ParseParameters->RemainingName;
143 
144  /* Assume we don't find anything */
145  *ParseParameters->Object = NULL;
146 
147  /* Check for an empty name */
148  if (!RemainingName->Length)
149  {
150  /* Make sure this is a window station, can't parse a desktop now */
151  if (ParseParameters->ObjectType != ExWindowStationObjectType)
152  {
153  /* Fail */
155  }
156 
157  /* Reference the window station and return */
158  ObReferenceObject(ParseParameters->ParseObject);
159  *ParseParameters->Object = ParseParameters->ParseObject;
160  return STATUS_SUCCESS;
161  }
162 
163  /* Check for leading slash */
164  if (RemainingName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
165  {
166  /* Skip it */
167  RemainingName->Buffer++;
168  RemainingName->Length -= sizeof(WCHAR);
169  RemainingName->MaximumLength -= sizeof(WCHAR);
170  }
171 
172  /* Check if there is still a slash */
174  {
175  /* In this case, fail */
177  }
178 
179  /*
180  * Check if we are parsing a desktop.
181  */
182  if (ParseParameters->ObjectType == ExDesktopObjectType)
183  {
184  /* Then call the desktop parse routine */
185  return IntDesktopObjectParse(ParseParameters->ParseObject,
186  ParseParameters->ObjectType,
187  ParseParameters->AccessState,
188  ParseParameters->AccessMode,
189  ParseParameters->Attributes,
190  ParseParameters->CompleteName,
192  ParseParameters->Context,
193  ParseParameters->SecurityQos,
194  ParseParameters->Object);
195  }
196 
197  /* Should hopefully never get here */
199 }
200 
201 NTSTATUS
202 NTAPI
205 {
206  PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS OkToCloseParameters = Parameters;
207  PPROCESSINFO ppi;
208 
210 
211  if (ppi && (OkToCloseParameters->Handle == ppi->hwinsta))
212  {
213  return STATUS_ACCESS_DENIED;
214  }
215 
216  return STATUS_SUCCESS;
217 }
218 
219 /* PRIVATE FUNCTIONS **********************************************************/
220 
221 /*
222  * IntValidateWindowStationHandle
223  *
224  * Validates the window station handle.
225  *
226  * Remarks
227  * If the function succeeds, the handle remains referenced. If the
228  * fucntion fails, last error is set.
229  */
230 
233  HWINSTA WindowStation,
237  POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
238 {
240 
241  if (WindowStation == NULL)
242  {
243  ERR("Invalid window station handle\n");
245  return STATUS_INVALID_HANDLE;
246  }
247 
248  Status = ObReferenceObjectByHandle(WindowStation,
251  AccessMode,
252  (PVOID*)Object,
253  pObjectHandleInfo);
254 
255  if (!NT_SUCCESS(Status))
257 
258  return Status;
259 }
260 
263 {
264  TEXTMETRICW tmw;
265  UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
266  PDESKTOP pdesk;
267 
269  {
270  ERR("PDEVOBJ_lChangeDisplaySettings() failed.\n");
271  return FALSE;
272  }
273 
275  if (NULL == ScreenDeviceContext)
276  {
278  return FALSE;
279  }
281 
283  {
284  return FALSE;
285  }
286 
288 
291 
292  /* Update the system metrics */
293  InitMetrics();
294 
295  /* Set new size of the monitor */
297 
298  /* Update the SERVERINFO */
303  gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
306  {
307  gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
308  }
309  else
310  {
311  gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
312  }
313  // Font is realized and this dc was previously set to internal DC_ATTR.
314  gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
315  gpsi->tmSysFont = tmw;
316 
317  /* Put the pointer in the center of the screen */
318  gpsi->ptCursor.x = gpsi->aiSysMet[SM_CXSCREEN] / 2;
319  gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2;
320 
321  /* Attach monitor */
323 
324  /* Setup the cursor */
326 
327  /* Setup the icons */
329 
330  /* Setup Menu */
331  MenuInit();
332 
333  /* Show the desktop */
334  pdesk = IntGetActiveDesktop();
335  ASSERT(pdesk);
336  co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE);
337 
338  /* HACK: display wallpaper on all secondary displays */
339  {
340  PGRAPHICS_DEVICE pGraphicsDevice;
341  UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
342  UNICODE_STRING DisplayName;
343  HDC hdc;
344  ULONG iDevNum;
345 
346  for (iDevNum = 1; (pGraphicsDevice = EngpFindGraphicsDevice(NULL, iDevNum)) != NULL; iDevNum++)
347  {
348  RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
349  hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
351  }
352  }
353 
354  return TRUE;
355 }
356 
359 {
360  if (NULL != ScreenDeviceContext)
361  { // No need to allocate a new dcattr.
365  }
368 }
369 
372 {
373  return ScreenDeviceContext;
374 }
375 
378 {
380  if ( gpidLogon != PsGetCurrentProcessId() )
381  {
382  if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
383  {
384  ERR("Requires Interactive Window Station\n");
386  return FALSE;
387  }
389  {
390  ERR("Access Denied\n");
392  return FALSE;
393  }
394  }
395  return TRUE;
396 }
397 
398 // Win: _GetProcessWindowStation
401 {
402  PWINSTATION_OBJECT pWinSta;
404  HWINSTA hWinSta = ppi->hwinsta;
405  if (phWinSta)
406  *phWinSta = hWinSta;
407  IntValidateWindowStationHandle(hWinSta, UserMode, 0, &pWinSta, 0);
408  return pWinSta;
409 }
410 
411 /* PUBLIC FUNCTIONS ***********************************************************/
412 
413 /*
414  * NtUserCreateWindowStation
415  *
416  * Creates a new window station.
417  *
418  * Parameters
419  * lpszWindowStationName
420  * Pointer to a null-terminated string specifying the name of the
421  * window station to be created. Window station names are
422  * case-insensitive and cannot contain backslash characters (\).
423  * Only members of the Administrators group are allowed to specify a
424  * name.
425  *
426  * dwDesiredAccess
427  * Requested type of access
428  *
429  * lpSecurity
430  * Security descriptor
431  *
432  * Unknown3, Unknown4, Unknown5, Unknown6
433  * Unused
434  *
435  * Return Value
436  * If the function succeeds, the return value is a handle to the newly
437  * created window station. If the specified window station already
438  * exists, the function succeeds and returns a handle to the existing
439  * window station. If the function fails, the return value is NULL.
440  *
441  * Status
442  * @implemented
443  */
444 
445 NTSTATUS
446 FASTCALL
448  OUT HWINSTA* phWinSta,
451  IN KPROCESSOR_MODE OwnerMode,
452  IN ACCESS_MASK dwDesiredAccess,
453  DWORD Unknown2,
454  DWORD Unknown3,
455  DWORD Unknown4,
456  DWORD Unknown5,
457  DWORD Unknown6)
458 {
460  HWINSTA hWinSta;
461  PWINSTATION_OBJECT WindowStation;
462 
463  TRACE("IntCreateWindowStation called\n");
464 
465  ASSERT(phWinSta);
466  *phWinSta = NULL;
467 
470  AccessMode,
471  NULL,
472  dwDesiredAccess,
473  NULL,
474  (PVOID*)&hWinSta);
475  if (NT_SUCCESS(Status))
476  {
477  TRACE("IntCreateWindowStation opened window station '%wZ'\n",
478  ObjectAttributes->ObjectName);
479  *phWinSta = hWinSta;
480  return Status;
481  }
482 
483  /*
484  * No existing window station found, try to create a new one.
485  */
486 
487  /* Create the window station object */
491  OwnerMode,
492  NULL,
493  sizeof(WINSTATION_OBJECT),
494  0,
495  0,
496  (PVOID*)&WindowStation);
497  if (!NT_SUCCESS(Status))
498  {
499  ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
500  ObjectAttributes->ObjectName, Status);
502  return Status;
503  }
504 
505  /* Initialize the window station */
506  RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
507 
508  InitializeListHead(&WindowStation->DesktopListHead);
509  WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
510  Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
511  if (!NT_SUCCESS(Status))
512  {
513  ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
514  ObjectAttributes->ObjectName, Status);
515  ObDereferenceObject(WindowStation);
517  return Status;
518  }
519 
520  Status = ObInsertObject(WindowStation,
521  NULL,
522  dwDesiredAccess,
523  0,
524  NULL,
525  (PVOID*)&hWinSta);
526  if (!NT_SUCCESS(Status))
527  {
528  ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
530  return Status;
531  }
532 
533  // FIXME! TODO: Add this new window station to a linked list
534 
535  if (InputWindowStation == NULL)
536  {
537  ERR("Initializing input window station\n");
538 
539  /* Only Winlogon can create the interactive window station */
541 
542  InputWindowStation = WindowStation;
543  WindowStation->Flags &= ~WSS_NOIO;
544 
545  InitCursorImpl();
546 
549 
550  /* Desktop functions require the desktop thread running so wait for it to initialize */
551  UserLeaveCo();
553  UserRequest,
554  UserMode,
555  FALSE,
556  NULL);
557  UserEnterCo();
558  }
559  else
560  {
561  WindowStation->Flags |= WSS_NOIO;
562  }
563 
564  TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
565  ObjectAttributes->ObjectName, WindowStation, hWinSta);
566 
567  *phWinSta = hWinSta;
569 
570  return STATUS_SUCCESS;
571 }
572 
573 static VOID
575  IN OUT PUNICODE_STRING WindowStationName,
576  IN PUNICODE_STRING TebStaticUnicodeString,
577  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL,
578  IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
579 {
580  SIZE_T MemSize = 0;
581 
582  /* Try to restore the user's UserModeObjectAttributes */
583  if (UserModeObjectAttributes && LocalObjectAttributes)
584  {
585  _SEH2_TRY
586  {
587  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
588  *UserModeObjectAttributes = *LocalObjectAttributes;
589  }
591  {
592  NOTHING;
593  }
594  _SEH2_END;
595  }
596 
597  /* Free the user-mode memory */
598  if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
599  {
600  ZwFreeVirtualMemory(ZwCurrentProcess(),
601  (PVOID*)&WindowStationName,
602  &MemSize,
603  MEM_RELEASE);
604  }
605 }
606 
607 static NTSTATUS
609  IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes,
610  IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes,
611  OUT PUNICODE_STRING* WindowStationName,
612  OUT PUNICODE_STRING* TebStaticUnicodeString)
613 {
615  SIZE_T MemSize;
616 
617  LUID CallerLuid;
618  PTEB Teb;
619  USHORT StrSize;
620 
621  *WindowStationName = NULL;
622  *TebStaticUnicodeString = NULL;
623 
624  /* Retrieve the current process LUID */
625  Status = GetProcessLuid(NULL, NULL, &CallerLuid);
626  if (!NT_SUCCESS(Status))
627  {
628  ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
629  return Status;
630  }
631 
632  /* Compute the needed string size */
633  MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
635  CallerLuid.HighPart,
636  CallerLuid.LowPart);
637  MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
638  if (MemSize > MAXUSHORT)
639  {
640  ERR("Window station name length is too long.\n");
641  return STATUS_NAME_TOO_LONG;
642  }
643  StrSize = (USHORT)MemSize;
644 
645  /*
646  * Check whether it's short enough so that we can use the static buffer
647  * in the TEB. Otherwise continue with virtual memory allocation.
648  */
649  Teb = NtCurrentTeb();
650  if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
651  {
652  /* We can use the TEB's static unicode string */
655 
656  /* Remember the TEB's static unicode string address for later */
657  *TebStaticUnicodeString = &Teb->StaticUnicodeString;
658 
659  *WindowStationName = *TebStaticUnicodeString;
660  (*WindowStationName)->Length = 0;
661  }
662  else
663  {
664  /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
665  MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
666 
667  /* Allocate the memory in user-mode */
668  Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
669  (PVOID*)WindowStationName,
670  0,
671  &MemSize,
672  MEM_COMMIT,
674  if (!NT_SUCCESS(Status))
675  {
676  ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
677  return Status;
678  }
679 
680  RtlInitEmptyUnicodeString(*WindowStationName,
681  (PWCHAR)((ULONG_PTR)*WindowStationName +
682  ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
683  StrSize);
684  }
685 
686  /* Build a valid window station name from the LUID */
687  Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
688  (*WindowStationName)->MaximumLength,
689  L"%wZ\\Service-0x%x-%x$",
691  CallerLuid.HighPart,
692  CallerLuid.LowPart);
693  if (!NT_SUCCESS(Status))
694  {
695  ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
696  goto Quit;
697  }
698  (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
699 
700  /* Try to update the user's UserModeObjectAttributes */
701  _SEH2_TRY
702  {
703  ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
704  *LocalObjectAttributes = *UserModeObjectAttributes;
705 
706  UserModeObjectAttributes->ObjectName = *WindowStationName;
707  UserModeObjectAttributes->RootDirectory = NULL;
708 
710  }
712  {
714  }
715  _SEH2_END;
716 
717 Quit:
718  if (!NT_SUCCESS(Status))
719  {
720  /* Release the window station name */
721  FreeUserModeWindowStationName(*WindowStationName,
722  *TebStaticUnicodeString,
723  NULL, NULL);
724  }
725 
726  return Status;
727 }
728 
729 HWINSTA
730 APIENTRY
733  IN ACCESS_MASK dwDesiredAccess,
734  DWORD Unknown2,
735  DWORD Unknown3,
736  DWORD Unknown4,
737  DWORD Unknown5,
738  DWORD Unknown6)
739 {
741  HWINSTA hWinSta = NULL;
742  OBJECT_ATTRIBUTES LocalObjectAttributes;
743  PUNICODE_STRING WindowStationName = NULL;
744  PUNICODE_STRING TebStaticUnicodeString = NULL;
745  KPROCESSOR_MODE OwnerMode = UserMode;
746 
747  TRACE("NtUserCreateWindowStation called\n");
748 
749  /* Capture the object attributes and the window station name */
750  _SEH2_TRY
751  {
753  LocalObjectAttributes = *ObjectAttributes;
754  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
755  {
756  ERR("Invalid ObjectAttributes length!\n");
758  _SEH2_LEAVE;
759  }
760 
761  /*
762  * Check whether the caller provided a window station name together
763  * with a RootDirectory handle.
764  *
765  * If the caller did not provide a window station name, build a new one
766  * based on the logon session identifier for the calling process.
767  * The new name is allocated in user-mode, as the rest of ObjectAttributes
768  * already is, so that the validation performed by the Object Manager
769  * can be done adequately.
770  */
771  if ((LocalObjectAttributes.ObjectName == NULL ||
772  LocalObjectAttributes.ObjectName->Buffer == NULL ||
773  LocalObjectAttributes.ObjectName->Length == 0 ||
774  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
775  /* &&
776  LocalObjectAttributes.RootDirectory == NULL */)
777  {
778  /* No, build the new window station name */
780  &LocalObjectAttributes,
781  &WindowStationName,
782  &TebStaticUnicodeString);
783  if (!NT_SUCCESS(Status))
784  {
785  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
786  _SEH2_LEAVE;
787  }
788  OwnerMode = KernelMode;
789  }
790  }
792  {
794  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
795  }
796  _SEH2_END;
797 
798  if (!NT_SUCCESS(Status))
799  {
801  return NULL;
802  }
803 
805 
806  /* Create the window station */
807  Status = IntCreateWindowStation(&hWinSta,
809  UserMode,
810  OwnerMode,
811  dwDesiredAccess,
812  Unknown2,
813  Unknown3,
814  Unknown4,
815  Unknown5,
816  Unknown6);
817  UserLeave();
818 
819  if (NT_SUCCESS(Status))
820  {
821  TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
822  ObjectAttributes->ObjectName, hWinSta);
823  }
824  else
825  {
826  ASSERT(hWinSta == NULL);
827  ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
828  ObjectAttributes->ObjectName, Status);
829  }
830 
831  /* Try to restore the user's ObjectAttributes and release the window station name */
832  FreeUserModeWindowStationName(WindowStationName,
833  TebStaticUnicodeString,
834  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
835  &LocalObjectAttributes);
836 
837  if (!NT_SUCCESS(Status))
838  {
839  ASSERT(hWinSta == NULL);
841  }
842 
843  return hWinSta;
844 }
845 
846 /*
847  * NtUserOpenWindowStation
848  *
849  * Opens an existing window station.
850  *
851  * Parameters
852  * lpszWindowStationName
853  * Name of the existing window station.
854  *
855  * dwDesiredAccess
856  * Requested type of access.
857  *
858  * Return Value
859  * If the function succeeds, the return value is the handle to the
860  * specified window station. If the function fails, the return value
861  * is NULL.
862  *
863  * Remarks
864  * The returned handle can be closed with NtUserCloseWindowStation.
865  *
866  * Status
867  * @implemented
868  */
869 
870 HWINSTA
871 APIENTRY
874  IN ACCESS_MASK dwDesiredAccess)
875 {
877  HWINSTA hWinSta = NULL;
878  OBJECT_ATTRIBUTES LocalObjectAttributes;
879  PUNICODE_STRING WindowStationName = NULL;
880  PUNICODE_STRING TebStaticUnicodeString = NULL;
881  KPROCESSOR_MODE OwnerMode = UserMode;
882 
883  TRACE("NtUserOpenWindowStation called\n");
884 
885  /* Capture the object attributes and the window station name */
886  _SEH2_TRY
887  {
889  LocalObjectAttributes = *ObjectAttributes;
890  if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
891  {
892  ERR("Invalid ObjectAttributes length!\n");
894  _SEH2_LEAVE;
895  }
896 
897  /*
898  * Check whether the caller did not provide a window station name,
899  * or provided the special "Service-0x00000000-00000000$" name.
900  *
901  * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
902  * is used instead of an empty name (observed when API-monitoring
903  * OpenWindowStation() called with an empty window station name).
904  */
905  if ((LocalObjectAttributes.ObjectName == NULL ||
906  LocalObjectAttributes.ObjectName->Buffer == NULL ||
907  LocalObjectAttributes.ObjectName->Length == 0 ||
908  LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
909  /* &&
910  LocalObjectAttributes.RootDirectory == NULL */)
911  {
912  /* No, remember that for later */
913  LocalObjectAttributes.ObjectName = NULL;
914  }
915  if (LocalObjectAttributes.ObjectName &&
916  LocalObjectAttributes.ObjectName->Length ==
917  sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
918  _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
919  L"Service-0x00000000-00000000$",
920  LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
921  {
922  /* No, remember that for later */
923  LocalObjectAttributes.ObjectName = NULL;
924  }
925 
926  /*
927  * If the caller did not provide a window station name, build a new one
928  * based on the logon session identifier for the calling process.
929  * The new name is allocated in user-mode, as the rest of ObjectAttributes
930  * already is, so that the validation performed by the Object Manager
931  * can be done adequately.
932  */
933  if (!LocalObjectAttributes.ObjectName)
934  {
935  /* No, build the new window station name */
937  &LocalObjectAttributes,
938  &WindowStationName,
939  &TebStaticUnicodeString);
940  if (!NT_SUCCESS(Status))
941  {
942  ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
943  _SEH2_LEAVE;
944  }
945  OwnerMode = KernelMode;
946  }
947  }
949  {
951  ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
952  }
953  _SEH2_END;
954 
955  if (!NT_SUCCESS(Status))
956  {
958  return NULL;
959  }
960 
961  /* Open the window station */
964  UserMode,
965  NULL,
966  dwDesiredAccess,
967  NULL,
968  (PVOID*)&hWinSta);
969  if (NT_SUCCESS(Status))
970  {
971  TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
972  ObjectAttributes->ObjectName, hWinSta);
973  }
974  else
975  {
976  ASSERT(hWinSta == NULL);
977  ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
978  ObjectAttributes->ObjectName, Status);
979  }
980 
981  /* Try to restore the user's ObjectAttributes and release the window station name */
982  FreeUserModeWindowStationName(WindowStationName,
983  TebStaticUnicodeString,
984  (OwnerMode == KernelMode ? ObjectAttributes : NULL),
985  &LocalObjectAttributes);
986 
987  if (!NT_SUCCESS(Status))
988  {
989  ASSERT(hWinSta == NULL);
991  }
992 
993  return hWinSta;
994 }
995 
996 /*
997  * NtUserCloseWindowStation
998  *
999  * Closes a window station handle.
1000  *
1001  * Parameters
1002  * hWinSta
1003  * Handle to the window station.
1004  *
1005  * Return Value
1006  * Status
1007  *
1008  * Remarks
1009  * The window station handle can be created with NtUserCreateWindowStation
1010  * or NtUserOpenWindowStation. Attempts to close a handle to the window
1011  * station assigned to the calling process will fail.
1012  *
1013  * Status
1014  * @implemented
1015  */
1016 
1017 BOOL
1018 APIENTRY
1020  HWINSTA hWinSta)
1021 {
1023  NTSTATUS Status;
1024 
1025  TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
1026 
1027  if (hWinSta == UserGetProcessWindowStation())
1028  {
1029  ERR("Attempted to close process window station\n");
1030  return FALSE;
1031  }
1032 
1034  UserMode,
1035  0,
1036  &Object,
1037  NULL);
1038  if (!NT_SUCCESS(Status))
1039  {
1040  ERR("Validation of window station handle (%p) failed\n", hWinSta);
1041  return FALSE;
1042  }
1043 
1045 
1046  TRACE("Closing window station handle (%p)\n", hWinSta);
1047 
1048  Status = ObCloseHandle(hWinSta, UserMode);
1049  if (!NT_SUCCESS(Status))
1050  {
1052  return FALSE;
1053  }
1054 
1055  return TRUE;
1056 }
1057 
1058 /*
1059  * NtUserGetObjectInformation
1060  *
1061  * The NtUserGetObjectInformation function retrieves information about a
1062  * window station or desktop object.
1063  *
1064  * Parameters
1065  * hObj
1066  * Handle to the window station or desktop object for which to
1067  * return information. This can be a handle of type HDESK or HWINSTA
1068  * (for example, a handle returned by NtUserCreateWindowStation,
1069  * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
1070  *
1071  * nIndex
1072  * Specifies the object information to be retrieved.
1073  *
1074  * pvInfo
1075  * Pointer to a buffer to receive the object information.
1076  *
1077  * nLength
1078  * Specifies the size, in bytes, of the buffer pointed to by the
1079  * pvInfo parameter.
1080  *
1081  * lpnLengthNeeded
1082  * Pointer to a variable receiving the number of bytes required to
1083  * store the requested information. If this variable's value is
1084  * greater than the value of the nLength parameter when the function
1085  * returns, the function returns FALSE, and none of the information
1086  * is copied to the pvInfo buffer. If the value of the variable pointed
1087  * to by lpnLengthNeeded is less than or equal to the value of nLength,
1088  * the entire information block is copied.
1089  *
1090  * Return Value
1091  * If the function succeeds, the return value is nonzero. If the function
1092  * fails, the return value is zero.
1093  *
1094  * Status
1095  * @unimplemented
1096  */
1097 
1098 BOOL APIENTRY
1100  HANDLE hObject,
1101  DWORD nIndex,
1102  PVOID pvInformation,
1103  DWORD nLength,
1104  PDWORD nLengthNeeded)
1105 {
1106  NTSTATUS Status;
1107  PWINSTATION_OBJECT WinStaObject = NULL;
1108  PDESKTOP DesktopObject = NULL;
1109  POBJECT_HEADER ObjectHeader;
1110  POBJECT_HEADER_NAME_INFO NameInfo;
1111  OBJECT_HANDLE_INFORMATION HandleInfo;
1112  USEROBJECTFLAGS ObjectFlags;
1113  PUNICODE_STRING pStrNameU = NULL;
1114  PVOID pvData = NULL;
1115  SIZE_T nDataSize = 0;
1116 
1117  _SEH2_TRY
1118  {
1119  if (nLengthNeeded)
1120  ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1121  ProbeForWrite(pvInformation, nLength, 1);
1122  }
1124  {
1126  return FALSE;
1127  }
1128  _SEH2_END;
1129 
1130  /* Try window station */
1131  TRACE("Trying to open window station 0x%p\n", hObject);
1133  0,
1135  UserMode,
1136  (PVOID*)&WinStaObject,
1137  &HandleInfo);
1138 
1140  {
1141  /* Try desktop */
1142  TRACE("Trying to open desktop %p\n", hObject);
1143  WinStaObject = NULL;
1144  Status = IntValidateDesktopHandle(hObject,
1145  UserMode,
1146  0,
1147  &DesktopObject);
1148  }
1149 
1150  if (!NT_SUCCESS(Status))
1151  {
1152  ERR("Failed: 0x%x\n", Status);
1153  goto Exit;
1154  }
1155 
1156  TRACE("WinSta or Desktop opened!\n");
1157 
1158  /* Get data */
1159  switch (nIndex)
1160  {
1161  case UOI_FLAGS:
1162  {
1163  ObjectFlags.fReserved = FALSE;
1164  ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1165 
1166  ObjectFlags.dwFlags = 0;
1167  if (WinStaObject != NULL)
1168  {
1169  if (!(WinStaObject->Flags & WSS_NOIO))
1170  ObjectFlags.dwFlags |= WSF_VISIBLE;
1171  }
1172  else if (DesktopObject != NULL)
1173  {
1174  FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1175  }
1176  else
1177  {
1178  ERR("No associated WinStaObject nor DesktopObject!\n");
1179  }
1180 
1181  pvData = &ObjectFlags;
1182  nDataSize = sizeof(ObjectFlags);
1184  break;
1185  }
1186 
1187  case UOI_NAME:
1188  {
1189  if (WinStaObject != NULL)
1190  {
1191  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1192  NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1193 
1194  if (NameInfo && (NameInfo->Name.Length > 0))
1195  {
1196  /* Named window station */
1197  pStrNameU = &NameInfo->Name;
1198  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1199  }
1200  else
1201  {
1202  /* Unnamed window station (should never happen!) */
1203  ASSERT(FALSE);
1204  pStrNameU = NULL;
1205  nDataSize = sizeof(UNICODE_NULL);
1206  }
1208  }
1209  else if (DesktopObject != NULL)
1210  {
1211  pvData = DesktopObject->pDeskInfo->szDesktopName;
1212  nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1214  }
1215  else
1216  {
1218  }
1219  break;
1220  }
1221 
1222  case UOI_TYPE:
1223  {
1224  if (WinStaObject != NULL)
1225  {
1226  ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1227  pStrNameU = &ObjectHeader->Type->Name;
1228  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1230  }
1231  else if (DesktopObject != NULL)
1232  {
1233  ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1234  pStrNameU = &ObjectHeader->Type->Name;
1235  nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1237  }
1238  else
1239  {
1241  }
1242  break;
1243  }
1244 
1245  case UOI_USER_SID:
1247  ERR("UOI_USER_SID unimplemented!\n");
1248  break;
1249 
1250  default:
1252  break;
1253  }
1254 
1255 Exit:
1256  if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1258 
1259  _SEH2_TRY
1260  {
1261  if (nLengthNeeded)
1262  *nLengthNeeded = nDataSize;
1263 
1264  /* Try to copy data to caller */
1265  if (Status == STATUS_SUCCESS && (nDataSize > 0))
1266  {
1267  TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1268  if (pvData)
1269  {
1270  /* Copy the data */
1271  RtlCopyMemory(pvInformation, pvData, nDataSize);
1272  }
1273  else if (pStrNameU)
1274  {
1275  /* Copy and NULL-terminate the string */
1276  RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1277  ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1278  }
1279  else
1280  {
1281  /* Zero the memory */
1282  RtlZeroMemory(pvInformation, nDataSize);
1283  }
1284  }
1285  }
1287  {
1289  }
1290  _SEH2_END;
1291 
1292  /* Release objects */
1293  if (DesktopObject != NULL)
1294  ObDereferenceObject(DesktopObject);
1295  if (WinStaObject != NULL)
1296  ObDereferenceObject(WinStaObject);
1297 
1298  if (!NT_SUCCESS(Status))
1299  {
1301  return FALSE;
1302  }
1303 
1304  return TRUE;
1305 }
1306 
1307 /*
1308  * NtUserSetObjectInformation
1309  *
1310  * The NtUserSetObjectInformation function sets information about a
1311  * window station or desktop object.
1312  *
1313  * Parameters
1314  * hObj
1315  * Handle to the window station or desktop object for which to set
1316  * object information. This value can be a handle of type HDESK or
1317  * HWINSTA.
1318  *
1319  * nIndex
1320  * Specifies the object information to be set.
1321  *
1322  * pvInfo
1323  * Pointer to a buffer containing the object information.
1324  *
1325  * nLength
1326  * Specifies the size, in bytes, of the information contained in the
1327  * buffer pointed to by pvInfo.
1328  *
1329  * Return Value
1330  * If the function succeeds, the return value is nonzero. If the function
1331  * fails the return value is zero.
1332  *
1333  * Status
1334  * @unimplemented
1335  */
1336 
1337 BOOL
1338 APIENTRY
1340  HANDLE hObject,
1341  DWORD nIndex,
1342  PVOID pvInformation,
1343  DWORD nLength)
1344 {
1345  /* FIXME: ZwQueryObject */
1346  /* FIXME: ZwSetInformationObject */
1348  return FALSE;
1349 }
1350 
1351 
1352 HWINSTA FASTCALL
1354 {
1356 
1357  return ppi->hwinsta;
1358 }
1359 
1360 
1361 /*
1362  * NtUserGetProcessWindowStation
1363  *
1364  * Returns a handle to the current process window station.
1365  *
1366  * Return Value
1367  * If the function succeeds, the return value is handle to the window
1368  * station assigned to the current process. If the function fails, the
1369  * return value is NULL.
1370  *
1371  * Status
1372  * @implemented
1373  */
1374 
1375 HWINSTA APIENTRY
1377 {
1378  return UserGetProcessWindowStation();
1379 }
1380 
1381 BOOL FASTCALL
1382 UserSetProcessWindowStation(HWINSTA hWindowStation)
1383 {
1384  NTSTATUS Status;
1385  PPROCESSINFO ppi;
1386  OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1387  PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1388  HWINSTA hCacheWinSta;
1389 
1391 
1392  /* Reference the new window station */
1393  if (hWindowStation != NULL)
1394  {
1395  Status = IntValidateWindowStationHandle(hWindowStation,
1396  UserMode,
1397  0,
1398  &NewWinSta,
1399  &ObjectHandleInfo);
1400  if (!NT_SUCCESS(Status))
1401  {
1402  TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1404  return FALSE;
1405  }
1406  }
1407 
1408  OldWinSta = ppi->prpwinsta;
1409  hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1410 
1411  /* Dereference the previous window station */
1412  if (OldWinSta != NULL)
1413  {
1414  ObDereferenceObject(OldWinSta);
1415  }
1416 
1417  /*
1418  * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1419  */
1420 
1421  /* Close the cached EPROCESS window station handle if needed */
1422  if (hCacheWinSta != NULL)
1423  {
1424  /* Reference the window station */
1425  Status = ObReferenceObjectByHandle(hCacheWinSta,
1426  0,
1428  UserMode,
1429  (PVOID*)&OldWinSta,
1430  NULL);
1431  if (!NT_SUCCESS(Status))
1432  {
1433  ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1434  /* We failed, reset the cache */
1435  hCacheWinSta = NULL;
1436  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1437  }
1438  else
1439  {
1440  /*
1441  * Close the old handle and reset the cache only
1442  * if we are setting a different window station.
1443  */
1444  if (NewWinSta != OldWinSta)
1445  {
1446  ObCloseHandle(hCacheWinSta, UserMode);
1447  hCacheWinSta = NULL;
1448  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1449  }
1450 
1451  /* Dereference the window station */
1452  ObDereferenceObject(OldWinSta);
1453  }
1454  }
1455 
1456  /* Duplicate and save a new cached EPROCESS window station handle */
1457  if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1458  {
1459  Status = ZwDuplicateObject(ZwCurrentProcess(),
1460  hWindowStation,
1461  ZwCurrentProcess(),
1462  (PHANDLE)&hCacheWinSta,
1463  0,
1464  0,
1466  if (!NT_SUCCESS(Status))
1467  {
1468  ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1469  }
1470  else
1471  {
1472  PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1473  }
1474  }
1475 
1476  ppi->prpwinsta = NewWinSta;
1477  ppi->hwinsta = hWindowStation;
1478  ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1479  TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1480 
1482  {
1483  ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1484  }
1485  else
1486  {
1487  ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1488  }
1489 
1490  if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1491  {
1492  ppi->W32PF_flags |= W32PF_IOWINSTA;
1493  }
1494  else /* Might be closed if the handle is NULL */
1495  {
1496  ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1497  }
1498  return TRUE;
1499 }
1500 
1501 /*
1502  * NtUserSetProcessWindowStation
1503  *
1504  * Assigns a window station to the current process.
1505  *
1506  * Parameters
1507  * hWinSta
1508  * Handle to the window station.
1509  *
1510  * Return Value
1511  * Status
1512  *
1513  * Status
1514  * @implemented
1515  */
1516 
1517 BOOL APIENTRY
1518 NtUserSetProcessWindowStation(HWINSTA hWindowStation)
1519 {
1520  BOOL ret;
1521 
1523 
1524  ret = UserSetProcessWindowStation(hWindowStation);
1525 
1526  UserLeave();
1527 
1528  return ret;
1529 }
1530 
1531 /*
1532  * NtUserLockWindowStation
1533  *
1534  * Locks switching desktops. Only the logon application is allowed to call this function.
1535  *
1536  * Status
1537  * @implemented
1538  */
1539 
1540 BOOL APIENTRY
1541 NtUserLockWindowStation(HWINSTA hWindowStation)
1542 {
1544  NTSTATUS Status;
1545 
1546  TRACE("About to set process window station with handle (%p)\n",
1547  hWindowStation);
1548 
1550  {
1551  ERR("Unauthorized process attempted to lock the window station!\n");
1553  return FALSE;
1554  }
1555 
1556  Status = IntValidateWindowStationHandle(hWindowStation,
1557  UserMode,
1558  0,
1559  &Object,
1560  NULL);
1561  if (!NT_SUCCESS(Status))
1562  {
1563  TRACE("Validation of window station handle (%p) failed\n",
1564  hWindowStation);
1566  return FALSE;
1567  }
1568 
1569  Object->Flags |= WSS_LOCKED;
1570 
1572  return TRUE;
1573 }
1574 
1575 /*
1576  * NtUserUnlockWindowStation
1577  *
1578  * Unlocks switching desktops. Only the logon application is allowed to call this function.
1579  *
1580  * Status
1581  * @implemented
1582  */
1583 
1584 BOOL APIENTRY
1585 NtUserUnlockWindowStation(HWINSTA hWindowStation)
1586 {
1588  NTSTATUS Status;
1589  BOOL Ret;
1590 
1591  TRACE("About to set process window station with handle (%p)\n",
1592  hWindowStation);
1593 
1595  {
1596  ERR("Unauthorized process attempted to unlock the window station!\n");
1598  return FALSE;
1599  }
1600 
1601  Status = IntValidateWindowStationHandle(hWindowStation,
1602  UserMode,
1603  0,
1604  &Object,
1605  NULL);
1606  if (!NT_SUCCESS(Status))
1607  {
1608  TRACE("Validation of window station handle (%p) failed\n",
1609  hWindowStation);
1611  return FALSE;
1612  }
1613 
1614  Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1615  Object->Flags &= ~WSS_LOCKED;
1616 
1618  return Ret;
1619 }
1620 
1621 static NTSTATUS FASTCALL
1623  ULONG dwSize,
1624  PVOID lpBuffer,
1625  PULONG pRequiredSize)
1626 {
1628  NTSTATUS Status;
1630  char InitialBuffer[256], *Buffer;
1632  DWORD EntryCount;
1634  WCHAR NullWchar;
1635 
1636  //
1637  // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1638  // with judicious parameters one can create window stations elsewhere
1639  // than in Windows\WindowStations directory, Win32k definitely MUST
1640  // maintain a list of window stations it has created, and not rely
1641  // on the enumeration of Windows\WindowStations !!!
1642  //
1643 
1644  /*
1645  * Try to open the directory.
1646  */
1650  NULL,
1651  NULL);
1652 
1655  &ObjectAttributes);
1656 
1657  if (!NT_SUCCESS(Status))
1658  {
1659  return Status;
1660  }
1661 
1662  /* First try to query the directory using a fixed-size buffer */
1663  Context = 0;
1664  Buffer = NULL;
1665  Status = ZwQueryDirectoryObject(DirectoryHandle,
1666  InitialBuffer,
1667  sizeof(InitialBuffer),
1668  FALSE,
1669  TRUE,
1670  &Context,
1671  &ReturnLength);
1672  if (NT_SUCCESS(Status))
1673  {
1674  if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1675  FALSE, &Context, NULL))
1676  {
1677  /* Our fixed-size buffer is large enough */
1678  Buffer = InitialBuffer;
1679  }
1680  }
1681 
1682  if (NULL == Buffer)
1683  {
1684  /* Need a larger buffer, check how large exactly */
1685  Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1686  &ReturnLength);
1687  if (!NT_SUCCESS(Status))
1688  {
1689  ERR("ZwQueryDirectoryObject failed\n");
1691  return Status;
1692  }
1693 
1696  if (NULL == Buffer)
1697  {
1699  return STATUS_NO_MEMORY;
1700  }
1701 
1702  /* We should have a sufficiently large buffer now */
1703  Context = 0;
1704  Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1706  if (! NT_SUCCESS(Status) ||
1707  STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1708  FALSE, &Context, NULL))
1709  {
1710  /* Something went wrong, maybe someone added a directory entry? Just give up. */
1714  }
1715  }
1716 
1718 
1719  /*
1720  * Count the required size of buffer.
1721  */
1722  ReturnLength = sizeof(DWORD);
1723  EntryCount = 0;
1725  0 != DirEntry->Name.Length;
1726  DirEntry++)
1727  {
1728  ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1729  EntryCount++;
1730  }
1731  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1732  if (NULL != pRequiredSize)
1733  {
1734  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1735  if (! NT_SUCCESS(Status))
1736  {
1737  if (Buffer != InitialBuffer)
1738  {
1740  }
1741  return STATUS_BUFFER_TOO_SMALL;
1742  }
1743  }
1744 
1745  /*
1746  * Check if the supplied buffer is large enough.
1747  */
1748  if (dwSize < ReturnLength)
1749  {
1750  if (Buffer != InitialBuffer)
1751  {
1753  }
1754  return STATUS_BUFFER_TOO_SMALL;
1755  }
1756 
1757  /*
1758  * Generate the resulting buffer contents.
1759  */
1760  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1761  if (! NT_SUCCESS(Status))
1762  {
1763  if (Buffer != InitialBuffer)
1764  {
1766  }
1767  return Status;
1768  }
1769  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1770 
1771  NullWchar = L'\0';
1773  0 != DirEntry->Name.Length;
1774  DirEntry++)
1775  {
1776  Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
1777  if (! NT_SUCCESS(Status))
1778  {
1779  if (Buffer != InitialBuffer)
1780  {
1782  }
1783  return Status;
1784  }
1785  lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
1786  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1787  if (! NT_SUCCESS(Status))
1788  {
1789  if (Buffer != InitialBuffer)
1790  {
1792  }
1793  return Status;
1794  }
1795  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1796  }
1797 
1798  /*
1799  * Clean up
1800  */
1801  if (Buffer != InitialBuffer)
1802  {
1804  }
1805 
1806  return STATUS_SUCCESS;
1807 }
1808 
1809 static NTSTATUS FASTCALL
1811  HWINSTA hWindowStation,
1812  ULONG dwSize,
1813  PVOID lpBuffer,
1814  PULONG pRequiredSize)
1815 {
1816  NTSTATUS Status;
1817  PWINSTATION_OBJECT WindowStation;
1818  PLIST_ENTRY DesktopEntry;
1819  PDESKTOP DesktopObject;
1820  DWORD EntryCount;
1822  WCHAR NullWchar;
1823  UNICODE_STRING DesktopName;
1824 
1825  Status = IntValidateWindowStationHandle(hWindowStation,
1826  UserMode,
1827  0,
1828  &WindowStation,
1829  NULL);
1830  if (! NT_SUCCESS(Status))
1831  {
1832  return Status;
1833  }
1834 
1835  /*
1836  * Count the required size of buffer.
1837  */
1838  ReturnLength = sizeof(DWORD);
1839  EntryCount = 0;
1840  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1841  DesktopEntry != &WindowStation->DesktopListHead;
1842  DesktopEntry = DesktopEntry->Flink)
1843  {
1844  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1845  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1846  ReturnLength += DesktopName.Length + sizeof(WCHAR);
1847  EntryCount++;
1848  }
1849  TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1850  if (NULL != pRequiredSize)
1851  {
1852  Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1853  if (! NT_SUCCESS(Status))
1854  {
1855  ObDereferenceObject(WindowStation);
1856  return STATUS_BUFFER_TOO_SMALL;
1857  }
1858  }
1859 
1860  /*
1861  * Check if the supplied buffer is large enough.
1862  */
1863  if (dwSize < ReturnLength)
1864  {
1865  ObDereferenceObject(WindowStation);
1866  return STATUS_BUFFER_TOO_SMALL;
1867  }
1868 
1869  /*
1870  * Generate the resulting buffer contents.
1871  */
1872  Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1873  if (! NT_SUCCESS(Status))
1874  {
1875  ObDereferenceObject(WindowStation);
1876  return Status;
1877  }
1878  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1879 
1880  NullWchar = L'\0';
1881  for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1882  DesktopEntry != &WindowStation->DesktopListHead;
1883  DesktopEntry = DesktopEntry->Flink)
1884  {
1885  DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1886  RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1887  Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
1888  if (! NT_SUCCESS(Status))
1889  {
1890  ObDereferenceObject(WindowStation);
1891  return Status;
1892  }
1893  lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
1894  Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1895  if (! NT_SUCCESS(Status))
1896  {
1897  ObDereferenceObject(WindowStation);
1898  return Status;
1899  }
1900  lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1901  }
1902 
1903  /*
1904  * Clean up and return
1905  */
1906  ObDereferenceObject(WindowStation);
1907  return STATUS_SUCCESS;
1908 }
1909 
1910 /*
1911  * NtUserBuildNameList
1912  *
1913  * Function used for enumeration of desktops or window stations.
1914  *
1915  * Parameters
1916  * hWinSta
1917  * For enumeration of window stations this parameter must be set to
1918  * zero. Otherwise it's handle for window station.
1919  *
1920  * dwSize
1921  * Size of buffer passed by caller.
1922  *
1923  * lpBuffer
1924  * Buffer passed by caller. If the function succeeds, the buffer is
1925  * filled with window station/desktop count (in first DWORD) and
1926  * NULL-terminated window station/desktop names.
1927  *
1928  * pRequiredSize
1929  * If the function succeeds, this is the number of bytes copied.
1930  * Otherwise it's size of buffer needed for function to succeed.
1931  *
1932  * Status
1933  * @implemented
1934  */
1935 
1938  HWINSTA hWindowStation,
1939  ULONG dwSize,
1940  PVOID lpBuffer,
1941  PULONG pRequiredSize)
1942 {
1943  /* The WindowStation name list and desktop name list are build in completely
1944  different ways. Call the appropriate function */
1945  return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
1946  BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
1947 }
1948 
1949 /*
1950  * @implemented
1951  */
1952 BOOL APIENTRY
1954 {
1956  {
1957  return FALSE;
1958  }
1959 
1960  if (!IntIsWindow(hWnd))
1961  {
1962  return FALSE;
1963  }
1964 
1965  hwndSAS = hWnd;
1966 
1967  return TRUE;
1968 }
1969 
1970 BOOL
1971 APIENTRY
1973 {
1974  BOOL ret;
1976 
1978 
1979  if (pti->rpdesk == IntGetActiveDesktop())
1980  {
1982  }
1983  else
1984  {
1985  ret = FALSE;
1986  }
1987 
1988  UserLeave();
1989 
1990  return ret;
1991 }
1992 
1993 BOOL
1994 NTAPI
1996  IN HWINSTA hWindowStation,
1997  IN PLUID pluid,
1998  IN PSID psid OPTIONAL,
1999  IN DWORD size)
2000 {
2001  BOOL Ret = FALSE;
2002  NTSTATUS Status;
2003  PWINSTATION_OBJECT WindowStation = NULL;
2004  LUID luidUser;
2005 
2007 
2009  {
2011  goto Leave;
2012  }
2013 
2014  /* Validate the window station */
2015  Status = IntValidateWindowStationHandle(hWindowStation,
2016  UserMode,
2017  0,
2018  &WindowStation,
2019  NULL);
2020  if (!NT_SUCCESS(Status))
2021  {
2022  goto Leave;
2023  }
2024 
2025  /* Capture the user LUID */
2026  _SEH2_TRY
2027  {
2028  ProbeForRead(pluid, sizeof(LUID), 1);
2029  luidUser = *pluid;
2030  }
2032  {
2034  _SEH2_YIELD(goto Leave);
2035  }
2036  _SEH2_END;
2037 
2038  /* Reset the window station user LUID */
2039  RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
2040 
2041  /* Reset the window station user SID */
2042  if (WindowStation->psidUser)
2043  {
2044  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2045  WindowStation->psidUser = NULL;
2046  }
2047 
2048  /* Copy the new user SID if one has been provided */
2049  if (psid)
2050  {
2052  if (WindowStation->psidUser == NULL)
2053  {
2055  goto Leave;
2056  }
2057 
2059  _SEH2_TRY
2060  {
2061  ProbeForRead(psid, size, 1);
2062  RtlCopyMemory(WindowStation->psidUser, psid, size);
2063  }
2065  {
2067  }
2068  _SEH2_END;
2069 
2070  if (!NT_SUCCESS(Status))
2071  {
2072  ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
2073  WindowStation->psidUser = NULL;
2074  goto Leave;
2075  }
2076  }
2077 
2078  /* Copy the new user LUID */
2079  WindowStation->luidUser = luidUser;
2080 
2081  Ret = TRUE;
2082 
2083 Leave:
2084  if (WindowStation)
2085  ObDereferenceObject(WindowStation);
2086 
2087  UserLeave();
2088  return Ret;
2089 }
2090 
2091 /* 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:2532
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:1541
#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:1353
NTSTATUS APIENTRY NtUserBuildNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1937
#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:262
#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:1972
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:731
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:872
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:1953
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
KPROCESSOR_MODE AccessMode
Definition: pstypes.h:1672
LIST_ENTRY DesktopListHead
Definition: winsta.h:19
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:257
#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:88
#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
struct tagKL * spklList
Definition: winsta.h:23
#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:138
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:447
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:9
_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:1339
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:371
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1827
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1810
NTSTATUS FASTCALL IntValidateWindowStationHandle(HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
Definition: winsta.c:232
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
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:795
#define WSF_VISIBLE
Definition: winuser.h:2442
#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:1585
_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:377
__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:1019
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:17
#define UserEnterCo
Definition: ntuser.h:8
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:358
int ret
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
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:1382
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:469
BOOL NTAPI NtUserSetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:1995
NTSTATUS NTAPI IntWinStaOkToClose(_In_ PVOID Parameters)
Definition: winsta.c:203
#define WSS_LOCKED
Definition: winsta.h:7
static NTSTATUS FASTCALL BuildWindowStationNameList(ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1622
#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:1617
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:20
_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:2935
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:258
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:1237
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:608
#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:1518
#define MAXUSHORT
Definition: typedefs.h:83
HWINSTA APIENTRY NtUserGetProcessWindowStation(VOID)
Definition: winsta.c:1376
#define MEM_RELEASE
Definition: nt_native.h:1316
BOOL APIENTRY NtUserGetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength, PDWORD nLengthNeeded)
Definition: winsta.c:1099
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:574
PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj)
Definition: object.c:861
#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:39
_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:1262
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:32
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
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
Definition: winsta.c:400
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
ACCESS_MASK amwinsta
Definition: win32.h:259
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:1635
_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