ReactOS 0.4.17-dev-684-ga6524ef
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>
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 */
29
30/* INITIALIZATION FUNCTIONS ****************************************************/
31
32CODE_SEG("INIT")
36{
37 GENERIC_MAPPING IntWindowStationMapping = { WINSTA_READ,
41
42 /* Set Winsta Object Attributes */
44 ExWindowStationObjectType->TypeInfo.GenericMapping = IntWindowStationMapping;
46
47 return STATUS_SUCCESS;
48}
49
53{
57 WCHAR wstrWindowStationsDir[MAX_PATH];
58
59 /* Create the WindowStations directory and cache its path for later use */
61 if (SessionId == 0)
62 {
65 }
66 else
67 {
68 Status = RtlStringCbPrintfW(wstrWindowStationsDir,
69 sizeof(wstrWindowStationsDir),
70 L"%ws\\%lu%ws",
74 if (!NT_SUCCESS(Status))
75 return Status;
76
77 if (!RtlCreateUnicodeString(&gustrWindowStationsDir, wstrWindowStationsDir))
79 }
80
84 NULL,
85 NULL);
87 if (!NT_SUCCESS(Status))
88 ERR("Could not create %wZ directory (Status 0x%X)\n", &gustrWindowStationsDir, Status);
89 else
90 TRACE("Created directory %wZ for session %lu\n", &gustrWindowStationsDir, SessionId);
91
92 return Status;
93}
94
95/* OBJECT CALLBACKS ***********************************************************/
96
101{
103 PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeleteParameters->Object;
104
105 TRACE("Deleting window station 0x%p\n", WinSta);
106
107 WinSta->Flags |= WSS_DYING;
108
109 if (WinSta == InputWindowStation)
110 {
111 ERR("WARNING: Deleting the interactive window station '%wZ'!\n",
113
114 /* The window station must NOT be tagged as non-interactive */
115 ASSERT(!(WinSta->Flags & WSS_NOIO));
116
117 /* Only Winlogon can close and delete the interactive window station */
119
121
122 /* Signal and cleanup the global desktop-switch event */
124 {
126
130
131 /* Close the handle in the CSRSS process */
137 }
138 }
139
141
143
145
146 return STATUS_SUCCESS;
147}
148
150NTAPI
153{
156
157 /* Assume we don't find anything */
158 *ParseParameters->Object = NULL;
159
160 /* Check for an empty name */
161 if (!RemainingName->Length)
162 {
163 /* Make sure this is a window station, can't parse a desktop now */
164 if (ParseParameters->ObjectType != ExWindowStationObjectType)
165 {
166 /* Fail */
168 }
169
170 /* Reference the window station and return */
171 ObReferenceObject(ParseParameters->ParseObject);
172 *ParseParameters->Object = ParseParameters->ParseObject;
173 return STATUS_SUCCESS;
174 }
175
176 /* Check for leading slash */
177 if (RemainingName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
178 {
179 /* Skip it */
180 RemainingName->Buffer++;
181 RemainingName->Length -= sizeof(WCHAR);
182 RemainingName->MaximumLength -= sizeof(WCHAR);
183 }
184
185 /* Check if there is still a slash */
187 {
188 /* In this case, fail */
190 }
191
192 /*
193 * Check if we are parsing a desktop.
194 */
195 if (ParseParameters->ObjectType == ExDesktopObjectType)
196 {
197 /* Then call the desktop parse routine */
198 return IntDesktopObjectParse(ParseParameters->ParseObject,
199 ParseParameters->ObjectType,
200 ParseParameters->AccessState,
201 ParseParameters->AccessMode,
202 ParseParameters->Attributes,
203 ParseParameters->CompleteName,
205 ParseParameters->Context,
206 ParseParameters->SecurityQos,
207 ParseParameters->Object);
208 }
209
210 /* Should hopefully never get here */
212}
213
215NTAPI
218{
220 PPROCESSINFO ppi;
221
223
224 if (ppi && (OkToCloseParameters->Handle == ppi->hwinsta))
225 {
227 }
228
229 return STATUS_SUCCESS;
230}
231
232/* PRIVATE FUNCTIONS **********************************************************/
233
234/*
235 * IntValidateWindowStationHandle
236 *
237 * Validates the window station handle.
238 *
239 * Remarks
240 * If the function succeeds, the handle remains referenced.
241 * If the function fails, last error is set.
242 */
245 HWINSTA WindowStation,
249 POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
250{
252
253 if (WindowStation == NULL)
254 {
255 ERR("Invalid window station handle\n");
258 }
259
260 Status = ObReferenceObjectByHandle(WindowStation,
264 (PVOID*)Object,
265 pObjectHandleInfo);
266
267 if (!NT_SUCCESS(Status))
269
270 return Status;
271}
272
275{
276 TEXTMETRICW tmw;
277 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
278 PDESKTOP pdesk;
279 LONG lRet;
280
282 if (lRet != DISP_CHANGE_SUCCESSFUL && !gbBaseVideo)
283 {
284 ERR("Failed to initialize graphics, switching to base video\n");
290 }
291 if (lRet != DISP_CHANGE_SUCCESSFUL)
292 {
293 ERR("PDEVOBJ_lChangeDisplaySettings() failed.\n");
294 return FALSE;
295 }
296
299 {
301 return FALSE;
302 }
304
306 {
307 return FALSE;
308 }
309
311
314
315 /* Update the system metrics */
316 InitMetrics();
317
318 /* Set new size of the monitor */
320
321 /* Update the SERVERINFO */
326 gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
329 {
330 gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
331 }
332 else
333 {
334 gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
335 }
336 // Font is realized and this dc was previously set to internal DC_ATTR.
337 gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
338 gpsi->tmSysFont = tmw;
339
340 /* Put the pointer in the center of the screen */
341 gpsi->ptCursor.x = gpsi->aiSysMet[SM_CXSCREEN] / 2;
342 gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2;
343
344 /* Attach monitor */
346
347 /* Setup the cursor */
349
350 /* Setup the icons */
352
353 /* Setup Menu */
354 MenuInit();
355
356 /* Show the desktop */
357 pdesk = IntGetActiveDesktop();
358 ASSERT(pdesk);
359 co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE);
360
361 /* HACK: display wallpaper on all secondary displays */
362 {
363 PGRAPHICS_DEVICE pGraphicsDevice;
364 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
365 UNICODE_STRING DisplayName;
366 HDC hdc;
367 ULONG iDevNum;
368
369 for (iDevNum = 1; (pGraphicsDevice = EngpFindGraphicsDevice(NULL, iDevNum)) != NULL; iDevNum++)
370 {
371 RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
372 hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
374 }
375 }
376
377 return TRUE;
378}
379
382{
384 { // No need to allocate a new dcattr.
388 }
391}
392
395{
396 return ScreenDeviceContext;
397}
398
401{
404 {
405 if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
406 {
407 ERR("Requires Interactive Window Station\n");
409 return FALSE;
410 }
412 {
413 ERR("Access Denied\n");
415 return FALSE;
416 }
417 }
418 return TRUE;
419}
420
423{
424 PWINSTATION_OBJECT pWinSta;
426 HWINSTA hWinSta = ppi->hwinsta;
427 if (phWinSta)
428 *phWinSta = hWinSta;
429 IntValidateWindowStationHandle(hWinSta, UserMode, 0, &pWinSta, 0);
430 return pWinSta;
431}
432
433/* PUBLIC FUNCTIONS ***********************************************************/
434
439static NTSTATUS
441{
444 HANDLE BnoHandle, EventHandle;
446 SECURITY_DESCRIPTOR EventSd;
448 WCHAR BnoBuffer[50];
449
450 /* We must not be called more than once */
454
455 /* Open the per-session BaseNamedObjects directory */
456 SessionId = PsGetCurrentProcessSessionId(); // gSessionId
457 if (SessionId)
458 {
459 RtlStringCbPrintfW(BnoBuffer, sizeof(BnoBuffer),
460 L"\\Sessions\\%lu\\BaseNamedObjects",
461 /*SESSION_DIR,*/ SessionId);
462 RtlInitUnicodeString(&Name, BnoBuffer);
463 }
464 else
465 {
466 RtlInitUnicodeString(&Name, L"\\BaseNamedObjects");
467 }
469 &Name,
471 NULL,
472 NULL);
473 Status = ZwOpenDirectoryObject(&BnoHandle,
476 if (!NT_SUCCESS(Status))
477 {
478 ERR("Failed to open '%wZ', Status 0x%08lx\n", &Name, Status);
479 return Status;
480 }
481
482 /* Build a security descriptor for SYNCHRONIZE world-access for the event */
483 // TODO: Modularize together with some functions in security.c
484 {
485 PACL Dacl;
487
488 /* Initialize the absolute security descriptor */
491 {
492 ERR("Failed to initialize absolute SD, Status 0x%08lx\n", Status);
493 goto Quit;
494 }
495
496 DaclSize = sizeof(ACL) +
498
499 /* Allocate memory for the DACL */
501 if (!Dacl)
502 {
503 ERR("Failed to allocate memory for service DACL!\n");
505 goto Quit;
506 }
507
508 /* Now create the DACL */
510 if (!NT_SUCCESS(Status))
511 {
512 ERR("Failed to create service DACL, Status 0x%08lx\n", Status);
514 goto Quit;
515 }
516
517 /* Everyone has the right to synchronize with the desktop switch event */
520 if (!NT_SUCCESS(Status))
521 {
522 ERR("Failed to set up window station ACE for authenticated user, Status 0x%08lx\n", Status);
524 goto Quit;
525 }
526
527 /* Set the DACL for the absolute SD */
530 {
531 ERR("Failed to set up DACL for absolute SD, Status 0x%08lx\n", Status);
533 goto Quit;
534 }
535
536 /* No need for a SACL */
539
540 /* This descriptor is ownerless */
543
544 /* This descriptor has no primary group */
547 }
548
549 /* Create or open the named event in the BNO directory */
550 RtlInitUnicodeString(&Name, L"WinSta0_DesktopSwitch");
551
552 /*
553 * Create and obtain a user-mode handle to the switch event in the CSRSS
554 * process, so as to make it its owner and ensure the event name persists.
555 * Then, retrieve a pointer to the underlying event object.
556 *
557 * (*ALTERNATIVELY*, we could instead:
558 * create and obtain a kernel-mode handle to the event, and retrieve a
559 * pointer to the underlying event object. Only then, duplicate the handle
560 * into the CSRSS process to ensure the event name persists.)
561 */
562 {
564
568 &Name,
569 /* No OBJ_KERNEL_HANDLE: directly create a user-mode handle */
571 BnoHandle,
572 &EventSd);
573 Status = ZwCreateEvent(&EventHandle,
577 FALSE);
578 if (!NT_SUCCESS(Status))
579 {
580 ERR("Event '%wZ' creation failed, Status 0x%08lx\n", &Name, Status);
581 }
582 else
583 {
584 /* Reference the object and keep it global */
588 UserMode, // We use a user-mode handle
590 NULL);
591 if (NT_SUCCESS(Status))
592 {
593 /* We succeeded, keep the handle around to ensure the object name persists */
595 /*
596 * *ALTERNATIVELY*, we would duplicate the handle in the CSRSS process:
597 *
598 * KAPC_STATE ApcState;
599 * KeStackAttachProcess(&gpepCSRSS->Pcb, &ApcState);
600 * Status = ObOpenObjectByPointer(gpDesktopSwitchEvent,
601 * 0,
602 * NULL,
603 * EVENT_ALL_ACCESS,
604 * NULL,
605 * KernelMode,
606 * &ghDesktopSwitchEvent);
607 * KeUnstackDetachProcess(&ApcState);
608 *
609 * then close the original kernel handle:
610 * ObCloseHandle(EventHandle, KernelMode);
611 */
612 }
613 else
614 {
615 /* We failed, close the handle */
616 ERR("Failed to reference the event object, Status 0x%08lx\n", Status);
618 }
619 }
621 }
622
623 /* We are done with the SD DACL */
625Quit:
626 /* We don't need the BNO handle anymore */
627 ObCloseHandle(BnoHandle, KernelMode);
628
629 return Status;
630}
631
632/*
633 * NtUserCreateWindowStation
634 *
635 * Creates a new window station.
636 *
637 * Parameters
638 * lpszWindowStationName
639 * Pointer to a null-terminated string specifying the name of the
640 * window station to be created. Window station names are
641 * case-insensitive and cannot contain backslash characters (\‍).
642 * Only members of the Administrators group are allowed to specify a
643 * name.
644 *
645 * dwDesiredAccess
646 * Requested type of access
647 *
648 * lpSecurity
649 * Security descriptor
650 *
651 * Unknown3, Unknown4, Unknown5, Unknown6
652 * Unused
653 *
654 * Return Value
655 * If the function succeeds, the return value is a handle to the newly
656 * created window station. If the specified window station already
657 * exists, the function succeeds and returns a handle to the existing
658 * window station. If the function fails, the return value is NULL.
659 *
660 * Status
661 * @implemented
662 */
666 OUT HWINSTA* phWinSta,
669 IN KPROCESSOR_MODE OwnerMode,
670 IN ACCESS_MASK dwDesiredAccess,
671 DWORD Unknown2,
676{
678 HWINSTA hWinSta;
679 PWINSTATION_OBJECT WindowStation;
680
681 TRACE("IntCreateWindowStation called\n");
682
683 ASSERT(phWinSta);
684 *phWinSta = NULL;
685
689 NULL,
690 dwDesiredAccess,
691 NULL,
692 (PVOID*)&hWinSta);
693 if (NT_SUCCESS(Status))
694 {
695 TRACE("IntCreateWindowStation opened window station '%wZ'\n",
696 ObjectAttributes->ObjectName);
697 *phWinSta = hWinSta;
698 return Status;
699 }
700
701 /*
702 * No existing window station found, try to create a new one.
703 */
704
705 /* Create the window station object */
709 OwnerMode,
710 NULL,
711 sizeof(WINSTATION_OBJECT),
712 0,
713 0,
714 (PVOID*)&WindowStation);
715 if (!NT_SUCCESS(Status))
716 {
717 ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
718 ObjectAttributes->ObjectName, Status);
720 return Status;
721 }
722 RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
723
724 /* Assign the session ID to the window station */
725 WindowStation->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
726
727 /* Initialize the window station */
728 InitializeListHead(&WindowStation->DesktopListHead);
729 Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
730 if (!NT_SUCCESS(Status))
731 {
732 ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
733 ObjectAttributes->ObjectName, Status);
734 ObDereferenceObject(WindowStation);
736 return Status;
737 }
738
740 {
741 ERR("Initializing input window station\n");
742
743 /* Only Winlogon can create the interactive window station */
745
746 InputWindowStation = WindowStation;
747 WindowStation->Flags &= ~WSS_NOIO;
748 }
749 else
750 {
751 WindowStation->Flags |= WSS_NOIO;
752 }
753
754 /* Create the global WinSta0_DesktopSwitch event
755 * only when creating the interactive WinSta0 */
756 if (InputWindowStation == WindowStation)
757 {
759 if (!NT_SUCCESS(Status))
760 {
761 ObDereferenceObject(WindowStation);
763 return Status;
764 }
765 }
766
767 Status = ObInsertObject(WindowStation,
768 NULL,
769 dwDesiredAccess,
770 0,
771 NULL,
772 (PVOID*)&hWinSta);
773 if (!NT_SUCCESS(Status))
774 {
775 ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
776 /* WindowStation is dereferenced on ObInsertObject() failure */
778 return Status;
779 }
780
781 // FIXME! TODO: Add this new window station to a linked list
782
783 if (InputWindowStation == WindowStation)
784 {
785 ERR("Initializing input window station\n");
786
788
791
792 /* Desktop functions require the desktop thread running so wait for it to initialize */
793 UserLeaveCo();
796 UserMode,
797 FALSE,
798 NULL);
799 UserEnterCo();
800 }
801
802 TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
803 ObjectAttributes->ObjectName, WindowStation, hWinSta);
804
805 *phWinSta = hWinSta;
807 return STATUS_SUCCESS;
808}
809
810static VOID
812 IN OUT PUNICODE_STRING WindowStationName,
813 IN PUNICODE_STRING TebStaticUnicodeString,
814 IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL,
815 IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
816{
817 SIZE_T MemSize = 0;
818
819 /* Try to restore the user's UserModeObjectAttributes */
820 if (UserModeObjectAttributes && LocalObjectAttributes)
821 {
823 {
824 ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
825 *UserModeObjectAttributes = *LocalObjectAttributes;
826 }
828 {
829 NOTHING;
830 }
831 _SEH2_END;
832 }
833
834 /* Free the user-mode memory */
835 if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
836 {
837 ZwFreeVirtualMemory(ZwCurrentProcess(),
838 (PVOID*)&WindowStationName,
839 &MemSize,
841 }
842}
843
844static NTSTATUS
846 IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes,
847 IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes,
848 OUT PUNICODE_STRING* WindowStationName,
849 OUT PUNICODE_STRING* TebStaticUnicodeString)
850{
852 SIZE_T MemSize;
853
854 LUID CallerLuid;
855 PTEB Teb;
856 USHORT StrSize;
857
858 *WindowStationName = NULL;
859 *TebStaticUnicodeString = NULL;
860
861 /* Retrieve the current process LUID */
862 Status = GetProcessLuid(NULL, NULL, &CallerLuid);
863 if (!NT_SUCCESS(Status))
864 {
865 ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
866 return Status;
867 }
868
869 /* Compute the needed string size */
870 MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
872 CallerLuid.HighPart,
873 CallerLuid.LowPart);
874 MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
875 if (MemSize > MAXUSHORT)
876 {
877 ERR("Window station name length is too long.\n");
879 }
880 StrSize = (USHORT)MemSize;
881
882 /*
883 * Check whether it's short enough so that we can use the static buffer
884 * in the TEB. Otherwise continue with virtual memory allocation.
885 */
886 Teb = NtCurrentTeb();
887 if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
888 {
889 /* We can use the TEB's static unicode string */
892
893 /* Remember the TEB's static unicode string address for later */
894 *TebStaticUnicodeString = &Teb->StaticUnicodeString;
895
896 *WindowStationName = *TebStaticUnicodeString;
897 (*WindowStationName)->Length = 0;
898 }
899 else
900 {
901 /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
902 MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
903
904 /* Allocate the memory in user-mode */
905 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
906 (PVOID*)WindowStationName,
907 0,
908 &MemSize,
911 if (!NT_SUCCESS(Status))
912 {
913 ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
914 return Status;
915 }
916
917 RtlInitEmptyUnicodeString(*WindowStationName,
918 (PWCHAR)((ULONG_PTR)*WindowStationName +
919 ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
920 StrSize);
921 }
922
923 /* Build a valid window station name from the LUID */
924 Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
925 (*WindowStationName)->MaximumLength,
926 L"%wZ\\Service-0x%x-%x$",
928 CallerLuid.HighPart,
929 CallerLuid.LowPart);
930 if (!NT_SUCCESS(Status))
931 {
932 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
933 goto Quit;
934 }
935 (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
936
937 /* Try to update the user's UserModeObjectAttributes */
939 {
940 ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
941 *LocalObjectAttributes = *UserModeObjectAttributes;
942
943 UserModeObjectAttributes->ObjectName = *WindowStationName;
944 UserModeObjectAttributes->RootDirectory = NULL;
945
947 }
949 {
951 }
952 _SEH2_END;
953
954Quit:
955 if (!NT_SUCCESS(Status))
956 {
957 /* Release the window station name */
958 FreeUserModeWindowStationName(*WindowStationName,
959 *TebStaticUnicodeString,
960 NULL, NULL);
961 }
962
963 return Status;
964}
965
966HWINSTA
970 IN ACCESS_MASK dwDesiredAccess,
971 DWORD Unknown2,
976{
978 HWINSTA hWinSta = NULL;
979 OBJECT_ATTRIBUTES LocalObjectAttributes;
980 PUNICODE_STRING WindowStationName = NULL;
981 PUNICODE_STRING TebStaticUnicodeString = NULL;
982 KPROCESSOR_MODE OwnerMode = UserMode;
983
984 TRACE("NtUserCreateWindowStation called\n");
985
986 /* Capture the object attributes and the window station name */
988 {
990 LocalObjectAttributes = *ObjectAttributes;
991 if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
992 {
993 ERR("Invalid ObjectAttributes length!\n");
996 }
997
998 /*
999 * Check whether the caller provided a window station name together
1000 * with a RootDirectory handle.
1001 *
1002 * If the caller did not provide a window station name, build a new one
1003 * based on the logon session identifier for the calling process.
1004 * The new name is allocated in user-mode, as the rest of ObjectAttributes
1005 * already is, so that the validation performed by the Object Manager
1006 * can be done adequately.
1007 */
1008 if ((LocalObjectAttributes.ObjectName == NULL ||
1009 LocalObjectAttributes.ObjectName->Buffer == NULL ||
1010 LocalObjectAttributes.ObjectName->Length == 0 ||
1011 LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
1012 /* &&
1013 LocalObjectAttributes.RootDirectory == NULL */)
1014 {
1015 /* No, build the new window station name */
1017 &LocalObjectAttributes,
1018 &WindowStationName,
1019 &TebStaticUnicodeString);
1020 if (!NT_SUCCESS(Status))
1021 {
1022 ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
1024 }
1025 OwnerMode = KernelMode;
1026 }
1027 }
1029 {
1031 ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
1032 }
1033 _SEH2_END;
1034
1035 if (!NT_SUCCESS(Status))
1036 {
1038 return NULL;
1039 }
1040
1042
1043 /* Create the window station */
1044 Status = IntCreateWindowStation(&hWinSta,
1046 UserMode,
1047 OwnerMode,
1048 dwDesiredAccess,
1049 Unknown2,
1050 Unknown3,
1051 Unknown4,
1052 Unknown5,
1053 Unknown6);
1054 UserLeave();
1055
1056 if (NT_SUCCESS(Status))
1057 {
1058 TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
1059 ObjectAttributes->ObjectName, hWinSta);
1060 }
1061 else
1062 {
1063 ASSERT(hWinSta == NULL);
1064 ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
1065 ObjectAttributes->ObjectName, Status);
1066 }
1067
1068 /* Try to restore the user's ObjectAttributes and release the window station name */
1069 FreeUserModeWindowStationName(WindowStationName,
1070 TebStaticUnicodeString,
1071 (OwnerMode == KernelMode ? ObjectAttributes : NULL),
1072 &LocalObjectAttributes);
1073
1074 if (!NT_SUCCESS(Status))
1075 {
1076 ASSERT(hWinSta == NULL);
1078 }
1079
1080 return hWinSta;
1081}
1082
1083/*
1084 * NtUserOpenWindowStation
1085 *
1086 * Opens an existing window station.
1087 *
1088 * Parameters
1089 * lpszWindowStationName
1090 * Name of the existing window station.
1091 *
1092 * dwDesiredAccess
1093 * Requested type of access.
1094 *
1095 * Return Value
1096 * If the function succeeds, the return value is the handle to the
1097 * specified window station. If the function fails, the return value
1098 * is NULL.
1099 *
1100 * Remarks
1101 * The returned handle can be closed with NtUserCloseWindowStation.
1102 *
1103 * Status
1104 * @implemented
1105 */
1106HWINSTA
1110 IN ACCESS_MASK dwDesiredAccess)
1111{
1113 HWINSTA hWinSta = NULL;
1114 OBJECT_ATTRIBUTES LocalObjectAttributes;
1115 PUNICODE_STRING WindowStationName = NULL;
1116 PUNICODE_STRING TebStaticUnicodeString = NULL;
1117 KPROCESSOR_MODE OwnerMode = UserMode;
1118
1119 TRACE("NtUserOpenWindowStation called\n");
1120
1121 /* Capture the object attributes and the window station name */
1122 _SEH2_TRY
1123 {
1125 LocalObjectAttributes = *ObjectAttributes;
1126 if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
1127 {
1128 ERR("Invalid ObjectAttributes length!\n");
1131 }
1132
1133 /*
1134 * Check whether the caller did not provide a window station name,
1135 * or provided the special "Service-0x00000000-00000000$" name.
1136 *
1137 * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
1138 * is used instead of an empty name (observed when API-monitoring
1139 * OpenWindowStation() called with an empty window station name).
1140 */
1141 if ((LocalObjectAttributes.ObjectName == NULL ||
1142 LocalObjectAttributes.ObjectName->Buffer == NULL ||
1143 LocalObjectAttributes.ObjectName->Length == 0 ||
1144 LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
1145 /* &&
1146 LocalObjectAttributes.RootDirectory == NULL */)
1147 {
1148 /* No, remember that for later */
1149 LocalObjectAttributes.ObjectName = NULL;
1150 }
1151 if (LocalObjectAttributes.ObjectName &&
1152 LocalObjectAttributes.ObjectName->Length ==
1153 sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
1154 _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
1155 L"Service-0x00000000-00000000$",
1156 LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
1157 {
1158 /* No, remember that for later */
1159 LocalObjectAttributes.ObjectName = NULL;
1160 }
1161
1162 /*
1163 * If the caller did not provide a window station name, build a new one
1164 * based on the logon session identifier for the calling process.
1165 * The new name is allocated in user-mode, as the rest of ObjectAttributes
1166 * already is, so that the validation performed by the Object Manager
1167 * can be done adequately.
1168 */
1169 if (!LocalObjectAttributes.ObjectName)
1170 {
1171 /* No, build the new window station name */
1173 &LocalObjectAttributes,
1174 &WindowStationName,
1175 &TebStaticUnicodeString);
1176 if (!NT_SUCCESS(Status))
1177 {
1178 ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
1180 }
1181 OwnerMode = KernelMode;
1182 }
1183 }
1185 {
1187 ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
1188 }
1189 _SEH2_END;
1190
1191 if (!NT_SUCCESS(Status))
1192 {
1194 return NULL;
1195 }
1196
1197 /* Open the window station */
1200 UserMode,
1201 NULL,
1202 dwDesiredAccess,
1203 NULL,
1204 (PVOID*)&hWinSta);
1205 if (NT_SUCCESS(Status))
1206 {
1207 TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
1208 ObjectAttributes->ObjectName, hWinSta);
1209 }
1210 else
1211 {
1212 ASSERT(hWinSta == NULL);
1213 ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
1214 ObjectAttributes->ObjectName, Status);
1215 }
1216
1217 /* Try to restore the user's ObjectAttributes and release the window station name */
1218 FreeUserModeWindowStationName(WindowStationName,
1219 TebStaticUnicodeString,
1220 (OwnerMode == KernelMode ? ObjectAttributes : NULL),
1221 &LocalObjectAttributes);
1222
1223 if (!NT_SUCCESS(Status))
1224 {
1225 ASSERT(hWinSta == NULL);
1227 }
1228
1229 return hWinSta;
1230}
1231
1232/*
1233 * NtUserCloseWindowStation
1234 *
1235 * Closes a window station handle.
1236 *
1237 * Parameters
1238 * hWinSta
1239 * Handle to the window station.
1240 *
1241 * Return Value
1242 * Status
1243 *
1244 * Remarks
1245 * The window station handle can be created with NtUserCreateWindowStation
1246 * or NtUserOpenWindowStation. Attempts to close a handle to the window
1247 * station assigned to the calling process will fail.
1248 *
1249 * Status
1250 * @implemented
1251 */
1252BOOL
1255 HWINSTA hWinSta)
1256{
1259
1260 TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
1261
1262 if (hWinSta == UserGetProcessWindowStation())
1263 {
1264 ERR("Attempted to close process window station\n");
1265 return FALSE;
1266 }
1267
1269 UserMode,
1270 0,
1271 &Object,
1272 NULL);
1273 if (!NT_SUCCESS(Status))
1274 {
1275 ERR("Validation of window station handle (%p) failed\n", hWinSta);
1276 return FALSE;
1277 }
1278
1280
1281 TRACE("Closing window station handle (%p)\n", hWinSta);
1282
1283 Status = ObCloseHandle(hWinSta, UserMode);
1284 if (!NT_SUCCESS(Status))
1285 {
1287 return FALSE;
1288 }
1289
1290 return TRUE;
1291}
1292
1293/*
1294 * NtUserGetObjectInformation
1295 *
1296 * The NtUserGetObjectInformation function retrieves information about a
1297 * window station or desktop object.
1298 *
1299 * Parameters
1300 * hObj
1301 * Handle to the window station or desktop object for which to
1302 * return information. This can be a handle of type HDESK or HWINSTA
1303 * (for example, a handle returned by NtUserCreateWindowStation,
1304 * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
1305 *
1306 * nIndex
1307 * Specifies the object information to be retrieved.
1308 *
1309 * pvInfo
1310 * Pointer to a buffer to receive the object information.
1311 *
1312 * nLength
1313 * Specifies the size, in bytes, of the buffer pointed to by the
1314 * pvInfo parameter.
1315 *
1316 * lpnLengthNeeded
1317 * Pointer to a variable receiving the number of bytes required to
1318 * store the requested information. If this variable's value is
1319 * greater than the value of the nLength parameter when the function
1320 * returns, the function returns FALSE, and none of the information
1321 * is copied to the pvInfo buffer. If the value of the variable pointed
1322 * to by lpnLengthNeeded is less than or equal to the value of nLength,
1323 * the entire information block is copied.
1324 *
1325 * Return Value
1326 * If the function succeeds, the return value is nonzero. If the function
1327 * fails, the return value is zero.
1328 *
1329 * Status
1330 * @unimplemented
1331 */
1334 HANDLE hObject,
1335 DWORD nIndex,
1336 PVOID pvInformation,
1337 DWORD nLength,
1338 PDWORD nLengthNeeded)
1339{
1341 PWINSTATION_OBJECT WinStaObject = NULL;
1342 PDESKTOP DesktopObject = NULL;
1343 POBJECT_HEADER ObjectHeader;
1344 POBJECT_HEADER_NAME_INFO NameInfo;
1345 OBJECT_HANDLE_INFORMATION HandleInfo;
1346 USEROBJECTFLAGS ObjectFlags;
1347 PUNICODE_STRING pStrNameU = NULL;
1348 PVOID pvData = NULL;
1349 SIZE_T nDataSize = 0;
1350
1351 _SEH2_TRY
1352 {
1353 if (nLengthNeeded)
1354 ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1355 ProbeForWrite(pvInformation, nLength, 1);
1356 }
1358 {
1360 return FALSE;
1361 }
1362 _SEH2_END;
1363
1364 /* Try window station */
1365 TRACE("Trying to open window station 0x%p\n", hObject);
1367 0,
1369 UserMode,
1370 (PVOID*)&WinStaObject,
1371 &HandleInfo);
1372
1374 {
1375 /* Try desktop */
1376 TRACE("Trying to open desktop %p\n", hObject);
1377 WinStaObject = NULL;
1379 UserMode,
1380 0,
1381 &DesktopObject);
1382 }
1383
1384 if (!NT_SUCCESS(Status))
1385 {
1386 ERR("Failed: 0x%x\n", Status);
1387 goto Exit;
1388 }
1389
1390 TRACE("WinSta or Desktop opened!\n");
1391
1392 /* Get data */
1393 switch (nIndex)
1394 {
1395 case UOI_FLAGS:
1396 {
1397 ObjectFlags.fReserved = FALSE;
1398 ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1399
1400 ObjectFlags.dwFlags = 0;
1401 if (WinStaObject != NULL)
1402 {
1403 if (!(WinStaObject->Flags & WSS_NOIO))
1404 ObjectFlags.dwFlags |= WSF_VISIBLE;
1405 }
1406 else if (DesktopObject != NULL)
1407 {
1408 FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1409 }
1410 else
1411 {
1412 ERR("No associated WinStaObject nor DesktopObject!\n");
1413 }
1414
1415 pvData = &ObjectFlags;
1416 nDataSize = sizeof(ObjectFlags);
1418 break;
1419 }
1420
1421 case UOI_NAME:
1422 {
1423 if (WinStaObject != NULL)
1424 {
1425 ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1426 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1427
1428 if (NameInfo && (NameInfo->Name.Length > 0))
1429 {
1430 /* Named window station */
1431 pStrNameU = &NameInfo->Name;
1432 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1433 }
1434 else
1435 {
1436 /* Unnamed window station (should never happen!) */
1437 ASSERT(FALSE);
1438 pStrNameU = NULL;
1439 nDataSize = sizeof(UNICODE_NULL);
1440 }
1442 }
1443 else if (DesktopObject != NULL)
1444 {
1445 pvData = DesktopObject->pDeskInfo->szDesktopName;
1446 nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1448 }
1449 else
1450 {
1452 }
1453 break;
1454 }
1455
1456 case UOI_TYPE:
1457 {
1458 if (WinStaObject != NULL)
1459 {
1460 ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1461 pStrNameU = &ObjectHeader->Type->Name;
1462 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1464 }
1465 else if (DesktopObject != NULL)
1466 {
1467 ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1468 pStrNameU = &ObjectHeader->Type->Name;
1469 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1471 }
1472 else
1473 {
1475 }
1476 break;
1477 }
1478
1479 case UOI_USER_SID:
1481 ERR("UOI_USER_SID unimplemented!\n");
1482 break;
1483
1484 default:
1486 break;
1487 }
1488
1489Exit:
1490 if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1492
1493 _SEH2_TRY
1494 {
1495 if (nLengthNeeded)
1496 *nLengthNeeded = nDataSize;
1497
1498 /* Try to copy data to caller */
1499 if (Status == STATUS_SUCCESS && (nDataSize > 0))
1500 {
1501 TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1502 if (pvData)
1503 {
1504 /* Copy the data */
1505 RtlCopyMemory(pvInformation, pvData, nDataSize);
1506 }
1507 else if (pStrNameU)
1508 {
1509 /* Copy and NULL-terminate the string */
1510 RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1511 ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1512 }
1513 else
1514 {
1515 /* Zero the memory */
1516 RtlZeroMemory(pvInformation, nDataSize);
1517 }
1518 }
1519 }
1521 {
1523 }
1524 _SEH2_END;
1525
1526 /* Release objects */
1527 if (DesktopObject != NULL)
1528 ObDereferenceObject(DesktopObject);
1529 if (WinStaObject != NULL)
1530 ObDereferenceObject(WinStaObject);
1531
1532 if (!NT_SUCCESS(Status))
1533 {
1535 return FALSE;
1536 }
1537
1538 return TRUE;
1539}
1540
1541/*
1542 * NtUserSetObjectInformation
1543 *
1544 * The NtUserSetObjectInformation function sets information about a
1545 * window station or desktop object.
1546 *
1547 * Parameters
1548 * hObj
1549 * Handle to the window station or desktop object for which to set
1550 * object information. This value can be a handle of type HDESK or
1551 * HWINSTA.
1552 *
1553 * nIndex
1554 * Specifies the object information to be set.
1555 *
1556 * pvInfo
1557 * Pointer to a buffer containing the object information.
1558 *
1559 * nLength
1560 * Specifies the size, in bytes, of the information contained in the
1561 * buffer pointed to by pvInfo.
1562 *
1563 * Return Value
1564 * If the function succeeds, the return value is nonzero. If the function
1565 * fails the return value is zero.
1566 *
1567 * Status
1568 * @unimplemented
1569 */
1570BOOL
1573 HANDLE hObject,
1574 DWORD nIndex,
1575 PVOID pvInformation,
1576 DWORD nLength)
1577{
1578 /* FIXME: ZwQueryObject */
1579 /* FIXME: ZwSetInformationObject */
1581 return FALSE;
1582}
1583
1584
1585HWINSTA FASTCALL
1587{
1589
1590 return ppi->hwinsta;
1591}
1592
1593
1594/*
1595 * NtUserGetProcessWindowStation
1596 *
1597 * Returns a handle to the current process window station.
1598 *
1599 * Return Value
1600 * If the function succeeds, the return value is handle to the window
1601 * station assigned to the current process. If the function fails, the
1602 * return value is NULL.
1603 *
1604 * Status
1605 * @implemented
1606 */
1607HWINSTA APIENTRY
1609{
1611}
1612
1614UserSetProcessWindowStation(HWINSTA hWindowStation)
1615{
1617 PPROCESSINFO ppi;
1618 OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1619 PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1620 HWINSTA hCacheWinSta;
1621
1623
1624 /* Reference the new window station */
1625 if (hWindowStation != NULL)
1626 {
1627 Status = IntValidateWindowStationHandle(hWindowStation,
1628 UserMode,
1629 0,
1630 &NewWinSta,
1631 &ObjectHandleInfo);
1632 if (!NT_SUCCESS(Status))
1633 {
1634 TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1636 return FALSE;
1637 }
1638 }
1639
1640 OldWinSta = ppi->prpwinsta;
1641 hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1642
1643 /* Dereference the previous window station */
1644 if (OldWinSta != NULL)
1645 {
1646 ObDereferenceObject(OldWinSta);
1647 }
1648
1649 /*
1650 * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1651 */
1652
1653 /* Close the cached EPROCESS window station handle if needed */
1654 if (hCacheWinSta != NULL)
1655 {
1656 /* Reference the window station */
1657 Status = ObReferenceObjectByHandle(hCacheWinSta,
1658 0,
1660 UserMode,
1661 (PVOID*)&OldWinSta,
1662 NULL);
1663 if (!NT_SUCCESS(Status))
1664 {
1665 ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1666 /* We failed, reset the cache */
1667 hCacheWinSta = NULL;
1668 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1669 }
1670 else
1671 {
1672 /*
1673 * Close the old handle and reset the cache only
1674 * if we are setting a different window station.
1675 */
1676 if (NewWinSta != OldWinSta)
1677 {
1678 ObCloseHandle(hCacheWinSta, UserMode);
1679 hCacheWinSta = NULL;
1680 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1681 }
1682
1683 /* Dereference the window station */
1684 ObDereferenceObject(OldWinSta);
1685 }
1686 }
1687
1688 /* Duplicate and save a new cached EPROCESS window station handle */
1689 if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1690 {
1691 Status = ZwDuplicateObject(ZwCurrentProcess(),
1692 hWindowStation,
1694 (PHANDLE)&hCacheWinSta,
1695 0,
1696 0,
1698 if (!NT_SUCCESS(Status))
1699 {
1700 ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1701 }
1702 else
1703 {
1704 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1705 }
1706 }
1707
1708 ppi->prpwinsta = NewWinSta;
1709 ppi->hwinsta = hWindowStation;
1710 ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1711 TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1712
1714 {
1715 ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1716 }
1717 else
1718 {
1719 ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1720 }
1721
1722 if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1723 {
1724 ppi->W32PF_flags |= W32PF_IOWINSTA;
1725 }
1726 else /* Might be closed if the handle is NULL */
1727 {
1728 ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1729 }
1730 return TRUE;
1731}
1732
1733/*
1734 * NtUserSetProcessWindowStation
1735 *
1736 * Assigns a window station to the current process.
1737 *
1738 * Parameters
1739 * hWinSta
1740 * Handle to the window station.
1741 *
1742 * Return Value
1743 * Status
1744 *
1745 * Status
1746 * @implemented
1747 */
1749NtUserSetProcessWindowStation(HWINSTA hWindowStation)
1750{
1751 BOOL ret;
1752
1754
1755 ret = UserSetProcessWindowStation(hWindowStation);
1756
1757 UserLeave();
1758
1759 return ret;
1760}
1761
1762/*
1763 * NtUserLockWindowStation
1764 *
1765 * Locks switching desktops. Only the logon application is allowed to call this function.
1766 *
1767 * Status
1768 * @implemented
1769 */
1771NtUserLockWindowStation(HWINSTA hWindowStation)
1772{
1775
1776 TRACE("About to set process window station with handle (%p)\n",
1777 hWindowStation);
1778
1780 {
1781 ERR("Unauthorized process attempted to lock the window station!\n");
1783 return FALSE;
1784 }
1785
1786 Status = IntValidateWindowStationHandle(hWindowStation,
1787 UserMode,
1788 0,
1789 &Object,
1790 NULL);
1791 if (!NT_SUCCESS(Status))
1792 {
1793 TRACE("Validation of window station handle (%p) failed\n",
1794 hWindowStation);
1796 return FALSE;
1797 }
1798
1799 Object->Flags |= WSS_LOCKED;
1800
1802 return TRUE;
1803}
1804
1805/*
1806 * NtUserUnlockWindowStation
1807 *
1808 * Unlocks switching desktops. Only the logon application is allowed to call this function.
1809 *
1810 * Status
1811 * @implemented
1812 */
1814NtUserUnlockWindowStation(HWINSTA hWindowStation)
1815{
1818 BOOL Ret;
1819
1820 TRACE("About to set process window station with handle (%p)\n",
1821 hWindowStation);
1822
1824 {
1825 ERR("Unauthorized process attempted to unlock the window station!\n");
1827 return FALSE;
1828 }
1829
1830 Status = IntValidateWindowStationHandle(hWindowStation,
1831 UserMode,
1832 0,
1833 &Object,
1834 NULL);
1835 if (!NT_SUCCESS(Status))
1836 {
1837 TRACE("Validation of window station handle (%p) failed\n",
1838 hWindowStation);
1840 return FALSE;
1841 }
1842
1843 Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1844 Object->Flags &= ~WSS_LOCKED;
1845
1847 return Ret;
1848}
1849
1850static NTSTATUS FASTCALL
1852 ULONG dwSize,
1854 PULONG pRequiredSize)
1855{
1859 char InitialBuffer[256], *Buffer;
1861 DWORD EntryCount;
1863 WCHAR NullWchar;
1864
1865 //
1866 // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1867 // with judicious parameters one can create window stations elsewhere
1868 // than in Windows\WindowStations directory, Win32k definitely MUST
1869 // maintain a list of window stations it has created, and not rely
1870 // on the enumeration of Windows\WindowStations !!!
1871 //
1872
1873 /*
1874 * Try to open the directory.
1875 */
1879 NULL,
1880 NULL);
1881
1885
1886 if (!NT_SUCCESS(Status))
1887 {
1888 return Status;
1889 }
1890
1891 /* First try to query the directory using a fixed-size buffer */
1892 Context = 0;
1893 Buffer = NULL;
1894 Status = ZwQueryDirectoryObject(DirectoryHandle,
1895 InitialBuffer,
1896 sizeof(InitialBuffer),
1897 FALSE,
1898 TRUE,
1899 &Context,
1900 &ReturnLength);
1901 if (NT_SUCCESS(Status))
1902 {
1903 if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1904 FALSE, &Context, NULL))
1905 {
1906 /* Our fixed-size buffer is large enough */
1907 Buffer = InitialBuffer;
1908 }
1909 }
1910
1911 if (NULL == Buffer)
1912 {
1913 /* Need a larger buffer, check how large exactly */
1914 Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1915 &ReturnLength);
1916 if (!NT_SUCCESS(Status))
1917 {
1918 ERR("ZwQueryDirectoryObject failed\n");
1920 return Status;
1921 }
1922
1925 if (NULL == Buffer)
1926 {
1928 return STATUS_NO_MEMORY;
1929 }
1930
1931 /* We should have a sufficiently large buffer now */
1932 Context = 0;
1933 Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1935 if (! NT_SUCCESS(Status) ||
1936 STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1937 FALSE, &Context, NULL))
1938 {
1939 /* Something went wrong, maybe someone added a directory entry? Just give up. */
1943 }
1944 }
1945
1947
1948 /*
1949 * Count the required size of buffer.
1950 */
1951 ReturnLength = sizeof(DWORD);
1952 EntryCount = 0;
1954 0 != DirEntry->Name.Length;
1955 DirEntry++)
1956 {
1957 ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1958 EntryCount++;
1959 }
1960 TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1961 if (NULL != pRequiredSize)
1962 {
1963 Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1964 if (! NT_SUCCESS(Status))
1965 {
1966 if (Buffer != InitialBuffer)
1967 {
1969 }
1971 }
1972 }
1973
1974 /*
1975 * Check if the supplied buffer is large enough.
1976 */
1977 if (dwSize < ReturnLength)
1978 {
1979 if (Buffer != InitialBuffer)
1980 {
1982 }
1984 }
1985
1986 /*
1987 * Generate the resulting buffer contents.
1988 */
1989 Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1990 if (! NT_SUCCESS(Status))
1991 {
1992 if (Buffer != InitialBuffer)
1993 {
1995 }
1996 return Status;
1997 }
1998 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1999
2000 NullWchar = L'\0';
2002 0 != DirEntry->Name.Length;
2003 DirEntry++)
2004 {
2005 Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
2006 if (! NT_SUCCESS(Status))
2007 {
2008 if (Buffer != InitialBuffer)
2009 {
2011 }
2012 return Status;
2013 }
2014 lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
2015 Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
2016 if (! NT_SUCCESS(Status))
2017 {
2018 if (Buffer != InitialBuffer)
2019 {
2021 }
2022 return Status;
2023 }
2024 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
2025 }
2026
2027 /*
2028 * Clean up
2029 */
2030 if (Buffer != InitialBuffer)
2031 {
2033 }
2034
2035 return STATUS_SUCCESS;
2036}
2037
2038static NTSTATUS FASTCALL
2040 HWINSTA hWindowStation,
2041 ULONG dwSize,
2043 PULONG pRequiredSize)
2044{
2046 PWINSTATION_OBJECT WindowStation;
2047 PLIST_ENTRY DesktopEntry;
2048 PDESKTOP DesktopObject;
2049 DWORD EntryCount;
2051 WCHAR NullWchar;
2052 UNICODE_STRING DesktopName;
2053
2054 Status = IntValidateWindowStationHandle(hWindowStation,
2055 UserMode,
2056 0,
2057 &WindowStation,
2058 NULL);
2059 if (! NT_SUCCESS(Status))
2060 {
2061 return Status;
2062 }
2063
2064 /*
2065 * Count the required size of buffer.
2066 */
2067 ReturnLength = sizeof(DWORD);
2068 EntryCount = 0;
2069 for (DesktopEntry = WindowStation->DesktopListHead.Flink;
2070 DesktopEntry != &WindowStation->DesktopListHead;
2071 DesktopEntry = DesktopEntry->Flink)
2072 {
2073 DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
2074 RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
2075 ReturnLength += DesktopName.Length + sizeof(WCHAR);
2076 EntryCount++;
2077 }
2078 TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
2079 if (NULL != pRequiredSize)
2080 {
2081 Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
2082 if (! NT_SUCCESS(Status))
2083 {
2084 ObDereferenceObject(WindowStation);
2086 }
2087 }
2088
2089 /*
2090 * Check if the supplied buffer is large enough.
2091 */
2092 if (dwSize < ReturnLength)
2093 {
2094 ObDereferenceObject(WindowStation);
2096 }
2097
2098 /*
2099 * Generate the resulting buffer contents.
2100 */
2101 Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
2102 if (! NT_SUCCESS(Status))
2103 {
2104 ObDereferenceObject(WindowStation);
2105 return Status;
2106 }
2107 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
2108
2109 NullWchar = L'\0';
2110 for (DesktopEntry = WindowStation->DesktopListHead.Flink;
2111 DesktopEntry != &WindowStation->DesktopListHead;
2112 DesktopEntry = DesktopEntry->Flink)
2113 {
2114 DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
2115 RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
2116 Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
2117 if (! NT_SUCCESS(Status))
2118 {
2119 ObDereferenceObject(WindowStation);
2120 return Status;
2121 }
2122 lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
2123 Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
2124 if (! NT_SUCCESS(Status))
2125 {
2126 ObDereferenceObject(WindowStation);
2127 return Status;
2128 }
2129 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
2130 }
2131
2132 /*
2133 * Clean up and return
2134 */
2135 ObDereferenceObject(WindowStation);
2136 return STATUS_SUCCESS;
2137}
2138
2139/*
2140 * NtUserBuildNameList
2141 *
2142 * Function used for enumeration of desktops or window stations.
2143 *
2144 * Parameters
2145 * hWinSta
2146 * For enumeration of window stations this parameter must be set to
2147 * zero. Otherwise it's handle for window station.
2148 *
2149 * dwSize
2150 * Size of buffer passed by caller.
2151 *
2152 * lpBuffer
2153 * Buffer passed by caller. If the function succeeds, the buffer is
2154 * filled with window station/desktop count (in first DWORD) and
2155 * NULL-terminated window station/desktop names.
2156 *
2157 * pRequiredSize
2158 * If the function succeeds, this is the number of bytes copied.
2159 * Otherwise it's size of buffer needed for function to succeed.
2160 *
2161 * Status
2162 * @implemented
2163 */
2166 HWINSTA hWindowStation,
2167 ULONG dwSize,
2169 PULONG pRequiredSize)
2170{
2171 /* The WindowStation name list and desktop name list are build in completely
2172 different ways. Call the appropriate function */
2173 return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
2174 BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
2175}
2176
2177/*
2178 * @implemented
2179 */
2182{
2183 BOOL Ret = FALSE;
2184
2186
2187 if (!IntIsWindow(hWnd))
2188 goto Leave;
2189
2191 {
2193 goto Leave;
2194 }
2195
2196 hwndSAS = hWnd;
2197 Ret = TRUE;
2198
2199Leave:
2200 UserLeave();
2201 return Ret;
2202}
2203
2204BOOL
2207{
2208 BOOL ret;
2210
2212
2213 if (pti->rpdesk == IntGetActiveDesktop())
2214 {
2216 }
2217 else
2218 {
2219 ret = FALSE;
2220 }
2221
2222 UserLeave();
2223
2224 return ret;
2225}
2226
2227BOOL
2228NTAPI
2230 IN HWINSTA hWindowStation,
2231 IN PLUID pluid,
2232 IN PSID psid OPTIONAL,
2233 IN DWORD size)
2234{
2235 BOOL Ret = FALSE;
2237 PWINSTATION_OBJECT WindowStation = NULL;
2238 LUID luidUser;
2239
2241
2243 {
2245 goto Leave;
2246 }
2247
2248 /* Validate the window station */
2249 Status = IntValidateWindowStationHandle(hWindowStation,
2250 UserMode,
2251 0,
2252 &WindowStation,
2253 NULL);
2254 if (!NT_SUCCESS(Status))
2255 {
2256 goto Leave;
2257 }
2258
2259 /* Capture the user LUID */
2260 _SEH2_TRY
2261 {
2262 ProbeForRead(pluid, sizeof(LUID), 1);
2263 luidUser = *pluid;
2264 }
2266 {
2268 _SEH2_YIELD(goto Leave);
2269 }
2270 _SEH2_END;
2271
2272 /* Reset the window station user LUID */
2273 RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
2274
2275 /* Reset the window station user SID */
2276 if (WindowStation->psidUser)
2277 {
2279 WindowStation->psidUser = NULL;
2280 }
2281
2282 /* Copy the new user SID if one has been provided */
2283 if (psid)
2284 {
2286 if (WindowStation->psidUser == NULL)
2287 {
2289 goto Leave;
2290 }
2291
2293 _SEH2_TRY
2294 {
2295 ProbeForRead(psid, size, 1);
2296 RtlCopyMemory(WindowStation->psidUser, psid, size);
2297 }
2299 {
2301 }
2302 _SEH2_END;
2303
2304 if (!NT_SUCCESS(Status))
2305 {
2307 WindowStation->psidUser = NULL;
2308 goto Leave;
2309 }
2310 }
2311
2312 /* Copy the new user LUID */
2313 WindowStation->luidUser = luidUser;
2314
2315 Ret = TRUE;
2316
2317Leave:
2318 if (WindowStation)
2319 ObDereferenceObject(WindowStation);
2320
2321 UserLeave();
2322 return Ret;
2323}
2324
2325/* EOF */
#define CODE_SEG(...)
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
static HANDLE DirectoryHandle
Definition: ObType.cpp:48
PRTL_UNICODE_STRING_BUFFER PULONG PULONG Unknown4
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
Definition: bufpool.h:45
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD IN DWORD Unknown6
Definition: conport.c:40
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD Unknown5
Definition: conport.c:39
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:37
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
BOOL UserCreateSystemThread(DWORD Type)
Definition: csr.c:247
PEPROCESS gpepCSRSS
Definition: csr.c:15
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
BOOL NTAPI GreSetDCOwner(HDC hdc, ULONG ulOwner)
Definition: dclife.c:455
HDC FASTCALL IntGdiCreateDC(PUNICODE_STRING Driver, PUNICODE_STRING pustrDevice, PVOID pUMdhpdev, CONST PDEVMODEW pdmInit, BOOL CreateAsIC)
Definition: dclife.c:1040
#define BufferSize
Definition: mmc.h:75
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define APIENTRY
Definition: api.h:79
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define wcschr
Definition: compat.h:17
#define MAX_PATH
Definition: compat.h:34
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
ULONG SessionId
Definition: dllmain.c:28
#define SESSION_DIR
Definition: dllmain.c:38
_ACRTIMP int __cdecl _scwprintf(const wchar_t *,...)
Definition: wcs.c:1678
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:24
GLsizeiptr size
Definition: glext.h:5919
PSERVERINFO gpsi
Definition: imm.c:18
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:800
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:993
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define NOTHING
Definition: input_list.c:10
HDC hSystemBM
Definition: stockobj.c:52
#define NtCurrentTeb
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
PMDEVOBJ gpmdev
Definition: mdevobj.c:14
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
struct _ACL ACL
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:100
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:97
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1625
NTSYSAPI NTSTATUS NTAPI RtlDestroyAtomTable(IN PRTL_ATOM_TABLE AtomTable)
Definition: atom.c:204
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateAtomTable(_In_ ULONG TableSize, _Inout_ PRTL_ATOM_TABLE *AtomTable)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1626
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
_In_ LPWSTR _In_ DWORD _In_ LPCVOID pvData
Definition: netsh.h:116
#define _In_
Definition: no_sal2.h:158
#define SYNCHRONIZE
Definition: nt_native.h:61
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1259
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define DIRECTORY_QUERY
Definition: nt_native.h:1257
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FASTCALL
Definition: nt_native.h:50
#define MEM_RELEASE
Definition: nt_native.h:1319
#define DWORD
Definition: nt_native.h:44
#define MEM_COMMIT
Definition: nt_native.h:1316
#define UNICODE_NULL
@ NotificationEvent
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
NTSYSAPI NTSTATUS NTAPI RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Group, IN BOOLEAN GroupDefaulted)
Definition: sd.c:410
NTSYSAPI NTSTATUS NTAPI RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN SaclPresent, IN PACL Sacl, IN BOOLEAN SaclDefaulted)
Definition: sd.c:342
POBJECT_TYPE ExEventObjectType
Definition: event.c:18
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
VOID NTAPI PsSetProcessWindowStation(PEPROCESS Process, PVOID WindowStation)
Definition: process.c:1314
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
PVOID NTAPI PsGetProcessWin32WindowStation(PEPROCESS Process)
Definition: process.c:1203
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:387
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
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
NTSTATUS NTAPI IntWinStaObjectDelete(_In_ PVOID Parameters)
Definition: winsta.c:99
BOOL APIENTRY NtUserLockWorkStation(VOID)
Definition: winsta.c:2206
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
VOID FASTCALL IntEndDesktopGraphics(VOID)
Definition: winsta.c:381
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:811
NTSTATUS NTAPI IntWinStaOkToClose(_In_ PVOID Parameters)
Definition: winsta.c:216
UNICODE_STRING gustrWindowStationsDir
Definition: winsta.c:27
BOOL APIENTRY NtUserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1749
NTSTATUS APIENTRY NtUserBuildNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:2165
NTSTATUS NTAPI InitWindowStationImpl(VOID)
Definition: winsta.c:35
HWND hwndSAS
Definition: winsta.c:24
BOOL FASTCALL CheckWinstaAttributeAccess(ACCESS_MASK DesiredAccess)
Definition: winsta.c:400
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
Definition: winsta.c:422
BOOL APIENTRY NtUserSetLogonNotifyWindow(HWND hWnd)
Definition: winsta.c:2181
static NTSTATUS FASTCALL BuildWindowStationNameList(ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1851
BOOL APIENTRY NtUserCloseWindowStation(HWINSTA hWinSta)
Definition: winsta.c:1254
HWINSTA APIENTRY NtUserCreateWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
Definition: winsta.c:968
BOOL APIENTRY NtUserSetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength)
Definition: winsta.c:1572
BOOL NTAPI NtUserSetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:2229
BOOL APIENTRY NtUserLockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1771
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:2039
static NTSTATUS BuildUserModeWindowStationName(IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes, IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes, OUT PUNICODE_STRING *WindowStationName, OUT PUNICODE_STRING *TebStaticUnicodeString)
Definition: winsta.c:845
BOOL APIENTRY NtUserUnlockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1814
HWINSTA APIENTRY NtUserOpenWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess)
Definition: winsta.c:1108
HWINSTA FASTCALL UserGetProcessWindowStation(VOID)
Definition: winsta.c:1586
HANDLE ghWinStaDir
Definition: winsta.c:28
HWINSTA APIENTRY NtUserGetProcessWindowStation(VOID)
Definition: winsta.c:1608
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:665
BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID)
Definition: winsta.c:274
NTSTATUS FASTCALL IntValidateWindowStationHandle(HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
Definition: winsta.c:244
HDC FASTCALL IntGetScreenDC(VOID)
Definition: winsta.c:394
BOOL APIENTRY NtUserGetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength, PDWORD nLengthNeeded)
Definition: winsta.c:1333
static NTSTATUS IntCreateDesktopSwitchEvent(VOID)
Creates the global per-session \BaseNamedObjects\WinSta0_DesktopSwitch event.
Definition: winsta.c:440
NTSTATUS NTAPI UserCreateWinstaDirectory(VOID)
Definition: winsta.c:52
NTSTATUS NTAPI IntWinStaObjectParse(_In_ PVOID Parameters)
Definition: winsta.c:151
BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1614
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3406
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:2957
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:2554
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:1040
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:493
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:849
short WCHAR
Definition: pedump.c:58
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__kernel_entry W32KAPI INT APIENTRY NtGdiGetDeviceCaps(_In_ HDC hdc, _In_ INT i)
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetStockObject(_In_ INT iObject)
__kernel_entry W32KAPI HFONT APIENTRY NtGdiSelectFont(_In_ HDC hdc, _In_ HFONT hf)
Definition: dcobjs.c:597
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
#define _SEH2_LEAVE
Definition: pseh2_64.h:206
PSE_EXPORTS SeExports
Definition: semgr.c:21
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
HANDLE gpidLogon
Definition: simplecall.c:15
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ PVOID Context
Definition: storport.h:2269
WCHAR szDesktopName[1]
Definition: ntuser.h:158
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
KPROCESS Pcb
Definition: pstypes.h:1369
ULONG ulVertRes
Definition: winddi.h:883
ULONG ulHorzRes
Definition: winddi.h:882
WCHAR szWinDeviceName[CCHDEVICENAME/2]
Definition: pdevobj.h:60
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LONG HighPart
DWORD LowPart
PPDEVOBJ ppdevGlobal
Definition: mdevobj.h:16
PUNICODE_STRING ObjectName
Definition: umtypes.h:187
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
UNICODE_STRING Name
Definition: obtypes.h:454
POBJECT_TYPE Type
Definition: obtypes.h:514
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:379
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:386
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:411
UNICODE_STRING Name
Definition: obtypes.h:404
GDIINFO gdiinfo
Definition: pdevobj.h:123
HWINSTA hwinsta
Definition: win32.h:268
ACCESS_MASK amwinsta
Definition: win32.h:269
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:267
PSID SeWorldSid
Definition: setypes.h:1232
Definition: compat.h:836
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:877
UNICODE_STRING StaticUnicodeString
Definition: compat.h:876
struct _DESKTOP * rpdesk
Definition: win32.h:92
USHORT MaximumLength
Definition: env_spec_w32.h:370
PUNICODE_STRING RemainingName
Definition: pstypes.h:1784
_Out_ PUNICODE_STRING CompleteName
Definition: pstypes.h:1783
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: pstypes.h:1786
KPROCESSOR_MODE AccessMode
Definition: pstypes.h:1781
DWORD dwSessionId
Definition: winsta.h:17
struct tagKL * spklList
Definition: winsta.h:23
PRTL_ATOM_TABLE AtomTable
Definition: winsta.h:20
PVOID psidUser
Definition: winsta.h:39
LIST_ENTRY DesktopListHead
Definition: winsta.h:19
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
#define LN_LOCK_WORKSTATION
Definition: undocuser.h:119
#define WM_LOGONNOTIFY
Definition: undocuser.h:39
#define UserEnterCo
Definition: ntuser.h:3
#define UserLeaveCo
Definition: ntuser.h:4
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define W32PF_IOWINSTA
Definition: win32.h:23
#define W32PF_READSCREENACCESSGRANTED
Definition: win32.h:8
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
POBJECT_TYPE ExWindowStationObjectType
Definition: win32k.c:21
PGRAPHICS_DEVICE NTAPI EngpFindGraphicsDevice(_In_opt_ PUNICODE_STRING pustrDevice, _In_ ULONG iDevNum)
Definition: device.c:795
NTSTATUS EngpUpdateGraphicsDeviceList(VOID)
Definition: device.c:182
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:30
BOOL FASTCALL IntCreatePrimarySurface(VOID)
Definition: device.c:17
VOID FASTCALL IntDestroyPrimarySurface(VOID)
Definition: device.c:32
DWORD FASTCALL IntGetCharDimensions(_In_ HDC hdc, _Out_opt_ PTEXTMETRICW ptm, _Out_opt_ PDWORD height)
Definition: font.c:337
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
BOOL APIENTRY co_IntLoadDefaultCursors(VOID)
Definition: callback.c:471
BOOL FASTCALL co_IntSetWndIcons(VOID)
Definition: callback.c:1101
VOID NTAPI UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
Definition: clipboard.c:354
#define ST_DESKTOP_THREAD
Definition: csr.h:36
#define ST_RIT
Definition: csr.h:35
BOOL InitCursorImpl(VOID)
Definition: cursoricon.c:64
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1286
PKEVENT gpDesktopSwitchEvent
WinSta0_DesktopSwitch legacy (NT 3.5+) event.
Definition: desktop.c:56
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:55
HDC ScreenDeviceContext
Definition: desktop.c:52
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1651
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1633
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1261
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:63
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1853
HANDLE ghDesktopSwitchEvent
WinSta0_DesktopSwitch handle in the CSRSS process.
Definition: desktop.c:57
BOOL gbBaseVideo
Definition: display.c:12
BOOL MenuInit(VOID)
Definition: menu.c:359
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1395
BOOL NTAPI InitMetrics(VOID)
Definition: metric.c:40
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:814
NTSTATUS NTAPI UserAttachMonitor(IN HDEV hDev)
Definition: monitor.c:129
NTSTATUS NTAPI UserUpdateMonitorSize(IN HDEV hDev)
Definition: monitor.c:225
PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj)
Definition: object.c:857
#define WINSTA_WRITE
Definition: security.h:48
#define WINSTA_READ
Definition: security.h:42
#define WINSTA_ACCESS_ALL
Definition: security.h:57
#define WINSTA_EXECUTE
Definition: security.h:53
#define USERTAG_SECURITY
Definition: tags.h:275
#define TAG_WINSTA
Definition: tags.h:11
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:177
struct _WINSTATION_OBJECT WINSTATION_OBJECT
#define WSS_LOCKED
Definition: winsta.h:7
#define WINSTA_OBJ_DIR
Definition: winsta.h:3
struct _WINSTATION_OBJECT * PWINSTATION_OBJECT
#define WSS_DYING
Definition: winsta.h:11
#define WSS_NOIO
Definition: winsta.h:9
WINBASEAPI _In_ DWORD nLength
Definition: wincon.h:682
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR, PSID, BOOLEAN)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
Definition: winerror.h:1285
#define RASTERCAPS
Definition: wingdi.h:745
#define LOGPIXELSY
Definition: wingdi.h:719
#define PLANES
Definition: wingdi.h:721
#define SYSTEM_FONT
Definition: wingdi.h:911
#define BITSPIXEL
Definition: wingdi.h:720
#define RC_PALETTE
Definition: wingdi.h:790
#define SM_CYSCREEN
Definition: winuser.h:971
#define UOI_NAME
Definition: winuser.h:1095
#define DISP_CHANGE_SUCCESSFUL
Definition: winuser.h:190
#define UOI_TYPE
Definition: winuser.h:1096
#define UOI_USER_SID
Definition: winuser.h:1097
#define WINSTA_READSCREEN
Definition: winuser.h:415
#define WSF_VISIBLE
Definition: winuser.h:2488
#define UOI_FLAGS
Definition: winuser.h:1094
#define SM_CXSCREEN
Definition: winuser.h:970
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857
#define EVENT_INCREMENT
Definition: iotypes.h:597
@ UserRequest
Definition: ketypes.h:473
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
KAPC_STATE
Definition: ketypes.h:1727
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define DUPLICATE_SAME_ACCESS
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3304
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39
#define ZwCurrentProcess()