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