New macros InitializeUnicodeString(), RtlInitUnicodeStringFromLiteral() and UNICODE_S...
[reactos.git] / reactos / subsys / win32k / ntuser / winsta.c
1 /* $Id: winsta.c,v 1.7 2002/08/20 20:37:19 hyperion Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Window stations and desktops
6 * FILE: subsys/win32k/ntuser/winsta.c
7 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * REVISION HISTORY:
9 * 06-06-2001 CSH Created
10 * NOTES: Exported functions set the Win32 last error value
11 * on errors. The value can be retrieved with the Win32
12 * function GetLastError().
13 * TODO: The process window station is created on
14 * the first USER32/GDI32 call not related
15 * to window station/desktop handling
16 */
17
18 /* INCLUDES ******************************************************************/
19
20 #include <ddk/ntddk.h>
21 #include <win32k/win32k.h>
22 #include <include/winsta.h>
23 #include <include/object.h>
24 #include <include/guicheck.h>
25 #include <napi/win32.h>
26 #include <include/class.h>
27 #include <include/window.h>
28
29 #define NDEBUG
30 #include <debug.h>
31
32 /* GLOBALS *******************************************************************/
33
34 #define WINSTA_ROOT_NAME L"\\Windows\\WindowStations"
35
36 LRESULT CALLBACK
37 W32kDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
38
39 STATIC PWNDCLASS_OBJECT DesktopWindowClass;
40
41 /* Currently active desktop */
42 STATIC HDESK InputDesktopHandle = NULL;
43 STATIC PDESKTOP_OBJECT InputDesktop = NULL;
44 STATIC PWINSTATION_OBJECT InputWindowStation = NULL;
45
46 /* FUNCTIONS *****************************************************************/
47
48 PDESKTOP_OBJECT
49 W32kGetActiveDesktop(VOID)
50 {
51 return(InputDesktop);
52 }
53
54 NTSTATUS
55 InitWindowStationImpl(VOID)
56 {
57 OBJECT_ATTRIBUTES ObjectAttributes;
58 HANDLE WindowStationsDirectory;
59 UNICODE_STRING UnicodeString;
60 NTSTATUS Status;
61 WNDCLASSEX wcx;
62
63 /*
64 * Create the '\Windows\WindowStations' directory
65 */
66 RtlInitUnicodeStringFromLiteral(&UnicodeString,
67 WINSTA_ROOT_NAME);
68
69 InitializeObjectAttributes(&ObjectAttributes,
70 &UnicodeString,
71 0,
72 NULL,
73 NULL);
74
75 Status = ZwCreateDirectoryObject(&WindowStationsDirectory,
76 0,
77 &ObjectAttributes);
78 if (!NT_SUCCESS(Status))
79 {
80 DPRINT("Could not create \\Windows\\WindowStations directory "
81 "(Status 0x%X)\n", Status);
82 return Status;
83 }
84
85 /*
86 * Create the desktop window class
87 */
88 wcx.style = 0;
89 wcx.lpfnWndProc = W32kDesktopWindowProc;
90 wcx.cbClsExtra = wcx.cbWndExtra = 0;
91 wcx.hInstance = wcx.hIcon = wcx.hCursor = NULL;
92 wcx.hbrBackground = NULL;
93 wcx.lpszMenuName = NULL;
94 wcx.lpszClassName = L"DesktopWindowClass";
95 DesktopWindowClass = W32kCreateClass(&wcx, TRUE);
96
97 return(STATUS_SUCCESS);
98 }
99
100 NTSTATUS
101 CleanupWindowStationImpl(VOID)
102 {
103 return STATUS_SUCCESS;
104 }
105
106
107 NTSTATUS
108 ValidateWindowStationHandle(HWINSTA WindowStation,
109 KPROCESSOR_MODE AccessMode,
110 ACCESS_MASK DesiredAccess,
111 PWINSTATION_OBJECT *Object)
112 {
113 NTSTATUS Status;
114
115 Status = ObReferenceObjectByHandle(WindowStation,
116 DesiredAccess,
117 ExWindowStationObjectType,
118 AccessMode,
119 (PVOID*)Object,
120 NULL);
121 if (!NT_SUCCESS(Status))
122 {
123 SetLastNtError(Status);
124 }
125
126 return Status;
127 }
128
129 NTSTATUS
130 ValidateDesktopHandle(HDESK Desktop,
131 KPROCESSOR_MODE AccessMode,
132 ACCESS_MASK DesiredAccess,
133 PDESKTOP_OBJECT *Object)
134 {
135 NTSTATUS Status;
136
137 Status = ObReferenceObjectByHandle(Desktop,
138 DesiredAccess,
139 ExDesktopObjectType,
140 AccessMode,
141 (PVOID*)Object,
142 NULL);
143 if (!NT_SUCCESS(Status))
144 {
145 SetLastNtError(Status);
146 }
147
148 return Status;
149 }
150
151 /*
152 * FUNCTION:
153 * Closes a window station handle
154 * ARGUMENTS:
155 * hWinSta = Handle to the window station
156 * RETURNS:
157 * Status
158 * NOTES:
159 * The window station handle can be created with
160 * NtUserCreateWindowStation() or NtUserOpenWindowStation().
161 * Attemps to close a handle to the window station assigned
162 * to the calling process will fail
163 */
164 BOOL
165 STDCALL
166 NtUserCloseWindowStation(
167 HWINSTA hWinSta)
168 {
169 PWINSTATION_OBJECT Object;
170 NTSTATUS Status;
171
172 DPRINT("About to close window station handle (0x%X)\n", hWinSta);
173
174 Status = ValidateWindowStationHandle(
175 hWinSta,
176 KernelMode,
177 0,
178 &Object);
179 if (!NT_SUCCESS(Status)) {
180 DPRINT("Validation of window station handle (0x%X) failed\n", hWinSta);
181 return FALSE;
182 }
183
184 ObDereferenceObject(Object);
185
186 DPRINT("Closing window station handle (0x%X)\n", hWinSta);
187
188 Status = ZwClose(hWinSta);
189 if (!NT_SUCCESS(Status)) {
190 SetLastNtError(Status);
191 return FALSE;
192 } else {
193 return TRUE;
194 }
195 }
196
197 /*
198 * FUNCTION:
199 * Creates a new window station
200 * ARGUMENTS:
201 * lpszWindowStationName = Name of the new window station
202 * dwDesiredAccess = Requested type of access
203 * lpSecurity = Security descriptor
204 * Unknown3 = Unused
205 * Unknown4 = Unused
206 * Unknown5 = Unused
207 * RETURNS:
208 * Handle to the new window station that can be closed with
209 * NtUserCloseWindowStation()
210 * Zero on failure
211 */
212 HWINSTA STDCALL
213 NtUserCreateWindowStation(PUNICODE_STRING lpszWindowStationName,
214 ACCESS_MASK dwDesiredAccess,
215 LPSECURITY_ATTRIBUTES lpSecurity,
216 DWORD Unknown3,
217 DWORD Unknown4,
218 DWORD Unknown5)
219 {
220 OBJECT_ATTRIBUTES ObjectAttributes;
221 UNICODE_STRING WindowStationName;
222 PWINSTATION_OBJECT WinStaObject;
223 WCHAR NameBuffer[MAX_PATH];
224 NTSTATUS Status;
225 HWINSTA WinSta;
226
227 wcscpy(NameBuffer, WINSTA_ROOT_NAME);
228 wcscat(NameBuffer, L"\\");
229 wcscat(NameBuffer, lpszWindowStationName->Buffer);
230 RtlInitUnicodeString(&WindowStationName, NameBuffer);
231
232 DPRINT("Trying to open window station (%wZ)\n", &WindowStationName);
233
234 /* Initialize ObjectAttributes for the window station object */
235 InitializeObjectAttributes(&ObjectAttributes,
236 &WindowStationName,
237 0,
238 NULL,
239 NULL);
240
241 Status = ObOpenObjectByName(&ObjectAttributes,
242 ExWindowStationObjectType,
243 NULL,
244 UserMode,
245 dwDesiredAccess,
246 NULL,
247 &WinSta);
248 if (NT_SUCCESS(Status))
249 {
250 DPRINT("Successfully opened window station (%wZ)\n", WindowStationName);
251 return((HWINSTA)WinSta);
252 }
253
254 DPRINT("Creating window station (%wZ)\n", &WindowStationName);
255
256 Status = ObCreateObject(&WinSta,
257 STANDARD_RIGHTS_REQUIRED,
258 &ObjectAttributes,
259 ExWindowStationObjectType,
260 (PVOID*)&WinStaObject);
261 if (!NT_SUCCESS(Status))
262 {
263 DPRINT("Failed creating window station (%wZ)\n", &WindowStationName);
264 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
265 return (HWINSTA)0;
266 }
267
268 WinStaObject->HandleTable = ObmCreateHandleTable();
269 if (!WinStaObject->HandleTable)
270 {
271 DPRINT("Failed creating handle table\n");
272 ObDereferenceObject(WinStaObject);
273 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
274 return((HWINSTA)0);
275 }
276
277 DPRINT("Window station successfully created (%wZ)\n", &WindowStationName);
278
279 return((HWINSTA)WinSta);
280 }
281
282 BOOL
283 STDCALL
284 NtUserGetObjectInformation(
285 HANDLE hObject,
286 DWORD nIndex,
287 PVOID pvInformation,
288 DWORD nLength,
289 PDWORD nLengthNeeded)
290 {
291 return FALSE;
292 }
293
294 /*
295 * FUNCTION:
296 * Returns a handle to the current process window station
297 * ARGUMENTS:
298 * None
299 * RETURNS:
300 * Handle to the window station assigned to the current process
301 * Zero on failure
302 * NOTES:
303 * The handle need not be closed by the caller
304 */
305 HWINSTA
306 STDCALL
307 NtUserGetProcessWindowStation(VOID)
308 {
309 return PROCESS_WINDOW_STATION();
310 }
311
312 BOOL
313 STDCALL
314 NtUserLockWindowStation(
315 HWINSTA hWindowStation)
316 {
317 UNIMPLEMENTED
318
319 return 0;
320 }
321
322 /*
323 * FUNCTION:
324 * Opens an existing window station
325 * ARGUMENTS:
326 * lpszWindowStationName = Name of the existing window station
327 * dwDesiredAccess = Requested type of access
328 * RETURNS:
329 * Handle to the window station
330 * Zero on failure
331 * NOTES:
332 * The returned handle can be closed with NtUserCloseWindowStation()
333 */
334 HWINSTA
335 STDCALL
336 NtUserOpenWindowStation(
337 PUNICODE_STRING lpszWindowStationName,
338 ACCESS_MASK dwDesiredAccess)
339 {
340 OBJECT_ATTRIBUTES ObjectAttributes;
341 UNICODE_STRING WindowStationName;
342 PWINSTATION_OBJECT WinStaObject;
343 WCHAR NameBuffer[MAX_PATH];
344 NTSTATUS Status;
345 HWINSTA WinSta;
346
347 wcscpy(NameBuffer, WINSTA_ROOT_NAME);
348 wcscat(NameBuffer, L"\\");
349 wcscat(NameBuffer, lpszWindowStationName->Buffer);
350 RtlInitUnicodeString(&WindowStationName, NameBuffer);
351
352 DPRINT("Trying to open window station (%wZ)\n", &WindowStationName);
353
354 /* Initialize ObjectAttributes for the window station object */
355 InitializeObjectAttributes(
356 &ObjectAttributes,
357 &WindowStationName,
358 0,
359 NULL,
360 NULL);
361
362 Status = ObOpenObjectByName(
363 &ObjectAttributes,
364 ExDesktopObjectType,
365 NULL,
366 UserMode,
367 dwDesiredAccess,
368 NULL,
369 &WinSta);
370 if (NT_SUCCESS(Status))
371 {
372 DPRINT("Successfully opened window station (%wZ)\n", &WindowStationName);
373 return (HWINSTA)WinSta;
374 }
375
376 SetLastNtError(Status);
377 return (HWINSTA)0;
378 }
379
380 BOOL
381 STDCALL
382 NtUserSetObjectInformation(
383 HANDLE hObject,
384 DWORD nIndex,
385 PVOID pvInformation,
386 DWORD nLength)
387 {
388 /* FIXME: ZwQueryObject */
389 /* FIXME: ZwSetInformationObject */
390 SetLastNtError(STATUS_UNSUCCESSFUL);
391 return FALSE;
392 }
393
394 /*
395 * FUNCTION:
396 * Assigns a window station to the current process
397 * ARGUMENTS:
398 * hWinSta = Handle to the window station
399 * RETURNS:
400 * Status
401 */
402 BOOL STDCALL
403 NtUserSetProcessWindowStation(HWINSTA hWindowStation)
404 {
405 PWINSTATION_OBJECT Object;
406 NTSTATUS Status;
407
408 DPRINT("About to set process window station with handle (0x%X)\n",
409 hWindowStation);
410
411 Status = ValidateWindowStationHandle(hWindowStation,
412 KernelMode,
413 0,
414 &Object);
415 if (!NT_SUCCESS(Status))
416 {
417 DPRINT("Validation of window station handle (0x%X) failed\n",
418 hWindowStation);
419 return FALSE;
420 }
421
422 ObDereferenceObject(Object);
423
424 SET_PROCESS_WINDOW_STATION(hWindowStation);
425 DPRINT("IoGetCurrentProcess()->Win32WindowStation 0x%X\n",
426 IoGetCurrentProcess()->Win32WindowStation);
427
428 return TRUE;
429 }
430
431 DWORD
432 STDCALL
433 NtUserSetWindowStationUser(
434 DWORD Unknown0,
435 DWORD Unknown1,
436 DWORD Unknown2,
437 DWORD Unknown3)
438 {
439 UNIMPLEMENTED
440
441 return 0;
442 }
443
444 BOOL
445 STDCALL
446 NtUserUnlockWindowStation(
447 HWINSTA hWindowStation)
448 {
449 UNIMPLEMENTED
450
451 return FALSE;
452 }
453
454
455 /*
456 * FUNCTION:
457 * Closes a desktop handle
458 * ARGUMENTS:
459 * hDesktop = Handle to the desktop
460 * RETURNS:
461 * Status
462 * NOTES:
463 * The desktop handle can be created with NtUserCreateDesktop() or
464 * NtUserOpenDesktop().
465 * The function will fail if any thread in the calling process is using the
466 * specified desktop handle or if the handle refers to the initial desktop
467 * of the calling process
468 */
469 BOOL
470 STDCALL
471 NtUserCloseDesktop(
472 HDESK hDesktop)
473 {
474 PDESKTOP_OBJECT Object;
475 NTSTATUS Status;
476
477 DPRINT("About to close desktop handle (0x%X)\n", hDesktop);
478
479 Status = ValidateDesktopHandle(
480 hDesktop,
481 KernelMode,
482 0,
483 &Object);
484 if (!NT_SUCCESS(Status)) {
485 DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
486 return FALSE;
487 }
488
489 ObDereferenceObject(Object);
490
491 DPRINT("Closing desktop handle (0x%X)\n", hDesktop);
492
493 Status = ZwClose(hDesktop);
494 if (!NT_SUCCESS(Status)) {
495 SetLastNtError(Status);
496 return FALSE;
497 } else {
498 return TRUE;
499 }
500 }
501
502 /*
503 * FUNCTION:
504 * Creates a new desktop
505 * ARGUMENTS:
506 * lpszDesktopName = Name of the new desktop
507 * dwFlags = Interaction flags
508 * dwDesiredAccess = Requested type of access
509 * lpSecurity = Security descriptor
510 * hWindowStation = Handle to window station on which to create the desktop
511 * RETURNS:
512 * Handle to the new desktop that can be closed with NtUserCloseDesktop()
513 * Zero on failure
514 */
515 HDESK STDCALL
516 NtUserCreateDesktop(PUNICODE_STRING lpszDesktopName,
517 DWORD dwFlags,
518 ACCESS_MASK dwDesiredAccess,
519 LPSECURITY_ATTRIBUTES lpSecurity,
520 HWINSTA hWindowStation)
521 {
522 OBJECT_ATTRIBUTES ObjectAttributes;
523 PWINSTATION_OBJECT WinStaObject;
524 PDESKTOP_OBJECT DesktopObject;
525 UNICODE_STRING DesktopName;
526 WCHAR NameBuffer[MAX_PATH];
527 NTSTATUS Status;
528 HDESK Desktop;
529
530 Status = ValidateWindowStationHandle(hWindowStation,
531 KernelMode,
532 0,
533 &WinStaObject);
534 if (!NT_SUCCESS(Status))
535 {
536 DPRINT("Failed validation of window station handle (0x%X)\n",
537 hWindowStation);
538 return((HDESK)0);
539 }
540
541 wcscpy(NameBuffer, WINSTA_ROOT_NAME);
542 wcscat(NameBuffer, L"\\");
543 wcscat(NameBuffer, WinStaObject->Name.Buffer);
544 wcscat(NameBuffer, L"\\");
545 wcscat(NameBuffer, lpszDesktopName->Buffer);
546 RtlInitUnicodeString(&DesktopName, NameBuffer);
547
548 ObDereferenceObject(WinStaObject);
549
550 DPRINT("Trying to open desktop (%wZ)\n", &DesktopName);
551
552 /* Initialize ObjectAttributes for the desktop object */
553 InitializeObjectAttributes(&ObjectAttributes,
554 &DesktopName,
555 0,
556 NULL,
557 NULL);
558 Status = ObOpenObjectByName(&ObjectAttributes,
559 ExDesktopObjectType,
560 NULL,
561 UserMode,
562 dwDesiredAccess,
563 NULL,
564 &Desktop);
565 if (NT_SUCCESS(Status))
566 {
567 DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
568 return((HDESK)Desktop);
569 }
570
571 DPRINT("Status for open operation (0x%X)\n", Status);
572
573 Status = ObCreateObject(&Desktop,
574 STANDARD_RIGHTS_REQUIRED,
575 &ObjectAttributes,
576 ExDesktopObjectType,
577 (PVOID*)&DesktopObject);
578 if (!NT_SUCCESS(Status))
579 {
580 DPRINT("Failed creating desktop (%wZ)\n", &DesktopName);
581 SetLastNtError(STATUS_UNSUCCESSFUL);
582 return((HDESK)0);
583 }
584
585 /* Initialize some local (to win32k) desktop state. */
586 DesktopObject->ActiveMessageQueue = NULL;
587 InitializeListHead(&DesktopObject->WindowListHead);
588 DesktopObject->DesktopWindow =
589 W32kCreateDesktopWindow(DesktopObject->WindowStation,
590 DesktopWindowClass,
591 640, 480);
592
593 return((HDESK)Desktop);
594 }
595
596 HDESK STDCALL
597 NtUserGetThreadDesktop(DWORD dwThreadId,
598 DWORD Unknown1)
599 {
600 UNIMPLEMENTED;
601 return((HDESK)0);
602 }
603
604 /*
605 * FUNCTION:
606 * Opens an existing desktop
607 * ARGUMENTS:
608 * lpszDesktopName = Name of the existing desktop
609 * dwFlags = Interaction flags
610 * dwDesiredAccess = Requested type of access
611 * RETURNS:
612 * Handle to the desktop
613 * Zero on failure
614 * NOTES:
615 * The returned handle can be closed with NtUserCloseDesktop()
616 */
617 HDESK
618 STDCALL
619 NtUserOpenDesktop(
620 PUNICODE_STRING lpszDesktopName,
621 DWORD dwFlags,
622 ACCESS_MASK dwDesiredAccess)
623 {
624 OBJECT_ATTRIBUTES ObjectAttributes;
625 PWINSTATION_OBJECT WinStaObject;
626 UNICODE_STRING DesktopName;
627 WCHAR NameBuffer[MAX_PATH];
628 NTSTATUS Status;
629 HDESK Desktop;
630
631 /* Validate the window station handle and
632 compose the fully qualified desktop name */
633
634 Status = ValidateWindowStationHandle(
635 PROCESS_WINDOW_STATION(),
636 KernelMode,
637 0,
638 &WinStaObject);
639 if (!NT_SUCCESS(Status))
640 {
641 DPRINT("Failed validation of window station handle (0x%X)\n",
642 PROCESS_WINDOW_STATION());
643 return (HDESK)0;
644 }
645
646 wcscpy(NameBuffer, WINSTA_ROOT_NAME);
647 wcscat(NameBuffer, L"\\");
648 wcscat(NameBuffer, WinStaObject->Name.Buffer);
649 wcscat(NameBuffer, L"\\");
650 wcscat(NameBuffer, lpszDesktopName->Buffer);
651 RtlInitUnicodeString(&DesktopName, NameBuffer);
652
653 ObDereferenceObject(WinStaObject);
654
655
656 DPRINT("Trying to open desktop station (%wZ)\n", &DesktopName);
657
658 /* Initialize ObjectAttributes for the desktop object */
659 InitializeObjectAttributes(
660 &ObjectAttributes,
661 &DesktopName,
662 0,
663 NULL,
664 NULL);
665
666 Status = ObOpenObjectByName(
667 &ObjectAttributes,
668 ExDesktopObjectType,
669 NULL,
670 UserMode,
671 dwDesiredAccess,
672 NULL,
673 &Desktop);
674 if (NT_SUCCESS(Status))
675 {
676 DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
677 return (HDESK)Desktop;
678 }
679
680 SetLastNtError(Status);
681 return (HDESK)0;
682 }
683
684 /*
685 * FUNCTION:
686 * Opens the input (interactive) desktop
687 * ARGUMENTS:
688 * dwFlags = Interaction flags
689 * fInherit = Inheritance option
690 * dwDesiredAccess = Requested type of access
691 * RETURNS:
692 * Handle to the input desktop
693 * Zero on failure
694 * NOTES:
695 * The returned handle can be closed with NtUserCloseDesktop()
696 */
697 HDESK
698 STDCALL
699 NtUserOpenInputDesktop(
700 DWORD dwFlags,
701 BOOL fInherit,
702 ACCESS_MASK dwDesiredAccess)
703 {
704 PDESKTOP_OBJECT Object;
705 NTSTATUS Status;
706 HDESK Desktop;
707
708 DPRINT("About to open input desktop\n");
709
710 /* Get a pointer to the desktop object */
711
712 Status = ValidateDesktopHandle(
713 InputDesktop,
714 KernelMode,
715 0,
716 &Object);
717 if (!NT_SUCCESS(Status)) {
718 DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
719 return (HDESK)0;
720 }
721
722 /* Create a new handle to the object */
723
724 Status = ObOpenObjectByPointer(
725 Object,
726 0,
727 NULL,
728 dwDesiredAccess,
729 ExDesktopObjectType,
730 UserMode,
731 &Desktop);
732
733 ObDereferenceObject(Object);
734
735 if (NT_SUCCESS(Status))
736 {
737 DPRINT("Successfully opened input desktop\n");
738 return (HDESK)Desktop;
739 }
740
741 SetLastNtError(Status);
742 return (HDESK)0;
743 }
744
745 BOOL STDCALL
746 NtUserPaintDesktop(HDC hDC)
747 {
748 UNIMPLEMENTED
749
750 return FALSE;
751 }
752
753 DWORD STDCALL
754 NtUserResolveDesktopForWOW(DWORD Unknown0)
755 {
756 UNIMPLEMENTED
757 return 0;
758 }
759
760 BOOL STDCALL
761 NtUserSetThreadDesktop(HDESK hDesktop)
762 {
763 PDESKTOP_OBJECT DesktopObject;
764 NTSTATUS Status;
765
766 /* Initialize the Win32 state if necessary. */
767 W32kGuiCheck();
768
769 /* Validate the new desktop. */
770 Status = ValidateDesktopHandle(hDesktop,
771 KernelMode,
772 0,
773 &DesktopObject);
774 if (!NT_SUCCESS(Status))
775 {
776 DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
777 return(FALSE);
778 }
779
780 /* Check for setting the same desktop as before. */
781 if (DesktopObject == PsGetWin32Thread()->Desktop)
782 {
783 ObDereferenceObject(DesktopObject);
784 return(TRUE);
785 }
786
787 /* FIXME: Should check here to see if the thread has any windows. */
788
789 ObDereferenceObject(PsGetWin32Thread()->Desktop);
790 PsGetWin32Thread()->Desktop = DesktopObject;
791
792 return(TRUE);
793 }
794
795 /*
796 * FUNCTION:
797 * Sets the current input (interactive) desktop
798 * ARGUMENTS:
799 * hDesktop = Handle to desktop
800 * RETURNS:
801 * Status
802 */
803 BOOL STDCALL
804 NtUserSwitchDesktop(HDESK hDesktop)
805 {
806 PDESKTOP_OBJECT DesktopObject;
807 NTSTATUS Status;
808
809 DPRINT("About to switch desktop (0x%X)\n", hDesktop);
810
811 Status = ValidateDesktopHandle(hDesktop,
812 KernelMode,
813 0,
814 &DesktopObject);
815 if (!NT_SUCCESS(Status))
816 {
817 DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
818 return(FALSE);
819 }
820
821 /* FIXME: Fail if the desktop belong to an invisible window station */
822 /* FIXME: Fail if the process is associated with a secured
823 desktop such as Winlogon or Screen-Saver */
824 /* FIXME: Connect to input device */
825
826 /* Set the active desktop in the desktop's window station. */
827 DesktopObject->WindowStation->ActiveDesktop = DesktopObject;
828
829 /* Set the global state. */
830 InputDesktopHandle = hDesktop;
831 InputDesktop = DesktopObject;
832 InputWindowStation = DesktopObject->WindowStation;
833
834 ObDereferenceObject(DesktopObject);
835
836 return(TRUE);
837 }
838
839 LRESULT CALLBACK
840 W32kDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
841 {
842 switch (msg)
843 {
844 case WM_CREATE:
845 return(0);
846
847 case WM_NCCREATE:
848 return(1);
849
850 default:
851 return(0);
852 }
853 }
854
855 /* EOF */