1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Native User stubs
5 * FILE: win32ss/user/ntuser/ntstubs.c
6 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 */
8
9 #include <win32k.h>
10 DBG_DEFAULT_CHANNEL(UserMisc);
11
12 //
13 // Works like BitBlt, http://msdn.microsoft.com/en-us/library/ms532278(VS.85).aspx
14 //
15 BOOL
16 APIENTRY
NtUserBitBltSysBmp(HDC hdc,INT nXDest,INT nYDest,INT nWidth,INT nHeight,INT nXSrc,INT nYSrc,DWORD dwRop)17 NtUserBitBltSysBmp(
18 HDC hdc,
19 INT nXDest,
20 INT nYDest,
21 INT nWidth,
22 INT nHeight,
23 INT nXSrc,
24 INT nYSrc,
25 DWORD dwRop )
26 {
27 BOOL Ret = FALSE;
28 UserEnterExclusive();
29
30 Ret = NtGdiBitBlt( hdc,
31 nXDest,
32 nYDest,
33 nWidth,
34 nHeight,
35 hSystemBM,
36 nXSrc,
37 nYSrc,
38 dwRop,
39 0,
40 0);
41
42 UserLeave();
43 return Ret;
44 }
45
46 DWORD
47 APIENTRY
NtUserDragObject(HWND hwnd1,HWND hwnd2,UINT u1,DWORD dw1,HCURSOR hc1)48 NtUserDragObject(
49 HWND hwnd1,
50 HWND hwnd2,
51 UINT u1,
52 DWORD dw1,
53 HCURSOR hc1
54 )
55 {
56 STUB
57
58 return 0;
59 }
60
61 BOOL
62 APIENTRY
NtUserDrawAnimatedRects(HWND hwnd,INT idAni,RECT * lprcFrom,RECT * lprcTo)63 NtUserDrawAnimatedRects(
64 HWND hwnd,
65 INT idAni,
66 RECT *lprcFrom,
67 RECT *lprcTo)
68 {
69 STUB
70
71 return 0;
72 }
73
74 DWORD
75 APIENTRY
NtUserEvent(DWORD Unknown0)76 NtUserEvent(
77 DWORD Unknown0)
78 {
79 STUB
80
81 return 0;
82 }
83
84 BOOL
85 APIENTRY
NtUserGetAltTabInfo(HWND hwnd,INT iItem,PALTTABINFO pati,LPWSTR pszItemText,UINT cchItemText,BOOL Ansi)86 NtUserGetAltTabInfo(
87 HWND hwnd,
88 INT iItem,
89 PALTTABINFO pati,
90 LPWSTR pszItemText,
91 UINT cchItemText,
92 BOOL Ansi)
93 {
94 STUB
95
96 return 0;
97 }
98
99 NTSTATUS
100 APIENTRY
NtUserInitializeClientPfnArrays(PPFNCLIENT pfnClientA,PPFNCLIENT pfnClientW,PPFNCLIENTWORKER pfnClientWorker,HINSTANCE hmodUser)101 NtUserInitializeClientPfnArrays(
102 PPFNCLIENT pfnClientA,
103 PPFNCLIENT pfnClientW,
104 PPFNCLIENTWORKER pfnClientWorker,
105 HINSTANCE hmodUser)
106 {
107 NTSTATUS Status = STATUS_SUCCESS;
108 TRACE("Enter NtUserInitializeClientPfnArrays User32 0x%p\n", hmodUser);
109
110 if (ClientPfnInit) return Status;
111
112 UserEnterExclusive();
113
114 _SEH2_TRY
115 {
116 ProbeForRead( pfnClientA, sizeof(PFNCLIENT), 1);
117 ProbeForRead( pfnClientW, sizeof(PFNCLIENT), 1);
118 ProbeForRead( pfnClientWorker, sizeof(PFNCLIENTWORKER), 1);
119 RtlCopyMemory(&gpsi->apfnClientA, pfnClientA, sizeof(PFNCLIENT));
120 RtlCopyMemory(&gpsi->apfnClientW, pfnClientW, sizeof(PFNCLIENT));
121 RtlCopyMemory(&gpsi->apfnClientWorker, pfnClientWorker, sizeof(PFNCLIENTWORKER));
122
123 //// FIXME: HAX! Temporary until server side is finished.
124 //// Copy the client side procs for now.
125 RtlCopyMemory(&gpsi->aStoCidPfn, pfnClientW, sizeof(gpsi->aStoCidPfn));
126
127 hModClient = hmodUser;
128 ClientPfnInit = TRUE;
129 }
130 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
131 {
132 Status =_SEH2_GetExceptionCode();
133 }
134 _SEH2_END
135
136 if (!NT_SUCCESS(Status))
137 {
138 ERR("Failed reading Client Pfns from user space.\n");
139 SetLastNtError(Status);
140 }
141
142 UserLeave();
143 return Status;
144 }
145
146 DWORD
147 APIENTRY
NtUserInitTask(DWORD Unknown0,DWORD Unknown1,DWORD Unknown2,DWORD Unknown3,DWORD Unknown4,DWORD Unknown5,DWORD Unknown6,DWORD Unknown7,DWORD Unknown8,DWORD Unknown9,DWORD Unknown10,DWORD Unknown11)148 NtUserInitTask(
149 DWORD Unknown0,
150 DWORD Unknown1,
151 DWORD Unknown2,
152 DWORD Unknown3,
153 DWORD Unknown4,
154 DWORD Unknown5,
155 DWORD Unknown6,
156 DWORD Unknown7,
157 DWORD Unknown8,
158 DWORD Unknown9,
159 DWORD Unknown10,
160 DWORD Unknown11)
161 {
162 STUB
163
164 return 0;
165 }
166
167 DWORD
168 APIENTRY
NtUserMNDragLeave(VOID)169 NtUserMNDragLeave(VOID)
170 {
171 STUB
172
173 return 0;
174 }
175
176 DWORD
177 APIENTRY
NtUserMNDragOver(DWORD Unknown0,DWORD Unknown1)178 NtUserMNDragOver(
179 DWORD Unknown0,
180 DWORD Unknown1)
181 {
182 STUB
183
184 return 0;
185 }
186
187 DWORD
188 APIENTRY
NtUserModifyUserStartupInfoFlags(DWORD Unknown0,DWORD Unknown1)189 NtUserModifyUserStartupInfoFlags(
190 DWORD Unknown0,
191 DWORD Unknown1)
192 {
193 STUB
194
195 return 0;
196 }
197
198 DWORD
199 APIENTRY
NtUserQueryUserCounters(DWORD Unknown0,DWORD Unknown1,DWORD Unknown2,DWORD Unknown3,DWORD Unknown4)200 NtUserQueryUserCounters(
201 DWORD Unknown0,
202 DWORD Unknown1,
203 DWORD Unknown2,
204 DWORD Unknown3,
205 DWORD Unknown4)
206 {
207 STUB
208
209 return 0;
210 }
211
212 DWORD
213 APIENTRY
NtUserRegisterTasklist(DWORD Unknown0)214 NtUserRegisterTasklist(
215 DWORD Unknown0)
216 {
217 STUB
218
219 return 0;
220 }
221
222 DWORD
223 APIENTRY
NtUserSetConsoleReserveKeys(DWORD Unknown0,DWORD Unknown1)224 NtUserSetConsoleReserveKeys(
225 DWORD Unknown0,
226 DWORD Unknown1)
227 {
228 STUB
229
230 return 0;
231 }
232
233 DWORD
234 APIENTRY
NtUserSetDbgTag(DWORD Unknown0,DWORD Unknown1)235 NtUserSetDbgTag(
236 DWORD Unknown0,
237 DWORD Unknown1)
238 {
239 STUB;
240
241 return 0;
242 }
243
244 DWORD
245 APIENTRY
NtUserSetDbgTagCount(DWORD Unknown0)246 NtUserSetDbgTagCount(
247 DWORD Unknown0)
248 {
249 STUB;
250
251 return 0;
252 }
253
254 DWORD
255 APIENTRY
NtUserSetRipFlags(DWORD Unknown0)256 NtUserSetRipFlags(
257 DWORD Unknown0)
258 {
259 STUB;
260
261 return 0;
262 }
263
264 DWORD
265 APIENTRY
NtUserDbgWin32HeapFail(DWORD Unknown0,DWORD Unknown1)266 NtUserDbgWin32HeapFail(
267 DWORD Unknown0,
268 DWORD Unknown1)
269 {
270 STUB
271
272 return 0;
273 }
274
275 DWORD
276 APIENTRY
NtUserDbgWin32HeapStat(DWORD Unknown0,DWORD Unknown1)277 NtUserDbgWin32HeapStat(
278 DWORD Unknown0,
279 DWORD Unknown1)
280 {
281 STUB
282
283 return 0;
284 }
285
286 BOOL
287 APIENTRY
NtUserSetSysColors(int cElements,IN CONST INT * lpaElements,IN CONST COLORREF * lpaRgbValues,FLONG Flags)288 NtUserSetSysColors(
289 int cElements,
290 IN CONST INT *lpaElements,
291 IN CONST COLORREF *lpaRgbValues,
292 FLONG Flags)
293 {
294 DWORD Ret = TRUE;
295
296 if (cElements == 0)
297 return TRUE;
298
299 /* We need this check to prevent overflow later */
300 if ((ULONG)cElements >= 0x40000000)
301 {
302 EngSetLastError(ERROR_NOACCESS);
303 return FALSE;
304 }
305
306 UserEnterExclusive();
307
308 _SEH2_TRY
309 {
310 ProbeForRead(lpaElements, cElements * sizeof(INT), 1);
311 ProbeForRead(lpaRgbValues, cElements * sizeof(COLORREF), 1);
312
313 IntSetSysColors(cElements, lpaElements, lpaRgbValues);
314 }
315 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
316 {
317 SetLastNtError(_SEH2_GetExceptionCode());
318 Ret = FALSE;
319 }
320 _SEH2_END;
321
322 if (Ret)
323 {
324 UserSendNotifyMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
325
326 UserRedrawDesktop();
327 }
328
329 UserLeave();
330 return Ret;
331 }
332
333 DWORD
334 APIENTRY
NtUserUpdateInstance(DWORD Unknown0,DWORD Unknown1,DWORD Unknown2)335 NtUserUpdateInstance(
336 DWORD Unknown0,
337 DWORD Unknown1,
338 DWORD Unknown2)
339 {
340 STUB
341
342 return 0;
343 }
344
345 BOOL
346 APIENTRY
NtUserUserHandleGrantAccess(IN HANDLE hUserHandle,IN HANDLE hJob,IN BOOL bGrant)347 NtUserUserHandleGrantAccess(
348 IN HANDLE hUserHandle,
349 IN HANDLE hJob,
350 IN BOOL bGrant)
351 {
352 STUB
353
354 return 0;
355 }
356
357 DWORD
358 APIENTRY
NtUserWaitForMsgAndEvent(DWORD Unknown0)359 NtUserWaitForMsgAndEvent(
360 DWORD Unknown0)
361 {
362 STUB
363
364 return 0;
365 }
366
367 DWORD
368 APIENTRY
NtUserWin32PoolAllocationStats(DWORD Unknown0,DWORD Unknown1,DWORD Unknown2,DWORD Unknown3,DWORD Unknown4,DWORD Unknown5)369 NtUserWin32PoolAllocationStats(
370 DWORD Unknown0,
371 DWORD Unknown1,
372 DWORD Unknown2,
373 DWORD Unknown3,
374 DWORD Unknown4,
375 DWORD Unknown5)
376 {
377 STUB
378
379 return 0;
380 }
381
382 DWORD
383 APIENTRY
NtUserYieldTask(VOID)384 NtUserYieldTask(VOID)
385 {
386 STUB
387
388 return 0;
389 }
390
391 DWORD
392 APIENTRY
NtUserGetRawInputBuffer(PRAWINPUT pData,PUINT pcbSize,UINT cbSizeHeader)393 NtUserGetRawInputBuffer(
394 PRAWINPUT pData,
395 PUINT pcbSize,
396 UINT cbSizeHeader)
397 {
398 STUB;
399 return 0;
400 }
401
402 DWORD
403 APIENTRY
NtUserGetRawInputData(HRAWINPUT hRawInput,UINT uiCommand,LPVOID pData,PUINT pcbSize,UINT cbSizeHeader)404 NtUserGetRawInputData(
405 HRAWINPUT hRawInput,
406 UINT uiCommand,
407 LPVOID pData,
408 PUINT pcbSize,
409 UINT cbSizeHeader)
410 {
411 STUB;
412 return 0;
413 }
414
415 DWORD
416 APIENTRY
NtUserGetRawInputDeviceInfo(HANDLE hDevice,UINT uiCommand,LPVOID pData,PUINT pcbSize)417 NtUserGetRawInputDeviceInfo(
418 HANDLE hDevice,
419 UINT uiCommand,
420 LPVOID pData,
421 PUINT pcbSize
422 )
423 {
424 STUB;
425 return 0;
426 }
427
428 DWORD
429 APIENTRY
NtUserGetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList,PUINT puiNumDevices,UINT cbSize)430 NtUserGetRawInputDeviceList(
431 PRAWINPUTDEVICELIST pRawInputDeviceList,
432 PUINT puiNumDevices,
433 UINT cbSize)
434 {
435 STUB;
436 return 0;
437 }
438
439 DWORD
440 APIENTRY
NtUserGetRegisteredRawInputDevices(PRAWINPUTDEVICE pRawInputDevices,PUINT puiNumDevices,UINT cbSize)441 NtUserGetRegisteredRawInputDevices(
442 PRAWINPUTDEVICE pRawInputDevices,
443 PUINT puiNumDevices,
444 UINT cbSize)
445 {
446 STUB;
447 return 0;
448 }
449
450 DWORD
451 APIENTRY
NtUserHardErrorControl(DWORD dwUnknown1,DWORD dwUnknown2,DWORD dwUnknown3)452 NtUserHardErrorControl(
453 DWORD dwUnknown1,
454 DWORD dwUnknown2,
455 DWORD dwUnknown3)
456 {
457 STUB;
458 return 0;
459 }
460
461 BOOL
462 NTAPI
NtUserNotifyProcessCreate(HANDLE NewProcessId,HANDLE ParentThreadId,ULONG dwUnknown,ULONG CreateFlags)463 NtUserNotifyProcessCreate(
464 HANDLE NewProcessId,
465 HANDLE ParentThreadId,
466 ULONG dwUnknown,
467 ULONG CreateFlags)
468 {
469 // STUB;
470 TRACE("NtUserNotifyProcessCreate is UNIMPLEMENTED\n");
471 return FALSE;
472 }
473
474 NTSTATUS
475 APIENTRY
NtUserProcessConnect(IN HANDLE ProcessHandle,OUT PUSERCONNECT pUserConnect,IN ULONG Size)476 NtUserProcessConnect(
477 IN HANDLE ProcessHandle,
478 OUT PUSERCONNECT pUserConnect,
479 IN ULONG Size)
480 {
481 NTSTATUS Status;
482 PEPROCESS Process = NULL;
483 PPROCESSINFO W32Process;
484
485 TRACE("NtUserProcessConnect\n");
486
487 if (pUserConnect == NULL ||
488 Size != sizeof(*pUserConnect))
489 {
490 return STATUS_UNSUCCESSFUL;
491 }
492
493 /* Get the process object the user handle was referencing */
494 Status = ObReferenceObjectByHandle(ProcessHandle,
495 PROCESS_VM_OPERATION,
496 *PsProcessType,
497 UserMode,
498 (PVOID*)&Process,
499 NULL);
500 if (!NT_SUCCESS(Status)) return Status;
501
502 UserEnterShared();
503
504 /* Get Win32 process information */
505 W32Process = PsGetProcessWin32Process(Process);
506
507 _SEH2_TRY
508 {
509 UINT i;
510
511 // FIXME: Check that pUserConnect->ulVersion == USER_VERSION;
512 // FIXME: Check the value of pUserConnect->dwDispatchCount.
513
514 ProbeForWrite(pUserConnect, sizeof(*pUserConnect), sizeof(PVOID));
515
516 // FIXME: Instead of assuming that the mapping of the heap desktop
517 // also holds there, we **MUST** create and map instead the shared
518 // section! Its client base must be stored in W32Process->pClientBase.
519 // What is currently done (ReactOS-specific only), is that within the
520 // IntUserHeapCommitRoutine()/MapGlobalUserHeap() routines we assume
521 // it's going to be also called early, so that we manually add a very
522 // first memory mapping that corresponds to the "global user heap",
523 // and that we use instead of a actual win32 "shared USER section"
524 // (see slide 29 of https://paper.bobylive.com/Meeting_Papers/BlackHat/USA-2011/BH_US_11_Mandt_win32k_Slides.pdf )
525
526 pUserConnect->siClient.ulSharedDelta =
527 (ULONG_PTR)W32Process->HeapMappings.KernelMapping -
528 (ULONG_PTR)W32Process->HeapMappings.UserMapping;
529
530 #define SERVER_TO_CLIENT(ptr) \
531 ((PVOID)((ULONG_PTR)ptr - pUserConnect->siClient.ulSharedDelta))
532
533 ASSERT(gpsi);
534 ASSERT(gHandleTable);
535
536 pUserConnect->siClient.psi = SERVER_TO_CLIENT(gpsi);
537 pUserConnect->siClient.aheList = SERVER_TO_CLIENT(gHandleTable);
538 pUserConnect->siClient.pDispInfo = NULL;
539
540 // NOTE: kernel server should also have a SHAREDINFO gSharedInfo;
541 // FIXME: These USER window-proc data should be used somehow!
542
543 pUserConnect->siClient.DefWindowMsgs.maxMsgs = 0;
544 pUserConnect->siClient.DefWindowMsgs.abMsgs = NULL;
545 pUserConnect->siClient.DefWindowSpecMsgs.maxMsgs = 0;
546 pUserConnect->siClient.DefWindowSpecMsgs.abMsgs = NULL;
547
548 for (i = 0; i < ARRAYSIZE(pUserConnect->siClient.awmControl); ++i)
549 {
550 pUserConnect->siClient.awmControl[i].maxMsgs = 0;
551 pUserConnect->siClient.awmControl[i].abMsgs = NULL;
552 }
553 #undef SERVER_TO_CLIENT
554 }
555 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
556 {
557 Status = _SEH2_GetExceptionCode();
558 }
559 _SEH2_END;
560
561 if (!NT_SUCCESS(Status))
562 SetLastNtError(Status);
563
564 UserLeave();
565
566 /* Dereference the process object */
567 ObDereferenceObject(Process);
568
569 return Status;
570 }
571
572 NTSTATUS
573 APIENTRY
NtUserQueryInformationThread(IN HANDLE ThreadHandle,IN USERTHREADINFOCLASS ThreadInformationClass,OUT PVOID ThreadInformation,IN ULONG ThreadInformationLength)574 NtUserQueryInformationThread(IN HANDLE ThreadHandle,
575 IN USERTHREADINFOCLASS ThreadInformationClass,
576 OUT PVOID ThreadInformation,
577 IN ULONG ThreadInformationLength)
578 {
579 NTSTATUS Status = STATUS_SUCCESS;
580 PETHREAD Thread;
581
582 /* Allow only CSRSS to perform this operation */
583 if (PsGetCurrentProcess() != gpepCSRSS)
584 return STATUS_ACCESS_DENIED;
585
586 UserEnterExclusive();
587
588 /* Get the Thread */
589 Status = ObReferenceObjectByHandle(ThreadHandle,
590 THREAD_QUERY_INFORMATION,
591 *PsThreadType,
592 UserMode,
593 (PVOID)&Thread,
594 NULL);
595 if (!NT_SUCCESS(Status)) goto Quit;
596
597 switch (ThreadInformationClass)
598 {
599 default:
600 {
601 STUB;
602 Status = STATUS_NOT_IMPLEMENTED;
603 break;
604 }
605 }
606
607 ObDereferenceObject(Thread);
608
609 Quit:
610 UserLeave();
611 return Status;
612 }
613
614 BOOL
615 APIENTRY
NtUserRealInternalGetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg,BOOL bGMSG)616 NtUserRealInternalGetMessage(
617 LPMSG lpMsg,
618 HWND hWnd,
619 UINT wMsgFilterMin,
620 UINT wMsgFilterMax,
621 UINT wRemoveMsg,
622 BOOL bGMSG)
623 {
624 STUB;
625 return 0;
626 }
627
628 BOOL
629 APIENTRY
NtUserRealWaitMessageEx(DWORD dwWakeMask,UINT uTimeout)630 NtUserRealWaitMessageEx(
631 DWORD dwWakeMask,
632 UINT uTimeout)
633 {
634 STUB;
635 return 0;
636 }
637
638 BOOL
639 APIENTRY
NtUserRegisterRawInputDevices(IN PCRAWINPUTDEVICE pRawInputDevices,IN UINT uiNumDevices,IN UINT cbSize)640 NtUserRegisterRawInputDevices(
641 IN PCRAWINPUTDEVICE pRawInputDevices,
642 IN UINT uiNumDevices,
643 IN UINT cbSize)
644 {
645 STUB;
646 return 0;
647 }
648
649 DWORD APIENTRY
NtUserResolveDesktopForWOW(DWORD Unknown0)650 NtUserResolveDesktopForWOW(DWORD Unknown0)
651 {
652 STUB
653 return 0;
654 }
655
656 DWORD
657 APIENTRY
NtUserSetInformationProcess(DWORD dwUnknown1,DWORD dwUnknown2,DWORD dwUnknown3,DWORD dwUnknown4)658 NtUserSetInformationProcess(
659 DWORD dwUnknown1,
660 DWORD dwUnknown2,
661 DWORD dwUnknown3,
662 DWORD dwUnknown4)
663 {
664 STUB;
665 return 0;
666 }
667
668 HDESK FASTCALL
669 IntGetDesktopObjectHandle(PDESKTOP DesktopObject);
670
671 NTSTATUS
672 APIENTRY
NtUserSetInformationThread(IN HANDLE ThreadHandle,IN USERTHREADINFOCLASS ThreadInformationClass,IN PVOID ThreadInformation,IN ULONG ThreadInformationLength)673 NtUserSetInformationThread(IN HANDLE ThreadHandle,
674 IN USERTHREADINFOCLASS ThreadInformationClass,
675 IN PVOID ThreadInformation,
676 IN ULONG ThreadInformationLength)
677 {
678 NTSTATUS Status = STATUS_SUCCESS;
679 PETHREAD Thread;
680
681 /* Allow only CSRSS to perform this operation */
682 if (PsGetCurrentProcess() != gpepCSRSS)
683 return STATUS_ACCESS_DENIED;
684
685 UserEnterExclusive();
686
687 /* Get the Thread */
688 Status = ObReferenceObjectByHandle(ThreadHandle,
689 THREAD_SET_INFORMATION,
690 *PsThreadType,
691 UserMode,
692 (PVOID)&Thread,
693 NULL);
694 if (!NT_SUCCESS(Status)) goto Quit;
695
696 switch (ThreadInformationClass)
697 {
698 case UserThreadInitiateShutdown:
699 {
700 ULONG CapturedFlags = 0;
701
702 TRACE("Shutdown initiated\n");
703
704 if (ThreadInformationLength != sizeof(CapturedFlags))
705 {
706 Status = STATUS_INFO_LENGTH_MISMATCH;
707 break;
708 }
709
710 /* Capture the caller value */
711 Status = STATUS_SUCCESS;
712 _SEH2_TRY
713 {
714 ProbeForWrite(ThreadInformation, sizeof(CapturedFlags), __alignof(CapturedFlags));
715 CapturedFlags = *(PULONG)ThreadInformation;
716 }
717 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
718 {
719 Status = _SEH2_GetExceptionCode();
720 _SEH2_YIELD(break);
721 }
722 _SEH2_END;
723
724 Status = UserInitiateShutdown(Thread, &CapturedFlags);
725
726 /* Return the modified value to the caller */
727 _SEH2_TRY
728 {
729 *(PULONG)ThreadInformation = CapturedFlags;
730 }
731 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
732 {
733 Status = _SEH2_GetExceptionCode();
734 }
735 _SEH2_END;
736
737 break;
738 }
739
740 case UserThreadEndShutdown:
741 {
742 NTSTATUS ShutdownStatus;
743
744 TRACE("Shutdown ended\n");
745
746 if (ThreadInformationLength != sizeof(ShutdownStatus))
747 {
748 Status = STATUS_INFO_LENGTH_MISMATCH;
749 break;
750 }
751
752 /* Capture the caller value */
753 Status = STATUS_SUCCESS;
754 _SEH2_TRY
755 {
756 ProbeForRead(ThreadInformation, sizeof(ShutdownStatus), __alignof(ShutdownStatus));
757 ShutdownStatus = *(NTSTATUS*)ThreadInformation;
758 }
759 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
760 {
761 Status = _SEH2_GetExceptionCode();
762 _SEH2_YIELD(break);
763 }
764 _SEH2_END;
765
766 Status = UserEndShutdown(Thread, ShutdownStatus);
767 break;
768 }
769
770 case UserThreadCsrApiPort:
771 {
772 HANDLE CsrPortHandle;
773
774
775 TRACE("Set CSR API Port for Win32k\n");
776 if (ThreadInformationLength != sizeof(CsrPortHandle))
777 {
778 Status = STATUS_INFO_LENGTH_MISMATCH;
779 break;
780 }
781
782 /* Capture the caller value */
783 Status = STATUS_SUCCESS;
784 _SEH2_TRY
785 {
786 ProbeForRead(ThreadInformation, sizeof(CsrPortHandle), __alignof(CsrPortHandle));
787 CsrPortHandle = *(PHANDLE)ThreadInformation;
788 }
789 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
790 {
791 Status = _SEH2_GetExceptionCode();
792 _SEH2_YIELD(break);
793 }
794 _SEH2_END;
795
796 Status = InitCsrApiPort(CsrPortHandle);
797 break;
798 }
799
800 case UserThreadUseActiveDesktop:
801 {
802 HDESK hdesk;
803
804 if (Thread != PsGetCurrentThread())
805 {
806 Status = STATUS_NOT_IMPLEMENTED;
807 break;
808 }
809
810 hdesk = IntGetDesktopObjectHandle(gpdeskInputDesktop);
811 IntSetThreadDesktop(hdesk, FALSE);
812
813 break;
814 }
815 case UserThreadRestoreDesktop:
816 {
817 if (Thread != PsGetCurrentThread())
818 {
819 Status = STATUS_NOT_IMPLEMENTED;
820 break;
821 }
822
823 IntSetThreadDesktop(NULL, FALSE);
824 break;
825 }
826 default:
827 {
828 STUB;
829 Status = STATUS_NOT_IMPLEMENTED;
830 break;
831 }
832 }
833
834 ObDereferenceObject(Thread);
835
836 Quit:
837 UserLeave();
838 return Status;
839 }
840
841 BOOL
842 APIENTRY
NtUserSoundSentry(VOID)843 NtUserSoundSentry(VOID)
844 {
845 STUB;
846 return 0;
847 }
848
849 DWORD
850 APIENTRY
NtUserTestForInteractiveUser(DWORD dwUnknown1)851 NtUserTestForInteractiveUser(
852 DWORD dwUnknown1)
853 {
854 STUB;
855 return 0;
856 }
857
858 DWORD
859 APIENTRY
NtUserRemoteConnect(DWORD dwUnknown1,DWORD dwUnknown2,DWORD dwUnknown3)860 NtUserRemoteConnect(
861 DWORD dwUnknown1,
862 DWORD dwUnknown2,
863 DWORD dwUnknown3)
864 {
865 STUB;
866 return 0;
867 }
868
869 DWORD
870 APIENTRY
NtUserRemoteRedrawRectangle(DWORD dwUnknown1,DWORD dwUnknown2,DWORD dwUnknown3,DWORD dwUnknown4)871 NtUserRemoteRedrawRectangle(
872 DWORD dwUnknown1,
873 DWORD dwUnknown2,
874 DWORD dwUnknown3,
875 DWORD dwUnknown4)
876 {
877 STUB;
878 return 0;
879 }
880
881 DWORD
882 APIENTRY
NtUserRemoteRedrawScreen(VOID)883 NtUserRemoteRedrawScreen(VOID)
884 {
885 STUB;
886 return 0;
887 }
888
889 DWORD
890 APIENTRY
NtUserRemoteStopScreenUpdates(VOID)891 NtUserRemoteStopScreenUpdates(VOID)
892 {
893 STUB;
894 return 0;
895 }
896
897 DWORD
898 APIENTRY
NtUserCtxDisplayIOCtl(DWORD dwUnknown1,DWORD dwUnknown2,DWORD dwUnknown3)899 NtUserCtxDisplayIOCtl(
900 DWORD dwUnknown1,
901 DWORD dwUnknown2,
902 DWORD dwUnknown3)
903 {
904 STUB;
905 return 0;
906 }
907
908 /*
909 * @unimplemented
910 */
911 BOOL APIENTRY
NtUserLockWindowUpdate(HWND hWnd)912 NtUserLockWindowUpdate(HWND hWnd)
913 {
914 STUB;
915 return FALSE;
916 }
917
918 DWORD APIENTRY
NtUserQuerySendMessage(DWORD Unknown0)919 NtUserQuerySendMessage(DWORD Unknown0)
920 {
921 STUB;
922
923 return 0;
924 }
925
NtUserAddClipboardFormatListener(HWND hwnd)926 BOOL APIENTRY NtUserAddClipboardFormatListener(
927 HWND hwnd
928 )
929 {
930 STUB;
931 return FALSE;
932 }
933
NtUserRemoveClipboardFormatListener(HWND hwnd)934 BOOL APIENTRY NtUserRemoveClipboardFormatListener(
935 HWND hwnd
936 )
937 {
938 STUB;
939 return FALSE;
940 }
941
NtUserGetUpdatedClipboardFormats(PUINT lpuiFormats,UINT cFormats,PUINT pcFormatsOut)942 BOOL APIENTRY NtUserGetUpdatedClipboardFormats(
943 PUINT lpuiFormats,
944 UINT cFormats,
945 PUINT pcFormatsOut
946 )
947 {
948 STUB;
949 return FALSE;
950 }
951
952 // Yes, I know, these do not belong here, just tell me where to put them
953 BOOL
954 APIENTRY
NtGdiMakeObjectXferable(_In_ HANDLE hHandle,_In_ DWORD dwProcessId)955 NtGdiMakeObjectXferable(
956 _In_ HANDLE hHandle,
957 _In_ DWORD dwProcessId)
958 {
959 STUB;
960 return 0;
961 }
962
963 BOOL
964 APIENTRY
NtGdiMakeObjectUnXferable(_In_ HANDLE hHandle)965 NtGdiMakeObjectUnXferable(
966 _In_ HANDLE hHandle)
967 {
968 STUB;
969 return 0;
970 }
971
972 DWORD
973 APIENTRY
NtDxEngGetRedirectionBitmap(DWORD Unknown0)974 NtDxEngGetRedirectionBitmap(
975 DWORD Unknown0)
976 {
977 STUB;
978 return 0;
979 }
980
981 /* EOF */
982