xref: /reactos/win32ss/user/ntuser/ntstubs.c (revision e5993f13)
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
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
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
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
76 NtUserEvent(
77    DWORD Unknown0)
78 {
79    STUB
80 
81    return 0;
82 }
83 
84 BOOL
85 APIENTRY
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
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
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
169 NtUserMNDragLeave(VOID)
170 {
171    STUB
172 
173    return 0;
174 }
175 
176 DWORD
177 APIENTRY
178 NtUserMNDragOver(
179    DWORD Unknown0,
180    DWORD Unknown1)
181 {
182    STUB
183 
184    return 0;
185 }
186 
187 DWORD
188 APIENTRY
189 NtUserModifyUserStartupInfoFlags(
190    DWORD Unknown0,
191    DWORD Unknown1)
192 {
193    STUB
194 
195    return 0;
196 }
197 
198 DWORD
199 APIENTRY
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
214 NtUserRegisterTasklist(
215    DWORD Unknown0)
216 {
217    STUB
218 
219    return 0;
220 }
221 
222 DWORD
223 APIENTRY
224 NtUserSetConsoleReserveKeys(
225    DWORD Unknown0,
226    DWORD Unknown1)
227 {
228    STUB
229 
230    return 0;
231 }
232 
233 DWORD
234 APIENTRY
235 NtUserSetDbgTag(
236    DWORD Unknown0,
237    DWORD Unknown1)
238 {
239    STUB;
240 
241    return 0;
242 }
243 
244 DWORD
245 APIENTRY
246 NtUserSetDbgTagCount(
247     DWORD Unknown0)
248 {
249     STUB;
250 
251     return 0;
252 }
253 
254 DWORD
255 APIENTRY
256 NtUserSetRipFlags(
257    DWORD Unknown0)
258 {
259    STUB;
260 
261    return 0;
262 }
263 
264 DWORD
265 APIENTRY
266 NtUserDbgWin32HeapFail(
267     DWORD Unknown0,
268     DWORD Unknown1)
269 {
270    STUB
271 
272    return 0;
273 }
274 
275 DWORD
276 APIENTRY
277 NtUserDbgWin32HeapStat(
278     DWORD Unknown0,
279     DWORD Unknown1)
280 {
281    STUB
282 
283    return 0;
284 }
285 
286 BOOL
287 APIENTRY
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
335 NtUserUpdateInstance(
336    DWORD Unknown0,
337    DWORD Unknown1,
338    DWORD Unknown2)
339 {
340    STUB
341 
342    return 0;
343 }
344 
345 BOOL
346 APIENTRY
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
359 NtUserWaitForMsgAndEvent(
360    DWORD Unknown0)
361 {
362    STUB
363 
364    return 0;
365 }
366 
367 DWORD
368 APIENTRY
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
384 NtUserYieldTask(VOID)
385 {
386    STUB
387 
388    return 0;
389 }
390 
391 DWORD
392 APIENTRY
393 NtUserGetRawInputBuffer(
394     PRAWINPUT pData,
395     PUINT pcbSize,
396     UINT cbSizeHeader)
397 {
398     STUB;
399     return 0;
400 }
401 
402 DWORD
403 APIENTRY
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
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
430 NtUserGetRawInputDeviceList(
431     PRAWINPUTDEVICELIST pRawInputDeviceList,
432     PUINT puiNumDevices,
433     UINT cbSize)
434 {
435     STUB;
436     return 0;
437 }
438 
439 DWORD
440 APIENTRY
441 NtUserGetRegisteredRawInputDevices(
442     PRAWINPUTDEVICE pRawInputDevices,
443     PUINT puiNumDevices,
444     UINT cbSize)
445 {
446     STUB;
447     return 0;
448 }
449 
450 DWORD
451 APIENTRY
452 NtUserHardErrorControl(
453     DWORD dwUnknown1,
454     DWORD dwUnknown2,
455     DWORD dwUnknown3)
456 {
457     STUB;
458     return 0;
459 }
460 
461 BOOL
462 NTAPI
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
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
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
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
630 NtUserRealWaitMessageEx(
631     DWORD dwWakeMask,
632     UINT uTimeout)
633 {
634     STUB;
635     return 0;
636 }
637 
638 BOOL
639 APIENTRY
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
650 NtUserResolveDesktopForWOW(DWORD Unknown0)
651 {
652     STUB
653     return 0;
654 }
655 
656 DWORD
657 APIENTRY
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
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(ULONG))
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), sizeof(PVOID));
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), sizeof(PVOID));
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), sizeof(PVOID));
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
843 NtUserSoundSentry(VOID)
844 {
845     STUB;
846     return 0;
847 }
848 
849 DWORD
850 APIENTRY
851 NtUserTestForInteractiveUser(
852     DWORD dwUnknown1)
853 {
854     STUB;
855     return 0;
856 }
857 
858 DWORD
859 APIENTRY
860 NtUserRemoteConnect(
861     DWORD dwUnknown1,
862     DWORD dwUnknown2,
863     DWORD dwUnknown3)
864 {
865     STUB;
866     return 0;
867 }
868 
869 DWORD
870 APIENTRY
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
883 NtUserRemoteRedrawScreen(VOID)
884 {
885     STUB;
886     return 0;
887 }
888 
889 DWORD
890 APIENTRY
891 NtUserRemoteStopScreenUpdates(VOID)
892 {
893     STUB;
894     return 0;
895 }
896 
897 DWORD
898 APIENTRY
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
912 NtUserLockWindowUpdate(HWND hWnd)
913 {
914     STUB;
915     return FALSE;
916 }
917 
918 DWORD APIENTRY
919 NtUserQuerySendMessage(DWORD Unknown0)
920 {
921     STUB;
922 
923     return 0;
924 }
925 
926 BOOL APIENTRY NtUserAddClipboardFormatListener(
927     HWND hwnd
928 )
929 {
930     STUB;
931     return FALSE;
932 }
933 
934 BOOL APIENTRY NtUserRemoveClipboardFormatListener(
935     HWND hwnd
936 )
937 {
938     STUB;
939     return FALSE;
940 }
941 
942 BOOL APIENTRY NtUserGetUpdatedClipboardFormats(
943     PUINT lpuiFormats,
944     UINT cFormats,
945     PUINT pcFormatsOut
946 )
947 {
948     STUB;
949     return FALSE;
950 }
951 
952 LONG_PTR
953 APIENTRY
954 NtUserSetClassLongPtr(
955     VOID)
956 {
957     STUB;
958     return 0;
959 }
960 
961 // Yes, I know, these do not belong here, just tell me where to put them
962 BOOL
963 APIENTRY
964 NtGdiMakeObjectXferable(
965     _In_ HANDLE hHandle,
966     _In_ DWORD dwProcessId)
967 {
968     STUB;
969     return 0;
970 }
971 
972 BOOL
973 APIENTRY
974 NtGdiMakeObjectUnXferable(
975     _In_ HANDLE hHandle)
976 {
977     STUB;
978     return 0;
979 }
980 
981 DWORD
982 APIENTRY
983 NtDxEngGetRedirectionBitmap(
984     DWORD Unknown0)
985 {
986     STUB;
987     return 0;
988 }
989 
990 /* EOF */
991