ReactOS 0.4.16-dev-1170-ge326b06
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
409// Win: _GetProcessWindowStation
412{
413 PWINSTATION_OBJECT pWinSta;
415 HWINSTA hWinSta = ppi->hwinsta;
416 if (phWinSta)
417 *phWinSta = hWinSta;
418 IntValidateWindowStationHandle(hWinSta, UserMode, 0, &pWinSta, 0);
419 return pWinSta;
420}
421
422/* PUBLIC FUNCTIONS ***********************************************************/
423
424/*
425 * NtUserCreateWindowStation
426 *
427 * Creates a new window station.
428 *
429 * Parameters
430 * lpszWindowStationName
431 * Pointer to a null-terminated string specifying the name of the
432 * window station to be created. Window station names are
433 * case-insensitive and cannot contain backslash characters (\‍).
434 * Only members of the Administrators group are allowed to specify a
435 * name.
436 *
437 * dwDesiredAccess
438 * Requested type of access
439 *
440 * lpSecurity
441 * Security descriptor
442 *
443 * Unknown3, Unknown4, Unknown5, Unknown6
444 * Unused
445 *
446 * Return Value
447 * If the function succeeds, the return value is a handle to the newly
448 * created window station. If the specified window station already
449 * exists, the function succeeds and returns a handle to the existing
450 * window station. If the function fails, the return value is NULL.
451 *
452 * Status
453 * @implemented
454 */
455
459 OUT HWINSTA* phWinSta,
462 IN KPROCESSOR_MODE OwnerMode,
463 IN ACCESS_MASK dwDesiredAccess,
464 DWORD Unknown2,
469{
471 HWINSTA hWinSta;
472 PWINSTATION_OBJECT WindowStation;
473
474 TRACE("IntCreateWindowStation called\n");
475
476 ASSERT(phWinSta);
477 *phWinSta = NULL;
478
482 NULL,
483 dwDesiredAccess,
484 NULL,
485 (PVOID*)&hWinSta);
486 if (NT_SUCCESS(Status))
487 {
488 TRACE("IntCreateWindowStation opened window station '%wZ'\n",
489 ObjectAttributes->ObjectName);
490 *phWinSta = hWinSta;
491 return Status;
492 }
493
494 /*
495 * No existing window station found, try to create a new one.
496 */
497
498 /* Create the window station object */
502 OwnerMode,
503 NULL,
504 sizeof(WINSTATION_OBJECT),
505 0,
506 0,
507 (PVOID*)&WindowStation);
508 if (!NT_SUCCESS(Status))
509 {
510 ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
511 ObjectAttributes->ObjectName, Status);
513 return Status;
514 }
515
516 /* Initialize the window station */
517 RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
518
519 InitializeListHead(&WindowStation->DesktopListHead);
520 WindowStation->dwSessionId = NtCurrentPeb()->SessionId;
521 Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
522 if (!NT_SUCCESS(Status))
523 {
524 ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
525 ObjectAttributes->ObjectName, Status);
526 ObDereferenceObject(WindowStation);
528 return Status;
529 }
530
531 Status = ObInsertObject(WindowStation,
532 NULL,
533 dwDesiredAccess,
534 0,
535 NULL,
536 (PVOID*)&hWinSta);
537 if (!NT_SUCCESS(Status))
538 {
539 ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
541 return Status;
542 }
543
544 // FIXME! TODO: Add this new window station to a linked list
545
547 {
548 ERR("Initializing input window station\n");
549
550 /* Only Winlogon can create the interactive window station */
552
553 InputWindowStation = WindowStation;
554 WindowStation->Flags &= ~WSS_NOIO;
555
557
560
561 /* Desktop functions require the desktop thread running so wait for it to initialize */
562 UserLeaveCo();
565 UserMode,
566 FALSE,
567 NULL);
568 UserEnterCo();
569 }
570 else
571 {
572 WindowStation->Flags |= WSS_NOIO;
573 }
574
575 TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
576 ObjectAttributes->ObjectName, WindowStation, hWinSta);
577
578 *phWinSta = hWinSta;
580
581 return STATUS_SUCCESS;
582}
583
584static VOID
586 IN OUT PUNICODE_STRING WindowStationName,
587 IN PUNICODE_STRING TebStaticUnicodeString,
588 IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL,
589 IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
590{
591 SIZE_T MemSize = 0;
592
593 /* Try to restore the user's UserModeObjectAttributes */
594 if (UserModeObjectAttributes && LocalObjectAttributes)
595 {
597 {
598 ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
599 *UserModeObjectAttributes = *LocalObjectAttributes;
600 }
602 {
603 NOTHING;
604 }
605 _SEH2_END;
606 }
607
608 /* Free the user-mode memory */
609 if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
610 {
611 ZwFreeVirtualMemory(ZwCurrentProcess(),
612 (PVOID*)&WindowStationName,
613 &MemSize,
615 }
616}
617
618static NTSTATUS
620 IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes,
621 IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes,
622 OUT PUNICODE_STRING* WindowStationName,
623 OUT PUNICODE_STRING* TebStaticUnicodeString)
624{
626 SIZE_T MemSize;
627
628 LUID CallerLuid;
629 PTEB Teb;
630 USHORT StrSize;
631
632 *WindowStationName = NULL;
633 *TebStaticUnicodeString = NULL;
634
635 /* Retrieve the current process LUID */
636 Status = GetProcessLuid(NULL, NULL, &CallerLuid);
637 if (!NT_SUCCESS(Status))
638 {
639 ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
640 return Status;
641 }
642
643 /* Compute the needed string size */
644 MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
646 CallerLuid.HighPart,
647 CallerLuid.LowPart);
648 MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
649 if (MemSize > MAXUSHORT)
650 {
651 ERR("Window station name length is too long.\n");
653 }
654 StrSize = (USHORT)MemSize;
655
656 /*
657 * Check whether it's short enough so that we can use the static buffer
658 * in the TEB. Otherwise continue with virtual memory allocation.
659 */
660 Teb = NtCurrentTeb();
661 if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
662 {
663 /* We can use the TEB's static unicode string */
666
667 /* Remember the TEB's static unicode string address for later */
668 *TebStaticUnicodeString = &Teb->StaticUnicodeString;
669
670 *WindowStationName = *TebStaticUnicodeString;
671 (*WindowStationName)->Length = 0;
672 }
673 else
674 {
675 /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
676 MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
677
678 /* Allocate the memory in user-mode */
679 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
680 (PVOID*)WindowStationName,
681 0,
682 &MemSize,
685 if (!NT_SUCCESS(Status))
686 {
687 ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
688 return Status;
689 }
690
691 RtlInitEmptyUnicodeString(*WindowStationName,
692 (PWCHAR)((ULONG_PTR)*WindowStationName +
693 ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
694 StrSize);
695 }
696
697 /* Build a valid window station name from the LUID */
698 Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
699 (*WindowStationName)->MaximumLength,
700 L"%wZ\\Service-0x%x-%x$",
702 CallerLuid.HighPart,
703 CallerLuid.LowPart);
704 if (!NT_SUCCESS(Status))
705 {
706 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
707 goto Quit;
708 }
709 (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
710
711 /* Try to update the user's UserModeObjectAttributes */
713 {
714 ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
715 *LocalObjectAttributes = *UserModeObjectAttributes;
716
717 UserModeObjectAttributes->ObjectName = *WindowStationName;
718 UserModeObjectAttributes->RootDirectory = NULL;
719
721 }
723 {
725 }
726 _SEH2_END;
727
728Quit:
729 if (!NT_SUCCESS(Status))
730 {
731 /* Release the window station name */
732 FreeUserModeWindowStationName(*WindowStationName,
733 *TebStaticUnicodeString,
734 NULL, NULL);
735 }
736
737 return Status;
738}
739
740HWINSTA
744 IN ACCESS_MASK dwDesiredAccess,
745 DWORD Unknown2,
750{
752 HWINSTA hWinSta = NULL;
753 OBJECT_ATTRIBUTES LocalObjectAttributes;
754 PUNICODE_STRING WindowStationName = NULL;
755 PUNICODE_STRING TebStaticUnicodeString = NULL;
756 KPROCESSOR_MODE OwnerMode = UserMode;
757
758 TRACE("NtUserCreateWindowStation called\n");
759
760 /* Capture the object attributes and the window station name */
762 {
764 LocalObjectAttributes = *ObjectAttributes;
765 if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
766 {
767 ERR("Invalid ObjectAttributes length!\n");
770 }
771
772 /*
773 * Check whether the caller provided a window station name together
774 * with a RootDirectory handle.
775 *
776 * If the caller did not provide a window station name, build a new one
777 * based on the logon session identifier for the calling process.
778 * The new name is allocated in user-mode, as the rest of ObjectAttributes
779 * already is, so that the validation performed by the Object Manager
780 * can be done adequately.
781 */
782 if ((LocalObjectAttributes.ObjectName == NULL ||
783 LocalObjectAttributes.ObjectName->Buffer == NULL ||
784 LocalObjectAttributes.ObjectName->Length == 0 ||
785 LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
786 /* &&
787 LocalObjectAttributes.RootDirectory == NULL */)
788 {
789 /* No, build the new window station name */
791 &LocalObjectAttributes,
792 &WindowStationName,
793 &TebStaticUnicodeString);
794 if (!NT_SUCCESS(Status))
795 {
796 ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
798 }
799 OwnerMode = KernelMode;
800 }
801 }
803 {
805 ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
806 }
807 _SEH2_END;
808
809 if (!NT_SUCCESS(Status))
810 {
812 return NULL;
813 }
814
816
817 /* Create the window station */
820 UserMode,
821 OwnerMode,
822 dwDesiredAccess,
823 Unknown2,
824 Unknown3,
825 Unknown4,
826 Unknown5,
827 Unknown6);
828 UserLeave();
829
830 if (NT_SUCCESS(Status))
831 {
832 TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
833 ObjectAttributes->ObjectName, hWinSta);
834 }
835 else
836 {
837 ASSERT(hWinSta == NULL);
838 ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
839 ObjectAttributes->ObjectName, Status);
840 }
841
842 /* Try to restore the user's ObjectAttributes and release the window station name */
843 FreeUserModeWindowStationName(WindowStationName,
844 TebStaticUnicodeString,
845 (OwnerMode == KernelMode ? ObjectAttributes : NULL),
846 &LocalObjectAttributes);
847
848 if (!NT_SUCCESS(Status))
849 {
850 ASSERT(hWinSta == NULL);
852 }
853
854 return hWinSta;
855}
856
857/*
858 * NtUserOpenWindowStation
859 *
860 * Opens an existing window station.
861 *
862 * Parameters
863 * lpszWindowStationName
864 * Name of the existing window station.
865 *
866 * dwDesiredAccess
867 * Requested type of access.
868 *
869 * Return Value
870 * If the function succeeds, the return value is the handle to the
871 * specified window station. If the function fails, the return value
872 * is NULL.
873 *
874 * Remarks
875 * The returned handle can be closed with NtUserCloseWindowStation.
876 *
877 * Status
878 * @implemented
879 */
880
881HWINSTA
885 IN ACCESS_MASK dwDesiredAccess)
886{
888 HWINSTA hWinSta = NULL;
889 OBJECT_ATTRIBUTES LocalObjectAttributes;
890 PUNICODE_STRING WindowStationName = NULL;
891 PUNICODE_STRING TebStaticUnicodeString = NULL;
892 KPROCESSOR_MODE OwnerMode = UserMode;
893
894 TRACE("NtUserOpenWindowStation called\n");
895
896 /* Capture the object attributes and the window station name */
898 {
900 LocalObjectAttributes = *ObjectAttributes;
901 if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
902 {
903 ERR("Invalid ObjectAttributes length!\n");
906 }
907
908 /*
909 * Check whether the caller did not provide a window station name,
910 * or provided the special "Service-0x00000000-00000000$" name.
911 *
912 * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
913 * is used instead of an empty name (observed when API-monitoring
914 * OpenWindowStation() called with an empty window station name).
915 */
916 if ((LocalObjectAttributes.ObjectName == NULL ||
917 LocalObjectAttributes.ObjectName->Buffer == NULL ||
918 LocalObjectAttributes.ObjectName->Length == 0 ||
919 LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
920 /* &&
921 LocalObjectAttributes.RootDirectory == NULL */)
922 {
923 /* No, remember that for later */
924 LocalObjectAttributes.ObjectName = NULL;
925 }
926 if (LocalObjectAttributes.ObjectName &&
927 LocalObjectAttributes.ObjectName->Length ==
928 sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
929 _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
930 L"Service-0x00000000-00000000$",
931 LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
932 {
933 /* No, remember that for later */
934 LocalObjectAttributes.ObjectName = NULL;
935 }
936
937 /*
938 * If the caller did not provide a window station name, build a new one
939 * based on the logon session identifier for the calling process.
940 * The new name is allocated in user-mode, as the rest of ObjectAttributes
941 * already is, so that the validation performed by the Object Manager
942 * can be done adequately.
943 */
944 if (!LocalObjectAttributes.ObjectName)
945 {
946 /* No, build the new window station name */
948 &LocalObjectAttributes,
949 &WindowStationName,
950 &TebStaticUnicodeString);
951 if (!NT_SUCCESS(Status))
952 {
953 ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
955 }
956 OwnerMode = KernelMode;
957 }
958 }
960 {
962 ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
963 }
964 _SEH2_END;
965
966 if (!NT_SUCCESS(Status))
967 {
969 return NULL;
970 }
971
972 /* Open the window station */
975 UserMode,
976 NULL,
977 dwDesiredAccess,
978 NULL,
979 (PVOID*)&hWinSta);
980 if (NT_SUCCESS(Status))
981 {
982 TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
983 ObjectAttributes->ObjectName, hWinSta);
984 }
985 else
986 {
987 ASSERT(hWinSta == NULL);
988 ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
989 ObjectAttributes->ObjectName, Status);
990 }
991
992 /* Try to restore the user's ObjectAttributes and release the window station name */
993 FreeUserModeWindowStationName(WindowStationName,
994 TebStaticUnicodeString,
995 (OwnerMode == KernelMode ? ObjectAttributes : NULL),
996 &LocalObjectAttributes);
997
998 if (!NT_SUCCESS(Status))
999 {
1000 ASSERT(hWinSta == NULL);
1002 }
1003
1004 return hWinSta;
1005}
1006
1007/*
1008 * NtUserCloseWindowStation
1009 *
1010 * Closes a window station handle.
1011 *
1012 * Parameters
1013 * hWinSta
1014 * Handle to the window station.
1015 *
1016 * Return Value
1017 * Status
1018 *
1019 * Remarks
1020 * The window station handle can be created with NtUserCreateWindowStation
1021 * or NtUserOpenWindowStation. Attempts to close a handle to the window
1022 * station assigned to the calling process will fail.
1023 *
1024 * Status
1025 * @implemented
1026 */
1027
1028BOOL
1031 HWINSTA hWinSta)
1032{
1035
1036 TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
1037
1038 if (hWinSta == UserGetProcessWindowStation())
1039 {
1040 ERR("Attempted to close process window station\n");
1041 return FALSE;
1042 }
1043
1045 UserMode,
1046 0,
1047 &Object,
1048 NULL);
1049 if (!NT_SUCCESS(Status))
1050 {
1051 ERR("Validation of window station handle (%p) failed\n", hWinSta);
1052 return FALSE;
1053 }
1054
1056
1057 TRACE("Closing window station handle (%p)\n", hWinSta);
1058
1059 Status = ObCloseHandle(hWinSta, UserMode);
1060 if (!NT_SUCCESS(Status))
1061 {
1063 return FALSE;
1064 }
1065
1066 return TRUE;
1067}
1068
1069/*
1070 * NtUserGetObjectInformation
1071 *
1072 * The NtUserGetObjectInformation function retrieves information about a
1073 * window station or desktop object.
1074 *
1075 * Parameters
1076 * hObj
1077 * Handle to the window station or desktop object for which to
1078 * return information. This can be a handle of type HDESK or HWINSTA
1079 * (for example, a handle returned by NtUserCreateWindowStation,
1080 * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
1081 *
1082 * nIndex
1083 * Specifies the object information to be retrieved.
1084 *
1085 * pvInfo
1086 * Pointer to a buffer to receive the object information.
1087 *
1088 * nLength
1089 * Specifies the size, in bytes, of the buffer pointed to by the
1090 * pvInfo parameter.
1091 *
1092 * lpnLengthNeeded
1093 * Pointer to a variable receiving the number of bytes required to
1094 * store the requested information. If this variable's value is
1095 * greater than the value of the nLength parameter when the function
1096 * returns, the function returns FALSE, and none of the information
1097 * is copied to the pvInfo buffer. If the value of the variable pointed
1098 * to by lpnLengthNeeded is less than or equal to the value of nLength,
1099 * the entire information block is copied.
1100 *
1101 * Return Value
1102 * If the function succeeds, the return value is nonzero. If the function
1103 * fails, the return value is zero.
1104 *
1105 * Status
1106 * @unimplemented
1107 */
1108
1111 HANDLE hObject,
1112 DWORD nIndex,
1113 PVOID pvInformation,
1114 DWORD nLength,
1115 PDWORD nLengthNeeded)
1116{
1118 PWINSTATION_OBJECT WinStaObject = NULL;
1119 PDESKTOP DesktopObject = NULL;
1120 POBJECT_HEADER ObjectHeader;
1121 POBJECT_HEADER_NAME_INFO NameInfo;
1122 OBJECT_HANDLE_INFORMATION HandleInfo;
1123 USEROBJECTFLAGS ObjectFlags;
1124 PUNICODE_STRING pStrNameU = NULL;
1125 PVOID pvData = NULL;
1126 SIZE_T nDataSize = 0;
1127
1128 _SEH2_TRY
1129 {
1130 if (nLengthNeeded)
1131 ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1132 ProbeForWrite(pvInformation, nLength, 1);
1133 }
1135 {
1137 return FALSE;
1138 }
1139 _SEH2_END;
1140
1141 /* Try window station */
1142 TRACE("Trying to open window station 0x%p\n", hObject);
1144 0,
1146 UserMode,
1147 (PVOID*)&WinStaObject,
1148 &HandleInfo);
1149
1151 {
1152 /* Try desktop */
1153 TRACE("Trying to open desktop %p\n", hObject);
1154 WinStaObject = NULL;
1156 UserMode,
1157 0,
1158 &DesktopObject);
1159 }
1160
1161 if (!NT_SUCCESS(Status))
1162 {
1163 ERR("Failed: 0x%x\n", Status);
1164 goto Exit;
1165 }
1166
1167 TRACE("WinSta or Desktop opened!\n");
1168
1169 /* Get data */
1170 switch (nIndex)
1171 {
1172 case UOI_FLAGS:
1173 {
1174 ObjectFlags.fReserved = FALSE;
1175 ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1176
1177 ObjectFlags.dwFlags = 0;
1178 if (WinStaObject != NULL)
1179 {
1180 if (!(WinStaObject->Flags & WSS_NOIO))
1181 ObjectFlags.dwFlags |= WSF_VISIBLE;
1182 }
1183 else if (DesktopObject != NULL)
1184 {
1185 FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1186 }
1187 else
1188 {
1189 ERR("No associated WinStaObject nor DesktopObject!\n");
1190 }
1191
1192 pvData = &ObjectFlags;
1193 nDataSize = sizeof(ObjectFlags);
1195 break;
1196 }
1197
1198 case UOI_NAME:
1199 {
1200 if (WinStaObject != NULL)
1201 {
1202 ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1203 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1204
1205 if (NameInfo && (NameInfo->Name.Length > 0))
1206 {
1207 /* Named window station */
1208 pStrNameU = &NameInfo->Name;
1209 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1210 }
1211 else
1212 {
1213 /* Unnamed window station (should never happen!) */
1214 ASSERT(FALSE);
1215 pStrNameU = NULL;
1216 nDataSize = sizeof(UNICODE_NULL);
1217 }
1219 }
1220 else if (DesktopObject != NULL)
1221 {
1222 pvData = DesktopObject->pDeskInfo->szDesktopName;
1223 nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1225 }
1226 else
1227 {
1229 }
1230 break;
1231 }
1232
1233 case UOI_TYPE:
1234 {
1235 if (WinStaObject != NULL)
1236 {
1237 ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1238 pStrNameU = &ObjectHeader->Type->Name;
1239 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1241 }
1242 else if (DesktopObject != NULL)
1243 {
1244 ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1245 pStrNameU = &ObjectHeader->Type->Name;
1246 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1248 }
1249 else
1250 {
1252 }
1253 break;
1254 }
1255
1256 case UOI_USER_SID:
1258 ERR("UOI_USER_SID unimplemented!\n");
1259 break;
1260
1261 default:
1263 break;
1264 }
1265
1266Exit:
1267 if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1269
1270 _SEH2_TRY
1271 {
1272 if (nLengthNeeded)
1273 *nLengthNeeded = nDataSize;
1274
1275 /* Try to copy data to caller */
1276 if (Status == STATUS_SUCCESS && (nDataSize > 0))
1277 {
1278 TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1279 if (pvData)
1280 {
1281 /* Copy the data */
1282 RtlCopyMemory(pvInformation, pvData, nDataSize);
1283 }
1284 else if (pStrNameU)
1285 {
1286 /* Copy and NULL-terminate the string */
1287 RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1288 ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1289 }
1290 else
1291 {
1292 /* Zero the memory */
1293 RtlZeroMemory(pvInformation, nDataSize);
1294 }
1295 }
1296 }
1298 {
1300 }
1301 _SEH2_END;
1302
1303 /* Release objects */
1304 if (DesktopObject != NULL)
1305 ObDereferenceObject(DesktopObject);
1306 if (WinStaObject != NULL)
1307 ObDereferenceObject(WinStaObject);
1308
1309 if (!NT_SUCCESS(Status))
1310 {
1312 return FALSE;
1313 }
1314
1315 return TRUE;
1316}
1317
1318/*
1319 * NtUserSetObjectInformation
1320 *
1321 * The NtUserSetObjectInformation function sets information about a
1322 * window station or desktop object.
1323 *
1324 * Parameters
1325 * hObj
1326 * Handle to the window station or desktop object for which to set
1327 * object information. This value can be a handle of type HDESK or
1328 * HWINSTA.
1329 *
1330 * nIndex
1331 * Specifies the object information to be set.
1332 *
1333 * pvInfo
1334 * Pointer to a buffer containing the object information.
1335 *
1336 * nLength
1337 * Specifies the size, in bytes, of the information contained in the
1338 * buffer pointed to by pvInfo.
1339 *
1340 * Return Value
1341 * If the function succeeds, the return value is nonzero. If the function
1342 * fails the return value is zero.
1343 *
1344 * Status
1345 * @unimplemented
1346 */
1347
1348BOOL
1351 HANDLE hObject,
1352 DWORD nIndex,
1353 PVOID pvInformation,
1354 DWORD nLength)
1355{
1356 /* FIXME: ZwQueryObject */
1357 /* FIXME: ZwSetInformationObject */
1359 return FALSE;
1360}
1361
1362
1363HWINSTA FASTCALL
1365{
1367
1368 return ppi->hwinsta;
1369}
1370
1371
1372/*
1373 * NtUserGetProcessWindowStation
1374 *
1375 * Returns a handle to the current process window station.
1376 *
1377 * Return Value
1378 * If the function succeeds, the return value is handle to the window
1379 * station assigned to the current process. If the function fails, the
1380 * return value is NULL.
1381 *
1382 * Status
1383 * @implemented
1384 */
1385
1386HWINSTA APIENTRY
1388{
1390}
1391
1393UserSetProcessWindowStation(HWINSTA hWindowStation)
1394{
1396 PPROCESSINFO ppi;
1397 OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1398 PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1399 HWINSTA hCacheWinSta;
1400
1402
1403 /* Reference the new window station */
1404 if (hWindowStation != NULL)
1405 {
1406 Status = IntValidateWindowStationHandle(hWindowStation,
1407 UserMode,
1408 0,
1409 &NewWinSta,
1410 &ObjectHandleInfo);
1411 if (!NT_SUCCESS(Status))
1412 {
1413 TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1415 return FALSE;
1416 }
1417 }
1418
1419 OldWinSta = ppi->prpwinsta;
1420 hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1421
1422 /* Dereference the previous window station */
1423 if (OldWinSta != NULL)
1424 {
1425 ObDereferenceObject(OldWinSta);
1426 }
1427
1428 /*
1429 * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1430 */
1431
1432 /* Close the cached EPROCESS window station handle if needed */
1433 if (hCacheWinSta != NULL)
1434 {
1435 /* Reference the window station */
1436 Status = ObReferenceObjectByHandle(hCacheWinSta,
1437 0,
1439 UserMode,
1440 (PVOID*)&OldWinSta,
1441 NULL);
1442 if (!NT_SUCCESS(Status))
1443 {
1444 ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1445 /* We failed, reset the cache */
1446 hCacheWinSta = NULL;
1447 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1448 }
1449 else
1450 {
1451 /*
1452 * Close the old handle and reset the cache only
1453 * if we are setting a different window station.
1454 */
1455 if (NewWinSta != OldWinSta)
1456 {
1457 ObCloseHandle(hCacheWinSta, UserMode);
1458 hCacheWinSta = NULL;
1459 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1460 }
1461
1462 /* Dereference the window station */
1463 ObDereferenceObject(OldWinSta);
1464 }
1465 }
1466
1467 /* Duplicate and save a new cached EPROCESS window station handle */
1468 if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1469 {
1470 Status = ZwDuplicateObject(ZwCurrentProcess(),
1471 hWindowStation,
1473 (PHANDLE)&hCacheWinSta,
1474 0,
1475 0,
1477 if (!NT_SUCCESS(Status))
1478 {
1479 ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1480 }
1481 else
1482 {
1483 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1484 }
1485 }
1486
1487 ppi->prpwinsta = NewWinSta;
1488 ppi->hwinsta = hWindowStation;
1489 ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1490 TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1491
1493 {
1494 ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1495 }
1496 else
1497 {
1498 ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1499 }
1500
1501 if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1502 {
1503 ppi->W32PF_flags |= W32PF_IOWINSTA;
1504 }
1505 else /* Might be closed if the handle is NULL */
1506 {
1507 ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1508 }
1509 return TRUE;
1510}
1511
1512/*
1513 * NtUserSetProcessWindowStation
1514 *
1515 * Assigns a window station to the current process.
1516 *
1517 * Parameters
1518 * hWinSta
1519 * Handle to the window station.
1520 *
1521 * Return Value
1522 * Status
1523 *
1524 * Status
1525 * @implemented
1526 */
1527
1529NtUserSetProcessWindowStation(HWINSTA hWindowStation)
1530{
1531 BOOL ret;
1532
1534
1535 ret = UserSetProcessWindowStation(hWindowStation);
1536
1537 UserLeave();
1538
1539 return ret;
1540}
1541
1542/*
1543 * NtUserLockWindowStation
1544 *
1545 * Locks switching desktops. Only the logon application is allowed to call this function.
1546 *
1547 * Status
1548 * @implemented
1549 */
1550
1552NtUserLockWindowStation(HWINSTA hWindowStation)
1553{
1556
1557 TRACE("About to set process window station with handle (%p)\n",
1558 hWindowStation);
1559
1561 {
1562 ERR("Unauthorized process attempted to lock the window station!\n");
1564 return FALSE;
1565 }
1566
1567 Status = IntValidateWindowStationHandle(hWindowStation,
1568 UserMode,
1569 0,
1570 &Object,
1571 NULL);
1572 if (!NT_SUCCESS(Status))
1573 {
1574 TRACE("Validation of window station handle (%p) failed\n",
1575 hWindowStation);
1577 return FALSE;
1578 }
1579
1580 Object->Flags |= WSS_LOCKED;
1581
1583 return TRUE;
1584}
1585
1586/*
1587 * NtUserUnlockWindowStation
1588 *
1589 * Unlocks switching desktops. Only the logon application is allowed to call this function.
1590 *
1591 * Status
1592 * @implemented
1593 */
1594
1596NtUserUnlockWindowStation(HWINSTA hWindowStation)
1597{
1600 BOOL Ret;
1601
1602 TRACE("About to set process window station with handle (%p)\n",
1603 hWindowStation);
1604
1606 {
1607 ERR("Unauthorized process attempted to unlock the window station!\n");
1609 return FALSE;
1610 }
1611
1612 Status = IntValidateWindowStationHandle(hWindowStation,
1613 UserMode,
1614 0,
1615 &Object,
1616 NULL);
1617 if (!NT_SUCCESS(Status))
1618 {
1619 TRACE("Validation of window station handle (%p) failed\n",
1620 hWindowStation);
1622 return FALSE;
1623 }
1624
1625 Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1626 Object->Flags &= ~WSS_LOCKED;
1627
1629 return Ret;
1630}
1631
1632static NTSTATUS FASTCALL
1634 ULONG dwSize,
1636 PULONG pRequiredSize)
1637{
1641 char InitialBuffer[256], *Buffer;
1643 DWORD EntryCount;
1645 WCHAR NullWchar;
1646
1647 //
1648 // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1649 // with judicious parameters one can create window stations elsewhere
1650 // than in Windows\WindowStations directory, Win32k definitely MUST
1651 // maintain a list of window stations it has created, and not rely
1652 // on the enumeration of Windows\WindowStations !!!
1653 //
1654
1655 /*
1656 * Try to open the directory.
1657 */
1661 NULL,
1662 NULL);
1663
1667
1668 if (!NT_SUCCESS(Status))
1669 {
1670 return Status;
1671 }
1672
1673 /* First try to query the directory using a fixed-size buffer */
1674 Context = 0;
1675 Buffer = NULL;
1676 Status = ZwQueryDirectoryObject(DirectoryHandle,
1677 InitialBuffer,
1678 sizeof(InitialBuffer),
1679 FALSE,
1680 TRUE,
1681 &Context,
1682 &ReturnLength);
1683 if (NT_SUCCESS(Status))
1684 {
1685 if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1686 FALSE, &Context, NULL))
1687 {
1688 /* Our fixed-size buffer is large enough */
1689 Buffer = InitialBuffer;
1690 }
1691 }
1692
1693 if (NULL == Buffer)
1694 {
1695 /* Need a larger buffer, check how large exactly */
1696 Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1697 &ReturnLength);
1698 if (!NT_SUCCESS(Status))
1699 {
1700 ERR("ZwQueryDirectoryObject failed\n");
1702 return Status;
1703 }
1704
1707 if (NULL == Buffer)
1708 {
1710 return STATUS_NO_MEMORY;
1711 }
1712
1713 /* We should have a sufficiently large buffer now */
1714 Context = 0;
1715 Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1717 if (! NT_SUCCESS(Status) ||
1718 STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1719 FALSE, &Context, NULL))
1720 {
1721 /* Something went wrong, maybe someone added a directory entry? Just give up. */
1725 }
1726 }
1727
1729
1730 /*
1731 * Count the required size of buffer.
1732 */
1733 ReturnLength = sizeof(DWORD);
1734 EntryCount = 0;
1736 0 != DirEntry->Name.Length;
1737 DirEntry++)
1738 {
1739 ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1740 EntryCount++;
1741 }
1742 TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1743 if (NULL != pRequiredSize)
1744 {
1745 Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1746 if (! NT_SUCCESS(Status))
1747 {
1748 if (Buffer != InitialBuffer)
1749 {
1751 }
1753 }
1754 }
1755
1756 /*
1757 * Check if the supplied buffer is large enough.
1758 */
1759 if (dwSize < ReturnLength)
1760 {
1761 if (Buffer != InitialBuffer)
1762 {
1764 }
1766 }
1767
1768 /*
1769 * Generate the resulting buffer contents.
1770 */
1771 Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1772 if (! NT_SUCCESS(Status))
1773 {
1774 if (Buffer != InitialBuffer)
1775 {
1777 }
1778 return Status;
1779 }
1780 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1781
1782 NullWchar = L'\0';
1784 0 != DirEntry->Name.Length;
1785 DirEntry++)
1786 {
1787 Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
1788 if (! NT_SUCCESS(Status))
1789 {
1790 if (Buffer != InitialBuffer)
1791 {
1793 }
1794 return Status;
1795 }
1796 lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
1797 Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1798 if (! NT_SUCCESS(Status))
1799 {
1800 if (Buffer != InitialBuffer)
1801 {
1803 }
1804 return Status;
1805 }
1806 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1807 }
1808
1809 /*
1810 * Clean up
1811 */
1812 if (Buffer != InitialBuffer)
1813 {
1815 }
1816
1817 return STATUS_SUCCESS;
1818}
1819
1820static NTSTATUS FASTCALL
1822 HWINSTA hWindowStation,
1823 ULONG dwSize,
1825 PULONG pRequiredSize)
1826{
1828 PWINSTATION_OBJECT WindowStation;
1829 PLIST_ENTRY DesktopEntry;
1830 PDESKTOP DesktopObject;
1831 DWORD EntryCount;
1833 WCHAR NullWchar;
1834 UNICODE_STRING DesktopName;
1835
1836 Status = IntValidateWindowStationHandle(hWindowStation,
1837 UserMode,
1838 0,
1839 &WindowStation,
1840 NULL);
1841 if (! NT_SUCCESS(Status))
1842 {
1843 return Status;
1844 }
1845
1846 /*
1847 * Count the required size of buffer.
1848 */
1849 ReturnLength = sizeof(DWORD);
1850 EntryCount = 0;
1851 for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1852 DesktopEntry != &WindowStation->DesktopListHead;
1853 DesktopEntry = DesktopEntry->Flink)
1854 {
1855 DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1856 RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1857 ReturnLength += DesktopName.Length + sizeof(WCHAR);
1858 EntryCount++;
1859 }
1860 TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1861 if (NULL != pRequiredSize)
1862 {
1863 Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1864 if (! NT_SUCCESS(Status))
1865 {
1866 ObDereferenceObject(WindowStation);
1868 }
1869 }
1870
1871 /*
1872 * Check if the supplied buffer is large enough.
1873 */
1874 if (dwSize < ReturnLength)
1875 {
1876 ObDereferenceObject(WindowStation);
1878 }
1879
1880 /*
1881 * Generate the resulting buffer contents.
1882 */
1883 Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1884 if (! NT_SUCCESS(Status))
1885 {
1886 ObDereferenceObject(WindowStation);
1887 return Status;
1888 }
1889 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1890
1891 NullWchar = L'\0';
1892 for (DesktopEntry = WindowStation->DesktopListHead.Flink;
1893 DesktopEntry != &WindowStation->DesktopListHead;
1894 DesktopEntry = DesktopEntry->Flink)
1895 {
1896 DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
1897 RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
1898 Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
1899 if (! NT_SUCCESS(Status))
1900 {
1901 ObDereferenceObject(WindowStation);
1902 return Status;
1903 }
1904 lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
1905 Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
1906 if (! NT_SUCCESS(Status))
1907 {
1908 ObDereferenceObject(WindowStation);
1909 return Status;
1910 }
1911 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
1912 }
1913
1914 /*
1915 * Clean up and return
1916 */
1917 ObDereferenceObject(WindowStation);
1918 return STATUS_SUCCESS;
1919}
1920
1921/*
1922 * NtUserBuildNameList
1923 *
1924 * Function used for enumeration of desktops or window stations.
1925 *
1926 * Parameters
1927 * hWinSta
1928 * For enumeration of window stations this parameter must be set to
1929 * zero. Otherwise it's handle for window station.
1930 *
1931 * dwSize
1932 * Size of buffer passed by caller.
1933 *
1934 * lpBuffer
1935 * Buffer passed by caller. If the function succeeds, the buffer is
1936 * filled with window station/desktop count (in first DWORD) and
1937 * NULL-terminated window station/desktop names.
1938 *
1939 * pRequiredSize
1940 * If the function succeeds, this is the number of bytes copied.
1941 * Otherwise it's size of buffer needed for function to succeed.
1942 *
1943 * Status
1944 * @implemented
1945 */
1946
1949 HWINSTA hWindowStation,
1950 ULONG dwSize,
1952 PULONG pRequiredSize)
1953{
1954 /* The WindowStation name list and desktop name list are build in completely
1955 different ways. Call the appropriate function */
1956 return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
1957 BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
1958}
1959
1960/*
1961 * @implemented
1962 */
1965{
1967 {
1968 return FALSE;
1969 }
1970
1971 if (!IntIsWindow(hWnd))
1972 {
1973 return FALSE;
1974 }
1975
1976 hwndSAS = hWnd;
1977
1978 return TRUE;
1979}
1980
1981BOOL
1984{
1985 BOOL ret;
1987
1989
1990 if (pti->rpdesk == IntGetActiveDesktop())
1991 {
1993 }
1994 else
1995 {
1996 ret = FALSE;
1997 }
1998
1999 UserLeave();
2000
2001 return ret;
2002}
2003
2004BOOL
2005NTAPI
2007 IN HWINSTA hWindowStation,
2008 IN PLUID pluid,
2009 IN PSID psid OPTIONAL,
2010 IN DWORD size)
2011{
2012 BOOL Ret = FALSE;
2014 PWINSTATION_OBJECT WindowStation = NULL;
2015 LUID luidUser;
2016
2018
2020 {
2022 goto Leave;
2023 }
2024
2025 /* Validate the window station */
2026 Status = IntValidateWindowStationHandle(hWindowStation,
2027 UserMode,
2028 0,
2029 &WindowStation,
2030 NULL);
2031 if (!NT_SUCCESS(Status))
2032 {
2033 goto Leave;
2034 }
2035
2036 /* Capture the user LUID */
2037 _SEH2_TRY
2038 {
2039 ProbeForRead(pluid, sizeof(LUID), 1);
2040 luidUser = *pluid;
2041 }
2043 {
2045 _SEH2_YIELD(goto Leave);
2046 }
2047 _SEH2_END;
2048
2049 /* Reset the window station user LUID */
2050 RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
2051
2052 /* Reset the window station user SID */
2053 if (WindowStation->psidUser)
2054 {
2056 WindowStation->psidUser = NULL;
2057 }
2058
2059 /* Copy the new user SID if one has been provided */
2060 if (psid)
2061 {
2063 if (WindowStation->psidUser == NULL)
2064 {
2066 goto Leave;
2067 }
2068
2070 _SEH2_TRY
2071 {
2072 ProbeForRead(psid, size, 1);
2073 RtlCopyMemory(WindowStation->psidUser, psid, size);
2074 }
2076 {
2078 }
2079 _SEH2_END;
2080
2081 if (!NT_SUCCESS(Status))
2082 {
2084 WindowStation->psidUser = NULL;
2085 goto Leave;
2086 }
2087 }
2088
2089 /* Copy the new user LUID */
2090 WindowStation->luidUser = luidUser;
2091
2092 Ret = TRUE;
2093
2094Leave:
2095 if (WindowStation)
2096 ObDereferenceObject(WindowStation);
2097
2098 UserLeave();
2099 return Ret;
2100}
2101
2102/* 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
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
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 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
PSERVERINFO gpsi
Definition: imm.c:18
PPEB Peb
Definition: dllmain.c:27
#define SESSION_DIR
Definition: dllmain.c:38
#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
_Check_return_ _CRTIMP int __cdecl _scwprintf(_In_z_ _Printf_format_string_ const wchar_t *_Format,...)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:801
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:993
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
#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:106
#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)
#define _In_
Definition: no_sal2.h:158
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FASTCALL
Definition: nt_native.h:50
#define MEM_RELEASE
Definition: nt_native.h:1316
#define DWORD
Definition: nt_native.h:44
#define MEM_COMMIT
Definition: nt_native.h:1313
#define UNICODE_NULL
__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 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:465
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
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:1983
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:585
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:1529
NTSTATUS APIENTRY NtUserBuildNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1948
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:411
BOOL APIENTRY NtUserSetLogonNotifyWindow(HWND hWnd)
Definition: winsta.c:1964
static NTSTATUS FASTCALL BuildWindowStationNameList(ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1633
BOOL APIENTRY NtUserCloseWindowStation(HWINSTA hWinSta)
Definition: winsta.c:1030
HWINSTA APIENTRY NtUserCreateWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
Definition: winsta.c:742
BOOL APIENTRY NtUserSetObjectInformation(HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength)
Definition: winsta.c:1350
BOOL NTAPI NtUserSetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:2006
BOOL APIENTRY NtUserLockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1552
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1821
static NTSTATUS BuildUserModeWindowStationName(IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes, IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes, OUT PUNICODE_STRING *WindowStationName, OUT PUNICODE_STRING *TebStaticUnicodeString)
Definition: winsta.c:619
BOOL APIENTRY NtUserUnlockWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1596
HWINSTA APIENTRY NtUserOpenWindowStation(IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess)
Definition: winsta.c:883
HWINSTA FASTCALL UserGetProcessWindowStation(VOID)
Definition: winsta.c:1364
HWINSTA APIENTRY NtUserGetProcessWindowStation(VOID)
Definition: winsta.c:1387
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:458
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:1110
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:1393
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
#define L(x)
Definition: ntvdm.h:50
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:865
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
#define _SEH2_LEAVE
Definition: pseh2_64.h:183
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#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
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:185
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:1676
_Out_ PUNICODE_STRING CompleteName
Definition: pstypes.h:1675
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: pstypes.h:1678
KPROCESSOR_MODE AccessMode
Definition: pstypes.h:1673
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
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
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:118
#define WM_LOGONNOTIFY
Definition: undocuser.h:37
#define UserEnterCo
Definition: ntuser.h:3
#define UserLeaveCo
Definition: ntuser.h:4
int ret
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_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:660
NTSTATUS EngpUpdateGraphicsDeviceList(VOID)
Definition: device.c:182
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
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:335
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
BOOL APIENTRY co_IntLoadDefaultCursors(VOID)
Definition: callback.c:471
BOOL FASTCALL co_IntSetWndIcons(VOID)
Definition: callback.c:1101
VOID NTAPI UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
Definition: clipboard.c:354
#define ST_DESKTOP_THREAD
Definition: csr.h:36
#define ST_RIT
Definition: csr.h:35
BOOL InitCursorImpl(VOID)
Definition: cursoricon.c:64
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1279
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:56
HDC ScreenDeviceContext
Definition: desktop.c:53
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1652
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1634
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:1854
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:45
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:815
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:860
#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:178
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
_In_ DWORD nLength
Definition: wincon.h:473
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3749
#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
Definition: winerror.h:940
#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:2463
#define UOI_FLAGS
Definition: winuser.h:1094
#define SM_CXSCREEN
Definition: winuser.h:970
@ UserRequest
Definition: ketypes.h:421
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ZwCurrentProcess()