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