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