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