xref: /reactos/win32ss/user/ntuser/ntstubs.c (revision 201f00ab)
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