Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ntstubs.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: ntstubs.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Kernel-mode stubs 00007 * 00008 * History: 00009 * 03-16-95 JimA Created. 00010 * 08-12-96 jparsons Added lparam validate for WM_NCCREATE [51986] 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 #include "cscall.h" 00017 00018 #include <dbt.h> 00019 #define PROTOS_ONLY 1 00020 #include "msgdef.h" 00021 00022 #if DBG 00023 int ThreadLockCount(void) 00024 { 00025 PTHREADINFO ptiCurrent = PtiCurrentShared(); 00026 PTL ptl = ptiCurrent->ptl; 00027 int nLocks = 0; 00028 00029 while (ptl != NULL) { 00030 nLocks++; 00031 ptl = ptl->next; 00032 } 00033 ptl = ptiCurrent->ptlW32; 00034 while (ptl != NULL) { 00035 nLocks++; 00036 ptl = ptl->next; 00037 } 00038 return nLocks; 00039 } 00040 void ThreadLockCheck(int nLocks) 00041 { 00042 int nNewCount = ThreadLockCount(); 00043 if (nLocks != nNewCount) { 00044 00045 if (**((PBOOLEAN*)&KdDebuggerEnabled)) { 00046 00047 /* 00048 * The below is as is because it is intended to work on both 00049 * free and checked builds when thread lock counting is on. 00050 */ 00051 #undef DbgPrint 00052 DbgPrint("ThreadLocks mismatch %d %d\n", nLocks, nNewCount); 00053 DbgBreakPoint(); 00054 } 00055 } 00056 } 00057 // The parameter is used ensure BEGINRECV* matches ENDRECV* in each stub 00058 #define DBG_THREADLOCK_START(s) { int nLocks ## s = ThreadLockCount(); 00059 #define DBG_THREADLOCK_END(s) ThreadLockCheck(nLocks ## s); } 00060 #else // DBG_THREADLOCK 00061 #define DBG_THREADLOCK_START(s) 00062 #define DBG_THREADLOCK_END(s) 00063 #endif // DBG_THREADLOCK 00064 00065 /* 00066 * Setup and control macros 00067 */ 00068 #define BEGINRECV(type, err) \ 00069 type retval; \ 00070 type errret = err; \ 00071 EnterCrit(); \ 00072 DBG_THREADLOCK_START(_) 00073 #define ENDRECV() ENDRECV_(_) 00074 00075 #define BEGINATOMICRECV(type, err) \ 00076 type retval; \ 00077 type errret = err; \ 00078 EnterCrit(); \ 00079 DBG_THREADLOCK_START(_) \ 00080 BEGINATOMICCHECK() 00081 #define ENDATOMICRECV() ENDATOMICRECV_(_) 00082 00083 #define BEGINRECVCSRSS(type, err) \ 00084 type retval; \ 00085 type errret = err; \ 00086 EnterCrit(); \ 00087 DBG_THREADLOCK_START(CSRSS) \ 00088 if (!ISCSRSS()) { \ 00089 retval = STATUS_ACCESS_DENIED; \ 00090 goto errorexit; \ 00091 } 00092 #define ENDRECVCSRSS() ENDRECV_(CSRSS) 00093 00094 #define BEGINRECV_SHARED(type, err) \ 00095 type retval; \ 00096 type errret = err; \ 00097 EnterSharedCrit(); \ 00098 DBG_THREADLOCK_START(SHARED) 00099 #define ENDRECV_SHARED() ENDRECV_(SHARED) 00100 00101 #define BEGINRECV_NOCRIT(type, err) \ 00102 type retval; \ 00103 type errret = err; 00104 00105 #define BEGINRECV_VOID() \ 00106 EnterCrit(); \ 00107 DBG_THREADLOCK_START(_VOID) 00108 #define ENDRECV_VOID() ENDRECV_VOID_(_VOID) 00109 00110 #define BEGINRECV_HWND(type, err, hwnd) \ 00111 type retval; \ 00112 type errret = err; \ 00113 PWND pwnd; \ 00114 EnterCrit(); \ 00115 DBG_THREADLOCK_START(HWND) \ 00116 if ((pwnd = ValidateHwnd((hwnd))) == NULL) { \ 00117 retval = errret; \ 00118 goto errorexit; \ 00119 } 00120 #define ENDRECV_HWND() ENDRECV_HWND_(HWND) 00121 00122 #define BEGINATOMICRECV_HWND(type, err, hwnd) \ 00123 type retval; \ 00124 type errret = err; \ 00125 PWND pwnd; \ 00126 EnterCrit(); \ 00127 DBG_THREADLOCK_START(HWND) \ 00128 BEGINATOMICCHECK() \ 00129 if ((pwnd = ValidateHwnd((hwnd))) == NULL) { \ 00130 retval = errret; \ 00131 goto errorexit; \ 00132 } 00133 #define ENDATOMICRECV_HWND() ENDATOMICRECV_HWND_(HWND) 00134 00135 #define BEGINRECV_HWND_VOID(hwnd) \ 00136 PWND pwnd; \ 00137 EnterCrit(); \ 00138 DBG_THREADLOCK_START(HWND_VOID) \ 00139 if ((pwnd = ValidateHwnd((hwnd))) == NULL) { \ 00140 goto errorexit; \ 00141 } 00142 #define ENDRECV_HWND_VOID() ENDRECV_VOID_(HWND_VOID) 00143 00144 #define BEGINRECV_HWND_SHARED(type, err, hwnd) \ 00145 type retval; \ 00146 type errret = err; \ 00147 PWND pwnd; \ 00148 EnterSharedCrit(); \ 00149 DBG_THREADLOCK_START(HWND_SHARED) \ 00150 if ((pwnd = ValidateHwnd((hwnd))) == NULL) { \ 00151 retval = errret; \ 00152 goto errorexit; \ 00153 } 00154 #define ENDRECV_HWND_SHARED() ENDRECV_HWND_(HWND_SHARED) 00155 00156 #define BEGINRECV_HWNDOPT_SHARED(type, err, hwnd) \ 00157 type retval; \ 00158 type errret = err; \ 00159 PWND pwnd; \ 00160 EnterSharedCrit(); \ 00161 DBG_THREADLOCK_START(HWND_OPT_SHARED) \ 00162 if (hwnd) { \ 00163 if ((pwnd = ValidateHwnd((hwnd))) == NULL) { \ 00164 retval = errret; \ 00165 goto errorexit; \ 00166 } \ 00167 } else { \ 00168 pwnd = NULL; \ 00169 } 00170 #define ENDRECV_HWNDOPT_SHARED() ENDRECV_HWND_(HWND_OPT_SHARED) 00171 00172 #define BEGINRECV_HWNDLOCK(type, err, hwnd) \ 00173 type retval; \ 00174 type errret = err; \ 00175 PWND pwnd; \ 00176 TL tlpwnd; \ 00177 PTHREADINFO ptiCurrent; \ 00178 EnterCrit(); \ 00179 DBG_THREADLOCK_START(HWNDLOCK) \ 00180 if ((pwnd = ValidateHwnd((hwnd))) == NULL) { \ 00181 retval = errret; \ 00182 goto errorexit2; \ 00183 } \ 00184 ptiCurrent = PtiCurrent(); \ 00185 ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd); 00186 #define ENDRECV_HWNDLOCK() ENDRECV_HWNDLOCK_(HWNDLOCK) 00187 00188 #define BEGINRECV_HWNDLOCK_ND(type, err, hwnd) \ 00189 type retval; \ 00190 type errret = err; \ 00191 PWND pwndND; \ 00192 TL tlpwnd; \ 00193 PTHREADINFO ptiCurrent; \ 00194 EnterCrit(); \ 00195 DBG_THREADLOCK_START(HWNDLOCK_ND) \ 00196 if (((pwndND = ValidateHwnd((hwnd))) == NULL) || \ 00197 (pwndND == _GetDesktopWindow()) || \ 00198 (pwndND == _GetMessageWindow())) { \ 00199 retval = errret; \ 00200 goto errorexit2; \ 00201 } \ 00202 ptiCurrent = PtiCurrent(); \ 00203 ThreadLockAlwaysWithPti(ptiCurrent, pwndND, &tlpwnd); 00204 #define ENDRECV_HWNDLOCK_ND() ENDRECV_HWNDLOCK_(HWNDLOCK_ND) 00205 00206 #define BEGINRECV_HWNDLOCK_OPT(type, err, hwnd) \ 00207 type retval; \ 00208 type errret = err; \ 00209 PWND pwnd; \ 00210 TL tlpwnd; \ 00211 PTHREADINFO ptiCurrent; \ 00212 EnterCrit(); \ 00213 DBG_THREADLOCK_START(HWNDLOCK_OPT) \ 00214 if (hwnd) { \ 00215 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { \ 00216 retval = errret; \ 00217 goto errorexit2; \ 00218 } \ 00219 } else { \ 00220 pwnd = NULL; \ 00221 } \ 00222 ptiCurrent = PtiCurrent(); \ 00223 ThreadLockWithPti(ptiCurrent, pwnd, &tlpwnd); 00224 #define ENDRECV_HWNDLOCK_OPT() ENDRECV_HWNDLOCK_(HWNDLOCK_OPT) 00225 00226 #define BEGINRECV_HWNDLOCK_VOID(hwnd) \ 00227 PWND pwnd; \ 00228 TL tlpwnd; \ 00229 PTHREADINFO ptiCurrent; \ 00230 EnterCrit(); \ 00231 DBG_THREADLOCK_START(HWNDLOCK_VOID) \ 00232 if ((pwnd = ValidateHwnd((hwnd))) == NULL) { \ 00233 goto errorexit2; \ 00234 } \ 00235 ptiCurrent = PtiCurrent(); \ 00236 ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd); 00237 00238 #define ISXPFNPROCINRANGE(range) \ 00239 ((xpfnProc >= SFI_BEGINTRANSLATE ## range) \ 00240 && (xpfnProc < SFI_ENDTRANSLATE ## range)) 00241 00242 #define VALIDATEXPFNPROC(range) \ 00243 UserAssert(SFI_ENDTRANSLATETABLE == ulMaxSimpleCall); \ 00244 UserAssert(SFI_ENDTRANSLATE ## range <= ulMaxSimpleCall); \ 00245 if (!ISXPFNPROCINRANGE(range)) { \ 00246 MSGERROR(0); \ 00247 } 00248 00249 00250 00251 #define CLEANUPRECV() \ 00252 cleanupexit: 00253 00254 #define ENDRECV_(s) \ 00255 goto errorexit; \ 00256 errorexit: \ 00257 DBG_THREADLOCK_END(s) \ 00258 LeaveCrit(); \ 00259 return retval; 00260 00261 #define ENDATOMICRECV_(s) \ 00262 goto errorexit; \ 00263 errorexit: \ 00264 ENDATOMICCHECK() \ 00265 DBG_THREADLOCK_END(s) \ 00266 LeaveCrit(); \ 00267 return retval; 00268 00269 #define ENDRECV_NOCRIT() \ 00270 goto errorexit; \ 00271 errorexit: \ 00272 return retval; 00273 00274 #define ENDRECV_VOID_(s) \ 00275 goto errorexit; \ 00276 errorexit: \ 00277 DBG_THREADLOCK_END(s) \ 00278 LeaveCrit(); \ 00279 return; 00280 00281 #define ENDRECV_HWND_(s) \ 00282 goto errorexit; \ 00283 errorexit: \ 00284 DBG_THREADLOCK_END(s) \ 00285 LeaveCrit(); \ 00286 return retval; 00287 00288 #define ENDATOMICRECV_HWND_(s) \ 00289 goto errorexit; \ 00290 errorexit: \ 00291 ENDATOMICCHECK() \ 00292 DBG_THREADLOCK_END(s) \ 00293 LeaveCrit(); \ 00294 return retval; 00295 00296 #define ENDRECV_HWNDLOCK_(s) \ 00297 goto errorexit; \ 00298 errorexit: \ 00299 ThreadUnlock(&tlpwnd); \ 00300 errorexit2: \ 00301 DBG_THREADLOCK_END(s) \ 00302 LeaveCrit(); \ 00303 return retval; 00304 00305 #define ENDRECV_HWNDLOCK_VOID() \ 00306 goto errorexit; \ 00307 errorexit: \ 00308 ThreadUnlock(&tlpwnd); \ 00309 errorexit2: \ 00310 DBG_THREADLOCK_END(HWNDLOCK_VOID) \ 00311 LeaveCrit(); \ 00312 return; 00313 00314 /* 00315 * MSGERROR - exit the stub with an error condition. 00316 * Parameters: 00317 * LastError (OPTIONAL): 00318 * == 0 If LastError is 0, the compiler will optimize away the call to 00319 * UserSetLastError(). The last error will not be set to zero! 00320 * != 0 If you want to SetLastError, provide a non-zero value. 00321 */ 00322 #define MSGERROR(LastError) { \ 00323 retval = errret; \ 00324 if (LastError) { \ 00325 UserSetLastError(LastError); \ 00326 } \ 00327 goto errorexit; } 00328 00329 00330 #define MSGERROR_VOID() { \ 00331 goto errorexit; } 00332 00333 /* 00334 * Same as MSGERROR but jumps to cleanup code instead of straight to the return 00335 */ 00336 #define MSGERRORCLEANUP(LastError) { \ 00337 retval = errret; \ 00338 if (LastError) { \ 00339 UserSetLastError(LastError); \ 00340 } \ 00341 goto cleanupexit; } 00342 00343 #define StubExceptionHandler(fSetLastError) W32ExceptionHandler((fSetLastError), RIP_WARNING) 00344 00345 #define TESTFLAGS(flags, mask) \ 00346 if (((flags) & ~(mask)) != 0) { \ 00347 RIPERR2(ERROR_INVALID_FLAGS, RIP_WARNING, "Invalid flags, %x & ~%x != 0 " #mask, \ 00348 flags, mask); \ 00349 MSGERROR(0); \ 00350 } 00351 00352 #define LIMITVALUE(value, limit, szText) \ 00353 if ((UINT)(value) > (UINT)(limit)) { \ 00354 RIPERR3(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid parameter, %d > %d in %s", \ 00355 value, limit, szText); \ 00356 MSGERROR(0); \ 00357 } 00358 00359 #define MESSAGECALL(api) \ 00360 LRESULT NtUserfn ## api( \ 00361 PWND pwnd, \ 00362 UINT msg, \ 00363 WPARAM wParam, \ 00364 LPARAM lParam, \ 00365 ULONG_PTR xParam, \ 00366 DWORD xpfnProc, \ 00367 BOOL bAnsi) 00368 00369 #define BEGINRECV_MESSAGECALL(err) \ 00370 LRESULT retval; \ 00371 LRESULT errret = err; \ 00372 PTHREADINFO ptiCurrent = PtiCurrent(); \ 00373 CheckCritIn(); 00374 00375 #define ENDRECV_MESSAGECALL() \ 00376 goto errorexit; \ 00377 errorexit: \ 00378 return retval; 00379 00380 #define BEGINRECV_HOOKCALL() \ 00381 LRESULT retval; \ 00382 LRESULT errret = 0; \ 00383 CheckCritIn(); 00384 00385 #define ENDRECV_HOOKCALL() \ 00386 goto errorexit; \ 00387 errorexit: \ 00388 return retval; 00389 00390 #define CALLPROC(p) FNID(p) 00391 00392 /* 00393 * Validation macros 00394 */ 00395 #define ValidateHWNDNoRIP(p,h) \ 00396 if ((p = ValidateHwnd(h)) == NULL) \ 00397 MSGERROR(0); 00398 00399 #define ValidateHWND(p,h) \ 00400 if ((p = ValidateHwnd(h)) == NULL) \ 00401 MSGERROR(0); 00402 00403 #define ValidateHWNDND(p,h) \ 00404 if ( ((p = ValidateHwnd(h)) == NULL) || \ 00405 (p == _GetDesktopWindow()) || \ 00406 (p == _GetMessageWindow()) \ 00407 ) \ 00408 MSGERROR(0); 00409 00410 #define ValidateHWNDOPT(p,h) \ 00411 if (h) { \ 00412 if ((p = ValidateHwnd(h)) == NULL) \ 00413 MSGERROR(0); \ 00414 } else { \ 00415 p = NULL; \ 00416 } 00417 00418 #define ValidateHWNDIA(p,h) \ 00419 if (h != HWND_TOP && \ 00420 h != HWND_BOTTOM && \ 00421 h != HWND_TOPMOST && \ 00422 h != HWND_NOTOPMOST) { \ 00423 if ( ((p = ValidateHwnd(h)) == NULL) || \ 00424 (p == _GetDesktopWindow()) || \ 00425 (p == _GetMessageWindow()) \ 00426 ) \ 00427 MSGERROR(0); \ 00428 } else { \ 00429 p = (PWND)h; \ 00430 } 00431 00432 #define ValidateHWNDFF(p,h) \ 00433 if ((h != (HWND)-1) && (h !=(HWND)0xffff)) { \ 00434 if ((p = ValidateHwnd(h)) == NULL) \ 00435 MSGERROR(0); \ 00436 } else { \ 00437 p = PWND_BROADCAST; \ 00438 } 00439 00440 #define ValidateHMENUOPT(p,h) \ 00441 if (h) { \ 00442 if ((p = ValidateHmenu(h)) == NULL) \ 00443 MSGERROR(0); \ 00444 } else { \ 00445 p = NULL; \ 00446 } 00447 00448 #define ValidateHMENU(p,h) \ 00449 if ((p = ValidateHmenu(h)) == NULL) \ 00450 MSGERROR(0); 00451 00452 #define ValidateHMENUMODIFY(p,h) \ 00453 if ((p = ValidateHmenu(h)) == NULL) { \ 00454 MSGERROR(0); \ 00455 } else if (TestMF(p, MFDESKTOP)) { \ 00456 RIPMSG1(RIP_WARNING, "ValidateHMENUMODIFY: Attempt to modify desktop menu:%#p", p); \ 00457 MSGERROR(0); \ 00458 } 00459 00460 #define ValidateHACCEL(p,h) \ 00461 if ((p = HMValidateHandle(h, TYPE_ACCELTABLE)) == NULL) \ 00462 MSGERROR(0); 00463 00464 #define ValidateHCURSOR(p,h) \ 00465 if ((p = HMValidateHandle(h, TYPE_CURSOR)) == NULL) \ 00466 MSGERROR(0); 00467 00468 #define ValidateHCURSOROPT(p,h) \ 00469 if (h) { \ 00470 if ((p = HMValidateHandle(h, TYPE_CURSOR)) == NULL) \ 00471 MSGERROR(0); \ 00472 } else { \ 00473 p = NULL; \ 00474 } 00475 00476 #define ValidateHICON(p,h) \ 00477 if ((p = HMValidateHandle(h, TYPE_CURSOR)) == NULL) \ 00478 MSGERROR(0); 00479 00480 #define ValidateHHOOK(p,h) \ 00481 if ((p = HMValidateHandle(h, TYPE_HOOK)) == NULL) \ 00482 MSGERROR(0); 00483 00484 #define ValidateHWINEVENTHOOK(p,h) \ 00485 if ((p = HMValidateHandle(h, TYPE_WINEVENTHOOK)) == NULL) \ 00486 MSGERROR(0); 00487 00488 #define ValidateHDWP(p,h) \ 00489 if ((p = HMValidateHandle(h, TYPE_SETWINDOWPOS)) == NULL) \ 00490 MSGERROR(0); 00491 00492 #define ValidateHMONITOR(p,h) \ 00493 if ((p = ValidateHmonitor(h)) == NULL) \ 00494 MSGERROR(0); 00495 00496 #define ValidateHIMC(p,h) \ 00497 if ((p = HMValidateHandle((HANDLE)h, TYPE_INPUTCONTEXT)) == NULL) \ 00498 MSGERROR(0); 00499 00500 #define ValidateHIMCOPT(p,h) \ 00501 if (h) { \ 00502 if ((p = HMValidateHandle((HANDLE)h, TYPE_INPUTCONTEXT)) == NULL) \ 00503 MSGERROR(0); \ 00504 } else { \ 00505 p = NULL; \ 00506 } 00507 00508 #define ValidateIMMEnabled() \ 00509 if (!IS_IME_ENABLED()) { \ 00510 RIPERR0(ERROR_CALL_NOT_IMPLEMENTED, RIP_VERBOSE, "IME is disabled in this system."); \ 00511 MSGERROR(0); \ 00512 } 00513 00514 #define ValidateIMMEnabledVOID() \ 00515 if (!IS_IME_ENABLED()) { \ 00516 RIPERR0(ERROR_CALL_NOT_IMPLEMENTED, RIP_VERBOSE, "IME is disabled in this system."); \ 00517 MSGERROR_VOID(); \ 00518 } 00519 00520 NTSTATUS 00521 NtUserRemoteConnect( 00522 IN PDOCONNECTDATA pDoConnectData, 00523 IN ULONG DisplayDriverNameLength, 00524 IN PWCHAR DisplayDriverName ) 00525 { 00526 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 00527 if (!ISTS()) { 00528 errret = STATUS_ACCESS_DENIED; 00529 MSGERROR(0); 00530 } 00531 00532 /* 00533 * Probe all read arguments -- no try block. 00534 */ 00535 #if DBG 00536 ProbeForRead(DisplayDriverName, DisplayDriverNameLength, sizeof(BYTE)); 00537 ProbeForRead(pDoConnectData, sizeof(DOCONNECTDATA), sizeof(BYTE)); 00538 #endif 00539 00540 retval = RemoteConnect( 00541 pDoConnectData, 00542 DisplayDriverNameLength, 00543 DisplayDriverName); 00544 00545 00546 TRACE("NtUserRemoteConnect"); 00547 ENDRECVCSRSS(); 00548 00549 } 00550 00551 NTSTATUS 00552 NtUserRemoteRedrawRectangle( 00553 IN WORD Left, 00554 IN WORD Top, 00555 IN WORD Right, 00556 IN WORD Bottom ) 00557 { 00558 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 00559 if (!ISTS()) { 00560 errret = STATUS_ACCESS_DENIED; 00561 MSGERROR(0); 00562 } 00563 00564 retval = RemoteRedrawRectangle( 00565 Left, 00566 Top, 00567 Right, 00568 Bottom); 00569 00570 TRACE("NtUserRemoteRedrawRectangle"); 00571 ENDRECVCSRSS(); 00572 } 00573 00574 00575 NTSTATUS 00576 NtUserRemoteRedrawScreen( 00577 VOID) 00578 { 00579 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 00580 if (!ISTS()) { 00581 errret = STATUS_ACCESS_DENIED; 00582 MSGERROR(0); 00583 } 00584 00585 /* 00586 * If there are any shadow connections, or it's not disconnected 00587 */ 00588 if (gnShadowers > 0 || gbConnected) 00589 retval = RemoteRedrawScreen(); 00590 else 00591 retval = STATUS_UNSUCCESSFUL; 00592 00593 TRACE("NtUserRemoteRedrawScreen"); 00594 ENDRECVCSRSS(); 00595 } 00596 00597 00598 NTSTATUS 00599 NtUserRemoteStopScreenUpdates( 00600 VOID) 00601 { 00602 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 00603 if (!ISTS()) { 00604 errret = STATUS_ACCESS_DENIED; 00605 MSGERROR(0); 00606 } 00607 00608 retval = xxxRemoteStopScreenUpdates(TRUE); 00609 00610 TRACE("NtUserRemoteStopScreenUpdates"); 00611 ENDRECVCSRSS(); 00612 } 00613 00614 NTSTATUS 00615 NtUserCtxDisplayIOCtl( 00616 IN ULONG DisplayIOCtlFlags, 00617 IN PUCHAR pDisplayIOCtlData, 00618 IN ULONG cbDisplayIOCtlData) 00619 { 00620 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 00621 if (!ISTS()) { 00622 errret = STATUS_ACCESS_DENIED; 00623 MSGERROR(0); 00624 } 00625 00626 /* 00627 * Probe all read arguments 00628 */ 00629 #if DBG 00630 ProbeForRead(pDisplayIOCtlData, cbDisplayIOCtlData, sizeof(BYTE)); 00631 #endif 00632 00633 retval = CtxDisplayIOCtl( 00634 DisplayIOCtlFlags, 00635 pDisplayIOCtlData, 00636 cbDisplayIOCtlData); 00637 00638 TRACE("NtUserCtxDisplayIOCtl"); 00639 ENDRECVCSRSS(); 00640 00641 } 00642 00643 UINT NtUserHardErrorControl( 00644 IN HARDERRORCONTROL dwCmd, 00645 IN HANDLE handle, 00646 OUT PDESKRESTOREDATA pdrdRestore OPTIONAL) 00647 { 00648 BEGINRECVCSRSS(BOOL, HEC_ERROR); 00649 00650 #if DBG 00651 if (ARGUMENT_PRESENT(pdrdRestore)) { 00652 ProbeForWrite(pdrdRestore, sizeof(DESKRESTOREDATA), sizeof(DWORD)); 00653 } 00654 #endif 00655 00656 retval = xxxHardErrorControl(dwCmd, handle, pdrdRestore); 00657 00658 TRACE("NtUserHardErrorControl"); 00659 ENDRECVCSRSS(); 00660 } 00661 00662 BOOL NtUserGetObjectInformation( // API GetUserObjectInformationA/W 00663 IN HANDLE hObject, 00664 IN int nIndex, 00665 OUT PVOID pvInfo, 00666 IN DWORD nLength, 00667 OUT OPTIONAL LPDWORD pnLengthNeeded) 00668 { 00669 DWORD dwAlign; 00670 DWORD dwLocalLength; 00671 BEGINATOMICRECV(BOOL, FALSE); 00672 00673 /* 00674 * Probe arguments 00675 */ 00676 try { 00677 #if defined(_X86_) 00678 dwAlign = sizeof(BYTE); 00679 #else 00680 if (nIndex == UOI_FLAGS) 00681 dwAlign = sizeof(DWORD); 00682 else 00683 dwAlign = sizeof(WCHAR); 00684 #endif 00685 ProbeForWrite(pvInfo, nLength, dwAlign); 00686 if (ARGUMENT_PRESENT(pnLengthNeeded)) 00687 ProbeForWriteUlong(pnLengthNeeded); 00688 00689 } except (StubExceptionHandler(TRUE)) { 00690 MSGERROR(0); 00691 } 00692 00693 /* 00694 * Make sure the handle doesn't get closed while we're playing with it. 00695 */ 00696 SetHandleInUse(hObject); 00697 00698 /* 00699 * pvInfo is client-side. GetUserObjectInformation 00700 * protects use of this pointer with try blocks. 00701 */ 00702 00703 retval = _GetUserObjectInformation(hObject, 00704 nIndex, pvInfo, 00705 nLength, &dwLocalLength); 00706 00707 /* 00708 * OK, we're done with the handle. 00709 */ 00710 SetHandleInUse(NULL); 00711 00712 if (ARGUMENT_PRESENT(pnLengthNeeded)) { 00713 try { 00714 *pnLengthNeeded = dwLocalLength; 00715 } except (StubExceptionHandler(TRUE)) { 00716 MSGERROR(0); 00717 } 00718 } 00719 00720 TRACE("NtUserGetObjectInformation"); 00721 ENDATOMICRECV(); 00722 } 00723 00724 BOOL NtUserWin32PoolAllocationStats( 00725 IN LPDWORD parrTags, 00726 IN SIZE_T tagsCount, 00727 OUT SIZE_T* lpdwMaxMem, 00728 OUT SIZE_T* lpdwCrtMem, 00729 OUT LPDWORD lpdwMaxAlloc, 00730 OUT LPDWORD lpdwCrtAlloc) 00731 { 00732 #ifdef POOL_INSTR_API 00733 SIZE_T dwMaxMem, dwCrtMem; 00734 DWORD dwMaxAlloc, dwCrtAlloc; 00735 00736 BEGINRECV(BOOL, FALSE); 00737 00738 retval = _Win32PoolAllocationStats(parrTags, 00739 tagsCount, 00740 &dwMaxMem, 00741 &dwCrtMem, 00742 &dwMaxAlloc, 00743 &dwCrtAlloc); 00744 /* 00745 * Probe and copy 00746 */ 00747 try { 00748 if (lpdwMaxMem != NULL) { 00749 ProbeForWrite(lpdwMaxMem, sizeof(SIZE_T), sizeof(DWORD)); 00750 *lpdwMaxMem = dwMaxMem; 00751 } 00752 if (lpdwCrtMem != NULL) { 00753 ProbeForWrite(lpdwCrtMem, sizeof(SIZE_T), sizeof(DWORD)); 00754 *lpdwCrtMem = dwCrtMem; 00755 } 00756 if (lpdwMaxAlloc != NULL) { 00757 ProbeForWrite(lpdwMaxAlloc, sizeof(DWORD), sizeof(DWORD)); 00758 *lpdwMaxAlloc = dwMaxAlloc; 00759 } 00760 if (lpdwCrtAlloc != NULL) { 00761 ProbeForWrite(lpdwCrtAlloc, sizeof(DWORD), sizeof(DWORD)); 00762 *lpdwCrtAlloc = dwCrtAlloc; 00763 } 00764 00765 } except (StubExceptionHandler(FALSE)) { 00766 MSGERROR(0); 00767 } 00768 00769 TRACE("NtUserWin32PoolAllocationStats"); 00770 ENDRECV(); 00771 #else 00772 UNREFERENCED_PARAMETER(parrTags); 00773 UNREFERENCED_PARAMETER(tagsCount); 00774 UNREFERENCED_PARAMETER(lpdwMaxMem); 00775 UNREFERENCED_PARAMETER(lpdwCrtMem); 00776 UNREFERENCED_PARAMETER(lpdwMaxAlloc); 00777 UNREFERENCED_PARAMETER(lpdwCrtAlloc); 00778 return FALSE; 00779 #endif // POOL_INSTR_API 00780 } 00781 00782 #if DBG 00783 00784 VOID NtUserDbgWin32HeapFail( // private DbgWin32HeapFail 00785 IN DWORD dwFlags, 00786 IN BOOL bFail) 00787 { 00788 BEGINRECV_VOID(); 00789 00790 if ((dwFlags | WHF_VALID) != WHF_VALID) { 00791 RIPMSG1(RIP_WARNING, "Invalid flags for DbgWin32HeapFail %x", dwFlags); 00792 MSGERROR_VOID(); 00793 } 00794 00795 Win32HeapFailAllocations(bFail); 00796 00797 TRACEVOID("NtUserDbgWin32HeapFail"); 00798 ENDRECV_VOID(); 00799 } 00800 00801 DWORD NtUserDbgWin32HeapStat( // private DbgWin32HeapStat 00802 PDBGHEAPSTAT phs, 00803 DWORD dwLen) 00804 { 00805 extern DWORD Win32HeapStat(PDBGHEAPSTAT phs, DWORD dwLen, BOOL bTagsAreShift); 00806 00807 DBGHEAPSTAT localHS[30]; 00808 BEGINRECV(DWORD, 0); 00809 00810 LIMITVALUE(dwLen, sizeof(localHS), "DbgWin32HeapStat"); 00811 00812 try{ 00813 ProbeForRead(phs, dwLen, CHARALIGN); 00814 RtlCopyMemory(localHS, phs, dwLen); 00815 } except (StubExceptionHandler(FALSE)) { 00816 MSGERROR(0); 00817 } 00818 00819 retval = Win32HeapStat(localHS, dwLen, FALSE); 00820 00821 try { 00822 ProbeForWrite(phs, dwLen, CHARALIGN); 00823 RtlCopyMemory(phs, localHS, dwLen); 00824 } except (StubExceptionHandler(FALSE)) { 00825 } 00826 TRACE("NtUserDbgWin32HeapStat"); 00827 ENDRECV(); 00828 } 00829 #endif // DBG 00830 00831 BOOL NtUserSetObjectInformation( // API SetUserObjectInformationA/W 00832 IN HANDLE hObject, 00833 IN int nIndex, 00834 IN PVOID pvInfo, 00835 IN DWORD nLength) 00836 { 00837 BEGINATOMICRECV(BOOL, FALSE); 00838 00839 /* 00840 * Probe arguments 00841 */ 00842 try { 00843 ProbeForRead(pvInfo, nLength, DATAALIGN); 00844 00845 } except (StubExceptionHandler(TRUE)) { 00846 MSGERROR(0); 00847 } 00848 00849 /* 00850 * Make sure the handle doesn't get closed while we're playing with it. 00851 */ 00852 SetHandleInUse(hObject); 00853 00854 /* 00855 * pvInfo is client-side. SetUserObjectInformation 00856 * protects use of this pointer with try blocks. 00857 */ 00858 retval = _SetUserObjectInformation(hObject, 00859 nIndex, pvInfo, nLength); 00860 00861 /* 00862 * OK, we're done with the handle. 00863 */ 00864 SetHandleInUse(NULL); 00865 00866 TRACE("NtUserSetObjectInformation"); 00867 ENDATOMICRECV(); 00868 } 00869 00870 NTSTATUS NtUserConsoleControl( // private NtUserConsoleControl 00871 IN CONSOLECONTROL ConsoleCommand, 00872 IN PVOID ConsoleInformation, 00873 IN DWORD ConsoleInformationLength) 00874 { 00875 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 00876 00877 #if DBG 00878 ProbeForWrite(ConsoleInformation, 00879 ConsoleInformationLength, 00880 sizeof(WORD)); 00881 #endif 00882 00883 retval = xxxConsoleControl(ConsoleCommand, 00884 ConsoleInformation, 00885 ConsoleInformationLength); 00886 00887 TRACE("NtUserConsoleControl"); 00888 ENDRECVCSRSS(); 00889 } 00890 00891 HWINSTA NtUserCreateWindowStation( // API CreateWindowStationA/W 00892 IN POBJECT_ATTRIBUTES pObja, 00893 IN ACCESS_MASK amRequest, 00894 IN HANDLE hKbdLayoutFile, 00895 IN DWORD offTable, 00896 IN PUNICODE_STRING pstrKLID, 00897 UINT uKbdInputLocale) 00898 00899 { 00900 NTSTATUS Status; 00901 OBJECT_ATTRIBUTES CapturedAttributes; 00902 SECURITY_QUALITY_OF_SERVICE qosCaptured; 00903 PSECURITY_DESCRIPTOR psdCaptured = NULL; 00904 LUID luidService; 00905 UNICODE_STRING strWinSta; 00906 UNICODE_STRING strKLID; 00907 WCHAR awchName[MAX_SESSION_PATH]; 00908 WCHAR awchKF[sizeof(((PKL)0)->spkf->awchKF)]; 00909 UINT chMax; 00910 KPROCESSOR_MODE OwnershipMode; 00911 00912 BEGINRECV(HWINSTA, NULL); 00913 00914 /* 00915 * Set status so we can clean up in case of failure 00916 */ 00917 Status = STATUS_SUCCESS; 00918 00919 try { 00920 /* 00921 * Probe and capture the ??? string 00922 */ 00923 strKLID = ProbeAndReadUnicodeString(pstrKLID); 00924 ProbeForReadUnicodeStringBuffer(strKLID); 00925 chMax = min(sizeof(awchKF) - sizeof(WCHAR), strKLID.Length) / sizeof(WCHAR); 00926 wcsncpycch(awchKF, strKLID.Buffer, chMax); 00927 awchKF[chMax] = 0; 00928 00929 /* 00930 * Probe and capture the object attributes 00931 */ 00932 CapturedAttributes = ProbeAndReadStructure(pObja, OBJECT_ATTRIBUTES); 00933 00934 /* 00935 * Probe and capture all other components of the object attributes. 00936 */ 00937 if (CapturedAttributes.ObjectName == NULL && CapturedAttributes.RootDirectory == NULL) { 00938 00939 /* 00940 * Use the logon authentication id to form the windowstation 00941 * name. 00942 */ 00943 Status = GetProcessLuid(NULL, &luidService); 00944 if (NT_SUCCESS(Status)) { 00945 swprintf(awchName, L"%ws\\Service-0x%x-%x$", 00946 szWindowStationDirectory, 00947 luidService.HighPart, luidService.LowPart); 00948 RtlInitUnicodeString(&strWinSta, awchName); 00949 CapturedAttributes.ObjectName = &strWinSta; 00950 } 00951 OwnershipMode = KernelMode; 00952 } else { 00953 strWinSta = ProbeAndReadUnicodeString(CapturedAttributes.ObjectName); 00954 ProbeForReadUnicodeStringBuffer(strWinSta); 00955 /* 00956 * Use the StaticUnicodeBuffer on the TEB as the buffer for the object name. 00957 * Even if this is client side and we pass KernelMode to the Ob call in 00958 * _OpenWindowStation this is safe because the TEB is not going to go away 00959 * during this call. The worst it can happen is to have the buffer in the TEB 00960 * trashed. 00961 */ 00962 strWinSta.Length = min(strWinSta.Length, STATIC_UNICODE_BUFFER_LENGTH * sizeof(WCHAR)); 00963 00964 RtlCopyMemory(NtCurrentTeb()->StaticUnicodeBuffer, 00965 strWinSta.Buffer, 00966 strWinSta.Length); 00967 00968 strWinSta.Buffer = NtCurrentTeb()->StaticUnicodeBuffer; 00969 CapturedAttributes.ObjectName = &strWinSta; 00970 OwnershipMode = UserMode; 00971 } 00972 00973 if (CapturedAttributes.SecurityQualityOfService) { 00974 PSECURITY_QUALITY_OF_SERVICE pqos; 00975 00976 pqos = CapturedAttributes.SecurityQualityOfService; 00977 qosCaptured = ProbeAndReadStructure(pqos, SECURITY_QUALITY_OF_SERVICE); 00978 CapturedAttributes.SecurityQualityOfService = &qosCaptured; 00979 } 00980 00981 if (NT_SUCCESS(Status) && CapturedAttributes.SecurityDescriptor != NULL) { 00982 Status = SeCaptureSecurityDescriptor( 00983 CapturedAttributes.SecurityDescriptor, 00984 UserMode, 00985 PagedPool, 00986 FALSE, 00987 &psdCaptured); 00988 if (!NT_SUCCESS(Status)) { 00989 psdCaptured = NULL; 00990 } 00991 CapturedAttributes.SecurityDescriptor = psdCaptured; 00992 } 00993 00994 } except (StubExceptionHandler(FALSE)) { 00995 Status = GetExceptionCode(); 00996 } 00997 if (!NT_SUCCESS(Status)) 00998 MSGERRORCLEANUP(ERROR_INVALID_PARAMETER); 00999 01000 /* 01001 * Create the windowstation and return a kernel handle. 01002 */ 01003 retval = xxxCreateWindowStation(&CapturedAttributes, 01004 OwnershipMode, 01005 amRequest, 01006 hKbdLayoutFile, 01007 offTable, 01008 awchKF, 01009 uKbdInputLocale); 01010 01011 CLEANUPRECV(); 01012 01013 /* 01014 * Release captured security descriptor. 01015 */ 01016 if (psdCaptured != NULL) { 01017 SeReleaseSecurityDescriptor( 01018 psdCaptured, 01019 UserMode, 01020 FALSE); 01021 } 01022 01023 TRACE("NtUserCreateWindowStation"); 01024 ENDRECV(); 01025 } 01026 01027 01028 HWINSTA NtUserOpenWindowStation( 01029 IN OUT POBJECT_ATTRIBUTES pObja, 01030 IN ACCESS_MASK amRequest) 01031 { 01032 NTSTATUS Status; 01033 LUID luidService; 01034 WCHAR awchName[sizeof(L"Service-0x0000-0000$") / sizeof(WCHAR)]; 01035 OBJECT_ATTRIBUTES Obja; 01036 UNICODE_STRING ObjectName; 01037 01038 BEGINRECV(HWINSTA, NULL); 01039 01040 retval = NULL; 01041 01042 /* 01043 * NT Bug 387849: We want to allow the caller to pass in a "template" to be 01044 * filled in for the Service windowstation. So, we need to walk through the 01045 * pObja structure and check the string out, replacing it with the real 01046 * object name if necessary. 01047 * 01048 * It is VERY important that we pass the pObja object to the executive 01049 * (through _OpenWindowStation) and not the Obja object. This is because we 01050 * will request UserMode for this object, and the executive will check that 01051 * it is actually getting a user-mode address. 01052 * 01053 * We will still make a copy of the structures to manipulate while we are 01054 * walking everything so that we don't need to worry about the rug being 01055 * removed from beneath us. The executive will do its own checking. 01056 */ 01057 01058 try { 01059 /* 01060 * Probe the object attributes. We need to be able to read the 01061 * OBJECT_ATTRIBUTES and to write the ObjectName (UNICODE_STRING). 01062 */ 01063 Obja = ProbeAndReadStructure(pObja, OBJECT_ATTRIBUTES); 01064 01065 ProbeForWrite(Obja.ObjectName, sizeof(*(Obja.ObjectName)), DATAALIGN); 01066 01067 ObjectName = ProbeAndReadUnicodeString(Obja.ObjectName); 01068 01069 /* 01070 * If we are trying to open the NULL or "" WindowStation, remap this 01071 * benign name to Service-0x????-????$. 01072 */ 01073 if (Obja.RootDirectory != NULL && 01074 ObjectName.Buffer != NULL && 01075 ObjectName.MaximumLength == sizeof(awchName) && 01076 ObjectName.Length == (sizeof(awchName) - sizeof(UNICODE_NULL))) { 01077 01078 /* 01079 * Use the logon authentication id to form the windowstation 01080 * name. Put this in the user's buffer since we were the one 01081 * who allocated it in OpenWindowStation. 01082 */ 01083 01084 ProbeForWrite(ObjectName.Buffer, ObjectName.MaximumLength, CHARALIGN); 01085 01086 if (!_wcsicmp(ObjectName.Buffer, L"Service-0x0000-0000$")) { 01087 Status = GetProcessLuid(NULL, &luidService); 01088 if (NT_SUCCESS(Status)) { 01089 swprintf(ObjectName.Buffer, 01090 L"Service-0x%x-%x$", 01091 luidService.HighPart, 01092 luidService.LowPart); 01093 /* 01094 * We need to re-initialize the string to get the counted 01095 * length correct. Otherwise the hashing function used 01096 * by ObpLookupDirectoryEntry will fail. 01097 */ 01098 RtlInitUnicodeString(Obja.ObjectName, ObjectName.Buffer); 01099 } 01100 } 01101 } 01102 01103 } except (StubExceptionHandler(TRUE)) { 01104 MSGERROR(0); 01105 } 01106 01107 /* 01108 * Open the WindowStation 01109 */ 01110 retval = _OpenWindowStation(pObja, amRequest, UserMode); 01111 01112 TRACE("NtUserOpenWindowStation"); 01113 ENDRECV(); 01114 01115 UNREFERENCED_PARAMETER(awchName); 01116 } 01117 01118 BOOL NtUserCloseWindowStation( 01119 IN HWINSTA hwinsta) 01120 { 01121 PWINDOWSTATION pwinsta; 01122 NTSTATUS Status; 01123 01124 BEGINRECV(BOOL, FALSE); 01125 01126 retval = FALSE; 01127 01128 Status = ValidateHwinsta(hwinsta, UserMode, 0, &pwinsta); 01129 if (NT_SUCCESS(Status)) { 01130 retval = _CloseWindowStation(hwinsta); 01131 ObDereferenceObject(pwinsta); 01132 } 01133 01134 TRACE("NtUserCloseWindowStation"); 01135 ENDRECV(); 01136 } 01137 01138 01139 BOOL NtUserSetProcessWindowStation( 01140 IN HWINSTA hwinsta) 01141 { 01142 BEGINRECV(BOOL, FALSE); 01143 01144 retval = xxxSetProcessWindowStation(hwinsta, UserMode); 01145 01146 TRACE("NtUserSetProcessWindowStation"); 01147 ENDRECV(); 01148 } 01149 01150 HWINSTA NtUserGetProcessWindowStation( 01151 VOID) 01152 { 01153 BEGINRECV_SHARED(HWINSTA, NULL); 01154 01155 _GetProcessWindowStation(&retval); 01156 01157 TRACE("NtUserGetProcessWindowStation"); 01158 ENDRECV_SHARED(); 01159 } 01160 01161 BOOL NtUserLockWorkStation( 01162 VOID) 01163 { 01164 BEGINRECV(BOOL, FALSE); 01165 01166 retval = _LockWorkStation(); 01167 01168 TRACE("NtUserLockWorkStation"); 01169 ENDRECV(); 01170 } 01171 01172 01173 HDESK NtUserCreateDesktop( // API CreateDesktopA/W 01174 IN POBJECT_ATTRIBUTES pObja, 01175 IN PUNICODE_STRING pstrDevice, 01176 IN LPDEVMODEW pDevmode, 01177 IN DWORD dwFlags, 01178 IN ACCESS_MASK amRequest) 01179 { 01180 BEGINRECV(HDESK, NULL); 01181 01182 /* 01183 * Fail this call for restricted threads 01184 */ 01185 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_DESKTOP)) { 01186 RIPMSG0(RIP_WARNING, "NtUserCreateDesktop failed for restricted thread"); 01187 MSGERROR(0); 01188 } 01189 01190 /* 01191 * Probe arguments 01192 */ 01193 try { 01194 ProbeForRead(pObja, sizeof(*pObja), sizeof(DWORD)); 01195 } except (StubExceptionHandler(TRUE)) { 01196 MSGERROR(0); 01197 } 01198 01199 /* 01200 * pObja, pDevmode, and pstrDevice are all client side addresses. 01201 * 01202 * pstrDevice and pDevmode are put into the Context info, 01203 * and they are used in ntgdi\dre\drvsup.cxx, 01204 * where thay are captured before use. 01205 01206 */ 01207 01208 retval = xxxCreateDesktop(pObja, 01209 UserMode, 01210 pstrDevice, 01211 pDevmode, 01212 dwFlags, 01213 amRequest); 01214 01215 TRACE("NtUserCreateDesktop"); 01216 ENDRECV(); 01217 } 01218 01219 HDESK NtUserOpenDesktop( 01220 IN POBJECT_ATTRIBUTES pObja, 01221 IN DWORD dwFlags, 01222 IN ACCESS_MASK amRequest) 01223 { 01224 BOOL bShutDown; 01225 01226 BEGINRECV(HDESK, NULL); 01227 01228 retval = xxxOpenDesktop(pObja, UserMode, dwFlags, amRequest, &bShutDown); 01229 01230 TRACE("NtUserOpenDesktop"); 01231 ENDRECV(); 01232 } 01233 01234 01235 HDESK NtUserOpenInputDesktop( 01236 IN DWORD dwFlags, 01237 IN BOOL fInherit, 01238 IN DWORD amRequest) 01239 { 01240 HWINSTA hwinsta; 01241 PWINDOWSTATION pwinsta; 01242 PDESKTOP pdesk; 01243 NTSTATUS Status; 01244 01245 BEGINRECV(HDESK, NULL); 01246 01247 if (grpdeskRitInput == NULL) { 01248 MSGERROR(ERROR_OPEN_FAILED); 01249 } else { 01250 pwinsta = _GetProcessWindowStation(&hwinsta); 01251 if (pwinsta == NULL) { 01252 MSGERROR(ERROR_ACCESS_DENIED); 01253 } 01254 if (pwinsta->dwWSF_Flags & WSF_NOIO) { 01255 MSGERROR(ERROR_INVALID_FUNCTION); 01256 } else { 01257 01258 /* 01259 * We should never return the 'Disconnect' desktop to 01260 * an app. We should return instead the desktop that we will 01261 * restore to from the Disconnect desktop. 01262 */ 01263 01264 pdesk = (gbDesktopLocked ? gspdeskShouldBeForeground : grpdeskRitInput); 01265 01266 /* 01267 * Require read/write access 01268 */ 01269 amRequest |= DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS; 01270 01271 Status = ObOpenObjectByPointer( 01272 pdesk, 01273 fInherit ? OBJ_INHERIT : 0, 01274 NULL, 01275 amRequest, 01276 *ExDesktopObjectType, 01277 UserMode, 01278 &retval); 01279 if (NT_SUCCESS(Status)) { 01280 01281 BOOL bShutDown; 01282 /* 01283 * Complete the desktop open 01284 */ 01285 if (!OpenDesktopCompletion(pdesk, retval, 01286 dwFlags, &bShutDown)) { 01287 01288 CloseProtectedHandle(retval); 01289 retval = NULL; 01290 } else { 01291 SetHandleFlag(retval, HF_PROTECTED, TRUE); 01292 } 01293 } else 01294 retval = NULL; 01295 } 01296 } 01297 01298 TRACE("NtUserOpenInputDesktop"); 01299 ENDRECV(); 01300 } 01301 01302 01303 NTSTATUS NtUserResolveDesktopForWOW ( // WOW ResolveDesktopForWOW 01304 IN OUT PUNICODE_STRING pstrDesktop) 01305 { 01306 UNICODE_STRING strDesktop, strDesktop2; 01307 PTHREADINFO ptiCurrent; 01308 TL tlBuffer; 01309 LPWSTR lpBuffer = NULL; 01310 BOOL fFreeBuffer = FALSE; 01311 BEGINRECV(NTSTATUS, STATUS_UNSUCCESSFUL); 01312 01313 retval = STATUS_SUCCESS; 01314 01315 ptiCurrent = PtiCurrent(); 01316 /* 01317 * Probe arguments 01318 */ 01319 try { 01320 strDesktop = ProbeAndReadUnicodeString(pstrDesktop); 01321 ProbeForReadUnicodeStringFullBuffer(strDesktop); 01322 RtlCopyMemory(&strDesktop2, &strDesktop, sizeof strDesktop); 01323 if (strDesktop.MaximumLength > 0) { 01324 PWSTR pszCapture = strDesktop.Buffer; 01325 strDesktop.Buffer = UserAllocPoolWithQuota(strDesktop.MaximumLength, TAG_TEXT2); 01326 if (strDesktop.Buffer) { 01327 fFreeBuffer = TRUE; 01328 ThreadLockPool(ptiCurrent, strDesktop.Buffer, &tlBuffer); 01329 RtlCopyMemory(strDesktop.Buffer, pszCapture, strDesktop.Length); 01330 } else 01331 ExRaiseStatus(STATUS_NO_MEMORY); 01332 01333 } else { 01334 strDesktop.Buffer = NULL; 01335 } 01336 } except (StubExceptionHandler(FALSE)) { 01337 MSGERRORCLEANUP(0); 01338 } 01339 01340 retval = xxxResolveDesktopForWOW(&strDesktop); 01341 01342 if (NT_SUCCESS(retval)) { 01343 try { 01344 /* 01345 * The string structure at pstrDesktop could have changed 01346 * so we will ignore it and drop the one we have already 01347 * probed down on top of it. We have already performed the 01348 * ResolveDesktopForWOW action, so we should not return an 01349 * error if this copy fails. 01350 */ 01351 01352 RtlCopyUnicodeString(&strDesktop2, &strDesktop); 01353 RtlCopyMemory(pstrDesktop, &strDesktop2, sizeof strDesktop2); 01354 } except (StubExceptionHandler(FALSE)) { 01355 } 01356 } 01357 01358 CLEANUPRECV(); 01359 if (fFreeBuffer) 01360 ThreadUnlockAndFreePool(ptiCurrent, &tlBuffer); 01361 TRACE("NtUserResolveDesktopForWOW"); 01362 ENDRECV(); 01363 } 01364 01365 HDESK NtUserResolveDesktop( 01366 IN HANDLE hProcess, 01367 IN PUNICODE_STRING pstrDesktop, 01368 IN BOOL fInherit, 01369 OUT HWINSTA *phwinsta) 01370 { 01371 UNICODE_STRING strDesktop; 01372 HWINSTA hwinsta = NULL; 01373 PTHREADINFO pti; 01374 TL tlBuffer; 01375 BOOL fFreeBuffer = FALSE; 01376 BOOL bShutDown = FALSE; 01377 01378 BEGINRECV(HDESK, NULL); 01379 01380 pti = PtiCurrent(); 01381 /* 01382 * Probe and capture desktop path 01383 */ 01384 try { 01385 strDesktop = ProbeAndReadUnicodeString(pstrDesktop); 01386 if (strDesktop.Length > 0) { 01387 PWSTR pszCapture = strDesktop.Buffer; 01388 ProbeForReadUnicodeStringBuffer(strDesktop); 01389 strDesktop.Buffer = UserAllocPoolWithQuota(strDesktop.Length, TAG_TEXT2); 01390 if (strDesktop.Buffer) { 01391 fFreeBuffer = TRUE; 01392 ThreadLockPool(pti, strDesktop.Buffer, &tlBuffer); 01393 RtlCopyMemory(strDesktop.Buffer, pszCapture, strDesktop.Length); 01394 } else 01395 ExRaiseStatus(STATUS_NO_MEMORY); 01396 } else { 01397 strDesktop.Buffer = NULL; 01398 } 01399 } except (StubExceptionHandler(TRUE)) { 01400 MSGERRORCLEANUP(0); 01401 } 01402 01403 retval = xxxResolveDesktop(hProcess, &strDesktop, &hwinsta, 01404 fInherit, &bShutDown); 01405 01406 CLEANUPRECV(); 01407 if (fFreeBuffer) 01408 ThreadUnlockAndFreePool(pti, &tlBuffer); 01409 01410 try { 01411 ProbeAndWriteHandle((PHANDLE)phwinsta, hwinsta); 01412 } except (StubExceptionHandler(TRUE)) { 01413 xxxCloseDesktop(retval, KernelMode); 01414 if (hwinsta) 01415 _CloseWindowStation(hwinsta); 01416 MSGERROR(0); 01417 } 01418 01419 TRACE("NtUserResolveDesktop"); 01420 ENDRECV(); 01421 } 01422 01423 BOOL NtUserCloseDesktop( 01424 IN HDESK hdesk) 01425 { 01426 BEGINRECV(BOOL, FALSE); 01427 01428 retval = xxxCloseDesktop(hdesk, UserMode); 01429 01430 TRACE("NtUserCloseDesktop"); 01431 ENDRECV(); 01432 } 01433 01434 BOOL NtUserSetThreadDesktop( 01435 IN HDESK hdesk) 01436 { 01437 PDESKTOP pdesk = NULL; 01438 NTSTATUS Status = STATUS_SUCCESS; 01439 01440 BEGINRECV(BOOL, FALSE); 01441 Status = ValidateHdesk(hdesk, UserMode, 0, &pdesk); 01442 if (NT_SUCCESS(Status)) { 01443 retval = xxxSetThreadDesktop(hdesk, pdesk); 01444 LogDesktop(pdesk, LD_DEREF_VALIDATE_HDESK1, FALSE, (ULONG_PTR)PtiCurrent()); 01445 ObDereferenceObject(pdesk); 01446 } else if (hdesk == NULL && PsGetCurrentProcess() == gpepCSRSS) { 01447 retval = xxxSetThreadDesktop(NULL, NULL); 01448 } else 01449 retval = FALSE; 01450 01451 TRACE("NtUserSetThreadDesktop"); 01452 ENDRECV(); 01453 } 01454 01455 HDESK NtUserGetThreadDesktop( 01456 IN DWORD dwThreadId, 01457 IN HDESK hdeskConsole) 01458 { 01459 BEGINRECV_SHARED(HDESK, NULL); 01460 01461 retval = xxxGetThreadDesktop(dwThreadId, hdeskConsole, UserMode); 01462 01463 TRACE("NtUserGetThreadDesktop"); 01464 ENDRECV_SHARED(); 01465 } 01466 01467 BOOL NtUserSwitchDesktop( 01468 IN HDESK hdesk) 01469 { 01470 PDESKTOP pdesk; 01471 TL tlpdesk; 01472 PTHREADINFO ptiCurrent; 01473 NTSTATUS Status; 01474 01475 BEGINRECV(BOOL, FALSE); 01476 01477 ptiCurrent = PtiCurrent(); 01478 01479 /* 01480 * Fail this call for restricted threads 01481 */ 01482 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_DESKTOP)) { 01483 RIPMSG0(RIP_WARNING, "NtUserSwitchDesktop failed for restricted thread"); 01484 MSGERROR(0); 01485 } 01486 01487 Status = ValidateHdesk(hdesk, UserMode, DESKTOP_SWITCHDESKTOP, &pdesk); 01488 if (NT_SUCCESS(Status)) { 01489 if (pdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO) { 01490 LogDesktop(pdesk, LD_DEREF_VALIDATE_HDESK2, FALSE, (ULONG_PTR)PtiCurrent()); 01491 ObDereferenceObject(pdesk); 01492 RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, ""); 01493 retval = FALSE; 01494 } else { 01495 ThreadLockDesktop(ptiCurrent, pdesk, &tlpdesk, LDLT_FN_NTUSERSWITCHDESKTOP); 01496 LogDesktop(pdesk, LD_DEREF_VALIDATE_HDESK3, FALSE, (ULONG_PTR)PtiCurrent()); 01497 ObDereferenceObject(pdesk); 01498 retval = xxxSwitchDesktop(NULL, pdesk, FALSE); 01499 ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_NTUSERSWITCHDESKTOP); 01500 } 01501 } else 01502 retval = FALSE; 01503 01504 TRACE("NtUserSwitchDesktop"); 01505 ENDRECV(); 01506 } 01507 01508 NTSTATUS NtUserInitializeClientPfnArrays( // private 01509 IN CONST PFNCLIENT *ppfnClientA OPTIONAL, 01510 IN CONST PFNCLIENT *ppfnClientW OPTIONAL, 01511 IN CONST PFNCLIENTWORKER *ppfnClientWorker OPTIONAL, 01512 IN HANDLE hModUser) 01513 { 01514 BEGINRECV(NTSTATUS, STATUS_UNSUCCESSFUL); 01515 01516 /* 01517 * Probe all read arguments 01518 */ 01519 try { 01520 if (ARGUMENT_PRESENT(ppfnClientA)) { 01521 ProbeForRead(ppfnClientA, sizeof(*ppfnClientA), sizeof(DWORD)); 01522 } 01523 if (ARGUMENT_PRESENT(ppfnClientW)) { 01524 ProbeForRead(ppfnClientW, sizeof(*ppfnClientW), sizeof(DWORD)); 01525 } 01526 01527 if (ARGUMENT_PRESENT(ppfnClientWorker)) { 01528 ProbeForRead(ppfnClientWorker, sizeof(*ppfnClientWorker), sizeof(DWORD)); 01529 } 01530 01531 retval = InitializeClientPfnArrays( 01532 ppfnClientA, ppfnClientW, ppfnClientWorker, hModUser); 01533 } except (StubExceptionHandler(FALSE)) { 01534 MSGERROR(0); 01535 } 01536 01537 TRACE("NtUserInitializeThreadInfo"); 01538 ENDRECV(); 01539 } 01540 01541 BOOL NtUserWaitForMsgAndEvent( 01542 IN HANDLE hevent) 01543 { 01544 BEGINRECV(BOOL, FALSE); 01545 01546 retval = xxxSleepTask(FALSE, hevent); 01547 01548 TRACE("NtUserWaitForMsgAndEvent"); 01549 ENDRECV(); 01550 } 01551 01552 DWORD NtUserDragObject( 01553 IN HWND hwndParent, 01554 IN HWND hwndFrom, 01555 IN UINT wFmt, 01556 IN ULONG_PTR dwData, 01557 IN HCURSOR hcur) 01558 { 01559 01560 // 01561 // N.B. This function has implicit window translation and thread locking 01562 // enabled. These operations are performed in the User server API 01563 // dispatcher. 01564 // 01565 01566 PWND pwndFrom; 01567 PCURSOR pcur; 01568 TL tlpwndFrom; 01569 TL tlpcur; 01570 01571 BEGINRECV_HWNDLOCK(DWORD, 0, hwndParent); 01572 01573 ValidateHWNDOPT(pwndFrom, hwndFrom); 01574 ValidateHCURSOROPT(pcur, hcur); 01575 01576 ThreadLockWithPti(ptiCurrent, pwndFrom, &tlpwndFrom); 01577 ThreadLockWithPti(ptiCurrent, pcur, &tlpcur); 01578 01579 retval = xxxDragObject( 01580 pwnd, 01581 pwndFrom, 01582 wFmt, 01583 dwData, 01584 pcur); 01585 01586 ThreadUnlock(&tlpcur); 01587 ThreadUnlock(&tlpwndFrom); 01588 01589 TRACE("NtUserDragObject"); 01590 ENDRECV_HWNDLOCK(); 01591 } 01592 01593 BOOL NtUserGetIconInfo( // API GetIconInfo 01594 IN HICON hIcon, 01595 OUT PICONINFO piconinfo, 01596 IN OUT OPTIONAL PUNICODE_STRING pstrInstanceName, 01597 IN OUT OPTIONAL PUNICODE_STRING pstrResName, 01598 OUT LPDWORD pbpp, 01599 IN BOOL fInternal) 01600 { 01601 PICON pIcon; 01602 UNICODE_STRING strInstanceName, *pstrInstanceLocal; 01603 UNICODE_STRING strResName, *pstrResLocal; 01604 01605 BEGINATOMICRECV(BOOL, FALSE); 01606 01607 /* 01608 * NOTE -- this can't be _SHARED since it calls Gre code with system HDC's. 01609 */ 01610 01611 ValidateHCURSOR(pIcon, hIcon); 01612 01613 /* 01614 * Probe arguments 01615 */ 01616 try { 01617 if (pstrInstanceName != NULL) { 01618 strInstanceName = ProbeAndReadUnicodeString(pstrInstanceName); 01619 ProbeForWrite(strInstanceName.Buffer, strInstanceName.MaximumLength, CHARALIGN); 01620 pstrInstanceLocal = &strInstanceName; 01621 } else { 01622 pstrInstanceLocal = NULL; 01623 } 01624 01625 if (pstrResName != NULL) { 01626 strResName = ProbeAndReadUnicodeString(pstrResName); 01627 ProbeForWrite(strResName.Buffer, strResName.MaximumLength, CHARALIGN); 01628 pstrResLocal = &strResName; 01629 } else { 01630 pstrResLocal = NULL; 01631 } 01632 01633 if (pbpp != NULL) { 01634 ProbeForWrite(pbpp, sizeof(DWORD), sizeof(DWORD)); 01635 } 01636 ProbeForWrite(piconinfo, sizeof(*piconinfo), DATAALIGN); 01637 } except (StubExceptionHandler(TRUE)) { 01638 MSGERROR(0); 01639 } 01640 01641 /* 01642 * All use of client-side pointers in InternalGetIconInfo 01643 * is protected by try/except. 01644 */ 01645 01646 retval = _InternalGetIconInfo( 01647 pIcon, 01648 piconinfo, 01649 pstrInstanceLocal, 01650 pstrResLocal, 01651 pbpp, 01652 fInternal); 01653 01654 try { 01655 if (pstrInstanceName != NULL) { 01656 RtlCopyMemory(pstrInstanceName, pstrInstanceLocal, sizeof(UNICODE_STRING)); 01657 } 01658 if (pstrResName != NULL) { 01659 RtlCopyMemory(pstrResName, pstrResLocal, sizeof(UNICODE_STRING)); 01660 } 01661 } except (StubExceptionHandler(TRUE)) { 01662 MSGERROR(0); 01663 } 01664 01665 TRACE("NtUserGetIconInfo"); 01666 ENDATOMICRECV(); 01667 } 01668 01669 BOOL NtUserGetIconSize( // private 01670 IN HICON hIcon, 01671 IN UINT istepIfAniCur, 01672 OUT int *pcx, 01673 OUT int *pcy) 01674 { 01675 PCURSOR picon; 01676 01677 BEGINRECV_SHARED(BOOL, FALSE); 01678 01679 ValidateHICON(picon, hIcon); 01680 01681 if (picon->CURSORF_flags & CURSORF_ACON) { 01682 PACON pacon = (PACON)picon; 01683 if (istepIfAniCur < (UINT)pacon->cpcur) { 01684 picon = pacon->aspcur[pacon->aicur[istepIfAniCur]]; 01685 } else { 01686 RIPMSG2(RIP_WARNING, "NtUserGetIconSize: Invalid istepIfAniCur:%#lx. picon:%#p", 01687 istepIfAniCur, picon); 01688 MSGERROR(0); 01689 } 01690 } 01691 01692 /* 01693 * Probe arguments 01694 */ 01695 try { 01696 ProbeAndWriteLong(pcx, picon->cx); 01697 ProbeAndWriteLong(pcy, picon->cy); 01698 01699 retval = 1; 01700 } except (StubExceptionHandler(FALSE)) { 01701 MSGERROR(0); 01702 } 01703 01704 TRACE("NtUserGetIconSize"); 01705 ENDRECV_SHARED(); 01706 } 01707 01708 01709 01710 BOOL NtUserDrawIconEx( // API DrawIconEx 01711 IN HDC hdc, 01712 IN int x, 01713 IN int y, 01714 IN HICON hicon, 01715 IN int cx, 01716 IN int cy, 01717 IN UINT istepIfAniCur, 01718 IN HBRUSH hbrush, 01719 IN UINT diFlags, 01720 IN BOOL fMeta, 01721 OUT DRAWICONEXDATA *pdid) 01722 { 01723 PCURSOR picon; 01724 01725 BEGINATOMICRECV(BOOL, FALSE); 01726 01727 ValidateHICON(picon, hicon); 01728 01729 if (fMeta) { 01730 if (picon->CURSORF_flags & CURSORF_ACON) 01731 picon = ((PACON)picon)->aspcur[((PACON)picon)->aicur[0]]; 01732 01733 /* 01734 * Probe arguments 01735 */ 01736 try { 01737 ProbeForWrite(pdid, sizeof(*pdid), DATAALIGN); 01738 01739 pdid->hbmMask = picon->hbmMask; 01740 pdid->hbmColor = picon->hbmColor; 01741 01742 pdid->cx = cx ? cx : picon->cx ; 01743 pdid->cy = cy ? cy : picon->cy ; 01744 01745 retval = 1; 01746 } except (StubExceptionHandler(TRUE)) { 01747 MSGERROR(0); 01748 } 01749 01750 } else { 01751 retval = _DrawIconEx(hdc, x, y, picon, 01752 cx, cy, 01753 istepIfAniCur, hbrush, 01754 diFlags ); 01755 } 01756 01757 TRACE("NtUserDrawIconEx"); 01758 ENDATOMICRECV(); 01759 } 01760 01761 HANDLE NtUserDeferWindowPos( 01762 IN HDWP hWinPosInfo, 01763 IN HWND hwnd, 01764 IN HWND hwndInsertAfter, 01765 IN int x, 01766 IN int y, 01767 IN int cx, 01768 IN int cy, 01769 IN UINT wFlags) 01770 { 01771 PWND pwnd; 01772 PWND pwndInsertAfter; 01773 PSMWP psmwp; 01774 01775 BEGINATOMICRECV(HANDLE, NULL); 01776 01777 TESTFLAGS(wFlags, SWP_VALID); 01778 01779 ValidateHWNDND(pwnd, hwnd); 01780 ValidateHWNDIA(pwndInsertAfter, hwndInsertAfter); 01781 ValidateHDWP(psmwp, hWinPosInfo); 01782 01783 if (wFlags & ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | 01784 SWP_NOREDRAW | SWP_NOACTIVATE | SWP_FRAMECHANGED | 01785 SWP_SHOWWINDOW | SWP_HIDEWINDOW | SWP_NOCOPYBITS | 01786 SWP_NOOWNERZORDER)) { 01787 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid flags (0x%lx) passed to DeferWindowPos", 01788 wFlags); 01789 MSGERROR(0); 01790 } 01791 01792 /* 01793 * Make sure the window coordinates can fit in WORDs. 01794 */ 01795 if (!(wFlags & SWP_NOMOVE)) { 01796 if (x > SHRT_MAX) { 01797 x = SHRT_MAX; 01798 } else if (x < SHRT_MIN) { 01799 x = SHRT_MIN; 01800 } 01801 if (y > SHRT_MAX) { 01802 y = SHRT_MAX; 01803 } else if (y < SHRT_MIN) { 01804 y = SHRT_MIN; 01805 } 01806 } 01807 01808 /* 01809 * Actually, if we were going to be really strict about this we'd 01810 * make sure that x + cx < SHRT_MAX, etc but since we do maintain 01811 * signed 32-bit coords internally this case doesn't cause a problem. 01812 */ 01813 if (!(wFlags & SWP_NOSIZE)) { 01814 if (cx < 0) { 01815 cx = 0; 01816 } else if (cx > SHRT_MAX) { 01817 cx = SHRT_MAX; 01818 } 01819 if (cy < 0) { 01820 cy = 0; 01821 } else if (cy > SHRT_MAX) { 01822 cy = SHRT_MAX; 01823 } 01824 } 01825 01826 #ifdef NEVER 01827 // 01828 // do not fail these conditions because real apps use them. 01829 // 01830 if (!(wFlags & SWP_NOMOVE) && 01831 (x > SHRT_MAX || x < SHRT_MIN || 01832 y > SHRT_MAX || y < SHRT_MIN)) { 01833 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid coordinate passed to SetWindowPos"); 01834 MSGERROR(0); 01835 } 01836 01837 /* 01838 * Actually, if we were going to be really strict about this we'd 01839 * make sure that x + cx < SHRT_MAX, etc but since we do maintain 01840 * signed 32-bit coords internally this case doesn't cause a problem. 01841 */ 01842 if (!(wFlags & SWP_NOSIZE) && 01843 (cx < 0 || cx > SHRT_MAX || 01844 cy < 0 || cy > SHRT_MAX)) { 01845 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid width/height passed to SetWindowPos"); 01846 MSGERROR(0); 01847 } 01848 #endif 01849 01850 retval = _DeferWindowPos( 01851 psmwp, 01852 pwnd, 01853 pwndInsertAfter, 01854 x, 01855 y, 01856 cx, 01857 cy, 01858 wFlags); 01859 retval = PtoH((PVOID)retval); 01860 01861 TRACE("NtUserDeferWindowPos"); 01862 ENDATOMICRECV(); 01863 } 01864 01865 BOOL NtUserEndDeferWindowPosEx( 01866 IN HDWP hWinPosInfo, 01867 IN BOOL fAsync) 01868 { 01869 PSMWP psmwp; 01870 TL tlpsmp; 01871 01872 BEGINRECV(BOOL, FALSE); 01873 01874 ValidateHDWP(psmwp, hWinPosInfo); 01875 01876 ThreadLockAlways(psmwp, &tlpsmp); 01877 01878 retval = xxxEndDeferWindowPosEx( 01879 psmwp, 01880 fAsync); 01881 01882 ThreadUnlock(&tlpsmp); 01883 01884 TRACE("NtUserEndDeferWindowPosEx"); 01885 ENDRECV(); 01886 } 01887 01888 BOOL NtUserGetMessage( // API GetMessageA/W 01889 OUT LPMSG pmsg, 01890 IN HWND hwnd, 01891 IN UINT wMsgFilterMin, 01892 IN UINT wMsgFilterMax) 01893 { 01894 MSG msg; 01895 01896 BEGINRECV(BOOL, FALSE); 01897 01898 retval = xxxGetMessage( 01899 &msg, 01900 hwnd, 01901 wMsgFilterMin, 01902 wMsgFilterMax); 01903 01904 /* 01905 * Probe arguments 01906 */ 01907 try { 01908 ProbeAndWriteStructure(pmsg, msg, MSG); 01909 } except (StubExceptionHandler(TRUE)) { 01910 MSGERROR(0); 01911 } 01912 01913 TRACE("NtUserGetMessage"); 01914 ENDRECV(); 01915 } 01916 01917 BOOL NtUserMoveWindow( 01918 IN HWND hwnd, 01919 IN int x, 01920 IN int y, 01921 IN int cx, 01922 IN int cy, 01923 IN BOOL fRepaint) 01924 { 01925 BEGINRECV_HWNDLOCK_ND(BOOL, FALSE, hwnd); 01926 01927 /* 01928 * Make sure the window coordinates can fit in WORDs. 01929 */ 01930 if (x > SHRT_MAX) { 01931 x = SHRT_MAX; 01932 } else if (x < SHRT_MIN) { 01933 x = SHRT_MIN; 01934 } 01935 if (y > SHRT_MAX) { 01936 y = SHRT_MAX; 01937 } else if (y < SHRT_MIN) { 01938 y = SHRT_MIN; 01939 } 01940 01941 /* 01942 * Actually, if we were going to be really strict about this we'd 01943 * make sure that x + cx < SHRT_MAX, etc but since we do maintain 01944 * signed 32-bit coords internally this case doesn't cause a problem. 01945 */ 01946 if (cx < 0) { 01947 cx = 0; 01948 } else if (cx > SHRT_MAX) { 01949 cx = SHRT_MAX; 01950 } 01951 if (cy < 0) { 01952 cy = 0; 01953 } else if (cy > SHRT_MAX) { 01954 cy = SHRT_MAX; 01955 } 01956 01957 #ifdef NEVER 01958 // 01959 // do not fail these conditions because real apps use them. 01960 // 01961 if (x > SHRT_MAX || x < SHRT_MIN || 01962 y > SHRT_MAX || y < SHRT_MIN) { 01963 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid coordinate passed to MoveWindow"); 01964 MSGERROR(0); 01965 } 01966 01967 /* 01968 * Actually, if we were going to be really strict about this we'd 01969 * make sure that x + cx < SHRT_MAX, etc but since we do maintain 01970 * signed 32-bit coords internally this case doesn't cause a problem. 01971 */ 01972 if (cx < 0 || cx > SHRT_MAX || 01973 cy < 0 || cy > SHRT_MAX) { 01974 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid width/height passed to MoveWindow"); 01975 MSGERROR(0); 01976 } 01977 #endif 01978 01979 retval = xxxMoveWindow( 01980 pwndND, 01981 x, 01982 y, 01983 cx, 01984 cy, 01985 fRepaint); 01986 01987 TRACE("NtUserMoveWindow"); 01988 ENDRECV_HWNDLOCK_ND(); 01989 } 01990 01991 int NtUserTranslateAccelerator( // API TranslateAcceleratorA/W 01992 IN HWND hwnd, 01993 IN HACCEL haccel, 01994 IN LPMSG lpmsg) 01995 { 01996 PWND pwnd; 01997 LPACCELTABLE pat; 01998 TL tlpwnd; 01999 TL tlpat; 02000 PTHREADINFO ptiCurrent; 02001 MSG msg; 02002 02003 BEGINRECV(int, 0); 02004 02005 /* 02006 * Probe arguments 02007 */ 02008 try { 02009 msg = ProbeAndReadMessage(lpmsg); 02010 } except (StubExceptionHandler(FALSE)) { 02011 MSGERROR(0); 02012 } 02013 02014 /* 02015 * This is called within a message loop. If the window gets destroyed, 02016 * there still may be other messages in the queue that get returned 02017 * after the window is destroyed. The app will call TranslateAccelerator() 02018 * on every one of these, causing RIPs.... Make it nice so it just 02019 * returns FALSE. 02020 */ 02021 ValidateHWNDNoRIP(pwnd, hwnd); 02022 ValidateHACCEL(pat, haccel); 02023 02024 ptiCurrent = PtiCurrent(); 02025 ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd); 02026 ThreadLockAlwaysWithPti(ptiCurrent, pat, &tlpat); 02027 02028 retval = xxxTranslateAccelerator( 02029 pwnd, 02030 pat, 02031 &msg); 02032 02033 ThreadUnlock(&tlpat); 02034 ThreadUnlock(&tlpwnd); 02035 02036 TRACE("NtUserTranslateAccelerator"); 02037 ENDRECV(); 02038 } 02039 02040 LONG_PTR NtUserSetClassLongPtr( // API SetClassLongPtrA/W 02041 IN HWND hwnd, 02042 IN int nIndex, 02043 OUT LONG_PTR dwNewLong, 02044 IN BOOL bAnsi) 02045 { 02046 UNICODE_STRING strMenuName; 02047 CLSMENUNAME cmn, *pcmnSave; 02048 02049 // 02050 // N.B. This function has implicit window translation and thread locking 02051 // enabled. These operations are performed in the User server API 02052 // dispatcher. 02053 // 02054 02055 BEGINRECV_HWNDLOCK(ULONG_PTR, 0, hwnd); 02056 02057 switch (nIndex) { 02058 case GCLP_MENUNAME: 02059 try { 02060 /* 02061 * There is no callback from the routine for 02062 * this value, so we can protect it with a try/except. 02063 * This is cheaper than capturing the name 02064 * and copying it back. FritzS 02065 */ 02066 02067 pcmnSave = (PCLSMENUNAME) dwNewLong; 02068 cmn = ProbeAndReadStructure(pcmnSave, CLSMENUNAME); 02069 strMenuName = ProbeAndReadUnicodeString(cmn.pusMenuName); 02070 ProbeForReadUnicodeStringBufferOrId(strMenuName); 02071 } except (StubExceptionHandler(TRUE)) { 02072 MSGERROR(0); 02073 } 02074 cmn.pusMenuName = &strMenuName; 02075 dwNewLong = (ULONG_PTR) &cmn; 02076 retval = xxxSetClassLongPtr( 02077 pwnd, 02078 nIndex, 02079 dwNewLong, 02080 bAnsi); 02081 try { 02082 ProbeAndWriteStructure(pcmnSave, cmn, CLSMENUNAME); 02083 } except (StubExceptionHandler(TRUE)) { 02084 MSGERROR(0); 02085 } 02086 break; 02087 02088 case GCL_STYLE: 02089 /* 02090 * I'm not sure how CS_VALID mask will affect existing apps, 02091 * so leave it for now --- except CS_IME flag, on which the system 02092 * deeply depends. 02093 */ 02094 #if DBG 02095 if (dwNewLong & ~CS_VALID) { 02096 RIPMSG1(RIP_WARNING, "NtUserSetClassLongPtr: Invalid style (%x) specified.", dwNewLong); 02097 } 02098 #endif 02099 if (dwNewLong & CS_IME) { 02100 RIPERR1(ERROR_INVALID_DATA, RIP_VERBOSE, "NtUserSetClassLongPtr: CS_IME is specified in new style (%x).", dwNewLong); 02101 MSGERROR(0); 02102 } 02103 default: 02104 retval = xxxSetClassLongPtr( 02105 pwnd, 02106 nIndex, 02107 dwNewLong, 02108 bAnsi); 02109 02110 } 02111 02112 TRACE("NtUserSetClassLongPtr"); 02113 ENDRECV_HWNDLOCK(); 02114 } 02115 02116 #ifdef _WIN64 02117 LONG NtUserSetClassLong( 02118 IN HWND hwnd, 02119 IN int nIndex, 02120 OUT LONG dwNewLong, 02121 IN BOOL bAnsi) 02122 { 02123 // 02124 // N.B. This function has implicit window translation and thread locking 02125 // enabled. These operations are performed in the User server API 02126 // dispatcher. 02127 // 02128 02129 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 02130 02131 switch (nIndex) { 02132 case GCL_STYLE: 02133 /* 02134 * I'm not sure how CS_VALID mask will affect existing apps, 02135 * so leave it for now --- except CS_IME flag, on which the system 02136 * deeply depends. 02137 */ 02138 #if DBG 02139 if (dwNewLong & ~CS_VALID) { 02140 RIPMSG1(RIP_WARNING, "NtUserSetClassLong: Invalid style (%x) specified.", dwNewLong); 02141 } 02142 #endif 02143 if (dwNewLong & CS_IME) { 02144 RIPERR1(ERROR_INVALID_DATA, RIP_VERBOSE, "NtUserSetClassLong: CS_IME is specified in new style (%x).", dwNewLong); 02145 MSGERROR(0); 02146 } 02147 } 02148 02149 retval = xxxSetClassLong( 02150 pwnd, 02151 nIndex, 02152 dwNewLong, 02153 bAnsi); 02154 02155 TRACE("NtUserSetClassLong"); 02156 ENDRECV_HWNDLOCK(); 02157 } 02158 #endif 02159 02160 BOOL NtUserSetKeyboardState( // API SetKeyboardState 02161 IN CONST BYTE *lpKeyState) 02162 { 02163 BEGINRECV(BOOL, FALSE); 02164 02165 /* 02166 * Probe arguments 02167 */ 02168 try { 02169 ProbeForRead(lpKeyState, 256, sizeof(BYTE)); 02170 02171 retval = _SetKeyboardState(lpKeyState); 02172 } except (StubExceptionHandler(TRUE)) { 02173 MSGERROR(0); 02174 } 02175 02176 TRACE("NtUserSetKeyboardState"); 02177 ENDRECV(); 02178 } 02179 02180 BOOL NtUserSetWindowPos( 02181 IN HWND hwnd, 02182 IN HWND hwndInsertAfter, 02183 IN int x, 02184 IN int y, 02185 IN int cx, 02186 IN int cy, 02187 IN UINT dwFlags) 02188 { 02189 PWND pwndT; 02190 PWND pwndInsertAfter; 02191 TL tlpwndT; 02192 02193 BEGINRECV_HWNDLOCK_ND(BOOL, FALSE, hwnd); 02194 02195 TESTFLAGS(dwFlags, SWP_VALID); 02196 02197 ValidateHWNDIA(pwndInsertAfter, hwndInsertAfter); 02198 02199 /* 02200 * Let's not allow the window to be shown/hidden once we 02201 * started the destruction of the window. 02202 */ 02203 if (TestWF(pwndND, WFINDESTROY)) { 02204 RIPERR1(ERROR_INVALID_PARAMETER, 02205 RIP_WARNING, 02206 "SetWindowPos: Window is being destroyed (pwnd == %#p)", 02207 pwndND); 02208 MSGERROR(0); 02209 } 02210 02211 if (dwFlags & ~SWP_VALID) { 02212 RIPERR1(ERROR_INVALID_PARAMETER, 02213 RIP_WARNING, 02214 "SetWindowPos: Invalid flags passed in (flags == 0x%lx)", 02215 dwFlags); 02216 MSGERROR(0); 02217 } 02218 02219 /* 02220 * Make sure the window coordinates can fit in WORDs. 02221 */ 02222 if (!(dwFlags & SWP_NOMOVE)) { 02223 if (x > SHRT_MAX) { 02224 x = SHRT_MAX; 02225 } else if (x < SHRT_MIN) { 02226 x = SHRT_MIN; 02227 } 02228 if (y > SHRT_MAX) { 02229 y = SHRT_MAX; 02230 } else if (y < SHRT_MIN) { 02231 y = SHRT_MIN; 02232 } 02233 } 02234 02235 /* 02236 * Actually, if we were going to be really strict about this we'd 02237 * make sure that x + cx < SHRT_MAX, etc but since we do maintain 02238 * signed 32-bit coords internally this case doesn't cause a problem. 02239 */ 02240 if (!(dwFlags & SWP_NOSIZE)) { 02241 if (cx < 0) { 02242 cx = 0; 02243 } else if (cx > SHRT_MAX) { 02244 cx = SHRT_MAX; 02245 } 02246 if (cy < 0) { 02247 cy = 0; 02248 } else if (cy > SHRT_MAX) { 02249 cy = SHRT_MAX; 02250 } 02251 } 02252 02253 #ifdef NEVER 02254 // 02255 // do not fail these conditions because real apps use them. 02256 // 02257 if (!(dwFlags & SWP_NOMOVE) && 02258 (x > SHRT_MAX || x < SHRT_MIN || 02259 y > SHRT_MAX || y < SHRT_MIN)) { 02260 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid coordinate passed to SetWindowPos"); 02261 MSGERROR(0); 02262 } 02263 02264 /* 02265 * Actually, if we were going to be really strict about this we'd 02266 * make sure that x + cx < SHRT_MAX, etc but since we do maintain 02267 * signed 32-bit coords internally this case doesn't cause a problem. 02268 */ 02269 if (!(dwFlags & SWP_NOSIZE) && 02270 (cx < 0 || cx > SHRT_MAX || 02271 cy < 0 || cy > SHRT_MAX)) { 02272 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid width/height passed to SetWindowPos"); 02273 MSGERROR(0); 02274 } 02275 #endif 02276 02277 switch((ULONG_PTR)pwndInsertAfter) { 02278 case (ULONG_PTR)HWND_TOPMOST: 02279 case (ULONG_PTR)HWND_NOTOPMOST: 02280 case (ULONG_PTR)HWND_TOP: 02281 case (ULONG_PTR)HWND_BOTTOM: 02282 pwndT = NULL; 02283 break; 02284 02285 default: 02286 pwndT = pwndInsertAfter; 02287 break; 02288 } 02289 02290 ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT); 02291 02292 retval = xxxSetWindowPos( 02293 pwndND, 02294 pwndInsertAfter, 02295 x, 02296 y, 02297 cx, 02298 cy, 02299 dwFlags); 02300 02301 ThreadUnlock(&tlpwndT); 02302 02303 TRACE("NtUserSetWindowPos"); 02304 ENDRECV_HWNDLOCK_ND(); 02305 } 02306 02307 BOOL NtUserSetShellWindowEx( 02308 IN HWND hwnd, 02309 IN HWND hwndBkGnd) 02310 { 02311 PWND pwndBkGnd; 02312 TL tlpwndBkGnd; 02313 02314 BEGINRECV_HWNDLOCK_ND(BOOL, FALSE, hwnd); 02315 02316 ValidateHWNDND(pwndBkGnd, hwndBkGnd); 02317 02318 ThreadLockAlwaysWithPti(ptiCurrent, pwndBkGnd, &tlpwndBkGnd); 02319 02320 retval = xxxSetShellWindow(pwndND, pwndBkGnd); 02321 02322 ThreadUnlock(&tlpwndBkGnd); 02323 02324 TRACE("NtUserSetShellWindowEx"); 02325 ENDRECV_HWNDLOCK_ND(); 02326 } 02327 02328 DWORD 02329 NtUserGetGuiResources( 02330 HANDLE hProcess, 02331 DWORD dwFlags) 02332 02333 { 02334 PEPROCESS Process; 02335 PW32PROCESS pW32Process; 02336 BEGINRECV_SHARED(DWORD, 0); 02337 02338 /* 02339 * Probe arguments 02340 */ 02341 if (dwFlags > GR_MAXOBJECT) { 02342 RIPERR1(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "GetGuiResources: invalid flag bits %x\n", 02343 dwFlags); 02344 MSGERROR(0); 02345 } 02346 02347 02348 if (hProcess == NtCurrentProcess()) { 02349 pW32Process = W32GetCurrentProcess(); 02350 } else { 02351 NTSTATUS Status; 02352 Status = ObReferenceObjectByHandle( 02353 hProcess, 02354 PROCESS_QUERY_INFORMATION, 02355 *PsProcessType, 02356 UserMode, 02357 &Process, 02358 NULL); 02359 02360 if (!NT_SUCCESS(Status)) { 02361 RIPERR2(ERROR_INVALID_PARAMETER, RIP_WARNING, "GetGuiResources: Failed with Process handle == %X, Status = %x\n", 02362 hProcess, Status); 02363 MSGERROR(0); 02364 } 02365 02366 /* 02367 * Make sure they are from the same session 02368 */ 02369 if (Process->SessionId != gSessionId) { 02370 RIPERR2(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "GetGuiResources: Different session. Failed with Process handle == %X, Status = %x\n", 02371 hProcess, Status); 02372 ObDereferenceObject(Process); 02373 MSGERROR(0); 02374 } 02375 02376 pW32Process = Process->Win32Process; 02377 } 02378 02379 if (pW32Process) { 02380 switch(dwFlags) { 02381 case GR_GDIOBJECTS: 02382 retval = pW32Process->GDIHandleCount; 02383 break; 02384 case GR_USEROBJECTS: 02385 retval = pW32Process->UserHandleCount; 02386 break; 02387 } 02388 } else 02389 retval = 0; 02390 02391 if (hProcess != NtCurrentProcess()) { 02392 ObDereferenceObject(Process); 02393 } 02394 02395 TRACE("NtUserGetGuiResources"); 02396 ENDRECV_SHARED(); 02397 } 02398 02399 02400 BOOL NtUserSystemParametersInfo( // API SystemParametersInfoA/W 02401 IN UINT wFlag, 02402 IN DWORD wParam, 02403 IN OUT LPVOID lpData, 02404 IN UINT flags) 02405 { 02406 UNICODE_STRING strData; 02407 ULONG ulLength, ulLength2; 02408 LPVOID lpDataSave; 02409 union { 02410 INT MouseData[3]; 02411 LOGFONTW LogFont; 02412 MOUSEKEYS MouseKeys; 02413 FILTERKEYS FilterKeys; 02414 STICKYKEYS StickyKeys; 02415 TOGGLEKEYS ToggleKeys; 02416 SOUNDSENTRY SoundSentry; 02417 ACCESSTIMEOUT AccessTimeout; 02418 RECT Rect; 02419 ANIMATIONINFO AnimationInfo; 02420 NONCLIENTMETRICS NonClientMetrics; 02421 MINIMIZEDMETRICS MinimizedMetrics; 02422 ICONMETRICS IconMetrics; 02423 HKL hkl; 02424 INTERNALSETHIGHCONTRAST ihc; 02425 HIGHCONTRAST hc; 02426 WCHAR szTemp[MAX_PATH]; 02427 } CaptureBuffer; 02428 PTHREADINFO pti; 02429 TL tlBuffer; 02430 BOOL fFreeBuffer = FALSE; 02431 BOOL fWrite = FALSE; 02432 02433 02434 02435 02436 BEGINRECV(BOOL, FALSE); 02437 02438 /* 02439 * Prevent restricted processes from setting system 02440 * parameters. 02441 * 02442 * clupu: this is ineficient and temporary. I'll change this 02443 * soon !!! 02444 */ 02445 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS)) { 02446 02447 switch (wFlag) { 02448 case SPI_SETBEEP: 02449 case SPI_SETMOUSE: 02450 case SPI_SETBORDER: 02451 case SPI_SETKEYBOARDSPEED: 02452 case SPI_ICONHORIZONTALSPACING: 02453 case SPI_SETSCREENSAVETIMEOUT: 02454 case SPI_SETSCREENSAVEACTIVE: 02455 case SPI_SETGRIDGRANULARITY: 02456 case SPI_SETDESKWALLPAPER: 02457 case SPI_SETDESKPATTERN: 02458 case SPI_SETKEYBOARDDELAY: 02459 case SPI_ICONVERTICALSPACING: 02460 case SPI_SETICONTITLEWRAP: 02461 case SPI_SETMENUDROPALIGNMENT: 02462 case SPI_SETDOUBLECLKWIDTH: 02463 case SPI_SETDOUBLECLKHEIGHT: 02464 case SPI_SETDOUBLECLICKTIME: 02465 case SPI_SETMOUSEBUTTONSWAP: 02466 case SPI_SETICONTITLELOGFONT: 02467 case SPI_SETFASTTASKSWITCH: 02468 case SPI_SETDRAGFULLWINDOWS: 02469 case SPI_SETNONCLIENTMETRICS: 02470 case SPI_SETMINIMIZEDMETRICS: 02471 case SPI_SETICONMETRICS: 02472 case SPI_SETWORKAREA: 02473 case SPI_SETPENWINDOWS: 02474 case SPI_SETHIGHCONTRAST: 02475 case SPI_SETKEYBOARDPREF: 02476 case SPI_SETSCREENREADER: 02477 case SPI_SETANIMATION: 02478 case SPI_SETFONTSMOOTHING: 02479 case SPI_SETDRAGWIDTH: 02480 case SPI_SETDRAGHEIGHT: 02481 case SPI_SETHANDHELD: 02482 case SPI_SETLOWPOWERTIMEOUT: 02483 case SPI_SETPOWEROFFTIMEOUT: 02484 case SPI_SETLOWPOWERACTIVE: 02485 case SPI_SETPOWEROFFACTIVE: 02486 case SPI_SETCURSORS: 02487 case SPI_SETICONS: 02488 case SPI_SETDEFAULTINPUTLANG: 02489 case SPI_SETLANGTOGGLE: 02490 case SPI_SETMOUSETRAILS: 02491 case SPI_SETSCREENSAVERRUNNING: 02492 case SPI_SETFILTERKEYS: 02493 case SPI_SETTOGGLEKEYS: 02494 case SPI_SETMOUSEKEYS: 02495 case SPI_SETSHOWSOUNDS: 02496 case SPI_SETSTICKYKEYS: 02497 case SPI_SETACCESSTIMEOUT: 02498 case SPI_SETSOUNDSENTRY: 02499 case SPI_SETSNAPTODEFBUTTON: 02500 case SPI_SETMOUSEHOVERWIDTH: 02501 case SPI_SETMOUSEHOVERHEIGHT: 02502 case SPI_SETMOUSEHOVERTIME: 02503 case SPI_SETWHEELSCROLLLINES: 02504 case SPI_SETMENUSHOWDELAY: 02505 case SPI_SETSHOWIMEUI: 02506 case SPI_SETMOUSESPEED: 02507 case SPI_SETACTIVEWINDOWTRACKING: 02508 case SPI_SETMENUANIMATION: 02509 case SPI_SETCOMBOBOXANIMATION: 02510 case SPI_SETLISTBOXSMOOTHSCROLLING: 02511 case SPI_SETGRADIENTCAPTIONS: 02512 case SPI_SETKEYBOARDCUES: 02513 case SPI_SETACTIVEWNDTRKZORDER: 02514 case SPI_SETHOTTRACKING: 02515 case SPI_SETMENUFADE: 02516 case SPI_SETSELECTIONFADE: 02517 case SPI_SETTOOLTIPANIMATION: 02518 case SPI_SETTOOLTIPFADE: 02519 case SPI_SETFOREGROUNDLOCKTIMEOUT: 02520 case SPI_SETACTIVEWNDTRKTIMEOUT: 02521 case SPI_SETFOREGROUNDFLASHCOUNT: 02522 MSGERROR(0); 02523 break; 02524 } 02525 } 02526 02527 try { 02528 switch(wFlag) { 02529 02530 case SPI_SETDESKPATTERN: 02531 /* 02532 * If wParam is -1, that means read the new wallpaper from 02533 * win.ini. If wParam is not -1, lParam points to the wallpaper 02534 * string. 02535 */ 02536 if (wParam == (WPARAM)-1) 02537 break; 02538 02539 /* 02540 * SetDeskPattern may take a string in lpData; if lpData 02541 * is one of the magic values it obviously is not a string 02542 */ 02543 if (lpData == (PVOID)IntToPtr( 0xFFFFFFFF ) || lpData == (PVOID)NULL) { 02544 /* 02545 * These are not really magic values, but in order not to break apps 02546 * we have to keep them valid. wParam =-1 will make lParam be ignored 02547 * MCostea 208416 02548 */ 02549 wParam = -1; 02550 break; 02551 } 02552 goto ProbeString; 02553 02554 case SPI_SETDESKWALLPAPER: 02555 02556 /* 02557 * If the caller passed in (-1) in the wParam, then the 02558 * wallpaper-name is to be loaded later. Otherwise, 02559 * they passed in a unicode-string in the lParam. 02560 */ 02561 if (wParam == (WPARAM)-1) 02562 break; 02563 02564 if (((LPWSTR)lpData == NULL) || 02565 ((LPWSTR)lpData == SETWALLPAPER_METRICS) || 02566 ((LPWSTR)lpData == SETWALLPAPER_DEFAULT)) { 02567 break; 02568 } 02569 02570 ProbeString: 02571 02572 /* 02573 * Probe and capture the string. Capture is necessary to 02574 * the pointer to be passed directly to the registry routines 02575 * which cannot cleanly handle exceptions. 02576 */ 02577 strData = ProbeAndReadUnicodeString((PUNICODE_STRING)lpData); 02578 #if defined(_X86_) 02579 ProbeForRead(strData.Buffer, strData.Length, sizeof(BYTE)); 02580 #else 02581 ProbeForRead(strData.Buffer, strData.Length, sizeof(WCHAR)); 02582 #endif 02583 lpData = UserAllocPoolWithQuota(strData.Length + sizeof(WCHAR), TAG_TEXT2); 02584 if (lpData == NULL) { 02585 ExRaiseStatus(STATUS_NO_MEMORY); 02586 } 02587 pti = PtiCurrent(); 02588 ThreadLockPool(pti, lpData, &tlBuffer); 02589 fFreeBuffer = TRUE; 02590 RtlCopyMemory(lpData, 02591 strData.Buffer, 02592 strData.Length); 02593 ((PWSTR)lpData)[strData.Length / sizeof(WCHAR)] = 0; 02594 break; 02595 02596 case SPI_SETMOUSE: 02597 ulLength = sizeof(INT) * 3; 02598 goto ProbeRead; 02599 case SPI_SETICONTITLELOGFONT: 02600 if (!ARGUMENT_PRESENT(lpData)) 02601 break; 02602 ulLength = sizeof(LOGFONTW); 02603 goto ProbeRead; 02604 case SPI_SETMOUSEKEYS: 02605 ulLength = sizeof(MOUSEKEYS); 02606 goto ProbeRead; 02607 case SPI_SETFILTERKEYS: 02608 ulLength = sizeof(FILTERKEYS); 02609 goto ProbeRead; 02610 case SPI_SETSTICKYKEYS: 02611 ulLength = sizeof(STICKYKEYS); 02612 goto ProbeRead; 02613 case SPI_SETTOGGLEKEYS: 02614 ulLength = sizeof(TOGGLEKEYS); 02615 goto ProbeRead; 02616 case SPI_SETSOUNDSENTRY: 02617 ulLength = sizeof(SOUNDSENTRY); 02618 goto ProbeRead; 02619 case SPI_SETACCESSTIMEOUT: 02620 ulLength = sizeof(ACCESSTIMEOUT); 02621 goto ProbeRead; 02622 case SPI_SETWORKAREA: 02623 ulLength = sizeof(RECT); 02624 goto ProbeRead; 02625 case SPI_SETANIMATION: 02626 ulLength = sizeof(ANIMATIONINFO); 02627 goto ProbeRead; 02628 case SPI_SETNONCLIENTMETRICS: 02629 ulLength = sizeof(NONCLIENTMETRICS); 02630 goto ProbeRead; 02631 case SPI_SETMINIMIZEDMETRICS: 02632 ulLength = sizeof(MINIMIZEDMETRICS); 02633 goto ProbeRead; 02634 case SPI_SETICONMETRICS: 02635 ulLength = sizeof(ICONMETRICS); 02636 goto ProbeRead; 02637 case SPI_SETDEFAULTINPUTLANG: 02638 ulLength = sizeof(HKL); 02639 goto ProbeRead; 02640 case SPI_SETHIGHCONTRAST: 02641 CaptureBuffer.ihc = ProbeAndReadStructure((INTERNALSETHIGHCONTRAST *)lpData, INTERNALSETHIGHCONTRAST); 02642 lpData = &CaptureBuffer.ihc; 02643 02644 /* 02645 * Now probe High Contrast string -- note that we send a client-side buffer pointer to the routine. 02646 */ 02647 02648 ProbeForReadUnicodeStringBuffer(CaptureBuffer.ihc.usDefaultScheme); 02649 if (CaptureBuffer.ihc.usDefaultScheme.Length == 0) { 02650 CaptureBuffer.ihc.usDefaultScheme.Buffer = NULL; 02651 } 02652 break; 02653 02654 /* 02655 * Probe and capture the data. Capture is necessary to 02656 * allow the pointer to be passed to the worker routines 02657 * where exceptions cannot be cleanly handled. 02658 */ 02659 ProbeRead: 02660 #if defined(_X86_) 02661 ProbeForRead(lpData, ulLength, sizeof(BYTE)); 02662 #else 02663 ProbeForRead(lpData, ulLength, sizeof(DWORD)); 02664 #endif 02665 RtlCopyMemory(&CaptureBuffer, lpData, ulLength); 02666 lpData = &CaptureBuffer; 02667 break; 02668 02669 case SPI_ICONHORIZONTALSPACING: // returns INT 02670 case SPI_ICONVERTICALSPACING: // returns INT 02671 if (!IS_PTR(lpData)) 02672 break; 02673 02674 /* 02675 * Fall through and probe the data 02676 */ 02677 case SPI_GETBEEP: // returns BOOL 02678 case SPI_GETBORDER: // returns INT 02679 case SPI_GETKEYBOARDSPEED: // returns DWORD 02680 case SPI_GETKEYBOARDDELAY: // returns INT 02681 case SPI_GETSCREENSAVETIMEOUT: // returns INT 02682 case SPI_GETLOWPOWERTIMEOUT: // returns INT 02683 case SPI_GETPOWEROFFTIMEOUT: // returns INT 02684 case SPI_GETSCREENSAVEACTIVE: // returns BOOL 02685 case SPI_GETLOWPOWERACTIVE: // returns BOOL 02686 case SPI_GETPOWEROFFACTIVE: // returns BOOL 02687 case SPI_GETGRIDGRANULARITY: // returns INT 02688 case SPI_GETICONTITLEWRAP: // returns BOOL 02689 case SPI_GETMENUDROPALIGNMENT: // returns BOOL 02690 case SPI_GETFASTTASKSWITCH: // returns BOOL 02691 case SPI_GETDRAGFULLWINDOWS: // returns INT 02692 case SPI_GETSHOWSOUNDS: // returns BOOL 02693 case SPI_GETFONTSMOOTHING: // returns INT 02694 case SPI_GETSNAPTODEFBUTTON: // returns BOOL 02695 case SPI_GETKEYBOARDPREF: // returns BOOL 02696 case SPI_GETSCREENREADER: // returns BOOL 02697 case SPI_GETDEFAULTINPUTLANG: 02698 case SPI_GETMOUSEHOVERWIDTH: 02699 case SPI_GETMOUSEHOVERHEIGHT: 02700 case SPI_GETMOUSEHOVERTIME: 02701 case SPI_GETWHEELSCROLLLINES: 02702 case SPI_GETMENUSHOWDELAY: 02703 case SPI_GETMOUSESPEED: 02704 case SPI_GETSCREENSAVERRUNNING: 02705 case SPI_GETSHOWIMEUI: 02706 goto ProbeWriteUlong; 02707 02708 case SPI_GETICONTITLELOGFONT: // returns LOGFONT 02709 ulLength = sizeof(LOGFONT); 02710 goto ProbeWrite; 02711 case SPI_GETMOUSE: // returns 3 INTs 02712 ulLength = sizeof(INT) * 3; 02713 goto ProbeWrite; 02714 case SPI_GETFILTERKEYS: // returns FILTERKEYS 02715 ulLength = sizeof(FILTERKEYS); 02716 goto ProbeWrite; 02717 case SPI_GETSTICKYKEYS: // returns STICKYKEYS 02718 ulLength = sizeof(STICKYKEYS); 02719 goto ProbeWrite; 02720 case SPI_GETMOUSEKEYS: // returns MOUSEKEYS 02721 ulLength = sizeof(MOUSEKEYS); 02722 goto ProbeWrite; 02723 case SPI_GETTOGGLEKEYS: // returns TOGGLEKEYS 02724 ulLength = sizeof(TOGGLEKEYS); 02725 goto ProbeWrite; 02726 case SPI_GETSOUNDSENTRY: // returns SOUNDSENTRY 02727 ulLength = sizeof(SOUNDSENTRY); 02728 goto ProbeWrite; 02729 case SPI_GETACCESSTIMEOUT: // returns ACCESSTIMEOUT 02730 ulLength = sizeof(ACCESSTIMEOUT); 02731 goto ProbeWrite; 02732 case SPI_GETANIMATION: // returns ANIMATIONINFO 02733 ulLength = sizeof(ANIMATIONINFO); 02734 goto ProbeWrite; 02735 case SPI_GETNONCLIENTMETRICS: // returns NONCLIENTMETRICS 02736 ulLength = sizeof(NONCLIENTMETRICS); 02737 goto ProbeWrite; 02738 case SPI_GETMINIMIZEDMETRICS: // returns MINIMIZEDMETRICS 02739 ulLength = sizeof(MINIMIZEDMETRICS); 02740 goto ProbeWrite; 02741 case SPI_GETICONMETRICS: // returns ICONMETRICS 02742 ulLength = sizeof(ICONMETRICS); 02743 goto ProbeWrite; 02744 02745 case SPI_GETHIGHCONTRAST: // returns HIGHCONTRAST 02746 ulLength = sizeof(HIGHCONTRASTW); 02747 ProbeForWrite(lpData, ulLength, DATAALIGN); 02748 lpDataSave = lpData; 02749 CaptureBuffer.hc = *((LPHIGHCONTRAST)lpData); 02750 lpData = &CaptureBuffer.hc; 02751 02752 /* 02753 * now probe string address 02754 */ 02755 02756 ulLength2 = MAX_SCHEME_NAME_SIZE * sizeof(WCHAR); 02757 02758 ProbeForWrite(((LPHIGHCONTRAST)lpData)->lpszDefaultScheme, ulLength2, CHARALIGN); 02759 fWrite = TRUE; 02760 break; 02761 case SPI_GETWORKAREA: // returns RECT 02762 ulLength = sizeof(RECT); 02763 goto ProbeWrite; 02764 02765 02766 /* 02767 * Bug 257718 - joejo 02768 * Add SPI_GETDESKWALLPAPER to SystemParametersInfo 02769 */ 02770 case SPI_GETDESKWALLPAPER: 02771 lpDataSave = lpData; 02772 lpData = CaptureBuffer.szTemp; 02773 ProbeForWriteBuffer((PWSTR)lpDataSave, wParam, CHARALIGN); 02774 wParam = (wParam < MAX_PATH) ? wParam : MAX_PATH; 02775 ulLength = wParam * sizeof(WCHAR); 02776 fWrite = TRUE; 02777 break; 02778 02779 default: 02780 if (wFlag < SPI_MAX) { 02781 break; 02782 } else if (!UPIsBOOLRange(wFlag) 02783 && !UPIsDWORDRange(wFlag)) { 02784 02785 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "NtUserSystemParametersInfo: Invalid SPI_:%#lx", wFlag); 02786 retval = FALSE; 02787 MSGERRORCLEANUP(0); 02788 } 02789 02790 /* 02791 * Let's enforce this or this parameter is gone for good. 02792 */ 02793 if (wParam != 0) { 02794 /* 02795 * Too late, Winstone98 is alreay using it (incorrectly). 02796 * Bummer, this has never been shipped and it's hacked already 02797 * Allow a special case to go through 02798 */ 02799 if ((PtiCurrent()->dwExpWinVer > VER40) 02800 || (wFlag != SPI_SETUIEFFECTS) 02801 || (wParam != 1)) { 02802 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "NtUserSystemParametersInfo: uiParam must be zero for SPI %#lx", wFlag); 02803 retval = FALSE; 02804 MSGERRORCLEANUP(0); 02805 } 02806 } 02807 02808 UserAssert(wFlag & SPIF_RANGETYPEMASK); 02809 02810 if (wFlag & SPIF_SET) { 02811 /* 02812 * If your dword data needs to be validated (i.e, range, value), 02813 * switch here on wFlag and do it here 02814 */ 02815 switch (wFlag) { 02816 case SPI_SETFOREGROUNDLOCKTIMEOUT: 02817 if (!CanForceForeground(PpiCurrent())) { 02818 RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, ""); 02819 retval = FALSE; 02820 MSGERRORCLEANUP(0); 02821 } 02822 break; 02823 } 02824 02825 } else { /* if (wFlag & SPIF_SET) */ 02826 ProbeWriteUlong: 02827 ulLength = sizeof(ULONG); 02828 lpDataSave = lpData; 02829 lpData = &CaptureBuffer; 02830 ProbeForWriteUlong((PULONG)lpDataSave); 02831 fWrite = TRUE; 02832 } 02833 break; 02834 02835 /* 02836 * Probe the data. wParam contains the length 02837 */ 02838 ProbeWrite: 02839 lpDataSave = lpData; 02840 lpData = &CaptureBuffer; 02841 ProbeForWrite(lpDataSave, ulLength, DATAALIGN); 02842 fWrite = TRUE; 02843 /* 02844 * Copy the first DWORD of the buffer. This will make sure that 02845 * the cbSize parameter of some structures gets copied. 02846 */ 02847 02848 UserAssert(ulLength >= sizeof(DWORD)); 02849 *(LPDWORD)lpData=*(LPDWORD)lpDataSave; 02850 } 02851 } except (StubExceptionHandler(TRUE)) { 02852 MSGERRORCLEANUP(0); 02853 } 02854 02855 retval = xxxSystemParametersInfo(wFlag, wParam, lpData, flags); 02856 02857 /* 02858 * Copy out any data we need to. 02859 */ 02860 if (fWrite) { 02861 try { 02862 RtlCopyMemory(lpDataSave, lpData, ulLength); 02863 } except (StubExceptionHandler(TRUE)) { 02864 MSGERRORCLEANUP(0); 02865 } 02866 } 02867 02868 CLEANUPRECV(); 02869 if (fFreeBuffer) 02870 ThreadUnlockAndFreePool(pti, &tlBuffer); 02871 02872 TRACE("NtUserSystemParametersInfo"); 02873 ENDRECV(); 02874 } 02875 02876 BOOL NtUserUpdatePerUserSystemParameters( 02877 IN HANDLE hToken, 02878 IN BOOL bUserLoggedOn) 02879 { 02880 BEGINRECV(BOOL, FALSE); 02881 02882 retval = xxxUpdatePerUserSystemParameters(hToken, bUserLoggedOn); 02883 02884 TRACE("NtUserUpdatePerUserSystemParameters"); 02885 ENDRECV(); 02886 } 02887 02888 DWORD NtUserDdeInitialize( // API DdeInitializeA/W 02889 OUT PHANDLE phInst, 02890 OUT HWND *phwnd, 02891 OUT LPDWORD pMonFlags, 02892 IN DWORD afCmd, 02893 IN PVOID pcii) 02894 { 02895 HANDLE hInst; 02896 HWND hwnd; 02897 DWORD MonFlags; 02898 02899 BEGINRECV(DWORD, DMLERR_INVALIDPARAMETER); 02900 02901 /* 02902 * NOTE -- pcii is a value that is passed back to the client side 02903 * for event callbacks. It is not probed because it is not used 02904 * on the kernel side. 02905 */ 02906 02907 retval = xxxCsDdeInitialize(&hInst, &hwnd, 02908 &MonFlags, afCmd, pcii); 02909 02910 /* 02911 * Probe arguments. pcii is not dereferenced in the kernel so probing 02912 * is not needed. 02913 */ 02914 if (retval == DMLERR_NO_ERROR) { 02915 try { 02916 ProbeAndWriteHandle(phInst, hInst); 02917 ProbeAndWriteHandle((PHANDLE)phwnd, hwnd); 02918 ProbeAndWriteUlong(pMonFlags, MonFlags); 02919 } except (StubExceptionHandler(TRUE)) { 02920 xxxDestroyThreadDDEObject(PtiCurrent(), HtoP(hInst)); 02921 MSGERROR(0); 02922 } 02923 } 02924 02925 TRACE("NtUserDdeInitialize"); 02926 ENDRECV(); 02927 } 02928 02929 DWORD NtUserUpdateInstance( // private, but pMonFlags from API DdeInitializeA/W 02930 IN HANDLE hInst, 02931 OUT LPDWORD pMonFlags, 02932 IN DWORD afCmd) 02933 { 02934 DWORD MonFlags; 02935 BEGINRECV(DWORD, DMLERR_INVALIDPARAMETER); 02936 02937 /* 02938 * Probe arguments 02939 */ 02940 try { 02941 ProbeForWriteUlong(pMonFlags); 02942 } except (StubExceptionHandler(FALSE)) { 02943 MSGERROR(0); 02944 } 02945 retval = _CsUpdateInstance(hInst, &MonFlags, afCmd); 02946 try { 02947 *pMonFlags = MonFlags; 02948 } except (StubExceptionHandler(TRUE)) { 02949 MSGERROR(0); 02950 } 02951 02952 TRACE("NtUserUpdateInstance"); 02953 ENDRECV(); 02954 } 02955 02956 DWORD NtUserEvent( // private 02957 IN PEVENT_PACKET pep) 02958 { 02959 WORD cbEventData; 02960 BEGINRECV(DWORD, 0); 02961 02962 /* 02963 * Probe arguments 02964 */ 02965 try { 02966 ProbeForRead(pep, sizeof(*pep), DATAALIGN); 02967 /* 02968 * capture so that another thread can't change it after the probe. 02969 */ 02970 cbEventData = pep->cbEventData; 02971 ProbeForRead(&pep->Data, cbEventData, DATAALIGN); 02972 } except (StubExceptionHandler(FALSE)) { 02973 MSGERROR(0); 02974 } 02975 02976 /* 02977 * The buffer is captured within a try/except in xxxCsEvent. 02978 */ 02979 02980 retval = xxxCsEvent((PEVENT_PACKET)pep, cbEventData); 02981 02982 TRACE("NtUserEvent"); 02983 ENDRECV(); 02984 } 02985 02986 BOOL NtUserFillWindow( 02987 IN HWND hwndBrush, 02988 IN HWND hwndPaint, 02989 IN HDC hdc, 02990 IN HBRUSH hbr) 02991 { 02992 02993 // 02994 // N.B. This function has implicit window translation and thread locking 02995 // enabled. These operations are performed in the User server API 02996 // dispatcher. 02997 // 02998 02999 PWND pwndBrush; 03000 TL tlpwndBrush; 03001 03002 BEGINRECV_HWNDLOCK(DWORD, 0, hwndPaint); 03003 03004 if (hdc == NULL) 03005 MSGERROR(0); 03006 03007 ValidateHWNDOPT(pwndBrush, hwndBrush); 03008 03009 ThreadLockWithPti(ptiCurrent, pwndBrush, &tlpwndBrush); 03010 03011 retval = xxxFillWindow( 03012 pwndBrush, 03013 pwnd, 03014 hdc, 03015 hbr); 03016 03017 ThreadUnlock(&tlpwndBrush); 03018 03019 TRACE("NtUserFillWindow"); 03020 ENDRECV_HWNDLOCK(); 03021 } 03022 03023 PCLS NtUserGetWOWClass( // wow 03024 IN HINSTANCE hInstance, 03025 IN PUNICODE_STRING pString) 03026 { 03027 UNICODE_STRING strClassName; 03028 03029 BEGINRECV_SHARED(PCLS, NULL); 03030 03031 /* 03032 * Probe arguments 03033 */ 03034 try { 03035 strClassName = ProbeAndReadUnicodeString(pString); 03036 ProbeForReadUnicodeStringBuffer(strClassName); 03037 } except (StubExceptionHandler(FALSE)) { 03038 MSGERROR(0); 03039 } 03040 03041 retval = _GetWOWClass( 03042 hInstance, 03043 strClassName.Buffer); 03044 03045 TRACE("NtUserGetWOWClass"); 03046 ENDRECV_SHARED(); 03047 } 03048 03049 UINT NtUserGetInternalWindowPos( // private 03050 IN HWND hwnd, 03051 OUT LPRECT lpRect OPTIONAL, 03052 OUT LPPOINT lpPoint OPTIONAL) 03053 { 03054 WINDOWPLACEMENT wp; 03055 03056 // 03057 // N.B. This function has implicit window handle translation. This 03058 // operation is performed in the User server API dispatcher. 03059 // 03060 03061 BEGINRECV_HWND_SHARED(DWORD, 0, hwnd); 03062 03063 /* 03064 * Probe arguments 03065 */ 03066 try { 03067 if (ARGUMENT_PRESENT(lpRect)) { 03068 ProbeForWriteRect(lpRect); 03069 } 03070 if (ARGUMENT_PRESENT(lpPoint)) { 03071 ProbeForWritePoint(lpPoint); 03072 } 03073 03074 } except (StubExceptionHandler(FALSE)) { 03075 MSGERROR(0); 03076 } 03077 03078 wp.length = sizeof(WINDOWPLACEMENT); 03079 03080 _GetWindowPlacement(pwnd, &wp); 03081 03082 retval = wp.showCmd; 03083 try { 03084 if (ARGUMENT_PRESENT(lpRect)) { 03085 RtlCopyMemory(lpRect, &wp.rcNormalPosition, sizeof (RECT)); 03086 } 03087 if (ARGUMENT_PRESENT(lpPoint)) { 03088 RtlCopyMemory(lpPoint, &wp.ptMinPosition, sizeof (POINT)); 03089 } 03090 03091 } except (StubExceptionHandler(FALSE)) { 03092 } 03093 03094 TRACE("NtUserGetInternalWindowPos"); 03095 ENDRECV_HWND_SHARED(); 03096 } 03097 03098 NTSTATUS NtUserInitTask( // wow 03099 IN UINT dwExpWinVer, 03100 IN DWORD dwAppCompatFlags, 03101 IN PUNICODE_STRING pstrModName, 03102 IN PUNICODE_STRING pstrBaseFileName, 03103 IN DWORD hTaskWow, 03104 IN DWORD dwHotkey, 03105 IN DWORD idTask, 03106 IN DWORD dwX, 03107 IN DWORD dwY, 03108 IN DWORD dwXSize, 03109 IN DWORD dwYSize) 03110 { 03111 UNICODE_STRING strModName; 03112 UNICODE_STRING strBaseFileName; 03113 03114 BEGINRECV(NTSTATUS, STATUS_UNSUCCESSFUL); 03115 03116 /* 03117 * Make sure this is really a WOW process. 03118 */ 03119 if (PpiCurrent()->pwpi == NULL) { 03120 MSGERROR(0); 03121 } 03122 03123 /* 03124 * Probe arguments 03125 */ 03126 try { 03127 strModName = ProbeAndReadUnicodeString(pstrModName); 03128 /* 03129 * pstrModName->Buffer has a UNICODE_NULL that's not counted in 03130 * the length, but we want to include it for convenience. The 03131 * probe routine does this. 03132 */ 03133 ProbeForReadUnicodeStringBuffer(strModName); 03134 03135 if (pstrBaseFileName) { 03136 strBaseFileName = ProbeAndReadUnicodeString(pstrBaseFileName); 03137 ProbeForReadUnicodeStringBuffer(strBaseFileName); 03138 } 03139 03140 } except (StubExceptionHandler(FALSE)) { 03141 MSGERROR(0); 03142 } 03143 03144 retval = zzzInitTask( 03145 dwExpWinVer, 03146 dwAppCompatFlags, 03147 &strModName, 03148 pstrBaseFileName ? &strBaseFileName : NULL, 03149 hTaskWow, 03150 dwHotkey, 03151 idTask, 03152 dwX, 03153 dwY, 03154 dwXSize, 03155 dwYSize); 03156 03157 TRACE("NtUserInitTask"); 03158 ENDRECV(); 03159 } 03160 03161 BOOL NtUserPostThreadMessage( 03162 IN DWORD id, 03163 IN UINT msg, 03164 IN WPARAM wParam, 03165 IN LPARAM lParam) 03166 { 03167 PTHREADINFO ptiCurrent, pti; 03168 03169 BEGINRECV(BOOL, FALSE); 03170 03171 /* 03172 * Prevent apps from setting hi 16 bits so we can use them internally. 03173 */ 03174 if (msg & MSGFLAG_MASK) { 03175 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid message"); 03176 MSGERROR(0); 03177 } 03178 03179 pti = PtiFromThreadId(id); 03180 if (pti == NULL) { 03181 struct tagWOWPROCESSINFO *pwpi; 03182 PTDB ptdb; 03183 03184 for (pwpi=gpwpiFirstWow; pwpi; pwpi=pwpi->pwpiNext) { 03185 for (ptdb=pwpi->ptdbHead; ptdb; ptdb=ptdb->ptdbNext) { 03186 if (ptdb->hTaskWow == id) { 03187 pti=ptdb->pti; 03188 goto PTM_DoIt; 03189 } 03190 } 03191 } 03192 03193 RIPERR0(ERROR_INVALID_THREAD_ID, RIP_VERBOSE, ""); 03194 MSGERROR(0); 03195 } 03196 03197 PTM_DoIt: 03198 03199 /* 03200 * Should be OK if any of the following are true 03201 * threads are running on the same desktop 03202 * request is on behalf of a system process 03203 * this process owns the desktop the thread is running in 03204 * the LUIDs match 03205 */ 03206 ptiCurrent = PtiCurrent(); 03207 if ( !(ptiCurrent->rpdesk == pti->rpdesk) && 03208 !(ptiCurrent->TIF_flags & TIF_CSRSSTHREAD) && 03209 !(GetDesktopView(ptiCurrent->ppi, pti->rpdesk))) { 03210 03211 LUID luidCurrent, luidTo; 03212 03213 if (!NT_SUCCESS(GetProcessLuid(ptiCurrent->pEThread, &luidCurrent)) || 03214 !NT_SUCCESS(GetProcessLuid(pti->pEThread, &luidTo)) || 03215 !RtlEqualLuid(&luidCurrent, &luidTo)) { 03216 RIPERR3(ERROR_INVALID_THREAD_ID, 03217 RIP_WARNING, 03218 "NtUserPostThreadMessage failed LUID check: msg(%lx), t1(%#p) -> t2(%#p)", 03219 msg, ptiCurrent, pti); 03220 MSGERROR(0); 03221 } 03222 } 03223 03224 retval = _PostThreadMessage( 03225 pti, 03226 msg, 03227 wParam, 03228 lParam); 03229 03230 TRACE("NtUserPostThreadMessage"); 03231 ENDRECV(); 03232 } 03233 03234 BOOL NtUserRegisterTasklist( 03235 IN HWND hwnd) 03236 { 03237 03238 // 03239 // N.B. This function has implicit window handle translation. This 03240 // operation is performed in the User server API dispatcher. 03241 // 03242 03243 BEGINRECV_HWND(DWORD, 0, hwnd); 03244 03245 retval = _RegisterTasklist( 03246 pwnd); 03247 03248 TRACE("NtUserRegisterTasklist"); 03249 ENDRECV_HWND(); 03250 } 03251 03252 BOOL NtUserCloseClipboard( 03253 VOID) 03254 { 03255 BEGINRECV(BOOL, FALSE); 03256 03257 retval = xxxCloseClipboard(NULL); 03258 03259 TRACE("NtUserCloseClipboard"); 03260 ENDRECV(); 03261 } 03262 03263 BOOL NtUserEmptyClipboard( 03264 VOID) 03265 { 03266 BEGINRECV(BOOL, FALSE); 03267 03268 retval = xxxEmptyClipboard(NULL); 03269 03270 TRACE("NtUserEmptyClipboard"); 03271 ENDRECV(); 03272 } 03273 03274 BOOL NtUserSetClipboardData( // API SetClipboardData 03275 IN UINT fmt, 03276 IN HANDLE hData, 03277 IN PSETCLIPBDATA pscd) 03278 { 03279 SETCLIPBDATA scd; 03280 03281 BEGINRECV(BOOL, FALSE); 03282 03283 /* 03284 * Check for jobs with JOB_OBJECT_UILIMIT_WRITECLIPBOARD 03285 */ 03286 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_WRITECLIPBOARD)) { 03287 RIPMSG0(RIP_WARNING, "NtUserSetClipboardData failed for restricted thread"); 03288 MSGERROR(0); 03289 } 03290 03291 /* 03292 * Probe arguments 03293 */ 03294 try { 03295 scd = ProbeAndReadSetClipBData(pscd); 03296 } except (StubExceptionHandler(TRUE)) { 03297 MSGERROR(0); 03298 } 03299 03300 retval = _SetClipboardData( 03301 fmt, 03302 hData, 03303 scd.fGlobalHandle, 03304 scd.fIncSerialNumber); 03305 03306 TRACE("NtUserSetClipboardData"); 03307 ENDRECV(); 03308 } 03309 03310 HANDLE NtUserConvertMemHandle( // worker routine, lpData not from API 03311 IN LPBYTE lpData, 03312 IN UINT cbData) 03313 { 03314 BEGINRECV(HANDLE, NULL); 03315 03316 /* 03317 * Probe arguments 03318 */ 03319 try { 03320 03321 ProbeForRead(lpData, cbData, sizeof(BYTE)); 03322 03323 } except (StubExceptionHandler(FALSE)) { 03324 MSGERROR(0); 03325 } 03326 03327 /* 03328 * lpData is client-side. 03329 */ 03330 retval = _ConvertMemHandle(lpData, cbData); 03331 03332 TRACE("NtUserConvertMemHandle"); 03333 ENDRECV(); 03334 } 03335 03336 NTSTATUS NtUserCreateLocalMemHandle( // helper routine 03337 IN HANDLE hMem, 03338 OUT LPBYTE lpData OPTIONAL, 03339 IN UINT cbData, 03340 OUT PUINT lpcbNeeded OPTIONAL) 03341 { 03342 PCLIPDATA pClipData; 03343 03344 BEGINRECV(NTSTATUS, STATUS_INVALID_HANDLE); 03345 03346 pClipData = HMValidateHandle(hMem, TYPE_CLIPDATA); 03347 if (pClipData == NULL) 03348 MSGERROR(0); 03349 03350 /* 03351 * Probe arguments 03352 */ 03353 try { 03354 if (ARGUMENT_PRESENT(lpData)) { 03355 ProbeForWrite(lpData, cbData, sizeof(BYTE)); 03356 } 03357 03358 if (ARGUMENT_PRESENT(lpcbNeeded)) { 03359 ProbeAndWriteUlong(lpcbNeeded, pClipData->cbData); 03360 } 03361 03362 if (!ARGUMENT_PRESENT(lpData) || cbData < pClipData->cbData) { 03363 retval = STATUS_BUFFER_TOO_SMALL; 03364 } else { 03365 RtlCopyMemory(lpData, &pClipData->abData, pClipData->cbData); 03366 retval = STATUS_SUCCESS; 03367 } 03368 } except (StubExceptionHandler(FALSE)) { 03369 MSGERROR(0); 03370 } 03371 03372 TRACE("NtUserCreateLocalMemHandle"); 03373 ENDRECV(); 03374 } 03375 03376 HHOOK NtUserSetWindowsHookEx( 03377 IN HANDLE hmod, 03378 IN PUNICODE_STRING pstrLib OPTIONAL, 03379 IN DWORD idThread, 03380 IN int nFilterType, 03381 IN PROC pfnFilterProc, 03382 IN DWORD dwFlags) 03383 { 03384 PTHREADINFO ptiThread; 03385 03386 BEGINRECV(HHOOK, NULL); 03387 03388 if (idThread != 0) { 03389 ptiThread = PtiFromThreadId(idThread); 03390 if (ptiThread == NULL) { 03391 RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, ""); 03392 MSGERROR(0); 03393 } 03394 } else { 03395 ptiThread = NULL; 03396 } 03397 03398 /* 03399 * Probe pstrLib in GetHmodTableIndex(). 03400 */ 03401 retval = (HHOOK)zzzSetWindowsHookEx( 03402 hmod, 03403 pstrLib, 03404 ptiThread, 03405 nFilterType, 03406 pfnFilterProc, 03407 dwFlags); 03408 retval = PtoH((PVOID)retval); 03409 03410 TRACE("NtUserSetWindowsHookEx"); 03411 ENDRECV(); 03412 } 03413 03414 HWINEVENTHOOK NtUserSetWinEventHook( 03415 IN DWORD eventMin, 03416 IN DWORD eventMax, 03417 IN HMODULE hmodWinEventProc, 03418 IN PUNICODE_STRING pstrLib OPTIONAL, 03419 IN WINEVENTPROC pfnWinEventProc, 03420 IN DWORD idEventProcess, 03421 IN DWORD idEventThread, 03422 IN DWORD dwFlags) 03423 { 03424 BEGINRECV(HWINEVENTHOOK, NULL); 03425 03426 TESTFLAGS(dwFlags, WINEVENT_VALID); 03427 03428 /* 03429 * Probe pstrLib in GetHmodTableIndex(). 03430 */ 03431 retval = (HWINEVENTHOOK)_SetWinEventHook( 03432 eventMin, 03433 eventMax, 03434 hmodWinEventProc, 03435 pstrLib, 03436 pfnWinEventProc, 03437 (HANDLE)LongToHandle( idEventProcess ), 03438 idEventThread, 03439 dwFlags); 03440 retval = PtoH((PVOID)retval); 03441 03442 TRACE("NtUserSetWinEventHook"); 03443 ENDRECV(); 03444 } 03445 03446 BOOL NtUserUnhookWinEvent( 03447 IN HWINEVENTHOOK hWinEventUnhook) 03448 { 03449 PEVENTHOOK peh; 03450 03451 BEGINATOMICRECV(BOOL, FALSE); 03452 03453 ValidateHWINEVENTHOOK(peh, hWinEventUnhook); 03454 03455 retval = _UnhookWinEvent(peh); 03456 03457 TRACE("NtUserUnhookWinEvent"); 03458 ENDATOMICRECV(); 03459 } 03460 03461 VOID NtUserNotifyWinEvent( 03462 IN DWORD event, 03463 IN HWND hwnd, 03464 IN LONG idObject, 03465 IN LONG idChild) 03466 { 03467 BEGINRECV_HWNDLOCK_VOID(hwnd); 03468 03469 if (!FWINABLE()) { 03470 MSGERROR_VOID(); 03471 } 03472 xxxWindowEvent(event, pwnd, idObject, idChild, WEF_USEPWNDTHREAD); 03473 03474 TRACEVOID("NtUserNotifyWinEvent"); 03475 ENDRECV_HWNDLOCK_VOID(); 03476 } 03477 03478 03479 BOOL NtUserGetGUIThreadInfo( // API GetGUIThreadInfo 03480 IN DWORD idThread, 03481 IN OUT PGUITHREADINFO pgui) 03482 { 03483 PTHREADINFO ptiThread; 03484 GUITHREADINFO gui; 03485 03486 BEGINRECV_SHARED(BOOL, FALSE); 03487 03488 if (idThread) { 03489 ptiThread = PtiFromThreadId(idThread); 03490 if (ptiThread == NULL) { 03491 RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "Bad thread id"); 03492 MSGERROR(0); 03493 } 03494 } else { 03495 ptiThread = NULL; 03496 } 03497 03498 /* 03499 * Probe arguments and copy results 03500 * C2: test pti & current thread on same desktop within _GetGUIThreadInfo 03501 */ 03502 try { 03503 ProbeForWrite(pgui, sizeof(*pgui), DATAALIGN); 03504 gui.cbSize = pgui->cbSize; 03505 } except (StubExceptionHandler(TRUE)) { 03506 MSGERROR(0); 03507 } 03508 03509 retval = _GetGUIThreadInfo(ptiThread, &gui); 03510 if (retval) { 03511 try { 03512 *pgui = gui; 03513 } except (StubExceptionHandler(TRUE)) { 03514 MSGERROR(0); 03515 } 03516 } 03517 03518 TRACE("NtUserGetGUIThreadInfo"); 03519 ENDRECV_SHARED(); 03520 } 03521 03522 /*****************************************************************************\ 03523 * GetTitleBarInfo 03524 * 03525 * Gets information about the title bar 03526 \*****************************************************************************/ 03527 BOOL NtUserGetTitleBarInfo(IN HWND hwnd, IN OUT PTITLEBARINFO ptbi) 03528 { 03529 TITLEBARINFO tbi; 03530 03531 BEGINRECV_HWNDLOCK(BOOL, FALSE, hwnd); 03532 03533 /* 03534 * Probe arguments and copy out results 03535 */ 03536 try { 03537 ProbeForWrite(ptbi, sizeof(*ptbi), DATAALIGN); 03538 tbi.cbSize = ptbi->cbSize; 03539 } except (StubExceptionHandler(TRUE)) { 03540 MSGERROR(0); 03541 } 03542 /* 03543 * Get the titlebar info 03544 */ 03545 retval = xxxGetTitleBarInfo(pwnd, &tbi); 03546 if (retval) { 03547 try { 03548 *ptbi = tbi; 03549 } except (StubExceptionHandler(TRUE)) { 03550 MSGERROR(0); 03551 } 03552 } 03553 03554 TRACE("NtUserGetTitleBarInfo"); 03555 ENDRECV_HWNDLOCK(); 03556 } 03557 03558 03559 /*****************************************************************************\ 03560 * NtUserGetComboBoxInfo 03561 * 03562 * Gets information about the combo box 03563 \*****************************************************************************/ 03564 BOOL NtUserGetComboBoxInfo(IN HWND hwnd, IN OUT PCOMBOBOXINFO pcbi) 03565 { 03566 COMBOBOXINFO cbi; 03567 03568 BEGINRECV_HWND_SHARED(BOOL, FALSE, hwnd); 03569 03570 /* 03571 * Probe arguments and copy out results 03572 */ 03573 try { 03574 ProbeForWrite(pcbi, sizeof(*pcbi), DATAALIGN); 03575 cbi.cbSize = pcbi->cbSize; 03576 } except (StubExceptionHandler(TRUE)) { 03577 MSGERROR(0); 03578 } 03579 03580 /* 03581 * Get the combobox info 03582 */ 03583 retval = _GetComboBoxInfo(pwnd, &cbi); 03584 03585 if (retval) { 03586 try { 03587 *pcbi = cbi; 03588 } except (StubExceptionHandler(TRUE)) { 03589 MSGERROR(0); 03590 } 03591 } 03592 03593 TRACE("NtUserGetComboBoxInfo"); 03594 ENDRECV_HWND_SHARED(); 03595 } 03596 03597 03598 /*****************************************************************************\ 03599 * NtUserGetListBoxInfo 03600 * 03601 * Gets information about the list box 03602 \*****************************************************************************/ 03603 DWORD NtUserGetListBoxInfo(IN HWND hwnd) 03604 { 03605 BEGINRECV_HWND_SHARED(DWORD, 0, hwnd); 03606 03607 /* 03608 * Get the listbox info 03609 */ 03610 retval = _GetListBoxInfo(pwnd); 03611 03612 TRACE("NtUserGetListBoxInfo"); 03613 ENDRECV_HWND_SHARED(); 03614 } 03615 03616 03617 /*****************************************************************************\ 03618 * GetCursorInfo 03619 * 03620 * Gets information about the global cursor 03621 \*****************************************************************************/ 03622 BOOL NtUserGetCursorInfo(IN OUT PCURSORINFO pci) 03623 { 03624 CURSORINFO ci = {0}; 03625 03626 BEGINRECV_SHARED(BOOL, FALSE); 03627 03628 ci.ptScreenPos = gpsi->ptCursor; 03629 ci.flags = 0; 03630 03631 if (gpcurPhysCurrent) 03632 ci.flags |= CURSOR_SHOWING; 03633 03634 /* 03635 * Get the current LOGICAL cursor (the one apps actually see from LoadCursor()) 03636 */ 03637 ci.hCursor = (HCURSOR)PtoH(gpcurLogCurrent); 03638 03639 retval = TRUE; 03640 03641 /* 03642 * Probe arguments and copy out result 03643 */ 03644 try { 03645 ProbeForWrite(pci, sizeof(*pci), DATAALIGN); 03646 if (pci->cbSize != sizeof(CURSORINFO)) { 03647 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "CURSORINFO.cbSize %d is wrong", pci->cbSize); 03648 retval = FALSE; 03649 } else { 03650 *pci = ci; 03651 } 03652 03653 } except (StubExceptionHandler(TRUE)) { 03654 MSGERROR(0); 03655 } 03656 03657 TRACE("NtUserGetCursorInfo"); 03658 ENDRECV_SHARED(); 03659 } 03660 03661 /*****************************************************************************\ 03662 * GetScrollBarInfo 03663 * 03664 * Gets information about the scroll bar 03665 \*****************************************************************************/ 03666 BOOL NtUserGetScrollBarInfo(IN HWND hwnd, IN LONG idObject, IN OUT PSCROLLBARINFO psbi) 03667 { 03668 SCROLLBARINFO sbi; 03669 03670 BEGINRECV_HWND_SHARED(BOOL, FALSE, hwnd); 03671 03672 /* 03673 * Probe arguments and copy out results 03674 */ 03675 try { 03676 ProbeForWrite(psbi, sizeof(*psbi), DATAALIGN); 03677 sbi.cbSize = psbi->cbSize; 03678 } except (StubExceptionHandler(TRUE)) { 03679 MSGERROR(0); 03680 } 03681 /* 03682 * Get the scrollbar info 03683 */ 03684 retval = _GetScrollBarInfo(pwnd, idObject, &sbi); 03685 03686 if (retval) { 03687 try { 03688 *psbi = sbi; 03689 } except (StubExceptionHandler(TRUE)) { 03690 MSGERROR(0); 03691 } 03692 } 03693 03694 TRACE("NtUserGetScrollBarInfo"); 03695 ENDRECV_HWND_SHARED(); 03696 } 03697 03698 HWND NtUserGetAncestor(IN HWND hwndChild, IN UINT gaFlags) 03699 { 03700 BEGINRECV_HWND_SHARED(HWND, NULL, hwndChild); 03701 03702 if ((gaFlags < GA_MIN) || (gaFlags > GA_MAX)) { 03703 RIPERR3(ERROR_INVALID_PARAMETER, RIP_WARNING, 03704 "NtUserGetAncestor: Invalid gaFlags parameter %d, not %d - %d", 03705 gaFlags, GA_MIN, GA_MAX); 03706 MSGERROR(0); 03707 } 03708 retval = (HWND)_GetAncestor(pwnd, gaFlags); 03709 retval = PtoH((PVOID)retval); 03710 03711 TRACE("NtUserGetAncestor"); 03712 ENDRECV_HWND_SHARED(); 03713 } 03714 03715 HWND NtUserRealChildWindowFromPoint(IN HWND hwndParent, IN POINT pt) 03716 { 03717 BEGINRECV_HWND_SHARED(HWND, NULL, hwndParent); 03718 03719 retval = (HWND)_RealChildWindowFromPoint(pwnd, pt); 03720 retval = PtoH((PVOID)retval); 03721 03722 TRACE("NtUserRealChildWindowFromPoint"); 03723 ENDRECV_HWND_SHARED(); 03724 } 03725 03726 BOOL NtUserGetAltTabInfo( 03727 IN HWND hwnd, 03728 IN int iItem, 03729 IN OUT PALTTABINFO pati, 03730 OUT LPWSTR lpszItemText, 03731 IN UINT cchItemText OPTIONAL, 03732 BOOL bAnsi) 03733 { 03734 ALTTABINFO ati; 03735 03736 BEGINRECV_HWNDOPT_SHARED(BOOL, FALSE, hwnd); 03737 03738 /* 03739 * If the specified window is not a switch window, then fail the call. 03740 * It's a dumb API we got from Windows 95, I am hereby allowing NULL hwnd. 03741 */ 03742 if (pwnd && (pwnd != gspwndAltTab)) { 03743 MSGERROR(ERROR_INVALID_WINDOW_HANDLE); 03744 } 03745 03746 /* 03747 * Probe arguments 03748 */ 03749 try { 03750 ProbeForWrite(pati, sizeof(*pati), DATAALIGN); 03751 if (bAnsi) { 03752 ProbeForWriteBuffer((LPSTR)lpszItemText, cchItemText, CHARALIGN); 03753 } else { 03754 ProbeForWriteBuffer(lpszItemText, cchItemText, CHARALIGN); 03755 } 03756 03757 /* 03758 * Validate AltTabInfo structure 03759 */ 03760 if (pati->cbSize != sizeof(ALTTABINFO)) { 03761 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "ALTTABINFO.cbSize %d is wrong", pati->cbSize); 03762 MSGERROR(0); 03763 } 03764 } except (StubExceptionHandler(TRUE)) { 03765 MSGERROR(0); 03766 } 03767 03768 /* 03769 * Get the alt tab info 03770 */ 03771 ati.cbSize = sizeof(ALTTABINFO); 03772 retval = _GetAltTabInfo(iItem, &ati, lpszItemText, cchItemText, bAnsi); 03773 if (retval) { 03774 try { 03775 *pati = ati; 03776 } except (StubExceptionHandler(TRUE)) { 03777 MSGERROR(0); 03778 } 03779 } 03780 03781 TRACE("NtUserGetAltTabInfo"); 03782 ENDRECV_HWNDOPT_SHARED(); 03783 } 03784 03785 BOOL NtUserGetMenuBarInfo( 03786 IN HWND hwnd, 03787 IN long idObject, 03788 IN long idItem, 03789 IN OUT PMENUBARINFO pmbi) 03790 { 03791 MENUBARINFO mbi; 03792 03793 BEGINRECV_HWNDLOCK(BOOL, FALSE, hwnd); 03794 03795 /* 03796 * Probe arguments 03797 */ 03798 try { 03799 #if defined(_X86_) 03800 ProbeForWrite(pmbi, sizeof(*pmbi), sizeof(BYTE)); 03801 #else 03802 ProbeForWrite(pmbi, sizeof(*pmbi), sizeof(DWORD)); 03803 #endif 03804 mbi.cbSize = pmbi->cbSize; 03805 } except (StubExceptionHandler(TRUE)) { 03806 MSGERROR(0); 03807 } 03808 03809 /* 03810 * Get the menubar info 03811 */ 03812 retval = xxxGetMenuBarInfo(pwnd, idObject, idItem, &mbi); 03813 03814 if (retval) { 03815 try { 03816 *pmbi = mbi; 03817 } except (StubExceptionHandler(TRUE)) { 03818 MSGERROR(0); 03819 } 03820 } 03821 03822 TRACE("NtUserGetMenuBarInfo"); 03823 ENDRECV_HWNDLOCK(); 03824 } 03825 03826 BOOL NtUserSetInternalWindowPos( // private SetInternalWindowPos 03827 IN HWND hwnd, 03828 IN UINT cmdShow, 03829 IN CONST RECT *lpRect, 03830 IN CONST POINT *lpPoint) 03831 { 03832 RECT rc; 03833 POINT pt; 03834 03835 // 03836 // N.B. This function has implicit window translation and thread locking 03837 // enabled. These operations are performed in the User server API 03838 // dispatcher. 03839 // 03840 03841 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 03842 03843 /* 03844 * Probe arguments 03845 */ 03846 try { 03847 rc = ProbeAndReadRect(lpRect); 03848 pt = ProbeAndReadPoint(lpPoint); 03849 } except (StubExceptionHandler(FALSE)) { 03850 MSGERROR(0); 03851 } 03852 03853 retval = xxxSetInternalWindowPos( 03854 pwnd, 03855 cmdShow, 03856 &rc, 03857 &pt); 03858 03859 TRACE("NtUserSetInternalWindowPos"); 03860 ENDRECV_HWNDLOCK(); 03861 } 03862 03863 03864 BOOL NtUserChangeClipboardChain( 03865 IN HWND hwndRemove, 03866 IN HWND hwndNewNext) 03867 { 03868 03869 // 03870 // N.B. This function has implicit window translation and thread locking 03871 // enabled. These operations are performed in the User server API 03872 // dispatcher. 03873 // 03874 03875 PWND pwndNewNext; 03876 TL tlpwndNewNext; 03877 03878 BEGINRECV_HWNDLOCK(DWORD, 0, hwndRemove); 03879 03880 ValidateHWNDOPT(pwndNewNext, hwndNewNext); 03881 03882 ThreadLockWithPti(ptiCurrent, pwndNewNext, &tlpwndNewNext); 03883 retval = xxxChangeClipboardChain( 03884 pwnd, 03885 pwndNewNext); 03886 03887 ThreadUnlock(&tlpwndNewNext); 03888 03889 TRACE("NtUserChangeClipboardChain"); 03890 ENDRECV_HWNDLOCK(); 03891 } 03892 03893 DWORD NtUserCheckMenuItem( 03894 IN HMENU hmenu, 03895 IN UINT wIDCheckItem, 03896 IN UINT wCheck) 03897 { 03898 PMENU pmenu; 03899 03900 BEGINATOMICRECV(DWORD, (DWORD)-1); 03901 03902 TESTFLAGS(wCheck, MF_VALID); 03903 03904 ValidateHMENUMODIFY(pmenu, hmenu); 03905 03906 retval = _CheckMenuItem( 03907 pmenu, 03908 wIDCheckItem, 03909 wCheck); 03910 03911 TRACE("NtUserCheckMenuItem"); 03912 ENDATOMICRECV(); 03913 } 03914 03915 HWND NtUserChildWindowFromPointEx( 03916 IN HWND hwndParent, 03917 IN POINT point, 03918 IN UINT flags) 03919 { 03920 03921 // 03922 // N.B. This function has implicit window handle translation. This 03923 // operation is performed in the User server API dispatcher. 03924 // 03925 03926 BEGINRECV_HWND(HWND, NULL, hwndParent); 03927 03928 retval = (HWND)_ChildWindowFromPointEx(pwnd, point, flags); 03929 retval = PtoH((PVOID)retval); 03930 03931 TRACE("NtUserChildWindowFromPointEx"); 03932 ENDRECV_HWND(); 03933 } 03934 03935 BOOL NtUserClipCursor( // API ClipCursor 03936 IN CONST RECT *lpRect OPTIONAL) 03937 { 03938 RECT rc; 03939 03940 BEGINRECV(BOOL, FALSE); 03941 03942 /* 03943 * Probe arguments 03944 */ 03945 if (ARGUMENT_PRESENT(lpRect)) { 03946 try { 03947 rc = ProbeAndReadRect(lpRect); 03948 lpRect = &rc; 03949 } except (StubExceptionHandler(TRUE)) { 03950 MSGERROR(0); 03951 } 03952 } 03953 03954 retval = zzzClipCursor(lpRect); 03955 03956 TRACE("NtUserClipCursor"); 03957 ENDRECV(); 03958 } 03959 03960 HACCEL NtUserCreateAcceleratorTable( // API CreateAcceleratorTableA/W 03961 IN LPACCEL paccel, 03962 IN INT cAccel) 03963 { 03964 BEGINRECV(HACCEL, NULL); 03965 03966 if (cAccel <= 0) { 03967 MSGERROR(0); 03968 } 03969 03970 /* 03971 * Probe arguments 03972 */ 03973 try { 03974 ProbeForReadBuffer(paccel, cAccel, DATAALIGN); 03975 } except (StubExceptionHandler(TRUE)) { 03976 MSGERROR(0); 03977 } 03978 03979 retval = (HACCEL)_CreateAcceleratorTable( 03980 paccel, 03981 cAccel * sizeof(ACCEL)); 03982 retval = PtoH((PVOID)retval); 03983 03984 TRACE("NtUserCreateAcceleratorTable"); 03985 ENDRECV(); 03986 } 03987 03988 BOOL NtUserDeleteMenu( 03989 IN HMENU hmenu, 03990 IN UINT nPosition, 03991 IN UINT dwFlags) 03992 { 03993 PMENU pmenu; 03994 TL tlpmenu; 03995 03996 BEGINRECV(BOOL, FALSE); 03997 03998 TESTFLAGS(dwFlags, MF_VALID); 03999 04000 ValidateHMENUMODIFY(pmenu, hmenu); 04001 ThreadLock(pmenu, &tlpmenu); 04002 retval = xxxDeleteMenu( 04003 pmenu, 04004 nPosition, 04005 dwFlags); 04006 ThreadUnlock(&tlpmenu); 04007 04008 TRACE("NtUserDeleteMenu"); 04009 ENDRECV(); 04010 } 04011 04012 BOOL NtUserDestroyAcceleratorTable( 04013 IN HACCEL hAccel) 04014 { 04015 LPACCELTABLE pat; 04016 04017 BEGINRECV(BOOL, FALSE); 04018 04019 ValidateHACCEL(pat, hAccel); 04020 04021 /* 04022 * Mark the object for destruction - if it says it's ok to free, 04023 * then free it. 04024 */ 04025 if (HMMarkObjectDestroy(pat)) 04026 HMFreeObject(pat); 04027 retval = TRUE; 04028 04029 TRACE("NtUserDestroyAcceleratorTable"); 04030 ENDRECV(); 04031 } 04032 04033 BOOL NtUserDestroyCursor( 04034 IN HCURSOR hcurs, 04035 IN DWORD cmd) 04036 { 04037 PCURSOR pcurs; 04038 04039 BEGINATOMICRECV(BOOL, FALSE); 04040 04041 ValidateHCURSOR(pcurs, hcurs); 04042 04043 retval = _DestroyCursor( 04044 pcurs, cmd); 04045 04046 TRACE("NtUserDestroyCursor"); 04047 ENDATOMICRECV(); 04048 } 04049 04050 HANDLE NtUserGetClipboardData( // API GetClipboardData 04051 IN UINT fmt, 04052 OUT PGETCLIPBDATA pgcd) 04053 { 04054 PTHREADINFO ptiCurrent; 04055 TL tlpwinsta; 04056 PWINDOWSTATION pwinsta; 04057 GETCLIPBDATA gcd; 04058 04059 BEGINRECV(HANDLE, NULL); 04060 04061 ptiCurrent = PtiCurrent(); 04062 if ((pwinsta = CheckClipboardAccess()) == NULL) 04063 MSGERROR(0); 04064 04065 /* 04066 * Check for jobs with JOB_OBJECT_UILIMIT_READCLIPBOARD 04067 */ 04068 if (IS_THREAD_RESTRICTED(ptiCurrent, JOB_OBJECT_UILIMIT_READCLIPBOARD)) { 04069 RIPERR0(ERROR_ACCESS_DENIED, RIP_WARNING, "NtUserGetClipboardData failed for restricted thread"); 04070 MSGERROR(0); 04071 } 04072 04073 ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta); 04074 04075 /* 04076 * Start out assuming the format requested 04077 * will be the format returned. 04078 */ 04079 gcd.uFmtRet = fmt; 04080 04081 retval = xxxGetClipboardData(pwinsta, fmt, &gcd); 04082 04083 /* 04084 * Probe arguments 04085 */ 04086 try { 04087 ProbeAndWriteStructure(pgcd, gcd, GETCLIPBDATA); 04088 } except (StubExceptionHandler(TRUE)) { 04089 MSGERRORCLEANUP(0); 04090 } 04091 04092 CLEANUPRECV(); 04093 ThreadUnlockWinSta(ptiCurrent, &tlpwinsta); 04094 04095 TRACE("NtUserGetClipboardData"); 04096 ENDRECV(); 04097 04098 } 04099 04100 BOOL NtUserDestroyMenu( 04101 IN HMENU hmenu) 04102 { 04103 PMENU pmenu; 04104 04105 BEGINATOMICRECV(BOOL, FALSE); 04106 04107 ValidateHMENUMODIFY(pmenu, hmenu); 04108 04109 retval = _DestroyMenu(pmenu); 04110 04111 TRACE("NtUserDestroyMenu"); 04112 ENDATOMICRECV(); 04113 } 04114 04115 BOOL NtUserDestroyWindow( 04116 IN HWND hwnd) 04117 { 04118 04119 // 04120 // N.B. This function has implicit window handle translation. This 04121 // operation is performed in the User server API dispatcher. 04122 // 04123 04124 BEGINRECV_HWND(DWORD, 0, hwnd); 04125 04126 retval = xxxDestroyWindow(pwnd); 04127 04128 TRACE("NtUserDestroyWindow"); 04129 ENDRECV_HWND(); 04130 } 04131 04132 LRESULT NtUserDispatchMessage( // API DispatchMessageA/W 04133 IN CONST MSG *pmsg) 04134 { 04135 MSG msg; 04136 04137 BEGINRECV(LRESULT, 0); 04138 04139 /* 04140 * Probe arguments 04141 */ 04142 try { 04143 msg = ProbeAndReadMessage(pmsg); 04144 } except (StubExceptionHandler(TRUE)) { 04145 MSGERROR(0); 04146 } 04147 04148 retval = xxxDispatchMessage(&msg); 04149 04150 TRACE("NtUserDispatchMessage"); 04151 ENDRECV(); 04152 } 04153 04154 BOOL NtUserEnableMenuItem( 04155 IN HMENU hMenu, 04156 IN UINT wIDEnableItem, 04157 IN UINT wEnable) 04158 { 04159 PMENU pmenu; 04160 TL tlmenu; 04161 04162 BEGINRECV(BOOL, -1); 04163 04164 TESTFLAGS(wEnable, MF_VALID); 04165 04166 ValidateHMENUMODIFY(pmenu, hMenu); 04167 04168 ThreadLockAlways(pmenu, &tlmenu); 04169 retval = xxxEnableMenuItem( 04170 pmenu, 04171 wIDEnableItem, 04172 wEnable); 04173 ThreadUnlock(&tlmenu); 04174 04175 TRACE("NtUserEnableMenuItem"); 04176 ENDRECV(); 04177 } 04178 04179 BOOL NtUserAttachThreadInput( 04180 IN DWORD idAttach, 04181 IN DWORD idAttachTo, 04182 IN BOOL fAttach) 04183 { 04184 PTHREADINFO ptiAttach; 04185 PTHREADINFO ptiAttachTo; 04186 04187 BEGINRECV(BOOL, FALSE); 04188 04189 /* 04190 * Always must attach or detach from a real thread id. 04191 */ 04192 if ((ptiAttach = PtiFromThreadId(idAttach)) == NULL) { 04193 MSGERROR(0); 04194 } 04195 if ((ptiAttachTo = PtiFromThreadId(idAttachTo)) == NULL) { 04196 MSGERROR(0); 04197 } 04198 04199 retval = zzzAttachThreadInput( 04200 ptiAttach, 04201 ptiAttachTo, 04202 fAttach); 04203 04204 TRACE("NtUserAttachThreadInput"); 04205 ENDRECV(); 04206 } 04207 04208 BOOL NtUserGetWindowPlacement( // API GetWindowPlacement 04209 IN HWND hwnd, 04210 OUT PWINDOWPLACEMENT pwp) 04211 { 04212 04213 // 04214 // N.B. This function has implicit window handle translation. This 04215 // operation is performed in the User server API dispatcher. 04216 // 04217 04218 /* 04219 * Note -- this routine updates the checkpoint, so it needs exclusive 04220 * use of the crit sect. 04221 */ 04222 04223 WINDOWPLACEMENT wp; 04224 BEGINRECV_HWND(DWORD, 0, hwnd); 04225 04226 /* 04227 * Probe arguments 04228 */ 04229 try { 04230 ProbeForWriteWindowPlacement(pwp); 04231 wp.length = pwp->length; 04232 #ifdef LATER 04233 if (pwp->length != sizeof(WINDOWPLACEMENT)) { 04234 if (TestWF(pwnd, WFWIN40COMPAT)) { 04235 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "GetWindowPlacement: invalid length %lX", pwp->length); 04236 MSGERROR(0); 04237 } else { 04238 RIPMSG1(RIP_WARNING, "GetWindowPlacement: invalid length %lX", pwp->length); 04239 pwp->length = sizeof(WINDOWPLACEMENT); 04240 } 04241 } 04242 #endif 04243 04244 } except (StubExceptionHandler(TRUE)) { 04245 MSGERROR(0); 04246 } 04247 04248 retval = _GetWindowPlacement(pwnd, &wp); 04249 04250 try { 04251 RtlCopyMemory(pwp, &wp, sizeof (WINDOWPLACEMENT)); 04252 } except (StubExceptionHandler(TRUE)) { 04253 MSGERROR(0); 04254 } 04255 04256 TRACE("NtUserGetWindowPlacement"); 04257 ENDRECV_HWND(); 04258 } 04259 04260 BOOL NtUserSetWindowPlacement( // API SetWindowPlacement 04261 IN HWND hwnd, 04262 IN CONST WINDOWPLACEMENT *pwp) 04263 { 04264 WINDOWPLACEMENT wp; 04265 04266 // 04267 // N.B. This function has implicit window translation and thread locking 04268 // enabled. These operations are performed in the User server API 04269 // dispatcher. 04270 // 04271 04272 BEGINRECV_HWNDLOCK_ND(BOOL, FALSE, hwnd); 04273 04274 /* 04275 * Probe arguments 04276 */ 04277 try { 04278 wp = ProbeAndReadWindowPlacement(pwp); 04279 } except (StubExceptionHandler(TRUE)) { 04280 MSGERROR(0); 04281 } 04282 04283 if (wp.length != sizeof(WINDOWPLACEMENT)) { 04284 if (Is400Compat(ptiCurrent->dwExpWinVer)) { 04285 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "SetWindowPlacement: invalid length %lX", pwp->length); 04286 MSGERROR(0); 04287 } else { 04288 RIPMSG1(RIP_WARNING, "SetWindowPlacement: invalid length %lX", pwp->length); 04289 } 04290 } 04291 04292 retval = xxxSetWindowPlacement(pwndND, &wp); 04293 04294 TRACE("NtUserSetWindowPlacement"); 04295 ENDRECV_HWNDLOCK_ND(); 04296 } 04297 04298 BOOL NtUserLockWindowUpdate( // API LockWindowUpdate 04299 IN HWND hwnd) 04300 { 04301 PWND pwnd; 04302 04303 BEGINATOMICRECV(BOOL, FALSE); 04304 04305 ValidateHWNDOPT(pwnd, hwnd); 04306 04307 retval = LockWindowUpdate2(pwnd, FALSE); 04308 04309 TRACE("NtUserLockWindowUpdate"); 04310 ENDATOMICRECV(); 04311 } 04312 04313 BOOL NtUserGetClipCursor( // API GetClipCursor 04314 OUT LPRECT lpRect) 04315 { 04316 /* 04317 * Check if the caller has the proper access rights: if not, this will 04318 * SetLastError to ERROR_ACCESS_DENIED and return FALSE. Do this *before* 04319 * BEGINRECV_SHARED, else we must use MSGERROR to release the critsect! 04320 */ 04321 RETURN_IF_ACCESS_DENIED(PpiCurrent()->amwinsta, 04322 WINSTA_READATTRIBUTES, 04323 FALSE); 04324 { 04325 BEGINRECV_SHARED(BOOL, FALSE); 04326 04327 /* 04328 * Probe arguments 04329 */ 04330 try { 04331 ProbeForWriteRect(lpRect); 04332 04333 *lpRect = grcCursorClip; 04334 retval = TRUE; 04335 } except (StubExceptionHandler(TRUE)) { 04336 MSGERROR(0); 04337 } 04338 04339 TRACE("NtUserGetClipCursor"); 04340 ENDRECV_SHARED(); 04341 } 04342 } 04343 04344 BOOL NtUserEnableScrollBar( 04345 IN HWND hwnd, 04346 IN UINT wSBflags, 04347 IN UINT wArrows) 04348 { 04349 04350 // 04351 // N.B. This function has implicit window translation and thread locking 04352 // enabled. These operations are performed in the User server API 04353 // dispatcher. 04354 // 04355 04356 BEGINRECV_HWNDLOCK_ND(BOOL, FALSE, hwnd); 04357 04358 LIMITVALUE(wSBflags, SB_MAX, "EnableScrollBar"); 04359 04360 retval = xxxEnableScrollBar( 04361 pwndND, 04362 wSBflags, 04363 wArrows); 04364 04365 TRACE("NtUserEnableScrollBar"); 04366 ENDRECV_HWNDLOCK_ND(); 04367 } 04368 04369 BOOL NtUserDdeSetQualityOfService( // API DdeSetQualityOfService 04370 IN HWND hwndClient, 04371 IN CONST SECURITY_QUALITY_OF_SERVICE *pqosNew, 04372 OUT PSECURITY_QUALITY_OF_SERVICE pqosPrev OPTIONAL) 04373 { 04374 SECURITY_QUALITY_OF_SERVICE qosNew, qosPrev; 04375 04376 // 04377 // N.B. This function has implicit window handle translation. This 04378 // operation is performed in the User server API dispatcher. 04379 // 04380 04381 BEGINRECV_HWND(BOOL, FALSE, hwndClient); 04382 04383 if (GETPTI(pwnd) != PtiCurrent()) { 04384 MSGERROR(0); 04385 } 04386 04387 /* 04388 * Probe arguments 04389 */ 04390 try { 04391 qosNew = ProbeAndReadStructure(pqosNew, SECURITY_QUALITY_OF_SERVICE); 04392 if (ARGUMENT_PRESENT(pqosPrev)) 04393 ProbeForWrite(pqosPrev, sizeof(*pqosPrev), sizeof(DWORD)); 04394 04395 } except (StubExceptionHandler(TRUE)) { 04396 MSGERROR(0); 04397 } 04398 04399 retval = _DdeSetQualityOfService( 04400 pwnd, 04401 &qosNew, 04402 &qosPrev); 04403 04404 try { 04405 if (ARGUMENT_PRESENT(pqosPrev)) 04406 *pqosPrev = qosPrev; 04407 } except (StubExceptionHandler(TRUE)) { 04408 MSGERROR(0); 04409 } 04410 04411 TRACE("NtUserDdeSetQualityOfService"); 04412 ENDRECV_HWND(); 04413 } 04414 04415 BOOL NtUserDdeGetQualityOfService( // private DdeGetQualityOfService 04416 IN HWND hwndClient, 04417 IN HWND hwndServer, 04418 OUT PSECURITY_QUALITY_OF_SERVICE pqos) 04419 { 04420 04421 // 04422 // N.B. This function has implicit window handle translation. This 04423 // operation is performed in the User server API dispatcher. 04424 // 04425 04426 PWND pwndServer; 04427 PTHREADINFO ptiCurrent; 04428 SECURITY_QUALITY_OF_SERVICE qos; 04429 04430 BEGINATOMICRECV_HWND(BOOL, FALSE, hwndClient); 04431 04432 ValidateHWNDOPT(pwndServer, hwndServer); 04433 ptiCurrent = PtiCurrent(); 04434 if (GETPTI(pwnd) != ptiCurrent && pwndServer != NULL && 04435 GETPTI(pwndServer) != ptiCurrent) { 04436 MSGERROR(0); 04437 } 04438 04439 /* 04440 * Probe arguments 04441 */ 04442 try { 04443 ProbeForWrite(pqos, sizeof(*pqos), DATAALIGN); 04444 04445 } except (StubExceptionHandler(FALSE)) { 04446 MSGERROR(0); 04447 } 04448 retval = _DdeGetQualityOfService( 04449 pwnd, 04450 pwndServer, 04451 &qos); 04452 try { 04453 RtlCopyMemory(pqos, &qos, sizeof (SECURITY_QUALITY_OF_SERVICE)); 04454 } except (StubExceptionHandler(FALSE)) { 04455 MSGERROR(0); 04456 } 04457 04458 TRACE("NtUserDdeGetQualityOfService"); 04459 ENDATOMICRECV_HWND(); 04460 } 04461 04462 DWORD NtUserGetMenuIndex( 04463 IN HMENU hMenu, 04464 IN HMENU hSubMenu) 04465 { 04466 04467 PMENU pmenu; 04468 PMENU psubmenu; 04469 DWORD idx; 04470 04471 BEGINRECV_SHARED(DWORD, 0); 04472 04473 ValidateHMENU(pmenu, hMenu); 04474 ValidateHMENU(psubmenu, hSubMenu); 04475 04476 retval = (DWORD)-1; 04477 04478 if (pmenu && psubmenu) { 04479 for (idx=0; idx<pmenu->cItems; idx++) 04480 if ((pmenu->rgItems[idx].spSubMenu == psubmenu)) { 04481 retval = idx; 04482 break; 04483 } 04484 } 04485 04486 TRACE("NtUserGetMenuIndex"); 04487 ENDRECV_SHARED(); 04488 } 04489 04490 VOID NtUserSetRipFlags(DWORD dwRipFlags, DWORD dwPID) 04491 { 04492 BEGINRECV_VOID(); 04493 04494 _SetRipFlags(dwRipFlags, dwPID); 04495 04496 TRACEVOID("NtUserSetRipFlags"); 04497 ENDRECV_VOID(); 04498 } 04499 04500 VOID NtUserSetDbgTag(int tag, DWORD dwBitFlags) 04501 { 04502 BEGINRECV_VOID(); 04503 04504 _SetDbgTag(tag, dwBitFlags); 04505 04506 TRACEVOID("NtUserSetRipFlags"); 04507 ENDRECV_VOID(); 04508 } 04509 04510 ULONG_PTR NtUserCallNoParam( 04511 IN DWORD xpfnProc) 04512 { 04513 BEGINRECV(ULONG_PTR, 0); 04514 04515 VALIDATEXPFNPROC(NOPARAM); 04516 04517 retval = (apfnSimpleCall[xpfnProc]()); 04518 if (ISXPFNPROCINRANGE(NOPARAMANDRETURNHANDLE)) { 04519 retval = (ULONG_PTR)PtoH((PVOID)retval); 04520 } 04521 04522 TRACE(apszSimpleCallNames[xpfnProc]); 04523 ENDRECV(); 04524 } 04525 04526 ULONG_PTR NtUserCallOneParam( 04527 IN ULONG_PTR dwParam, 04528 IN DWORD xpfnProc) 04529 { 04530 BEGINRECV(ULONG_PTR, 0); 04531 04532 VALIDATEXPFNPROC(ONEPARAM); 04533 04534 retval = (apfnSimpleCall[xpfnProc](dwParam)); 04535 if (ISXPFNPROCINRANGE(ONEPARAMANDRETURNHANDLE)) { 04536 retval = (ULONG_PTR)PtoH((PVOID)retval); 04537 } 04538 04539 TRACE(apszSimpleCallNames[xpfnProc]); 04540 ENDRECV(); 04541 } 04542 04543 ULONG_PTR NtUserCallHwnd( 04544 IN HWND hwnd, 04545 IN DWORD xpfnProc) 04546 { 04547 04548 // 04549 // N.B. This function has implicit window handle translation. This 04550 // operation is performed in the User server API dispatcher. 04551 // 04552 04553 BEGINRECV_HWNDLOCK(ULONG_PTR, 0, hwnd); 04554 04555 VALIDATEXPFNPROC(HWND); 04556 04557 retval = (apfnSimpleCall[xpfnProc](pwnd)); 04558 04559 TRACE(apszSimpleCallNames[xpfnProc]); 04560 ENDRECV_HWNDLOCK(); 04561 } 04562 04563 ULONG_PTR NtUserCallHwndLock( 04564 IN HWND hwnd, 04565 IN DWORD xpfnProc) 04566 { 04567 04568 // 04569 // N.B. This function has implicit window translation and thread locking 04570 // enabled. These operations are performed in the User server API 04571 // dispatcher. 04572 // 04573 04574 BEGINRECV_HWNDLOCK(ULONG_PTR, 0, hwnd); 04575 04576 VALIDATEXPFNPROC(HWNDLOCK); 04577 04578 retval = (apfnSimpleCall[xpfnProc](pwnd)); 04579 04580 TRACE(apszSimpleCallNames[xpfnProc]); 04581 ENDRECV_HWNDLOCK(); 04582 } 04583 04584 ULONG_PTR NtUserCallHwndOpt( 04585 IN HWND hwnd, 04586 IN DWORD xpfnProc) 04587 { 04588 PWND pwnd; 04589 04590 BEGINATOMICRECV(ULONG_PTR, 0); 04591 04592 ValidateHWNDOPT(pwnd, hwnd); 04593 04594 VALIDATEXPFNPROC(HWNDOPT); 04595 04596 retval = (apfnSimpleCall[xpfnProc](pwnd)); 04597 04598 TRACE(apszSimpleCallNames[xpfnProc]); 04599 ENDATOMICRECV(); 04600 } 04601 04602 ULONG_PTR NtUserCallHwndParam( 04603 IN HWND hwnd, 04604 IN ULONG_PTR dwParam, 04605 IN DWORD xpfnProc) 04606 { 04607 04608 // 04609 // N.B. This function has implicit window handle translation. This 04610 // operation is performed in the User server API dispatcher. 04611 // 04612 04613 BEGINRECV_HWNDLOCK(ULONG_PTR, 0, hwnd); 04614 04615 VALIDATEXPFNPROC(HWNDPARAM); 04616 04617 retval = (apfnSimpleCall[xpfnProc](pwnd, dwParam)); 04618 if (ISXPFNPROCINRANGE(HWNDPARAMANDRETURNHANDLE)) { 04619 retval = (ULONG_PTR)PtoH((PVOID)retval); 04620 } 04621 04622 TRACE(apszSimpleCallNames[xpfnProc]); 04623 ENDRECV_HWNDLOCK(); 04624 } 04625 04626 ULONG_PTR NtUserCallHwndParamLock( 04627 IN HWND hwnd, 04628 IN ULONG_PTR dwParam, 04629 IN DWORD xpfnProc) 04630 { 04631 04632 // 04633 // N.B. This function has implicit window translation and thread locking 04634 // enabled. These operations are performed in the User server API 04635 // dispatcher. 04636 // 04637 04638 BEGINRECV_HWNDLOCK(ULONG_PTR, 0, hwnd); 04639 04640 VALIDATEXPFNPROC(HWNDPARAMLOCK); 04641 04642 retval = (apfnSimpleCall[xpfnProc](pwnd, dwParam)); 04643 04644 TRACE(apszSimpleCallNames[xpfnProc]); 04645 ENDRECV_HWNDLOCK(); 04646 } 04647 04648 ULONG_PTR NtUserCallTwoParam( 04649 ULONG_PTR dwParam1, 04650 ULONG_PTR dwParam2, 04651 IN DWORD xpfnProc) 04652 { 04653 BEGINRECV(ULONG_PTR, 0); 04654 04655 VALIDATEXPFNPROC(TWOPARAM); 04656 04657 retval = (apfnSimpleCall[xpfnProc](dwParam1, dwParam2)); 04658 04659 TRACE(apszSimpleCallNames[xpfnProc]); 04660 ENDRECV(); 04661 } 04662 04663 BOOL NtUserThunkedMenuItemInfo( // worker for various menu APIs 04664 IN HMENU hMenu, 04665 IN UINT nPosition, 04666 IN BOOL fByPosition, 04667 IN BOOL fInsert, 04668 IN LPMENUITEMINFOW lpmii, 04669 IN PUNICODE_STRING pstrItem OPTIONAL) 04670 { 04671 PMENU pmenu; 04672 MENUITEMINFO mii; 04673 UNICODE_STRING strItem; 04674 TL tlpmenu; 04675 04676 BEGINRECV(BOOL, FALSE); 04677 04678 /* 04679 * Probe arguments 04680 * No need to SetLastError because lpmii always the address of 04681 * local stack structure in USER code, not an application address. 04682 */ 04683 try { 04684 mii = ProbeAndReadMenuItem(lpmii); 04685 04686 if (ARGUMENT_PRESENT(pstrItem)) { 04687 strItem = ProbeAndReadUnicodeString(pstrItem); 04688 ProbeForReadUnicodeStringBuffer(strItem); 04689 } else { 04690 RtlInitUnicodeString(&strItem, NULL); 04691 } 04692 } except (StubExceptionHandler(FALSE)) { 04693 MSGERROR(0); 04694 } 04695 04696 ValidateHMENUMODIFY(pmenu, hMenu); 04697 04698 ThreadLock(pmenu, &tlpmenu); 04699 /* 04700 * These routines only use the buffer in a try/except (actually in 04701 * xxxSetLPITEMInfo). 04702 */ 04703 if (fInsert) { 04704 retval = xxxInsertMenuItem( 04705 pmenu, 04706 nPosition, 04707 fByPosition, 04708 &mii, 04709 &strItem); 04710 } else { 04711 retval = xxxSetMenuItemInfo( 04712 pmenu, 04713 nPosition, 04714 fByPosition, 04715 &mii, 04716 &strItem); 04717 } 04718 ThreadUnlock(&tlpmenu); 04719 04720 TRACE("NtUserThunkedMenuItemInfo"); 04721 ENDRECV(); 04722 } 04723 04724 /***************************************************************************\ 04725 * NtUserThunkedMenuInfo 04726 * 04727 * History: 04728 * 07-23-96 GerardoB - Added header & fixed up for 5.0 04729 \***************************************************************************/ 04730 BOOL NtUserThunkedMenuInfo( // API SetMenuInfo 04731 IN HMENU hMenu, 04732 IN LPCMENUINFO lpmi) 04733 { 04734 PMENU pmenu; 04735 MENUINFO mi; 04736 TL tlpmenu; 04737 04738 BEGINRECV(BOOL, FALSE); 04739 04740 /* 04741 * Probe arguments 04742 */ 04743 try { 04744 mi = ProbeAndReadMenuInfo(lpmi); 04745 } except (StubExceptionHandler(TRUE)) { 04746 MSGERROR(0); 04747 } 04748 04749 ValidateHMENUMODIFY(pmenu, hMenu); 04750 04751 ThreadLock(pmenu, &tlpmenu); 04752 retval = xxxSetMenuInfo(pmenu, &mi); 04753 ThreadUnlock(&tlpmenu); 04754 04755 TRACE("NtUserThunkedMenuInfo"); 04756 ENDRECV(); 04757 } 04758 04759 BOOL NtUserSetMenuDefaultItem( 04760 IN HMENU hMenu, 04761 IN UINT wID, 04762 IN UINT fByPosition) 04763 { 04764 PMENU pmenu; 04765 04766 BEGINATOMICRECV(BOOL, FALSE); 04767 04768 ValidateHMENUMODIFY(pmenu, hMenu); 04769 04770 retval = _SetMenuDefaultItem( 04771 pmenu, 04772 wID, 04773 fByPosition); 04774 04775 TRACE("NtUserSetMenuDefaultItem"); 04776 ENDATOMICRECV(); 04777 } 04778 04779 BOOL NtUserSetMenuContextHelpId( 04780 IN HMENU hMenu, 04781 IN DWORD dwContextHelpId) 04782 { 04783 PMENU pmenu; 04784 04785 BEGINATOMICRECV(BOOL, FALSE); 04786 04787 ValidateHMENUMODIFY(pmenu, hMenu); 04788 04789 retval = _SetMenuContextHelpId( 04790 pmenu, 04791 dwContextHelpId); 04792 04793 TRACE("NtUserSetMenuContextHelpId"); 04794 ENDATOMICRECV(); 04795 } 04796 04797 BOOL NtUserSetMenuFlagRtoL( 04798 IN HMENU hMenu) 04799 { 04800 PMENU pmenu; 04801 04802 BEGINATOMICRECV(BOOL, FALSE); 04803 04804 ValidateHMENU(pmenu, hMenu); 04805 04806 retval = _SetMenuFlagRtoL(pmenu); 04807 04808 TRACE("NtUserSetMenuFlagRtoL"); 04809 ENDATOMICRECV(); 04810 } 04811 04812 BOOL NtUserDrawAnimatedRects( // API DrawAnimatedRects 04813 IN HWND hwnd, 04814 IN int idAni, 04815 IN CONST RECT *lprcFrom, 04816 IN CONST RECT *lprcTo) 04817 { 04818 PWND pwnd; 04819 TL tlpwnd; 04820 RECT rcFrom; 04821 RECT rcTo; 04822 04823 BEGINRECV(BOOL, FALSE); 04824 04825 ValidateHWNDOPT(pwnd, hwnd); 04826 04827 /* 04828 * Probe arguments 04829 */ 04830 try { 04831 rcFrom = ProbeAndReadRect(lprcFrom); 04832 rcTo = ProbeAndReadRect(lprcTo); 04833 } except (StubExceptionHandler(TRUE)) { 04834 MSGERROR(0); 04835 } 04836 04837 ThreadLock(pwnd, &tlpwnd); 04838 04839 retval = xxxDrawAnimatedRects( 04840 pwnd, 04841 idAni, 04842 &rcFrom, 04843 &rcTo 04844 ); 04845 04846 ThreadUnlock(&tlpwnd); 04847 04848 TRACE("NtUserDrawAnimatedRects"); 04849 ENDRECV(); 04850 } 04851 04852 BOOL NtUserDrawCaption( // API DrawCaption 04853 IN HWND hwnd, 04854 IN HDC hdc, 04855 IN CONST RECT *lprc, 04856 IN UINT flags) 04857 { 04858 RECT rc; 04859 04860 // 04861 // N.B. This function has implicit window translation and thread locking 04862 // enabled. These operations are performed in the User server API 04863 // dispatcher. 04864 // 04865 04866 BEGINRECV_HWNDLOCK(DWORD, FALSE, hwnd); 04867 04868 /* 04869 * Probe arguments 04870 */ 04871 try { 04872 rc = ProbeAndReadRect(lprc); 04873 } except (StubExceptionHandler(TRUE)) { 04874 MSGERROR(0); 04875 } 04876 04877 retval = xxxDrawCaptionTemp(pwnd, hdc, &rc, NULL, NULL, NULL, flags); 04878 04879 TRACE("NtUserDrawCaption"); 04880 ENDRECV_HWNDLOCK(); 04881 } 04882 04883 BOOL NtUserPaintDesktop( 04884 IN HDC hdc) 04885 { 04886 PTHREADINFO ptiCurrent; 04887 PWND pwndDesk; 04888 TL tlpwndDesk; 04889 04890 BEGINRECV(BOOL, FALSE); 04891 04892 ptiCurrent = PtiCurrent(); 04893 04894 if (ptiCurrent->rpdesk != NULL) { 04895 pwndDesk = ptiCurrent->rpdesk->pDeskInfo->spwnd; 04896 ThreadLockWithPti(ptiCurrent, pwndDesk, &tlpwndDesk); 04897 retval = xxxInternalPaintDesktop(pwndDesk, hdc, TRUE); 04898 ThreadUnlock(&tlpwndDesk); 04899 } else { 04900 MSGERROR(0); 04901 } 04902 04903 TRACE("NtUserPaintDesktop"); 04904 ENDRECV(); 04905 } 04906 04907 SHORT NtUserGetAsyncKeyState( 04908 IN int vKey) 04909 { 04910 04911 PTHREADINFO ptiCurrent; 04912 BEGINRECV_SHARED(SHORT, 0); 04913 04914 04915 ptiCurrent = PtiCurrentShared(); 04916 UserAssert(ptiCurrent); 04917 04918 /* 04919 * Don't allow other processes to spy on other deskops or a process 04920 * to spy on the foreground if the desktop does not allow input spying 04921 */ 04922 if ((ptiCurrent->rpdesk != grpdeskRitInput) || 04923 ( ((gptiForeground == NULL) || (PpiCurrent() != gptiForeground->ppi)) && 04924 !RtlAreAnyAccessesGranted(ptiCurrent->amdesk, (DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD)))) { 04925 RIPERR0(ERROR_ACCESS_DENIED, RIP_WARNING, "GetAysncKeyState: not" 04926 " foreground desktop or no desktop hooking (input spying)"); 04927 MSGERROR(0); 04928 } 04929 UserAssert(!(ptiCurrent->rpdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO)); 04930 04931 retval = _GetAsyncKeyState(vKey); 04932 04933 /* 04934 * Update the client side key state cache. 04935 */ 04936 ptiCurrent->pClientInfo->dwAsyncKeyCache = gpsi->dwAsyncKeyCache; 04937 RtlCopyMemory(ptiCurrent->pClientInfo->afAsyncKeyState, 04938 gafAsyncKeyState, 04939 CBASYNCKEYCACHE); 04940 RtlCopyMemory(ptiCurrent->pClientInfo->afAsyncKeyStateRecentDown, 04941 gafAsyncKeyStateRecentDown, 04942 CBASYNCKEYCACHE); 04943 04944 TRACE("NtUserGetAsyncKeyState"); 04945 ENDRECV_SHARED(); 04946 } 04947 04948 HBRUSH NtUserGetControlBrush( 04949 IN HWND hwnd, 04950 IN HDC hdc, 04951 IN UINT msg) 04952 { 04953 04954 // 04955 // N.B. This function has implicit window translation and thread locking 04956 // enabled. These operations are performed in the User server API 04957 // dispatcher. 04958 // 04959 04960 BEGINRECV_HWNDLOCK(HBRUSH, NULL, hwnd); 04961 04962 if (hdc == NULL) 04963 MSGERROR(0); 04964 04965 retval = xxxGetControlBrush( 04966 pwnd, 04967 hdc, 04968 msg); 04969 04970 TRACE("NtUserGetControlBrush"); 04971 ENDRECV_HWNDLOCK(); 04972 } 04973 04974 HBRUSH NtUserGetControlColor( 04975 IN HWND hwndParent, 04976 IN HWND hwndCtl, 04977 IN HDC hdc, 04978 IN UINT msg) 04979 { 04980 04981 // 04982 // N.B. This function has implicit window translation and thread locking 04983 // enabled. These operations are performed in the User server API 04984 // dispatcher. 04985 // 04986 04987 PWND pwndCtl; 04988 TL tlpwndCtl; 04989 04990 BEGINRECV_HWNDLOCK(HBRUSH, NULL, hwndParent); 04991 04992 ValidateHWND(pwndCtl, hwndCtl); 04993 04994 ThreadLockAlwaysWithPti(ptiCurrent, pwndCtl, &tlpwndCtl); 04995 04996 retval = xxxGetControlColor( 04997 pwnd, 04998 pwndCtl, 04999 hdc, 05000 msg); 05001 05002 ThreadUnlock(&tlpwndCtl); 05003 05004 TRACE("NtUserGetControlColor"); 05005 ENDRECV_HWNDLOCK(); 05006 } 05007 05008 BOOL NtUserEndMenu(VOID) 05009 { 05010 PTHREADINFO ptiCurrent; 05011 PWND pwnd; 05012 05013 BEGINRECV(BOOL, FALSE); 05014 05015 ptiCurrent = PtiCurrent(); 05016 05017 /* 05018 * The menu might be in the middle of some callback, so calling xxxEndMenu 05019 * directly might screw things up. So we post it a message to signal it to 05020 * go away at a good moment 05021 */ 05022 if (ptiCurrent->pMenuState != NULL) { 05023 pwnd = GetMenuStateWindow(ptiCurrent->pMenuState); 05024 05025 if (pwnd != NULL) { 05026 _PostMessage(pwnd, MN_ENDMENU, 0, 0); 05027 } else { 05028 /* 05029 * Is this menu messed up? 05030 */ 05031 UserAssert(pwnd != NULL); 05032 ptiCurrent->pMenuState->fInsideMenuLoop = FALSE; 05033 } 05034 } 05035 05036 retval = TRUE; 05037 05038 TRACEVOID("NtUserEndMenu"); 05039 ENDRECV(); 05040 } 05041 05042 int NtUserCountClipboardFormats( 05043 VOID) 05044 { 05045 PWINDOWSTATION pwinsta; 05046 05047 BEGINRECV_SHARED(int, 0); 05048 05049 /* 05050 * Blow it off if the caller doesn't have the proper access rights 05051 */ 05052 if ((pwinsta = CheckClipboardAccess()) == NULL) { 05053 MSGERROR(0); 05054 } 05055 05056 retval = pwinsta->cNumClipFormats; 05057 05058 TRACE("NtUserCountClipboardFormats"); 05059 ENDRECV_SHARED(); 05060 } 05061 05062 DWORD NtUserGetClipboardSequenceNumber( 05063 VOID) 05064 { 05065 PWINDOWSTATION pwinsta; 05066 05067 BEGINRECV_SHARED(DWORD, 0); 05068 05069 /* 05070 * Blow it off if the caller doesn't have the proper access rights 05071 */ 05072 if ((pwinsta = CheckClipboardAccess()) == NULL) { 05073 MSGERROR(0); 05074 } 05075 05076 retval = pwinsta->iClipSequenceNumber; 05077 05078 TRACE("NtUserGetClipboardSequenceNumber"); 05079 ENDRECV_SHARED(); 05080 } 05081 05082 UINT NtUserGetCaretBlinkTime(VOID) 05083 { 05084 BEGINRECV_SHARED(UINT, 0); 05085 05086 /* 05087 * Blow it off if the caller doesn't have the proper access rights. However, allow the 05088 * CSR process to use this value internally to the server. Note that if the client 05089 * tries to retrieve this value itself, the access check will function normally. 05090 */ 05091 if ((PpiCurrent()->Process != gpepCSRSS) && 05092 (!CheckGrantedAccess(PpiCurrent()->amwinsta, WINSTA_READATTRIBUTES))) { 05093 MSGERROR(0); 05094 } 05095 05096 retval = gpsi->dtCaretBlink; 05097 05098 TRACE("NtUserGetCaretBlinkTime"); 05099 ENDRECV_SHARED(); 05100 } 05101 05102 HWND NtUserGetClipboardOwner( 05103 VOID) 05104 { 05105 PWINDOWSTATION pwinsta; 05106 05107 BEGINRECV_SHARED(HWND, NULL); 05108 05109 /* 05110 * Blow it off if the caller doesn't have the proper access rights 05111 */ 05112 if ((pwinsta = CheckClipboardAccess()) == NULL) { 05113 MSGERROR(0); 05114 } 05115 05116 retval = PtoH(pwinsta->spwndClipOwner); 05117 05118 TRACE("NtUserGetClipboardOwner"); 05119 ENDRECV_SHARED(); 05120 } 05121 05122 HWND NtUserGetClipboardViewer( 05123 VOID) 05124 { 05125 PWINDOWSTATION pwinsta; 05126 05127 BEGINRECV_SHARED(HWND, NULL); 05128 05129 /* 05130 * Blow it off if the caller doesn't have the proper access rights 05131 */ 05132 if ((pwinsta = CheckClipboardAccess()) == NULL) { 05133 MSGERROR(0); 05134 } 05135 05136 retval = PtoH(pwinsta->spwndClipViewer); 05137 05138 TRACE("NtUserGetClipboardViewer"); 05139 ENDRECV_SHARED(); 05140 } 05141 05142 UINT NtUserGetDoubleClickTime( 05143 VOID) 05144 { 05145 BEGINRECV_SHARED(UINT, 0); 05146 05147 /* 05148 * Blow it off if the caller doesn't have the proper access rights. However, allow the 05149 * CSR process to use this value internally to the server. Note that if the client 05150 * tries to retrieve this value itself, the access check will function normally. 05151 */ 05152 if ((PpiCurrent()->Process != gpepCSRSS) && 05153 (!CheckGrantedAccess(PpiCurrent()->amwinsta, WINSTA_READATTRIBUTES))) { 05154 MSGERROR(0); 05155 } 05156 05157 retval = gdtDblClk; 05158 05159 TRACE("NtUserGetDoubleClickTime"); 05160 ENDRECV_SHARED(); 05161 } 05162 05163 HWND NtUserGetForegroundWindow( 05164 VOID) 05165 { 05166 BEGINRECV_SHARED(HWND, NULL); 05167 05168 /* 05169 * Only return a window if there is a foreground queue and the 05170 * caller has access to the current desktop. 05171 */ 05172 if (gpqForeground == NULL || gpqForeground->spwndActive == NULL || 05173 PtiCurrentShared()->rpdesk != gpqForeground->spwndActive->head.rpdesk) { 05174 MSGERROR(0); 05175 } 05176 05177 retval = PtoHq(gpqForeground->spwndActive); 05178 05179 TRACE("NtUserGetForegroundWindow"); 05180 ENDRECV_SHARED(); 05181 } 05182 05183 HWND NtUserGetOpenClipboardWindow( 05184 VOID) 05185 { 05186 PWINDOWSTATION pwinsta; 05187 05188 BEGINRECV_SHARED(HWND, NULL); 05189 05190 /* 05191 * Blow it off if the caller doesn't have the proper access rights 05192 */ 05193 if ((pwinsta = CheckClipboardAccess()) == NULL) { 05194 MSGERROR(0); 05195 } 05196 05197 retval = PtoH(pwinsta->spwndClipOpen); 05198 05199 TRACE("NtUserGetOpenClipboardWindow"); 05200 ENDRECV_SHARED(); 05201 } 05202 05203 int NtUserGetPriorityClipboardFormat( // API GetPriorityClipboardFormat 05204 IN UINT *paFormatPriorityList, 05205 IN int cFormats) 05206 { 05207 BEGINRECV_SHARED(int, 0); 05208 05209 /* 05210 * Probe arguments 05211 */ 05212 try { 05213 ProbeForReadBuffer(paFormatPriorityList, cFormats, DATAALIGN); 05214 05215 retval = _GetPriorityClipboardFormat( 05216 paFormatPriorityList, 05217 cFormats); 05218 } except (StubExceptionHandler(TRUE)) { 05219 MSGERROR(0); 05220 } 05221 05222 TRACE("NtUserGetPriorityClipboardFormat"); 05223 ENDRECV_SHARED(); 05224 } 05225 05226 HMENU NtUserGetSystemMenu( 05227 IN HWND hwnd, 05228 IN BOOL bRevert) 05229 { 05230 05231 // 05232 // N.B. This function has implicit window handle translation. This 05233 // operation is performed in the User server API dispatcher. 05234 // 05235 05236 BEGINRECV_HWNDLOCK(HMENU, NULL, hwnd); 05237 05238 retval = (HMENU)xxxGetSystemMenu(pwnd, bRevert); 05239 retval = PtoH((PVOID)retval); 05240 05241 TRACE("NtUserGetSystemMenu"); 05242 ENDRECV_HWNDLOCK(); 05243 } 05244 05245 BOOL NtUserGetUpdateRect( // API GetUpdateRect 05246 IN HWND hwnd, 05247 IN LPRECT prect OPTIONAL, 05248 IN BOOL bErase) 05249 { 05250 05251 // 05252 // N.B. This function has implicit window translation and thread locking 05253 // enabled. These operations are performed in the User server API 05254 // dispatcher. 05255 // 05256 05257 RECT rect2; 05258 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 05259 05260 retval = xxxGetUpdateRect( 05261 pwnd, 05262 prect? &rect2:NULL, 05263 bErase); 05264 /* 05265 * Probe arguments 05266 */ 05267 if (ARGUMENT_PRESENT(prect)) { 05268 try { 05269 ProbeAndWriteStructure(prect, rect2, RECT); 05270 } except (StubExceptionHandler(TRUE)) { 05271 MSGERROR(0); 05272 } 05273 } 05274 05275 TRACE("NtUserGetUpdateRect"); 05276 ENDRECV_HWNDLOCK(); 05277 } 05278 05279 BOOL NtUserHideCaret( 05280 IN HWND hwnd) 05281 { 05282 PWND pwnd; 05283 05284 BEGINRECV(BOOL, FALSE); 05285 05286 ValidateHWNDOPT(pwnd, hwnd); 05287 05288 retval = zzzHideCaret(pwnd); 05289 05290 TRACE("NtUserHideCaret"); 05291 ENDRECV(); 05292 } 05293 05294 BOOL NtUserHiliteMenuItem( 05295 IN HWND hwnd, 05296 IN HMENU hMenu, 05297 IN UINT uIDHiliteItem, 05298 IN UINT uHilite) 05299 { 05300 05301 // 05302 // N.B. This function has implicit window translation and thread locking 05303 // enabled. These operations are performed in the User server API 05304 // dispatcher. 05305 // 05306 05307 PMENU pmenu; 05308 TL tlpmenu; 05309 05310 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 05311 05312 TESTFLAGS(uHilite, MF_VALID); 05313 05314 ValidateHMENUMODIFY(pmenu, hMenu); 05315 05316 ThreadLockAlwaysWithPti(ptiCurrent, pmenu, &tlpmenu); 05317 05318 retval = xxxHiliteMenuItem( 05319 pwnd, 05320 pmenu, 05321 uIDHiliteItem, 05322 uHilite); 05323 05324 ThreadUnlock(&tlpmenu); 05325 05326 TRACE("NtUserHiliteMenuItem"); 05327 ENDRECV_HWNDLOCK(); 05328 } 05329 05330 BOOL NtUserInvalidateRect( // API InvalidateRect 05331 IN HWND hwnd, 05332 IN CONST RECT *prect OPTIONAL, 05333 IN BOOL bErase) 05334 { 05335 PWND pwnd; 05336 TL tlpwnd; 05337 RECT rc; 05338 05339 BEGINRECV(BOOL, FALSE); 05340 05341 ValidateHWNDOPT(pwnd, hwnd); 05342 05343 /* 05344 * Probe arguments 05345 */ 05346 if (ARGUMENT_PRESENT(prect)) { 05347 try { 05348 rc = ProbeAndReadRect(prect); 05349 prect = &rc; 05350 } except (StubExceptionHandler(TRUE)) { 05351 MSGERROR(0); 05352 } 05353 } 05354 05355 ThreadLock(pwnd, &tlpwnd); 05356 05357 retval = xxxInvalidateRect( 05358 pwnd, 05359 (PRECT)prect, 05360 bErase); 05361 05362 ThreadUnlock(&tlpwnd); 05363 05364 TRACE("NtUserInvalidateRect"); 05365 ENDRECV(); 05366 } 05367 05368 BOOL NtUserIsClipboardFormatAvailable( 05369 IN UINT nFormat) 05370 { 05371 PWINDOWSTATION pwinsta; 05372 05373 BEGINRECV_SHARED(BOOL, FALSE); 05374 05375 /* 05376 * Blow it off if the caller doesn't have the proper access rights 05377 */ 05378 if ((pwinsta = CheckClipboardAccess()) == NULL) { 05379 MSGERROR(0); 05380 } 05381 05382 retval = (FindClipFormat(pwinsta, nFormat) != NULL); 05383 05384 TRACE("NtUserIsClipboardFormatAvailable"); 05385 ENDRECV_SHARED(); 05386 } 05387 05388 BOOL NtUserKillTimer( 05389 IN HWND hwnd, 05390 IN UINT_PTR nIDEvent) 05391 { 05392 PWND pwnd; 05393 05394 BEGINATOMICRECV(BOOL, FALSE); 05395 05396 ValidateHWNDOPT(pwnd, hwnd); 05397 05398 retval = _KillTimer( 05399 pwnd, 05400 nIDEvent); 05401 05402 TRACE("NtUserKillTimer"); 05403 ENDATOMICRECV(); 05404 } 05405 05406 HWND NtUserMinMaximize( 05407 IN HWND hwnd, 05408 IN UINT nCmdShow, 05409 IN BOOL fKeepHidden) 05410 { 05411 BEGINRECV_HWNDLOCK_ND(HWND, NULL, hwnd); 05412 05413 retval = (HWND)xxxMinMaximize( 05414 pwndND, 05415 nCmdShow, 05416 ((fKeepHidden) ? MINMAX_KEEPHIDDEN : 0) | TEST_PUDF(PUDF_ANIMATE)); 05417 retval = PtoH((PVOID)retval); 05418 05419 TRACE("NtUserMinMaximize"); 05420 ENDRECV_HWNDLOCK_ND(); 05421 } 05422 05423 /**************************************************************************\ 05424 * NtUserMNDragOver 05425 * 05426 * Called from the IDropTarget interface to let menus update the selection 05427 * given the mouse position. It also returns the handle of the menu the 05428 * the index of the item the point is on. 05429 * 05430 * 10/28/96 GerardoB Created 05431 \**************************************************************************/ 05432 BOOL NtUserMNDragOver( // worker for menu drag & drop 05433 IN POINT * ppt, 05434 OUT PMNDRAGOVERINFO pmndoi) 05435 { 05436 POINT pt; 05437 MNDRAGOVERINFO mndoi; 05438 05439 BEGINRECV(BOOL, FALSE); 05440 05441 /* 05442 * No need to SetLastError since ppt and pmndoi are always addresses of 05443 * local stack variables in USER, not addresses from an application 05444 */ 05445 try { 05446 pt = ProbeAndReadPoint(ppt); 05447 } except (StubExceptionHandler(FALSE)) { 05448 RIPMSG1(RIP_WARNING, "NtUserMNDragOver: Exception:%#lx", GetExceptionCode()); 05449 MSGERROR(0); 05450 } 05451 05452 retval = xxxMNDragOver(&pt, &mndoi); 05453 05454 if (retval) { 05455 try { 05456 ProbeAndWriteStructure(pmndoi, mndoi, MNDRAGOVERINFO); 05457 } except (StubExceptionHandler(FALSE)) { 05458 RIPMSG1(RIP_WARNING, "NtUserMNDragOver: Exception:%#lx", GetExceptionCode()); 05459 MSGERROR(0); 05460 } 05461 } 05462 05463 TRACE("NtUserMNDragOver"); 05464 ENDRECV(); 05465 } 05466 /**************************************************************************\ 05467 * NtUserMNDragLeave 05468 * 05469 * Called from the IDropTarget interface to let the menu clean up 05470 * 05471 * 10/28/96 GerardoB Created 05472 \**************************************************************************/ 05473 BOOL NtUserMNDragLeave(VOID) 05474 { 05475 BEGINRECV(BOOL, FALSE); 05476 retval = xxxMNDragLeave(); 05477 TRACE("NtUserMNDragLeave"); 05478 ENDRECV(); 05479 } 05480 05481 BOOL NtUserOpenClipboard( // API OpenClipboard 05482 IN HWND hwnd, 05483 OUT PBOOL pfEmptyClient) 05484 { 05485 PWND pwnd; 05486 TL tlpwnd; 05487 BOOL fEmptyClient; 05488 05489 BEGINRECV(BOOL, FALSE); 05490 05491 ValidateHWNDOPT(pwnd, hwnd); 05492 05493 ThreadLock(pwnd, &tlpwnd); 05494 05495 retval = xxxOpenClipboard(pwnd, &fEmptyClient); 05496 05497 ThreadUnlock(&tlpwnd); 05498 05499 /* 05500 * Probe arguments 05501 * No need to SetLastError since pfEmptyClient is the address of a local 05502 * variable in USER client code, not an application address. 05503 */ 05504 try { 05505 ProbeAndWriteUlong(pfEmptyClient, fEmptyClient); 05506 } except (StubExceptionHandler(FALSE)) { 05507 MSGERROR(0); 05508 } 05509 05510 TRACE("NtUserOpenClipboard"); 05511 ENDRECV(); 05512 } 05513 05514 BOOL NtUserPeekMessage( 05515 OUT LPMSG pmsg, 05516 IN HWND hwnd, 05517 IN UINT wMsgFilterMin, 05518 IN UINT wMsgFilterMax, 05519 IN UINT wRemoveMsg) 05520 { 05521 MSG msg; 05522 05523 BEGINRECV(BOOL, FALSE); 05524 05525 TESTFLAGS(wRemoveMsg, PM_VALID); 05526 05527 retval = xxxPeekMessage( 05528 &msg, 05529 hwnd, 05530 wMsgFilterMin, 05531 wMsgFilterMax, 05532 wRemoveMsg); 05533 05534 /* 05535 * Probe and write arguments only if PeekMessage suceeds otherwise 05536 * we want to leave MSG undisturbed (bug 16224) to be compatible. 05537 */ 05538 if (retval) { 05539 try { 05540 ProbeAndWriteStructure(pmsg, msg, MSG); 05541 } except (StubExceptionHandler(TRUE)) { 05542 MSGERROR(0); 05543 } 05544 } 05545 05546 TRACE("NtUserPeekMessage"); 05547 ENDRECV(); 05548 } 05549 05550 BOOL NtUserPostMessage( 05551 IN HWND hwnd, 05552 IN UINT msg, 05553 IN WPARAM wParam, 05554 IN LPARAM lParam) 05555 { 05556 PWND pwnd; 05557 05558 BEGINRECV(BOOL, FALSE); 05559 05560 /* 05561 * Prevent apps from setting hi 16 bits so we can use them internally. 05562 */ 05563 if (msg & MSGFLAG_MASK) { 05564 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid message"); 05565 MSGERROR(0); 05566 } 05567 05568 switch ((ULONG_PTR)hwnd) { 05569 case -1: 05570 case 0x0000FFFF: 05571 pwnd = PWND_BROADCAST; 05572 break; 05573 05574 case 0: 05575 pwnd = NULL; 05576 break; 05577 05578 default: 05579 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 05580 /* 05581 * We fake terminates to dead windows! (SAS) 05582 */ 05583 errret = (msg == WM_DDE_TERMINATE); 05584 MSGERROR(0); 05585 } 05586 break; 05587 } 05588 05589 retval = _PostMessage( 05590 pwnd, 05591 msg, 05592 wParam, 05593 lParam); 05594 05595 TRACE("NtUserPostMessage"); 05596 ENDRECV(); 05597 } 05598 05599 BOOL NtUserSendNotifyMessage( // API SendNotifyMessageA/W 05600 IN HWND hwnd, 05601 IN UINT Msg, 05602 IN WPARAM wParam, 05603 IN LPARAM lParam OPTIONAL) 05604 { 05605 PWND pwnd; 05606 TL tlpwnd; 05607 LARGE_STRING strLParam; 05608 05609 BEGINRECV(BOOL, FALSE); 05610 05611 /* 05612 * Prevent apps from setting hi 16 bits so we can use them internally. 05613 */ 05614 if (Msg & MSGFLAG_MASK) { 05615 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid message"); 05616 MSGERROR(0); 05617 } 05618 05619 if ((Msg == WM_WININICHANGE || Msg == WM_DEVMODECHANGE) && 05620 ARGUMENT_PRESENT(lParam)) { 05621 try { 05622 strLParam = ProbeAndReadLargeString((PLARGE_STRING)lParam); 05623 ProbeForReadUnicodeStringBuffer(strLParam); 05624 lParam = (LPARAM)&strLParam; 05625 } except (StubExceptionHandler(TRUE)) { 05626 MSGERROR(0); 05627 } 05628 } 05629 05630 ValidateHWNDFF(pwnd, hwnd); 05631 05632 if (pwnd != PWND_BROADCAST) 05633 ThreadLockAlways(pwnd, &tlpwnd); 05634 05635 retval = xxxSendNotifyMessage( 05636 pwnd, 05637 Msg, 05638 wParam, 05639 lParam ); 05640 05641 if (pwnd != PWND_BROADCAST) 05642 ThreadUnlock(&tlpwnd); 05643 05644 TRACE("NtUserSendNotifyMessage"); 05645 ENDRECV(); 05646 } 05647 05648 BOOL NtUserSendMessageCallback( 05649 IN HWND hwnd, 05650 IN UINT wMsg, 05651 IN WPARAM wParam, 05652 IN LPARAM lParam, 05653 IN SENDASYNCPROC lpResultCallBack, 05654 IN ULONG_PTR dwData) 05655 { 05656 PWND pwnd; 05657 TL tlpwnd; 05658 05659 BEGINRECV(BOOL, FALSE); 05660 05661 /* 05662 * Prevent apps from setting hi 16 bits so we can use them internally. 05663 */ 05664 if (wMsg & MSGFLAG_MASK) { 05665 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid message"); 05666 MSGERROR(0); 05667 } 05668 05669 ValidateHWNDFF(pwnd, hwnd); 05670 05671 if (pwnd != PWND_BROADCAST) 05672 ThreadLockAlways(pwnd, &tlpwnd); 05673 05674 retval = xxxSendMessageCallback( 05675 pwnd, 05676 wMsg, 05677 wParam, 05678 lParam, 05679 lpResultCallBack, 05680 dwData, 05681 TRUE ); 05682 05683 if (pwnd != PWND_BROADCAST) 05684 ThreadUnlock(&tlpwnd); 05685 05686 TRACE("NtUserSendMessageCallback"); 05687 ENDRECV(); 05688 } 05689 05690 BOOL NtUserRegisterHotKey( 05691 IN HWND hwnd, 05692 IN int id, 05693 IN UINT fsModifiers, 05694 IN UINT vk) 05695 { 05696 PWND pwnd; 05697 05698 BEGINATOMICRECV(BOOL, FALSE); 05699 05700 TESTFLAGS(fsModifiers, MOD_VALID); 05701 05702 ValidateHWNDOPT(pwnd, hwnd); 05703 05704 retval = _RegisterHotKey( 05705 pwnd, 05706 id, 05707 fsModifiers, 05708 vk 05709 ); 05710 05711 TRACE("NtUserRegisterHotKey"); 05712 ENDATOMICRECV(); 05713 } 05714 05715 BOOL NtUserRemoveMenu( 05716 IN HMENU hmenu, 05717 IN UINT nPosition, 05718 IN UINT dwFlags) 05719 { 05720 PMENU pmenu; 05721 TL tlpmenu; 05722 05723 BEGINRECV(BOOL, FALSE); 05724 05725 TESTFLAGS(dwFlags, MF_VALID); 05726 05727 ValidateHMENUMODIFY(pmenu, hmenu); 05728 05729 ThreadLock( pmenu, &tlpmenu); 05730 retval = xxxRemoveMenu( 05731 pmenu, 05732 nPosition, 05733 dwFlags); 05734 ThreadUnlock(&tlpmenu); 05735 05736 TRACE("NtUserRemoveMenu"); 05737 ENDRECV(); 05738 } 05739 05740 BOOL NtUserScrollWindowEx( // API ScrollWindowEx 05741 IN HWND hwnd, 05742 IN int dx, 05743 IN int dy, 05744 IN CONST RECT *prcScroll OPTIONAL, 05745 IN CONST RECT *prcClip OPTIONAL, 05746 IN HRGN hrgnUpdate, 05747 OUT LPRECT prcUpdate OPTIONAL, 05748 IN UINT flags) 05749 { 05750 RECT rcScroll; 05751 RECT rcClip; 05752 RECT rcUpdate; 05753 05754 // 05755 // N.B. This function has implicit window translation and thread locking 05756 // enabled. These operations are performed in the User server API 05757 // dispatcher. 05758 // 05759 05760 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 05761 05762 /* 05763 * Probe arguments 05764 */ 05765 try { 05766 if (ARGUMENT_PRESENT(prcScroll)) { 05767 rcScroll = ProbeAndReadRect(prcScroll); 05768 prcScroll = &rcScroll; 05769 } 05770 if (ARGUMENT_PRESENT(prcClip)) { 05771 rcClip = ProbeAndReadRect(prcClip); 05772 prcClip = &rcClip; 05773 } 05774 05775 } except (StubExceptionHandler(TRUE)) { 05776 MSGERROR(0); 05777 } 05778 05779 retval = xxxScrollWindowEx( 05780 pwnd, 05781 dx, 05782 dy, 05783 (PRECT)prcScroll, 05784 (PRECT)prcClip, 05785 hrgnUpdate, 05786 prcUpdate ? &rcUpdate : NULL, 05787 flags); 05788 05789 if (ARGUMENT_PRESENT(prcUpdate)) { 05790 try { 05791 ProbeAndWriteStructure(prcUpdate, rcUpdate, RECT); 05792 } except (StubExceptionHandler(TRUE)) { 05793 MSGERROR(0); 05794 } 05795 } 05796 05797 TRACE("NtUserScrollWindow"); 05798 ENDRECV_HWNDLOCK(); 05799 } 05800 05801 HWND NtUserSetActiveWindow( 05802 IN HWND hwnd) 05803 { 05804 PWND pwnd; 05805 TL tlpwnd; 05806 05807 BEGINRECV(HWND, NULL); 05808 05809 ValidateHWNDOPT(pwnd, hwnd); 05810 05811 ThreadLock(pwnd, &tlpwnd); 05812 05813 retval = (HWND)xxxSetActiveWindow(pwnd); 05814 retval = PtoH((PVOID)retval); 05815 05816 ThreadUnlock(&tlpwnd); 05817 05818 TRACE("NtUserSetActiveWindow"); 05819 ENDRECV(); 05820 } 05821 05822 HWND NtUserSetCapture( 05823 IN HWND hwnd) 05824 { 05825 PWND pwnd; 05826 TL tlpwnd; 05827 05828 BEGINRECV(HWND, NULL); 05829 05830 ValidateHWNDOPT(pwnd, hwnd); 05831 05832 ThreadLock(pwnd, &tlpwnd); 05833 05834 retval = (HWND)xxxSetCapture(pwnd); 05835 retval = PtoH((PVOID)retval); 05836 05837 ThreadUnlock(&tlpwnd); 05838 05839 TRACE("NtUserSetCapture"); 05840 ENDRECV(); 05841 } 05842 05843 WORD NtUserSetClassWord( 05844 IN HWND hwnd, 05845 IN int nIndex, 05846 IN WORD wNewWord) 05847 { 05848 05849 // 05850 // N.B. This function has implicit window handle translation. This 05851 // operation is performed in the User server API dispatcher. 05852 // 05853 05854 BEGINRECV_HWND(WORD, 0, hwnd); 05855 05856 retval = _SetClassWord( 05857 pwnd, 05858 nIndex, 05859 wNewWord); 05860 05861 TRACE("NtUserSetClassWord"); 05862 ENDRECV_HWND(); 05863 } 05864 05865 HWND NtUserSetClipboardViewer( 05866 IN HWND hwnd) 05867 { 05868 PWND pwnd; 05869 TL tlpwnd; 05870 05871 BEGINRECV(HWND, NULL); 05872 05873 ValidateHWNDOPT(pwnd, hwnd); 05874 05875 ThreadLock(pwnd, &tlpwnd); 05876 05877 retval = (HWND)xxxSetClipboardViewer(pwnd); 05878 retval = PtoH((PVOID)retval); 05879 05880 ThreadUnlock(&tlpwnd); 05881 05882 TRACE("NtUserSetClipboardViewer"); 05883 ENDRECV(); 05884 } 05885 05886 HCURSOR NtUserSetCursor( 05887 IN HCURSOR hCursor) 05888 { 05889 PCURSOR pCursor; 05890 05891 BEGINRECV(HCURSOR, NULL); 05892 05893 ValidateHCURSOROPT(pCursor, hCursor); 05894 05895 retval = (HCURSOR)zzzSetCursor(pCursor); 05896 retval = PtoH((PVOID)retval); 05897 05898 TRACE("NtUserSetCursor"); 05899 ENDRECV(); 05900 } 05901 05902 HWND NtUserSetFocus( 05903 IN HWND hwnd) 05904 { 05905 PWND pwnd; 05906 TL tlpwnd; 05907 05908 BEGINRECV(HWND, NULL); 05909 05910 ValidateHWNDOPT(pwnd, hwnd); 05911 05912 ThreadLock(pwnd, &tlpwnd); 05913 05914 retval = (HWND)xxxSetFocus(pwnd); 05915 retval = PtoH((PVOID)retval); 05916 05917 ThreadUnlock(&tlpwnd); 05918 05919 TRACE("NtUserSetFocus"); 05920 ENDRECV(); 05921 } 05922 05923 BOOL NtUserSetMenu( 05924 IN HWND hwnd, 05925 IN HMENU hmenu, 05926 IN BOOL fRedraw) 05927 { 05928 05929 // 05930 // N.B. This function has implicit window translation and thread locking 05931 // enabled. These operations are performed in the User server API 05932 // dispatcher. 05933 // 05934 05935 PMENU pmenu; 05936 TL tlpmenu; 05937 05938 BEGINRECV_HWNDLOCK_ND(DWORD, 0, hwnd); 05939 05940 ValidateHMENUOPT(pmenu, hmenu); 05941 05942 ThreadLockWithPti(ptiCurrent, pmenu, &tlpmenu); 05943 05944 retval = xxxSetMenu( 05945 pwndND, 05946 pmenu, 05947 fRedraw); 05948 05949 ThreadUnlock(&tlpmenu); 05950 05951 TRACE("NtUserSetMenu"); 05952 ENDRECV_HWNDLOCK_ND(); 05953 } 05954 05955 HWND NtUserSetParent( 05956 IN HWND hwndChild, 05957 IN HWND hwndNewParent) 05958 { 05959 05960 PWND pwndNewParent; 05961 TL tlpwndNewParent; 05962 05963 BEGINRECV_HWNDLOCK_ND(HWND, NULL, hwndChild); 05964 05965 if (hwndNewParent == NULL) { 05966 pwndNewParent = _GetDesktopWindow(); 05967 } else if (hwndNewParent == HWND_MESSAGE) { 05968 pwndNewParent = _GetMessageWindow(); 05969 } else { 05970 ValidateHWND(pwndNewParent, hwndNewParent); 05971 } 05972 05973 ThreadLockWithPti(ptiCurrent, pwndNewParent, &tlpwndNewParent); 05974 05975 retval = (HWND)xxxSetParent( 05976 pwndND, 05977 pwndNewParent); 05978 retval = PtoH((PVOID)retval); 05979 05980 ThreadUnlock(&tlpwndNewParent); 05981 05982 TRACE("NtUserSetParent"); 05983 ENDRECV_HWNDLOCK_ND(); 05984 } 05985 05986 int NtUserSetScrollInfo( // API SetScrollInfo 05987 IN HWND hwnd, 05988 IN int nBar, 05989 IN LPCSCROLLINFO pInfo, 05990 IN BOOL fRedraw) 05991 { 05992 SCROLLINFO si; 05993 05994 // 05995 // N.B. This function has implicit window translation and thread locking 05996 // enabled. These operations are performed in the User server API 05997 // dispatcher. 05998 // 05999 06000 BEGINRECV_HWNDLOCK_ND(DWORD, 0, hwnd); 06001 06002 LIMITVALUE(nBar, SB_MAX, "SetScrollInfo"); 06003 06004 /* 06005 * Probe arguments 06006 */ 06007 try { 06008 si = ProbeAndReadScrollInfo(pInfo); 06009 } except (StubExceptionHandler(TRUE)) { 06010 MSGERROR(0); 06011 } 06012 06013 retval = xxxSetScrollBar( 06014 pwndND, 06015 nBar, 06016 &si, 06017 fRedraw); 06018 06019 TRACE("NtUserSetScrollInfo"); 06020 ENDRECV_HWNDLOCK_ND(); 06021 } 06022 06023 BOOL NtUserSetSysColors( // API SetSysColors 06024 IN int nCount, 06025 IN CONST INT *pSysColor, 06026 IN CONST COLORREF *pColorValues, 06027 IN UINT uOptions) 06028 { 06029 LPINT lpSysColors = NULL; 06030 LPDWORD lpSysColorValues = NULL; 06031 TL tlName, tlSysColors, tlSysColorValues; 06032 PUNICODE_STRING pProfileUserName = NULL; 06033 PTHREADINFO ptiCurrent; 06034 06035 BEGINRECV(BOOL, FALSE); 06036 06037 ptiCurrent = PtiCurrent(); 06038 06039 /* 06040 * Prevent restricted threads from changing global stuff 06041 */ 06042 if (IS_THREAD_RESTRICTED(ptiCurrent, JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS)) { 06043 MSGERROR(0); 06044 } 06045 06046 /* 06047 * Probe arguments 06048 */ 06049 if (nCount) { 06050 try { 06051 ProbeForReadBuffer(pSysColor, nCount, DATAALIGN); 06052 ProbeForReadBuffer(pColorValues, nCount, DATAALIGN); 06053 lpSysColors = UserAllocPoolWithQuota(nCount * sizeof(*pSysColor), TAG_COLORS); 06054 if (lpSysColors == NULL) { 06055 ExRaiseStatus(STATUS_NO_MEMORY); 06056 } 06057 RtlCopyMemory(lpSysColors, pSysColor, nCount * sizeof(*pSysColor)); 06058 lpSysColorValues = UserAllocPoolWithQuota(nCount * sizeof(*pColorValues), TAG_COLORVALUES); 06059 if (lpSysColorValues == NULL) { 06060 ExRaiseStatus(STATUS_NO_MEMORY); 06061 } 06062 RtlCopyMemory(lpSysColorValues, pColorValues, nCount * sizeof(*pColorValues)); 06063 06064 } except (StubExceptionHandler(TRUE)) { 06065 MSGERRORCLEANUP(0); 06066 } 06067 } 06068 06069 ThreadLockPool(ptiCurrent, lpSysColors, &tlSysColors); 06070 ThreadLockPool(ptiCurrent, lpSysColorValues, &tlSysColorValues); 06071 pProfileUserName = CreateProfileUserName(&tlName); 06072 retval = xxxSetSysColors(pProfileUserName, 06073 nCount, 06074 lpSysColors, 06075 lpSysColorValues, 06076 uOptions 06077 ); 06078 FreeProfileUserName(pProfileUserName, &tlName); 06079 ThreadUnlockPool(ptiCurrent, &tlSysColorValues); 06080 ThreadUnlockPool(ptiCurrent, &tlSysColors); 06081 06082 CLEANUPRECV(); 06083 if (lpSysColors) 06084 UserFreePool(lpSysColors); 06085 if (lpSysColorValues) 06086 UserFreePool(lpSysColorValues); 06087 06088 TRACE("NtUserSetSysColors"); 06089 ENDRECV(); 06090 } 06091 06092 UINT_PTR NtUserSetTimer( 06093 IN HWND hwnd, 06094 IN UINT_PTR nIDEvent, 06095 IN UINT wElapse, 06096 IN TIMERPROC pTimerFunc) 06097 { 06098 PWND pwnd; 06099 06100 BEGINATOMICRECV(UINT_PTR, 0); 06101 06102 ValidateHWNDOPT(pwnd, hwnd); 06103 06104 /* 06105 * If we let apps set a timer granularity less then 10 the app 06106 * spend too long processing timer messages. Some WOW apps like 06107 * Paradox in WinStone use zero to effectively get the minimal 06108 * timer value which was ~55ms in Win 3.1. We also step this 06109 * value up for 32 bit apps because the NT timer resolution 06110 * can very depending if the multimedia timers have turned up 06111 * the resolution. If they have NT apps that specify a low value 06112 * will not work properly because they will eat the CPU processing 06113 * WM_TIMER messages 06114 */ 06115 if (wElapse < 10) { 06116 RIPMSG1(RIP_WARNING, "SetTimer: timeout value was %ld set to 10", 06117 wElapse); 06118 wElapse = 10; 06119 } 06120 06121 retval = _SetTimer( 06122 pwnd, 06123 nIDEvent, 06124 wElapse, 06125 (TIMERPROC_PWND)pTimerFunc); 06126 06127 TRACE("NtUserSetTimer"); 06128 ENDATOMICRECV(); 06129 } 06130 06131 LONG_PTR NtUserSetWindowLongPtr( 06132 IN HWND hwnd, 06133 IN int nIndex, 06134 IN LONG_PTR dwNewLong, 06135 IN BOOL bAnsi) 06136 { 06137 06138 // 06139 // N.B. This function has implicit window handle translation. This 06140 // operation is performed in the User server API dispatcher. 06141 // 06142 06143 BEGINRECV_HWNDLOCK(ULONG_PTR, 0, hwnd); 06144 06145 retval = xxxSetWindowLongPtr( 06146 pwnd, 06147 nIndex, 06148 dwNewLong, 06149 bAnsi); 06150 06151 TRACE("NtUserSetWindowLongPtr"); 06152 ENDRECV_HWNDLOCK(); 06153 } 06154 06155 #ifdef _WIN64 06156 LONG NtUserSetWindowLong( 06157 IN HWND hwnd, 06158 IN int nIndex, 06159 IN LONG dwNewLong, 06160 IN BOOL bAnsi) 06161 { 06162 06163 // 06164 // N.B. This function has implicit window handle translation. This 06165 // operation is performed in the User server API dispatcher. 06166 // 06167 06168 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 06169 06170 retval = xxxSetWindowLong( 06171 pwnd, 06172 nIndex, 06173 dwNewLong, 06174 bAnsi); 06175 06176 TRACE("NtUserSetWindowLong"); 06177 ENDRECV_HWNDLOCK(); 06178 } 06179 #endif 06180 06181 WORD NtUserSetWindowWord( 06182 IN HWND hwnd, 06183 IN int nIndex, 06184 IN WORD wNewWord) 06185 { 06186 06187 // 06188 // N.B. This function has implicit window handle translation. This 06189 // operation is performed in the User server API dispatcher. 06190 // 06191 06192 BEGINRECV_HWND(WORD, 0, hwnd); 06193 06194 retval = _SetWindowWord( 06195 pwnd, 06196 nIndex, 06197 wNewWord); 06198 06199 TRACE("NtUserSetWindowWord"); 06200 ENDRECV_HWND(); 06201 } 06202 06203 HHOOK NtUserSetWindowsHookAW( 06204 IN int nFilterType, 06205 IN HOOKPROC pfnFilterProc, 06206 IN DWORD dwFlags) 06207 { 06208 BEGINRECV(HHOOK, NULL); 06209 06210 retval = (HHOOK)zzzSetWindowsHookAW( 06211 nFilterType, 06212 (PROC)pfnFilterProc, 06213 dwFlags); 06214 06215 TRACE("NtUserSetWindowsHookAW"); 06216 ENDRECV(); 06217 } 06218 06219 BOOL NtUserShowCaret( 06220 IN HWND hwnd) 06221 { 06222 PWND pwnd; 06223 06224 BEGINRECV(BOOL, FALSE); 06225 06226 ValidateHWNDOPT(pwnd, hwnd); 06227 06228 retval = zzzShowCaret( 06229 pwnd); 06230 06231 TRACE("NtUserShowCaret"); 06232 ENDRECV(); 06233 } 06234 06235 BOOL NtUserShowScrollBar( 06236 IN HWND hwnd, 06237 IN int iBar, 06238 IN BOOL fShow) 06239 { 06240 06241 // 06242 // N.B. This function has implicit window translation and thread locking 06243 // enabled. These operations are performed in the User server API 06244 // dispatcher. 06245 // 06246 06247 BEGINRECV_HWNDLOCK_ND(DWORD, 0, hwnd); 06248 06249 LIMITVALUE(iBar, SB_MAX, "ShowScrollBar"); 06250 06251 retval = xxxShowScrollBar( 06252 pwndND, 06253 iBar, 06254 fShow); 06255 06256 TRACE("NtUserShowScrollBar"); 06257 ENDRECV_HWNDLOCK_ND(); 06258 } 06259 06260 BOOL NtUserShowWindowAsync( 06261 IN HWND hwnd, 06262 IN int nCmdShow) 06263 { 06264 BEGINRECV_HWNDLOCK_ND(BOOL, FALSE, hwnd); 06265 06266 LIMITVALUE(nCmdShow, SW_MAX, "ShowWindowAsync"); 06267 06268 retval = _ShowWindowAsync(pwndND, nCmdShow, 0); 06269 06270 TRACE("NtUserShowWindowAsync"); 06271 ENDRECV_HWNDLOCK_ND(); 06272 } 06273 06274 BOOL NtUserShowWindow( 06275 IN HWND hwnd, 06276 IN int nCmdShow) 06277 { 06278 BEGINRECV_HWNDLOCK_ND(BOOL, FALSE, hwnd); 06279 06280 LIMITVALUE(nCmdShow, SW_MAX, "ShowWindow"); 06281 06282 /* 06283 * Let's not allow the window to be shown/hidden once we 06284 * started the destruction of the window. 06285 */ 06286 if (TestWF(pwndND, WFINDESTROY)) { 06287 RIPERR1(ERROR_INVALID_PARAMETER, 06288 RIP_WARNING, 06289 "ShowWindow: Window is being destroyed (%#p)", 06290 pwndND); 06291 MSGERROR(0); 06292 } 06293 06294 retval = xxxShowWindow(pwndND, nCmdShow | TEST_PUDF(PUDF_ANIMATE)); 06295 06296 TRACE("NtUserShowWindow"); 06297 ENDRECV_HWNDLOCK_ND(); 06298 } 06299 06300 BOOL NtUserTrackMouseEvent( // API TrackMouseEvent 06301 IN OUT LPTRACKMOUSEEVENT lpTME) 06302 { 06303 TRACKMOUSEEVENT tme; 06304 06305 BEGINRECV(BOOL, FALSE); 06306 06307 /* 06308 * Probe arguments 06309 */ 06310 try { 06311 tme = ProbeAndReadTrackMouseEvent(lpTME); 06312 06313 if (tme.cbSize != sizeof(tme)) { 06314 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "TrackMouseEvent: invalid size %lX", tme.cbSize); 06315 MSGERROR(0); 06316 } 06317 06318 TESTFLAGS(tme.dwFlags, TME_VALID); 06319 06320 } except (StubExceptionHandler(TRUE)) { 06321 MSGERROR(0); 06322 } 06323 06324 if (tme.dwFlags & TME_QUERY) { 06325 retval = QueryTrackMouseEvent(&tme); 06326 try { 06327 RtlCopyMemory(lpTME, &tme, sizeof(tme)); 06328 } except (StubExceptionHandler(TRUE)) { 06329 MSGERROR(0); 06330 } 06331 } else { 06332 retval = TrackMouseEvent(&tme); 06333 } 06334 06335 TRACE("NtUserTrackMouseEvent"); 06336 ENDRECV(); 06337 } 06338 06339 BOOL NtUserTrackPopupMenuEx( // API TrackPopupMenuEx 06340 IN HMENU hMenu, 06341 IN UINT uFlags, 06342 IN int x, 06343 IN int y, 06344 IN HWND hwnd, 06345 IN CONST TPMPARAMS *pparamst OPTIONAL) 06346 { 06347 PWND pwnd; 06348 PMENU pmenu; 06349 TL tlpwnd; 06350 TL tlpmenu; 06351 PTHREADINFO ptiCurrent; 06352 TPMPARAMS paramst; 06353 06354 BEGINRECV(BOOL, FALSE); 06355 06356 TESTFLAGS(uFlags, TPM_VALID); 06357 06358 ValidateHMENU(pmenu, hMenu); 06359 ValidateHWND(pwnd, hwnd); 06360 06361 ptiCurrent = PtiCurrent(); 06362 ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd); 06363 ThreadLockAlwaysWithPti(ptiCurrent, pmenu, &tlpmenu); 06364 06365 /* 06366 * Probe arguments 06367 */ 06368 try { 06369 if (ARGUMENT_PRESENT(pparamst)) { 06370 paramst = ProbeAndReadPopupParams(pparamst); 06371 pparamst = &paramst; 06372 } 06373 06374 } except (StubExceptionHandler(TRUE)) { 06375 MSGERRORCLEANUP(0); 06376 } 06377 retval = xxxTrackPopupMenuEx( 06378 pmenu, 06379 uFlags, 06380 x, 06381 y, 06382 pwnd, 06383 pparamst); 06384 06385 CLEANUPRECV(); 06386 06387 ThreadUnlock(&tlpmenu); 06388 ThreadUnlock(&tlpwnd); 06389 06390 TRACE("NtUserTrackPopupMenuEx"); 06391 ENDRECV(); 06392 } 06393 06394 BOOL NtUserTranslateMessage( // API TranslateMessage 06395 IN CONST MSG *lpMsg, 06396 IN UINT flags) 06397 { 06398 MSG msg; 06399 06400 BEGINRECV(BOOL, FALSE); 06401 06402 /* 06403 * Probe arguments 06404 */ 06405 try { 06406 msg = ProbeAndReadMessage(lpMsg); 06407 } except (StubExceptionHandler(TRUE)) { 06408 MSGERROR(0); 06409 } 06410 06411 if (ValidateHwnd(msg.hwnd) == NULL) { 06412 MSGERROR(0); 06413 } 06414 06415 retval = xxxTranslateMessage( 06416 &msg, 06417 flags); 06418 06419 TRACE("NtUserTranslateMessage"); 06420 ENDRECV(); 06421 } 06422 06423 BOOL NtUserUnhookWindowsHookEx( 06424 IN HHOOK hhk) 06425 { 06426 PHOOK phk; 06427 06428 BEGINRECV(BOOL, FALSE); 06429 06430 ValidateHHOOK(phk, hhk); 06431 06432 retval = zzzUnhookWindowsHookEx( 06433 phk); 06434 06435 TRACE("NtUserUnhookWindowsHookEx"); 06436 ENDRECV(); 06437 } 06438 06439 BOOL NtUserUnregisterHotKey( 06440 IN HWND hwnd, 06441 IN int id) 06442 { 06443 PWND pwnd; 06444 06445 BEGINATOMICRECV(BOOL, FALSE); 06446 06447 ValidateHWNDOPT(pwnd, hwnd); 06448 06449 retval = _UnregisterHotKey( 06450 pwnd, 06451 id); 06452 06453 TRACE("NtUserUnregisterHotKey"); 06454 ENDATOMICRECV(); 06455 } 06456 06457 BOOL NtUserValidateRect( // API ValidateRect 06458 IN HWND hwnd, 06459 IN CONST RECT *lpRect OPTIONAL) 06460 { 06461 PWND pwnd; 06462 TL tlpwnd; 06463 RECT rc; 06464 06465 BEGINRECV(BOOL, FALSE); 06466 06467 /* 06468 * Probe arguments 06469 */ 06470 if (ARGUMENT_PRESENT(lpRect)) { 06471 try { 06472 rc = ProbeAndReadRect(lpRect); 06473 lpRect = &rc; 06474 } except (StubExceptionHandler(TRUE)) { 06475 MSGERROR(0); 06476 } 06477 } 06478 06479 ValidateHWNDOPT(pwnd, hwnd); 06480 06481 ThreadLock(pwnd, &tlpwnd); 06482 06483 retval = xxxValidateRect(pwnd, (PRECT)lpRect); 06484 06485 ThreadUnlock(&tlpwnd); 06486 06487 TRACE("NtUserValidateRect"); 06488 ENDRECV(); 06489 } 06490 06491 DWORD NtUserWaitForInputIdle( 06492 IN ULONG_PTR idProcess, 06493 IN DWORD dwMilliseconds, 06494 IN BOOL fSharedWow) 06495 { 06496 BEGINRECV(DWORD, (DWORD)-1); 06497 06498 retval = xxxWaitForInputIdle( 06499 idProcess, 06500 dwMilliseconds, 06501 fSharedWow); 06502 06503 TRACE("NtUserWaitForInputIdle"); 06504 ENDRECV(); 06505 } 06506 06507 HWND NtUserWindowFromPoint( 06508 IN POINT Point) 06509 { 06510 BEGINRECV(HWND, NULL); 06511 06512 retval = (HWND)xxxWindowFromPoint( 06513 Point); 06514 retval = PtoH((PVOID)retval); 06515 06516 TRACE("NtUserWindowFromPoint"); 06517 ENDRECV(); 06518 } 06519 06520 HDC NtUserBeginPaint( // API BeginPaint 06521 IN HWND hwnd, 06522 OUT LPPAINTSTRUCT lpPaint) 06523 { 06524 PAINTSTRUCT ps; 06525 06526 // 06527 // N.B. This function has implicit window translation and thread locking 06528 // enabled. These operations are performed in the User server API 06529 // dispatcher. 06530 // 06531 06532 BEGINRECV_HWNDLOCK(HDC, NULL, hwnd); 06533 06534 retval = xxxBeginPaint(pwnd, &ps); 06535 06536 /* 06537 * Probe arguments 06538 */ 06539 try { 06540 ProbeAndWriteStructure(lpPaint, ps, PAINTSTRUCT); 06541 } except (StubExceptionHandler(TRUE)) { 06542 xxxEndPaint(pwnd, &ps); 06543 MSGERROR(0); 06544 } 06545 06546 TRACE("NtUserBeginPaint"); 06547 ENDRECV_HWNDLOCK(); 06548 } 06549 06550 BOOL NtUserCreateCaret( 06551 IN HWND hwnd, 06552 IN HBITMAP hBitmap, 06553 IN int nWidth, 06554 IN int nHeight) 06555 { 06556 06557 // 06558 // N.B. This function has implicit window handle translation. This 06559 // operation is performed in the User server API dispatcher. 06560 // 06561 06562 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 06563 06564 retval = xxxCreateCaret( 06565 pwnd, 06566 hBitmap, 06567 nWidth, 06568 nHeight 06569 ); 06570 06571 TRACE("NtUserCreateCaret"); 06572 ENDRECV_HWNDLOCK(); 06573 } 06574 06575 BOOL NtUserEndPaint( // API EndPaint 06576 IN HWND hwnd, 06577 IN CONST PAINTSTRUCT *lpPaint) 06578 { 06579 PAINTSTRUCT ps; 06580 06581 // 06582 // N.B. This function has implicit window handle translation. This 06583 // operation is performed in the User server API dispatcher. 06584 // 06585 06586 BEGINRECV_HWNDLOCK(BOOL, FALSE, hwnd); 06587 06588 /* 06589 * Probe arguments 06590 */ 06591 try { 06592 ps = ProbeAndReadPaintStruct(lpPaint); 06593 } except (StubExceptionHandler(TRUE)) { 06594 MSGERROR(0); 06595 } 06596 06597 retval = xxxEndPaint(pwnd, &ps); 06598 06599 TRACE("NtUserEndPaint"); 06600 ENDRECV_HWNDLOCK(); 06601 } 06602 06603 int NtUserExcludeUpdateRgn( 06604 IN HDC hdc, 06605 IN HWND hwnd) 06606 { 06607 06608 // 06609 // N.B. This function has implicit window handle translation. This 06610 // operation is performed in the User server API dispatcher. 06611 // 06612 06613 BEGINRECV_HWND(int, ERROR, hwnd); 06614 06615 if (hdc == NULL) 06616 MSGERROR(0); 06617 06618 retval = _ExcludeUpdateRgn(hdc, pwnd); 06619 06620 TRACE("NtUserExcludeUpdateRgn"); 06621 ENDRECV_HWND(); 06622 } 06623 06624 HDC NtUserGetDC( 06625 IN HWND hwnd) 06626 { 06627 PWND pwnd; 06628 BOOL bValid = TRUE; 06629 06630 BEGINATOMICRECV(HDC, NULL); 06631 06632 ValidateHWNDOPT(pwnd, hwnd); 06633 06634 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_HANDLES) && pwnd == NULL) { 06635 06636 PDESKTOP pdesk = PtiCurrent()->rpdesk; 06637 06638 /* 06639 * make sure it has access to the desktop window 06640 */ 06641 if (!ValidateHwnd(PtoH(pdesk->pDeskInfo->spwnd))) { 06642 bValid = FALSE; 06643 } 06644 } 06645 06646 retval = _GetDC(pwnd); 06647 06648 if (!bValid) { 06649 06650 HRGN hrgn; 06651 06652 /* 06653 * Select a NULL visible region on this DC so that restricted 06654 * processes don't mess with GetDC(NULL) 06655 */ 06656 hrgn = CreateEmptyRgn(); 06657 06658 GreSelectVisRgn(retval, hrgn, SVR_DELETEOLD); 06659 } 06660 06661 TRACE("NtUserGetDC"); 06662 ENDATOMICRECV(); 06663 } 06664 06665 HDC NtUserGetDCEx( 06666 IN HWND hwnd, 06667 IN HRGN hrgnClip, 06668 IN DWORD flags) 06669 { 06670 PWND pwnd; 06671 06672 BEGINATOMICRECV(HDC, NULL); 06673 06674 ValidateHWNDOPT(pwnd, hwnd); 06675 06676 if (pwnd == NULL) { 06677 pwnd = PtiCurrent()->rpdesk->pDeskInfo->spwnd; 06678 06679 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_HANDLES)) { 06680 /* 06681 * make sure it has access to the desktop window 06682 */ 06683 if (!ValidateHwnd(PtoH(pwnd))) { 06684 RIPMSG0(RIP_WARNING, 06685 "NtUserGetDCEx fails desktop window validation"); 06686 MSGERROR(0); 06687 } 06688 } 06689 } 06690 06691 retval = _GetDCEx( 06692 pwnd, 06693 hrgnClip, 06694 flags); 06695 06696 TRACE("NtUserGetDCEx"); 06697 ENDATOMICRECV(); 06698 } 06699 06700 HDC NtUserGetWindowDC( 06701 IN HWND hwnd) 06702 { 06703 PWND pwnd; 06704 06705 BEGINATOMICRECV(HDC, NULL); 06706 06707 ValidateHWNDOPT(pwnd, hwnd); 06708 06709 retval = _GetWindowDC(pwnd); 06710 06711 TRACE("NtUserGetWindowDC"); 06712 ENDATOMICRECV(); 06713 } 06714 06715 int NtUserGetUpdateRgn( 06716 IN HWND hwnd, 06717 IN HRGN hrgn, 06718 IN BOOL bErase) 06719 { 06720 06721 // 06722 // N.B. This function has implicit window translation and thread locking 06723 // enabled. These operations are performed in the User server API 06724 // dispatcher. 06725 // 06726 06727 BEGINRECV_HWNDLOCK(int, ERROR, hwnd); 06728 06729 retval = xxxGetUpdateRgn( 06730 pwnd, 06731 hrgn, 06732 bErase); 06733 06734 TRACE("NtUserGetUpdateRgn"); 06735 ENDRECV_HWNDLOCK(); 06736 } 06737 06738 BOOL NtUserRedrawWindow( // API RedrawWindow 06739 IN HWND hwnd, 06740 IN CONST RECT *lprcUpdate OPTIONAL, 06741 IN HRGN hrgnUpdate, 06742 IN UINT flags) 06743 { 06744 RECT rc; 06745 06746 // 06747 // N.B. This function has implicit window translation and thread locking 06748 // enabled. These operations are performed in the User server API 06749 // dispatcher. 06750 // 06751 06752 BEGINRECV_HWNDLOCK_OPT(BOOL, FALSE, hwnd); 06753 06754 /* 06755 * Probe arguments 06756 */ 06757 if (ARGUMENT_PRESENT(lprcUpdate)) { 06758 try { 06759 rc = ProbeAndReadRect(lprcUpdate); 06760 lprcUpdate = &rc; 06761 } except (StubExceptionHandler(TRUE)) { 06762 MSGERROR(0); 06763 } 06764 } 06765 06766 TESTFLAGS(flags, RDW_VALIDMASK); 06767 06768 retval = xxxRedrawWindow( 06769 pwnd, 06770 (PRECT)lprcUpdate, 06771 hrgnUpdate, 06772 flags); 06773 06774 TRACE("NtUserRedrawWindow"); 06775 ENDRECV_HWNDLOCK_OPT(); 06776 } 06777 06778 BOOL NtUserInvalidateRgn( 06779 IN HWND hwnd, 06780 IN HRGN hrgn, 06781 IN BOOL bErase) 06782 { 06783 06784 // 06785 // N.B. This function has implicit window translation and thread locking 06786 // enabled. These operations are performed in the User server API 06787 // dispatcher. 06788 // 06789 06790 BEGINRECV_HWNDLOCK(BOOL, FALSE, hwnd); 06791 06792 retval = xxxInvalidateRgn( 06793 pwnd, 06794 hrgn, 06795 bErase); 06796 06797 TRACE("NtUserInvalidateRgn"); 06798 ENDRECV_HWNDLOCK(); 06799 } 06800 06801 int NtUserSetWindowRgn( 06802 IN HWND hwnd, 06803 IN HRGN hrgn, 06804 IN BOOL bRedraw) 06805 { 06806 06807 // 06808 // N.B. This function has implicit window translation and thread locking 06809 // enabled. These operations are performed in the User server API 06810 // dispatcher. 06811 // 06812 06813 BEGINRECV_HWNDLOCK_ND(int, 0, hwnd); 06814 06815 retval = xxxSetWindowRgn( 06816 pwndND, 06817 hrgn, 06818 bRedraw); 06819 06820 TRACE("NtUserSetWindowRgn"); 06821 ENDRECV_HWNDLOCK_ND(); 06822 } 06823 06824 BOOL NtUserScrollDC( // API ScrollDC 06825 IN HDC hdc, 06826 IN int dx, 06827 IN int dy, 06828 IN CONST RECT *prcScroll OPTIONAL, 06829 IN CONST RECT *prcClip OPTIONAL, 06830 IN HRGN hrgnUpdate, 06831 OUT LPRECT prcUpdate OPTIONAL) 06832 { 06833 RECT rcScroll; 06834 RECT rcClip; 06835 RECT rcUpdate; 06836 06837 BEGINRECV(BOOL, FALSE); 06838 06839 /* 06840 * Probe arguments 06841 */ 06842 try { 06843 if (ARGUMENT_PRESENT(prcScroll)) { 06844 rcScroll = ProbeAndReadRect(prcScroll); 06845 prcScroll = &rcScroll; 06846 } 06847 if (ARGUMENT_PRESENT(prcClip)) { 06848 rcClip = ProbeAndReadRect(prcClip); 06849 prcClip = &rcClip; 06850 } 06851 06852 } except (StubExceptionHandler(TRUE)) { 06853 MSGERROR(0); 06854 } 06855 retval = _ScrollDC( 06856 hdc, 06857 dx, 06858 dy, 06859 (PRECT)prcScroll, 06860 (PRECT)prcClip, 06861 hrgnUpdate, 06862 prcUpdate ? &rcUpdate : NULL); 06863 06864 if (ARGUMENT_PRESENT(prcUpdate)) { 06865 try { 06866 ProbeAndWriteStructure(prcUpdate, rcUpdate, RECT); 06867 } except (StubExceptionHandler(TRUE)) { 06868 MSGERROR(0); 06869 } 06870 } 06871 ENDRECV(); 06872 } 06873 06874 int NtUserInternalGetWindowText( // private InternalGetWindowText 06875 IN HWND hwnd, 06876 OUT LPWSTR lpString, 06877 IN int nMaxCount) 06878 { 06879 06880 // 06881 // N.B. This function has implicit window handle translation. This 06882 // operation is performed in the User server API dispatcher. 06883 // 06884 06885 BEGINRECV_HWND_SHARED(DWORD, 0, hwnd); 06886 06887 if (nMaxCount) { 06888 /* 06889 * Probe arguments 06890 */ 06891 try { 06892 ProbeForWriteBuffer(lpString, nMaxCount, CHARALIGN); 06893 /* 06894 * Initialize string empty. 06895 */ 06896 *lpString = TEXT('\0'); 06897 if (pwnd->strName.Length) { 06898 retval = TextCopy(&pwnd->strName, lpString, nMaxCount); 06899 } else { 06900 retval = 0; 06901 } 06902 06903 } except (StubExceptionHandler(FALSE)) { 06904 MSGERROR(0); // private API, don't SetLastError 06905 } 06906 } else { 06907 MSGERROR(0); 06908 } 06909 06910 TRACE("NtUserInternalGetWindowText"); 06911 ENDRECV_HWND_SHARED(); 06912 } 06913 06914 int NtUserGetMouseMovePointsEx( // API GetMouseMovePointsEx 06915 IN UINT cbSize, 06916 IN CONST MOUSEMOVEPOINT *lppt, 06917 OUT MOUSEMOVEPOINT *lpptBuf, 06918 IN UINT nBufPoints, 06919 IN DWORD resolution) 06920 { 06921 MOUSEMOVEPOINT mmp; 06922 BEGINRECV(int, -1); 06923 06924 if (cbSize != sizeof(MOUSEMOVEPOINT) || nBufPoints > MAX_MOUSEPOINTS) { 06925 06926 RIPERR2(ERROR_INVALID_PARAMETER, RIP_VERBOSE, 06927 "GetMouseMovePointsEx: invalid cbSize %d or nBufPoints %d", 06928 cbSize, nBufPoints); 06929 MSGERROR(0); 06930 } 06931 06932 /* 06933 * Probe arguments 06934 */ 06935 try { 06936 mmp = ProbeAndReadStructure(lppt, MOUSEMOVEPOINT); 06937 ProbeForWriteBuffer(lpptBuf, nBufPoints, DATAALIGN); 06938 } except (StubExceptionHandler(TRUE)) { 06939 MSGERROR(0); 06940 } 06941 06942 /* 06943 * GetMouseMovePointsEx protects itself with a try block. 06944 * No it doesn't! 06945 */ 06946 06947 retval = _GetMouseMovePointsEx(&mmp, lpptBuf, nBufPoints, resolution); 06948 06949 TRACE("NtUserGetMouseMovePointsEx"); 06950 ENDRECV(); 06951 } 06952 06953 int NtUserToUnicodeEx( // API ToUnicode/ToUnicodeEx/ToAscii/ToAsciiEx 06954 IN UINT wVirtKey, 06955 IN UINT wScanCode, 06956 IN CONST BYTE *lpKeyState, 06957 OUT LPWSTR pwszBuff, 06958 IN int cchBuff, 06959 IN UINT wFlags, 06960 IN HKL hKeyboardLayout) 06961 { 06962 BYTE KeyState[256]; 06963 WCHAR wcBuff[4]; 06964 LPWSTR pwszBuffK; 06965 BOOL bAlloc = FALSE; 06966 PTHREADINFO ptiCurrent; 06967 TL tlInput; 06968 06969 BEGINRECV(int, 0); 06970 06971 if (cchBuff <= 0) { 06972 MSGERROR(ERROR_INVALID_PARAMETER); 06973 } 06974 06975 /* 06976 * Probe arguments 06977 */ 06978 try { 06979 ProbeForRead(lpKeyState, 256, sizeof(BYTE)); 06980 RtlCopyMemory(&KeyState, lpKeyState, 256); 06981 ProbeForWriteBuffer(pwszBuff, cchBuff, CHARALIGN); 06982 if (cchBuff < 4) { 06983 pwszBuffK = wcBuff; 06984 }else { 06985 pwszBuffK = UserAllocPoolWithQuota(cchBuff * sizeof(WCHAR), TAG_UNICODEBUFFER); 06986 if (pwszBuffK == NULL) { 06987 ExRaiseStatus(STATUS_NO_MEMORY); 06988 } 06989 bAlloc = TRUE; 06990 ptiCurrent = PtiCurrent(); 06991 ThreadLockPool(ptiCurrent, pwszBuffK, &tlInput); 06992 } 06993 } except (StubExceptionHandler(TRUE)) { 06994 MSGERROR(0); 06995 } 06996 06997 retval = xxxToUnicodeEx( 06998 wVirtKey, 06999 wScanCode, 07000 KeyState, 07001 pwszBuffK, 07002 cchBuff, 07003 wFlags, 07004 hKeyboardLayout); 07005 07006 try { 07007 RtlCopyMemory(pwszBuff, pwszBuffK, cchBuff*sizeof(WCHAR)); 07008 } except (StubExceptionHandler(TRUE)) { 07009 MSGERRORCLEANUP(0); 07010 } 07011 07012 CLEANUPRECV(); 07013 07014 if (bAlloc) { 07015 ThreadUnlockAndFreePool(ptiCurrent, &tlInput); 07016 } 07017 07018 TRACE("NtUserToUnicodeEx"); 07019 ENDRECV(); 07020 } 07021 07022 BOOL NtUserYieldTask( 07023 VOID) 07024 { 07025 PTHREADINFO ptiCurrent; 07026 07027 BEGINRECV(BOOL, FALSE); 07028 07029 /* 07030 * Make sure this process is running in the background if it is just 07031 * spinning. 07032 */ 07033 ptiCurrent = PtiCurrent(); 07034 07035 ptiCurrent->pClientInfo->cSpins++; 07036 07037 /* 07038 * CheckProcessBackground see input.c for comments 07039 */ 07040 if (ptiCurrent->pClientInfo->cSpins >= CSPINBACKGROUND) { 07041 ptiCurrent->pClientInfo->cSpins = 0; 07042 ptiCurrent->TIF_flags |= TIF_SPINNING; 07043 ptiCurrent->pClientInfo->dwTIFlags |= TIF_SPINNING; 07044 07045 if (!(ptiCurrent->ppi->W32PF_Flags & W32PF_FORCEBACKGROUNDPRIORITY)) { 07046 ptiCurrent->ppi->W32PF_Flags |= W32PF_FORCEBACKGROUNDPRIORITY; 07047 if (ptiCurrent->ppi == gppiWantForegroundPriority) { 07048 SetForegroundPriority(ptiCurrent, FALSE); 07049 } 07050 } 07051 } 07052 07053 retval = xxxUserYield(ptiCurrent); 07054 07055 TRACE("NtUserYieldTask"); 07056 ENDRECV(); 07057 } 07058 07059 BOOL NtUserWaitMessage( 07060 VOID) 07061 { 07062 BEGINRECV(BOOL, FALSE); 07063 07064 retval = xxxWaitMessage(); 07065 07066 TRACE("NtUserWaitMessage"); 07067 ENDRECV(); 07068 } 07069 07070 UINT NtUserLockWindowStation( 07071 IN HWINSTA hwinsta) 07072 { 07073 PWINDOWSTATION pwinsta; 07074 NTSTATUS Status; 07075 07076 BEGINRECV(UINT, 0); 07077 07078 Status = ValidateHwinsta(hwinsta, UserMode, 0, &pwinsta); 07079 if (!NT_SUCCESS(Status)) 07080 MSGERROR(0); 07081 07082 retval = _LockWindowStation(pwinsta); 07083 07084 ObDereferenceObject(pwinsta); 07085 07086 TRACE("NtUserLockWindowStation"); 07087 ENDRECV(); 07088 } 07089 07090 BOOL NtUserUnlockWindowStation( 07091 IN HWINSTA hwinsta) 07092 { 07093 PWINDOWSTATION pwinsta; 07094 NTSTATUS Status; 07095 07096 BEGINRECV(BOOL, FALSE); 07097 07098 Status = ValidateHwinsta(hwinsta, UserMode, 0, &pwinsta); 07099 if (!NT_SUCCESS(Status)) 07100 MSGERROR(0); 07101 07102 retval = _UnlockWindowStation(pwinsta); 07103 07104 ObDereferenceObject(pwinsta); 07105 07106 TRACE("NtUserUnlockWindowStation"); 07107 ENDRECV(); 07108 } 07109 07110 UINT NtUserSetWindowStationUser( // private SetWindowStationUser 07111 IN HWINSTA hwinsta, 07112 IN PLUID pLuidUser, 07113 IN PSID pSidUser OPTIONAL, 07114 IN DWORD cbSidUser) 07115 { 07116 PWINDOWSTATION pwinsta; 07117 NTSTATUS Status; 07118 LUID luid; 07119 BEGINATOMICRECV(UINT, FALSE); 07120 07121 Status = ValidateHwinsta(hwinsta, UserMode, 0, &pwinsta); 07122 if (!NT_SUCCESS(Status)) 07123 MSGERROR(0); 07124 07125 try { 07126 ProbeForRead(pLuidUser, sizeof(*pLuidUser), sizeof(DWORD)); 07127 luid = *pLuidUser; 07128 if (ARGUMENT_PRESENT(pSidUser)) { 07129 ProbeForRead(pSidUser, cbSidUser, sizeof(DWORD)); 07130 } 07131 } except (StubExceptionHandler(FALSE)) { 07132 MSGERRORCLEANUP(0); // don't SetLastError for private API 07133 } 07134 07135 /* 07136 * SetWindowStationUser uses pSidUser in a try block. 07137 */ 07138 07139 retval = _SetWindowStationUser(pwinsta, &luid, pSidUser, cbSidUser); 07140 07141 CLEANUPRECV(); 07142 07143 ObDereferenceObject(pwinsta); 07144 07145 TRACE("NtUserSetWindowStationUser"); 07146 ENDATOMICRECV(); 07147 } 07148 07149 BOOL NtUserSetLogonNotifyWindow( 07150 IN HWND hwnd) 07151 { 07152 07153 // 07154 // N.B. This function has implicit window handle translation. This 07155 // operation is performed in the User server API dispatcher. 07156 // 07157 07158 BEGINRECV_HWND(BOOL, FALSE, hwnd); 07159 07160 retval = _SetLogonNotifyWindow(pwnd); 07161 07162 TRACE("NtUserSetLogonNotifyWindow"); 07163 ENDRECV_HWND(); 07164 } 07165 07166 BOOL NtUserSetSystemCursor( 07167 IN HCURSOR hcur, 07168 IN DWORD id) 07169 { 07170 PCURSOR pcur; 07171 07172 BEGINRECV(BOOL, FALSE); 07173 07174 ValidateHCURSOR(pcur, hcur); 07175 07176 retval = zzzSetSystemCursor( 07177 pcur, 07178 id); 07179 07180 TRACE("NtUserSetSystemCursor"); 07181 ENDRECV(); 07182 } 07183 07184 HCURSOR NtUserGetCursorFrameInfo( // private GetCursorFrameInfo (Obsolete? - IanJa) 07185 IN HCURSOR hcur, 07186 IN int iFrame, 07187 OUT LPDWORD pjifRate, 07188 OUT LPINT pccur) 07189 { 07190 PCURSOR pcur; 07191 DWORD jifRate; 07192 INT ccur; 07193 07194 BEGINRECV_SHARED(HCURSOR, NULL); 07195 07196 ValidateHCURSOR(pcur, hcur); 07197 07198 /* 07199 * Probe arguments 07200 */ 07201 try { 07202 ProbeForWriteUlong(pjifRate); 07203 ProbeForWriteLong(pccur); 07204 } except (StubExceptionHandler(FALSE)) { 07205 MSGERROR(0); // don't SetLastError for private API 07206 } 07207 07208 retval = (HCURSOR)_GetCursorFrameInfo( 07209 pcur, 07210 iFrame, 07211 &jifRate, 07212 &ccur); 07213 retval = PtoH((PVOID)retval); 07214 try { 07215 *pjifRate = jifRate; 07216 *pccur = ccur; 07217 } except (StubExceptionHandler(FALSE)) { 07218 MSGERROR(0); // don't SetLastError for private API 07219 } 07220 07221 TRACE("NtUserGetCursorFrameInfo"); 07222 ENDRECV_SHARED(); 07223 } 07224 07225 BOOL NtUserSetCursorContents( 07226 IN HCURSOR hCursor, 07227 IN HCURSOR hCursorNew) 07228 { 07229 PCURSOR pCursor; 07230 PCURSOR pCursorNew; 07231 07232 BEGINATOMICRECV(BOOL, FALSE); 07233 07234 ValidateHCURSOR(pCursor, hCursor); 07235 ValidateHCURSOR(pCursorNew, hCursorNew); 07236 07237 retval = _SetCursorContents(pCursor, pCursorNew); 07238 07239 TRACE("NtUserSetCursorContents"); 07240 ENDATOMICRECV(); 07241 } 07242 07243 HCURSOR NtUserFindExistingCursorIcon( // Various Icon/Cursor APIs 07244 IN PUNICODE_STRING pstrModName, 07245 IN PUNICODE_STRING pstrResName, 07246 IN PCURSORFIND pcfSearch) 07247 { 07248 ATOM atomModName; 07249 UNICODE_STRING strModName; 07250 UNICODE_STRING strResName; 07251 PCURSOR pcurSrc; 07252 CURSORFIND cfSearch; 07253 07254 BEGINRECV_SHARED(HCURSOR, NULL); 07255 07256 /* 07257 * Probe arguments 07258 */ 07259 try { 07260 07261 cfSearch = ProbeAndReadCursorFind(pcfSearch); 07262 07263 ValidateHCURSOROPT(pcurSrc, cfSearch.hcur); 07264 07265 strModName = ProbeAndReadUnicodeString(pstrModName); 07266 ProbeForReadUnicodeStringBuffer(strModName); 07267 07268 strResName = ProbeAndReadUnicodeString(pstrResName); 07269 ProbeForReadUnicodeStringBufferOrId(strResName); 07270 07271 } except (StubExceptionHandler(TRUE)) { 07272 MSGERROR(0); 07273 } 07274 07275 /* 07276 * The ModName buffer is client-side, but UserFindAtom protects 07277 * access. 07278 */ 07279 07280 atomModName = UserFindAtom(strModName.Buffer); 07281 07282 if (atomModName) { 07283 07284 /* 07285 * The ResName buffer is client-side. FindExistincCursorIcon 07286 * protects access. 07287 */ 07288 retval = (HCURSOR)_FindExistingCursorIcon(atomModName, 07289 &strResName, 07290 pcurSrc, 07291 &cfSearch); 07292 07293 retval = (HCURSOR)PtoH((PCURSOR)retval); 07294 07295 } else { 07296 07297 retval = 0; 07298 } 07299 07300 07301 TRACE("NtUserFindExistingCursorIcon"); 07302 ENDRECV_SHARED(); 07303 } 07304 07305 BOOL NtUserSetCursorIconData( // worker called by CreateIcon, CreateCursor etc. 07306 IN HCURSOR hCursor, 07307 IN PUNICODE_STRING pstrModName, 07308 IN PUNICODE_STRING pstrResName, 07309 IN PCURSORDATA pData) 07310 { 07311 UNICODE_STRING strModName; 07312 UNICODE_STRING strResName; 07313 PCURSOR pCursor; 07314 CURSORDATA curData; 07315 DWORD cbData; 07316 07317 BEGINATOMICRECV(BOOL, FALSE); 07318 07319 ValidateHCURSOR(pCursor, hCursor); 07320 07321 /* 07322 * Probe arguments 07323 */ 07324 try { 07325 07326 strModName = ProbeAndReadUnicodeString(pstrModName); 07327 strResName = ProbeAndReadUnicodeString(pstrResName); 07328 07329 ProbeForReadUnicodeStringBuffer(strModName); 07330 ProbeForReadUnicodeStringBufferOrId(strResName); 07331 07332 curData = ProbeAndReadCursorData(pData); 07333 07334 if (curData.CURSORF_flags & CURSORF_ACON) { 07335 /* 07336 * Avoid overflow here. Or we might end up probing less 07337 * MCostea #199188 07338 */ 07339 if (HIWORD(curData.cpcur) | HIWORD(curData.cicur)) { 07340 MSGERROR(0); 07341 } 07342 /* 07343 * The code assumes that the memory was allocated in one chunk 07344 * as in CreateAniIcon(). To prevent evil apps, do this check. 07345 */ 07346 if ((INT_PTR)curData.ajifRate != curData.cpcur * (INT_PTR) sizeof(HCURSOR) || 07347 (INT_PTR)curData.aicur != (INT_PTR)curData.ajifRate + curData.cicur * (INT_PTR) sizeof(JIF)) { 07348 MSGERROR(0); 07349 } 07350 cbData = (curData.cpcur * sizeof(HCURSOR)) + 07351 (curData.cicur * sizeof(JIF)) + 07352 (curData.cicur * sizeof(DWORD)); 07353 07354 } else { 07355 cbData = 0; 07356 } 07357 ProbeForRead(curData.aspcur, cbData, sizeof(DWORD)); 07358 07359 } except (StubExceptionHandler(FALSE)) { 07360 /* 07361 * probed parameters are USER stack variables, not supplied by the 07362 * application itself, so don't bother to SetLastError. 07363 */ 07364 MSGERROR(0); 07365 } 07366 07367 /* 07368 * SetCursorIconData guards use of the buffer addresses 07369 * with try clauses. 07370 */ 07371 retval = _SetCursorIconData(pCursor, 07372 &strModName, 07373 &strResName, 07374 &curData, 07375 cbData); 07376 07377 TRACE("NtUserSetCursorIconData"); 07378 ENDATOMICRECV(); 07379 } 07380 07381 BOOL NtUserGetMenuItemRect( // API GetMenuItemRect 07382 IN HWND hwnd, 07383 IN HMENU hMenu, 07384 IN UINT uItem, 07385 OUT LPRECT lprcItem) 07386 { 07387 07388 // 07389 // N.B. This function has implicit window translation and thread locking 07390 // enabled. These operations are performed in the User server API 07391 // dispatcher. 07392 // 07393 07394 PMENU pmenu; 07395 TL tlpmenu; 07396 RECT rcItem; 07397 07398 BEGINRECV_HWNDLOCK_OPT(DWORD, 0, hwnd); 07399 07400 ValidateHMENU(pmenu, hMenu); 07401 07402 ThreadLockAlwaysWithPti(ptiCurrent, pmenu, &tlpmenu); 07403 07404 retval = xxxGetMenuItemRect( 07405 pwnd, 07406 pmenu, 07407 uItem, 07408 &rcItem); 07409 /* 07410 * Probe arguments 07411 */ 07412 try { 07413 ProbeAndWriteStructure(lprcItem, rcItem, RECT); 07414 } except (StubExceptionHandler(TRUE)) { 07415 MSGERRORCLEANUP(0); 07416 } 07417 07418 CLEANUPRECV(); 07419 07420 ThreadUnlock(&tlpmenu); 07421 07422 TRACE("NtUserGetMenuItemRect"); 07423 ENDRECV_HWNDLOCK_OPT(); 07424 } 07425 07426 int NtUserMenuItemFromPoint( // API MenuItemFromPoint 07427 IN HWND hwnd, 07428 IN HMENU hMenu, 07429 IN POINT ptScreen) 07430 { 07431 07432 // 07433 // N.B. This function has implicit window translation and thread locking 07434 // enabled. These operations are performed in the User server API 07435 // dispatcher. 07436 // 07437 07438 PMENU pmenu; 07439 TL tlpmenu; 07440 07441 BEGINRECV_HWNDLOCK_OPT(DWORD, -1, hwnd); 07442 07443 ValidateHMENU(pmenu, hMenu); 07444 07445 ThreadLockAlwaysWithPti(ptiCurrent, pmenu, &tlpmenu); 07446 07447 retval = xxxMenuItemFromPoint( 07448 pwnd, 07449 pmenu, 07450 ptScreen); 07451 07452 ThreadUnlock(&tlpmenu); 07453 07454 TRACE("NtUserMenuItemFromPoint"); 07455 ENDRECV_HWNDLOCK_OPT(); 07456 } 07457 07458 BOOL NtUserGetCaretPos( // API GetCaretPos 07459 OUT LPPOINT lpPoint) 07460 { 07461 07462 // 07463 // N.B. This function has implicit window handle translation. This 07464 // operation is performed in the User server API dispatcher. 07465 // 07466 07467 PTHREADINFO pti; 07468 PQ pq; 07469 BEGINRECV_SHARED(BOOL, FALSE); 07470 07471 /* 07472 * Probe arguments 07473 */ 07474 try { 07475 ProbeForWritePoint(lpPoint); 07476 07477 pti = PtiCurrentShared(); 07478 pq = pti->pq; 07479 lpPoint->x = pq->caret.x; 07480 lpPoint->y = pq->caret.y; 07481 retval = TRUE; 07482 } except (StubExceptionHandler(TRUE)) { 07483 MSGERROR(0); 07484 } 07485 07486 TRACE("NtUserGetCaretPos"); 07487 ENDRECV_SHARED(); 07488 } 07489 07490 BOOL NtUserDefSetText( 07491 IN HWND hwnd, 07492 IN PLARGE_STRING pstrText OPTIONAL) 07493 { 07494 LARGE_STRING strText; 07495 07496 // 07497 // N.B. This function has implicit window handle translation. This 07498 // operation is performed in the User server API dispatcher. 07499 // 07500 07501 BEGINRECV_HWND(DWORD, 0, hwnd); 07502 07503 /* 07504 * Probe arguments 07505 */ 07506 if (ARGUMENT_PRESENT(pstrText)) { 07507 try { 07508 strText = ProbeAndReadLargeString(pstrText); 07509 #if defined(_X86_) 07510 ProbeForRead(strText.Buffer, strText.Length, sizeof(BYTE)); 07511 #else 07512 ProbeForRead(strText.Buffer, strText.Length, 07513 strText.bAnsi ? sizeof(BYTE) : sizeof(WORD)); 07514 #endif 07515 pstrText = &strText; 07516 } except (StubExceptionHandler(TRUE)) { 07517 MSGERROR(0); // WM_SETTEXT lParam 07518 } 07519 } 07520 07521 /* 07522 * pstrText buffer is client side. DefSetText protects uses of the buffer. 07523 */ 07524 retval = DefSetText( 07525 pwnd, 07526 pstrText); 07527 07528 TRACE("NtUserDefSetText"); 07529 ENDRECV_HWND(); 07530 } 07531 07532 NTSTATUS NtUserQueryInformationThread( 07533 IN HANDLE hThread, 07534 IN USERTHREADINFOCLASS ThreadInfoClass, 07535 OUT PVOID ThreadInformation, 07536 IN ULONG ThreadInformationLength, 07537 IN OUT PULONG ReturnLength OPTIONAL) 07538 { 07539 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 07540 /* 07541 * note -- QueryInformationThread can call xxxSwitchDesktop, so it is not sharable 07542 */ 07543 07544 /* 07545 * Probe arguments -- no try/except 07546 */ 07547 07548 #if DBG 07549 if (ARGUMENT_PRESENT(ThreadInformation)) { 07550 switch (ThreadInfoClass) { 07551 case UserThreadShutdownInformation: 07552 case UserThreadFlags: 07553 case UserThreadWOWInformation: 07554 case UserThreadHungStatus: 07555 ProbeForWriteBoolean((PBOOLEAN)ThreadInformation); 07556 break; 07557 case UserThreadTaskName: 07558 ProbeForWrite(ThreadInformation, ThreadInformationLength, 07559 sizeof(WCHAR)); 07560 break; 07561 } 07562 } 07563 if (ARGUMENT_PRESENT(ReturnLength)) 07564 ProbeForWriteUlong(ReturnLength); 07565 #endif 07566 07567 retval = xxxQueryInformationThread(hThread, 07568 ThreadInfoClass, ThreadInformation, 07569 ThreadInformationLength, ReturnLength); 07570 07571 TRACE("NtUserQueryInformationThread"); 07572 ENDRECVCSRSS(); 07573 } 07574 07575 NTSTATUS NtUserSetInformationThread( 07576 IN HANDLE hThread, 07577 IN USERTHREADINFOCLASS ThreadInfoClass, 07578 IN PVOID ThreadInformation, 07579 IN ULONG ThreadInformationLength) 07580 { 07581 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 07582 07583 /* 07584 * Probe arguments outside a try clause -- CSRSS 07585 */ 07586 #if DBG 07587 if (ThreadInfoClass == UserThreadUseDesktop) { 07588 ProbeForWrite(ThreadInformation, ThreadInformationLength, 07589 sizeof(DWORD)); 07590 } else { 07591 ProbeForRead(ThreadInformation, ThreadInformationLength, 07592 sizeof(DWORD)); 07593 } 07594 07595 #endif 07596 07597 retval = xxxSetInformationThread(hThread, 07598 ThreadInfoClass, ThreadInformation, 07599 ThreadInformationLength); 07600 07601 07602 TRACE("NtUserSetInformationThread"); 07603 ENDRECVCSRSS(); 07604 } 07605 07606 NTSTATUS NtUserSetInformationProcess( 07607 IN HANDLE hProcess, 07608 IN USERPROCESSINFOCLASS ProcessInfoClass, 07609 IN PVOID ProcessInformation, 07610 IN ULONG ProcessInformationLength) 07611 { 07612 BEGINRECVCSRSS(NTSTATUS, STATUS_UNSUCCESSFUL); 07613 07614 /* 07615 * Probe arguments without try/except 07616 */ 07617 #if DBG 07618 ProbeForRead(ProcessInformation, ProcessInformationLength, 07619 sizeof(DWORD)); 07620 #endif 07621 07622 retval = SetInformationProcess(hProcess, 07623 ProcessInfoClass, ProcessInformation, 07624 ProcessInformationLength); 07625 07626 07627 TRACE("NtUserSetInformationProcess"); 07628 ENDRECVCSRSS(); 07629 } 07630 07631 BOOL NtUserNotifyProcessCreate( 07632 IN DWORD dwProcessId, 07633 IN DWORD dwParentThreadId, 07634 IN ULONG_PTR dwData, 07635 IN DWORD dwFlags) 07636 { 07637 extern BOOL xxxUserNotifyProcessCreate(DWORD idProcess, DWORD idParentThread, 07638 ULONG_PTR dwData, DWORD dwFlags); 07639 07640 BEGINRECVCSRSS(BOOL, FALSE); 07641 07642 retval = xxxUserNotifyProcessCreate(dwProcessId, 07643 dwParentThreadId, 07644 dwData, 07645 dwFlags); 07646 07647 TRACE("NtUserNotifyProcessCreate"); 07648 ENDRECVCSRSS(); 07649 } 07650 07651 NTSTATUS NtUserSoundSentry(VOID) 07652 { 07653 BEGINRECV(NTSTATUS, STATUS_UNSUCCESSFUL); 07654 07655 retval = (_UserSoundSentryWorker() ? 07656 STATUS_SUCCESS : STATUS_UNSUCCESSFUL); 07657 07658 TRACE("NtUserSoundSentry"); 07659 ENDRECV(); 07660 } 07661 07662 NTSTATUS NtUserTestForInteractiveUser( // private _UserTestTokenForInteractive 07663 IN PLUID pluidCaller) 07664 { 07665 LUID luidCaller; 07666 07667 BEGINRECV_SHARED(NTSTATUS, STATUS_UNSUCCESSFUL); 07668 07669 /* 07670 * Probe arguments 07671 */ 07672 try { 07673 luidCaller = ProbeAndReadStructure(pluidCaller, LUID); 07674 } except (StubExceptionHandler(FALSE)) { 07675 MSGERROR(0); 07676 } 07677 07678 retval = TestForInteractiveUser(&luidCaller); 07679 07680 TRACE("NtUserTestForInteractiveUser"); 07681 ENDRECV_SHARED(); 07682 } 07683 07684 BOOL NtUserSetConsoleReserveKeys( 07685 IN HWND hwnd, 07686 IN DWORD fsReserveKeys) 07687 { 07688 BOOL _SetConsoleReserveKeys(PWND, DWORD); 07689 07690 // 07691 // N.B. This function has implicit window handle translation. This 07692 // operation is performed in the User server API dispatcher. 07693 // 07694 07695 BEGINRECV_HWND(BOOL, FALSE, hwnd); 07696 07697 retval = _SetConsoleReserveKeys(pwnd, fsReserveKeys); 07698 07699 TRACE("NtUserSetConsoleReserveKeys"); 07700 ENDRECV_HWND(); 07701 } 07702 07703 VOID NtUserModifyUserStartupInfoFlags( 07704 IN DWORD dwMask, 07705 IN DWORD dwFlags) 07706 { 07707 BEGINRECV_VOID(); 07708 07709 PpiCurrent()->usi.dwFlags = (PpiCurrent()->usi.dwFlags & ~dwMask) | (dwFlags & dwMask); 07710 07711 TRACEVOID("NtUserModifyUserStartupInfoFlags"); 07712 ENDRECV_VOID(); 07713 } 07714 07715 BOOL NtUserSetWindowFNID( 07716 IN HWND hwnd, 07717 IN WORD fnid) 07718 { 07719 BEGINRECV_HWND(BOOL, FALSE, hwnd); 07720 07721 /* 07722 * Don't let apps mess with windows on other processes. 07723 */ 07724 if (GETPTI(pwnd)->ppi != PpiCurrent()) { 07725 MSGERROR(0); 07726 } 07727 07728 /* 07729 * Make sure the fnid is in the correct range. 07730 */ 07731 if (fnid != FNID_CLEANEDUP_BIT) { 07732 if ((fnid < FNID_CONTROLSTART) || (fnid > FNID_CONTROLEND) || (GETFNID(pwnd) != 0)) { 07733 MSGERROR(0); 07734 } 07735 } 07736 07737 /* 07738 * Remember what window class this window belongs to. Can't use 07739 * the real class because any app can call CallWindowProc() 07740 * directly no matter what the class is! 07741 */ 07742 pwnd->fnid |= fnid; 07743 retval = TRUE; 07744 07745 TRACE("NtUserSetWindowFNID"); 07746 ENDRECV_HWND(); 07747 } 07748 07749 #define AWS_MASK (BS_TYPEMASK | BS_RIGHT | BS_RIGHTBUTTON | \ 07750 WS_HSCROLL | WS_VSCROLL | SS_TYPEMASK) 07751 07752 VOID NtUserAlterWindowStyle( 07753 IN HWND hwnd, 07754 IN DWORD mask, 07755 IN DWORD flags) 07756 { 07757 BEGINRECV_HWND_VOID(hwnd); 07758 07759 if (GETPTI(pwnd)->ppi == PpiCurrent()) { 07760 07761 #if DBG 07762 if (mask & ~AWS_MASK) { 07763 RIPMSG1(RIP_WARNING, "NtUserAlterWindowStyle: bad mask %x", mask); 07764 } 07765 #endif 07766 07767 mask &= AWS_MASK; 07768 pwnd->style = (pwnd->style & (~mask)) | (flags & mask); 07769 } else { 07770 RIPMSG1(RIP_WARNING, "NtUserAlterWIndowStyle: current ppi doesn't own pwnd %#p", pwnd); 07771 } 07772 07773 TRACEVOID("NtUserAlterWindowStyle"); 07774 ENDRECV_HWND_VOID(); 07775 } 07776 07777 VOID NtUserSetThreadState( 07778 IN DWORD dwFlags, 07779 IN DWORD dwMask) 07780 { 07781 PTHREADINFO ptiCurrent; 07782 DWORD dwOldFlags; 07783 07784 if (dwFlags & ~(QF_DIALOGACTIVE)) { 07785 return; 07786 } 07787 07788 BEGINRECV_VOID(); 07789 07790 ptiCurrent = PtiCurrent(); 07791 dwOldFlags = ptiCurrent->pq->QF_flags; 07792 ptiCurrent->pq->QF_flags ^= ((dwOldFlags ^ dwFlags) & dwMask); 07793 07794 TRACEVOID("NtUserSetThreadState"); 07795 ENDRECV_VOID(); 07796 } 07797 07798 07799 ULONG_PTR NtUserGetThreadState( 07800 IN USERTHREADSTATECLASS ThreadState) 07801 { 07802 PTHREADINFO ptiCurrent = PtiCurrentShared(); 07803 07804 BEGINRECV_SHARED(ULONG_PTR, 0); 07805 07806 switch (ThreadState) { 07807 case UserThreadStateFocusWindow: 07808 retval = (ULONG_PTR)HW(ptiCurrent->pq->spwndFocus); 07809 break; 07810 case UserThreadStateActiveWindow: 07811 retval = (ULONG_PTR)HW(ptiCurrent->pq->spwndActive); 07812 break; 07813 case UserThreadStateCaptureWindow: 07814 retval = (ULONG_PTR)HW(ptiCurrent->pq->spwndCapture); 07815 break; 07816 case UserThreadStateDefaultImeWindow: 07817 retval = (ULONG_PTR)HW(ptiCurrent->spwndDefaultIme); 07818 break; 07819 case UserThreadStateDefaultInputContext: 07820 retval = (ULONG_PTR)PtoH(ptiCurrent->spDefaultImc); 07821 break; 07822 case UserThreadStateImeCompatFlags: 07823 UserAssert(ptiCurrent->ppi != NULL); 07824 retval = (DWORD)(ptiCurrent->ppi->dwImeCompatFlags); 07825 break; 07826 case UserThreadStatePreviousKeyboardLayout: 07827 retval = (ULONG_PTR)(ptiCurrent->hklPrev); 07828 break; 07829 case UserThreadStateIsWinlogonThread: 07830 // Client IMM checks if the process is Login; 07831 // to prevent switching dictionaries, etc. 07832 // LATER: gpidLogin per WinStation ? 07833 retval = (DWORD)(GetCurrentProcessId() == gpidLogon); 07834 break; 07835 case UserThreadStateIsConImeThread: 07836 UserAssert(ptiCurrent->rpdesk != NULL); 07837 retval = (DWORD)(PtiFromThreadId(ptiCurrent->rpdesk->dwConsoleIMEThreadId) == ptiCurrent); 07838 break; 07839 case UserThreadStateInputState: 07840 retval = (DWORD)_GetInputState(); 07841 break; 07842 case UserThreadStateCursor: 07843 retval = (ULONG_PTR)PtoH(ptiCurrent->pq->spcurCurrent); 07844 break; 07845 case UserThreadStateChangeBits: 07846 retval = ptiCurrent->pcti->fsChangeBits; 07847 break; 07848 case UserThreadStatePeekMessage: 07849 /* 07850 * Update the last read time so that hung app painting won't occur. 07851 */ 07852 SET_TIME_LAST_READ(ptiCurrent); 07853 retval = (DWORD)FALSE; 07854 break; 07855 case UserThreadStateExtraInfo: 07856 retval = ptiCurrent->pq->ExtraInfo; 07857 break; 07858 07859 case UserThreadStateInSendMessage: 07860 if (ptiCurrent->psmsCurrent != NULL) { 07861 if (ptiCurrent->psmsCurrent->ptiSender != NULL) { 07862 retval = ISMEX_SEND; 07863 } else if (ptiCurrent->psmsCurrent->flags & (SMF_CB_REQUEST | SMF_CB_REPLY)) { 07864 retval = ISMEX_CALLBACK; 07865 } else { 07866 retval = ISMEX_NOTIFY; 07867 } 07868 07869 if (ptiCurrent->psmsCurrent->flags & SMF_REPLY) { 07870 retval |= ISMEX_REPLIED; 07871 } 07872 } else { 07873 retval = ISMEX_NOSEND; 07874 } 07875 break; 07876 07877 case UserThreadStateMessageTime: 07878 retval = ptiCurrent->timeLast; 07879 break; 07880 case UserThreadStateIsForeground: 07881 retval = (ptiCurrent->pq == gpqForeground); 07882 break; 07883 case UserThreadConnect: 07884 retval = TRUE; 07885 break; 07886 default: 07887 RIPMSG1(RIP_WARNING, "NtUserGetThreadState invalid ThreadState:%#x", ThreadState); 07888 MSGERROR(0); 07889 } 07890 07891 ENDRECV_SHARED(); 07892 } 07893 07894 BOOL NtUserValidateHandleSecure( 07895 IN HANDLE h) 07896 { 07897 BEGINRECV(BOOL, FALSE); 07898 07899 retval = ValidateHandleSecure(h); 07900 07901 TRACE("NtUserValidateHandleSecure"); 07902 ENDRECV(); 07903 } 07904 07905 BOOL NtUserUserHandleGrantAccess( // API UserHandleGrantAccess 07906 IN HANDLE hUserHandle, 07907 IN HANDLE hJob, 07908 IN BOOL bGrant) 07909 { 07910 NTSTATUS Status; 07911 PEJOB Job; 07912 PW32JOB pW32Job; 07913 DWORD dw; 07914 PHE phe; 07915 PULONG_PTR pgh; 07916 BOOL retval; 07917 BOOL errret = FALSE; 07918 07919 Status = ObReferenceObjectByHandle( 07920 hJob, 07921 JOB_OBJECT_SET_ATTRIBUTES, 07922 *PsJobType, 07923 UserMode, 07924 (PVOID*)&Job, 07925 NULL); 07926 07927 if (!NT_SUCCESS(Status)) { 07928 RIPERR1(ERROR_INVALID_PARAMETER, 07929 RIP_WARNING, 07930 "UserHandleGrantAccess: invalid job handle %#p\n", 07931 hJob); 07932 return FALSE; 07933 } 07934 07935 /* 07936 * aquire the job's lock and after that enter the user 07937 * critical section. 07938 */ 07939 KeEnterCriticalRegion(); 07940 ExAcquireResourceExclusive(&Job->JobLock, TRUE); 07941 07942 EnterCrit(); 07943 07944 /* 07945 * bail out if it doesn't have UI restrictions 07946 */ 07947 if (Job->UIRestrictionsClass == 0) { 07948 RIPERR1(ERROR_INVALID_PARAMETER, 07949 RIP_WARNING, 07950 "UserHandleGrantAccess: job %#p doesn't have UI restrictions\n", 07951 hJob); 07952 MSGERRORCLEANUP(0); 07953 } 07954 07955 /* 07956 * see if we have a W32JOB structure created for this job 07957 */ 07958 pW32Job = gpJobsList; 07959 07960 while (pW32Job) { 07961 if (pW32Job->Job == Job) { 07962 break; 07963 } 07964 pW32Job = pW32Job->pNext; 07965 } 07966 07967 UserAssert(pW32Job != NULL); 07968 07969 try { 07970 /* 07971 * Now, validate the 'unsecure' handle 07972 */ 07973 if (HMValidateHandle(hUserHandle, TYPE_GENERIC) == NULL) { 07974 RIPERR1(ERROR_INVALID_PARAMETER, 07975 RIP_WARNING, 07976 "UserHandleGrantAccess: invalid handle %#p\n", 07977 hUserHandle); 07978 07979 MSGERRORCLEANUP(0); 07980 } 07981 07982 dw = HMIndexFromHandle(hUserHandle); 07983 07984 phe = &gSharedInfo.aheList[dw]; 07985 07986 phe->bFlags |= HANDLEF_GRANTED; 07987 07988 pgh = pW32Job->pgh; 07989 07990 if (bGrant) { 07991 /* 07992 * Add the handle to the process' list 07993 */ 07994 if (pW32Job->ughCrt == pW32Job->ughMax) { 07995 07996 if (pW32Job->ughCrt == 0) { 07997 pgh = UserAllocPool(GH_SIZE * sizeof(*pgh), TAG_GRANTEDHANDLES); 07998 } else { 07999 /* 08000 * we need to grow the array 08001 */ 08002 DWORD uBytes = (pW32Job->ughMax) * sizeof(*pgh); 08003 08004 pgh = UserReAllocPool(pgh, 08005 uBytes, 08006 uBytes + GH_SIZE * sizeof(*pgh), 08007 TAG_GRANTEDHANDLES); 08008 } 08009 08010 if (pgh == NULL) { 08011 RIPMSG0(RIP_WARNING, "UserHandleGrantAccess: out of memory\n"); 08012 MSGERRORCLEANUP(ERROR_NOT_ENOUGH_MEMORY); 08013 } 08014 08015 pW32Job->pgh = pgh; 08016 pW32Job->ughMax += GH_SIZE; 08017 } 08018 08019 UserAssert(pW32Job->ughCrt < pW32Job->ughMax); 08020 08021 /* 08022 * see if the handle is not already granted to this process 08023 */ 08024 for (dw = 0; dw < pW32Job->ughCrt; dw++) { 08025 if (*(pgh + dw) == (ULONG_PTR)hUserHandle) { 08026 break; 08027 } 08028 } 08029 08030 if (dw >= pW32Job->ughCrt) { 08031 08032 /* 08033 * add the handle to the granted handles table 08034 */ 08035 *(pgh + pW32Job->ughCrt) = (ULONG_PTR)hUserHandle; 08036 08037 (pW32Job->ughCrt)++; 08038 } 08039 } else { 08040 /* 08041 * Remove the handle from the granted list 08042 */ 08043 /* 08044 * search for the handle in the array. 08045 */ 08046 for (dw = 0; dw < pW32Job->ughCrt; dw++) { 08047 if (*(pgh + dw) == (ULONG_PTR)hUserHandle) { 08048 08049 /* 08050 * found the handle granted to this process 08051 */ 08052 RtlMoveMemory(pgh + dw, 08053 pgh + dw + 1, 08054 (pW32Job->ughCrt - dw - 1) * sizeof(*pgh)); 08055 08056 (pW32Job->ughCrt)--; 08057 break; 08058 } 08059 } 08060 #if DBG 08061 if (dw >= pW32Job->ughCrt) { 08062 RIPERR1(ERROR_INVALID_HANDLE, RIP_WARNING, 08063 "UserHandleGrantAccess(FALSE): handle not found %#p", 08064 hUserHandle); 08065 } 08066 #endif // DBG 08067 } 08068 08069 retval = TRUE; 08070 08071 } except (StubExceptionHandler(TRUE)) { 08072 MSGERRORCLEANUP(0); 08073 } 08074 08075 CLEANUPRECV(); 08076 08077 LeaveCrit(); 08078 ExReleaseResource(&Job->JobLock); 08079 KeLeaveCriticalRegion(); 08080 ObDereferenceObject(Job); 08081 08082 TRACE("NtUserUserHandleGrantAccess"); 08083 08084 return retval; 08085 } 08086 08087 HWND NtUserCreateWindowEx( 08088 IN DWORD dwExStyle, 08089 IN PLARGE_STRING pstrClassName, 08090 IN PLARGE_STRING pstrWindowName OPTIONAL, 08091 IN DWORD dwStyle, 08092 IN int x, 08093 IN int y, 08094 IN int nWidth, 08095 IN int nHeight, 08096 IN HWND hwndParent, 08097 IN HMENU hmenu, 08098 IN HANDLE hModule, 08099 IN LPVOID pParam, 08100 IN DWORD dwFlags) 08101 { 08102 LARGE_STRING strClassName; 08103 LARGE_STRING strWindowName; 08104 PWND pwndParent; 08105 PMENU pmenu; 08106 TL tlpwndParent; 08107 TL tlpmenu; 08108 BOOL fLockMenu = FALSE; 08109 PTHREADINFO ptiCurrent; 08110 08111 BEGINRECV(HWND, NULL); 08112 08113 if (hwndParent != HWND_MESSAGE) { 08114 ValidateHWNDOPT(pwndParent, hwndParent); 08115 } else 08116 pwndParent = _GetMessageWindow(); 08117 08118 08119 /* 08120 * Win3.1 only checks for WS_CHILD before treating pmenu as an id. This 08121 * is a bug, because throughout the code, the real check is TestwndChild(), 08122 * which checks (style & (WS_CHILD | WS_POPUP)) == WS_CHILD. This is 08123 * because old style "iconic popup" is WS_CHILD | WS_POPUP. So... if on 08124 * win3.1 an app used ws_iconicpopup, menu validation would not occur 08125 * (could crash if hmenu != NULL). On Win32, check for the real thing - 08126 * but allow NULL! 08127 */ 08128 ptiCurrent = PtiCurrent(); 08129 if (((dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD) && 08130 (hmenu != NULL)) { 08131 ValidateHMENU(pmenu, hmenu); 08132 08133 ThreadLockAlwaysWithPti(ptiCurrent, pmenu, &tlpmenu); 08134 fLockMenu = TRUE; 08135 08136 } else { 08137 pmenu = (PMENU)hmenu; 08138 } 08139 08140 /* 08141 * Mask out the new 5.0 extended style bits for apps 08142 * that would try to use them and we'll fail in xxxCreateWindowEx 08143 */ 08144 if (GetAppCompatFlags2(VER40) & GACF2_NO50EXSTYLEBITSCW) { 08145 08146 #if DBG 08147 if (dwExStyle & ~(WS_EX_VALID40 | WS_EX_INTERNAL)) { 08148 RIPMSG0(RIP_WARNING, "CreateWindowEx: appcompat removed 5.0 EX bits"); 08149 } 08150 #endif 08151 08152 dwExStyle &= (WS_EX_VALID40 | WS_EX_INTERNAL); 08153 } 08154 08155 /* 08156 * Probe arguments 08157 */ 08158 try { 08159 #if defined(_X86_) 08160 if (IS_PTR(pstrClassName)) { 08161 strClassName = ProbeAndReadLargeString(pstrClassName); 08162 ProbeForRead(strClassName.Buffer, strClassName.Length, 08163 sizeof(BYTE)); 08164 pstrClassName = &strClassName; 08165 } 08166 if (ARGUMENT_PRESENT(pstrWindowName)) { 08167 strWindowName = ProbeAndReadLargeString(pstrWindowName); 08168 ProbeForRead(strWindowName.Buffer, strWindowName.Length, 08169 sizeof(BYTE)); 08170 pstrWindowName = &strWindowName; 08171 } 08172 #else 08173 if (IS_PTR(pstrClassName)) { 08174 strClassName = ProbeAndReadLargeString(pstrClassName); 08175 ProbeForRead(strClassName.Buffer, strClassName.Length, 08176 sizeof(WORD)); 08177 pstrClassName = &strClassName; 08178 } 08179 if (ARGUMENT_PRESENT(pstrWindowName)) { 08180 strWindowName = ProbeAndReadLargeString(pstrWindowName); 08181 ProbeForRead(strWindowName.Buffer, strWindowName.Length, 08182 (strWindowName.bAnsi ? sizeof(BYTE) : sizeof(WORD))); 08183 pstrWindowName = &strWindowName; 08184 } 08185 #endif 08186 } except (StubExceptionHandler(TRUE)) { 08187 MSGERRORCLEANUP(0); 08188 } 08189 08190 ThreadLockWithPti(ptiCurrent, pwndParent, &tlpwndParent); 08191 08192 /* 08193 * The buffers for ClassName and WindowName are still in client space. 08194 */ 08195 08196 retval = (HWND)xxxCreateWindowEx( 08197 dwExStyle, 08198 pstrClassName, 08199 pstrWindowName, 08200 dwStyle, 08201 x, 08202 y, 08203 nWidth, 08204 nHeight, 08205 pwndParent, 08206 pmenu, 08207 hModule, 08208 pParam, 08209 dwFlags); 08210 retval = PtoH((PVOID)retval); 08211 08212 ThreadUnlock(&tlpwndParent); 08213 08214 CLEANUPRECV(); 08215 if (fLockMenu) 08216 ThreadUnlock(&tlpmenu); 08217 08218 TRACE("NtUserCreateWindowEx"); 08219 ENDRECV(); 08220 } 08221 08222 NTSTATUS NtUserBuildHwndList( // worker for EnumWindows, EnumThreadWindows etc. 08223 IN HDESK hdesk, 08224 IN HWND hwndNext, 08225 IN BOOL fEnumChildren, 08226 IN DWORD idThread, 08227 IN UINT cHwndMax, 08228 OUT HWND *phwndFirst, 08229 OUT PUINT pcHwndNeeded) 08230 { 08231 PWND pwndNext; 08232 PDESKTOP pdesk; 08233 PBWL pbwl; 08234 PTHREADINFO pti; 08235 UINT cHwndNeeded; 08236 UINT wFlags = BWL_ENUMLIST; 08237 BEGINATOMICRECV(NTSTATUS, STATUS_INVALID_HANDLE); 08238 08239 if (IS_IME_ENABLED()) { 08240 // special treatment of IME Window 08241 wFlags |= BWL_ENUMIMELAST; 08242 } 08243 08244 /* 08245 * Validate prior to referencing the desktop 08246 */ 08247 ValidateHWNDOPT(pwndNext, hwndNext); 08248 08249 if (idThread) { 08250 pti = PtiFromThreadId(idThread); 08251 if (pti == NULL || pti->rpdesk == NULL){ 08252 MSGERROR(ERROR_INVALID_PARAMETER); 08253 } 08254 pwndNext = pti->rpdesk->pDeskInfo->spwnd->spwndChild; 08255 } else { 08256 pti = NULL; 08257 } 08258 08259 if (hdesk) { 08260 retval = ValidateHdesk(hdesk, UserMode, DESKTOP_READOBJECTS, &pdesk); 08261 if (!NT_SUCCESS(retval)){ 08262 MSGERROR(ERROR_INVALID_HANDLE); 08263 } 08264 pwndNext = pdesk->pDeskInfo->spwnd->spwndChild; 08265 } else { 08266 pdesk = NULL; 08267 } 08268 08269 08270 if (pwndNext == NULL) { 08271 /* 08272 * Bug: 262004 joejo 08273 * If we have a valid desk (just no windows on it), then we need 08274 * to fall through. Otherwise, we'll just grab the current desktop and enum it's 08275 * windows! 08276 */ 08277 if (pdesk == NULL) { 08278 if (pti != NULL) { 08279 pwndNext = pti->rpdesk->pDeskInfo->spwnd->spwndChild; 08280 } else { 08281 pwndNext = _GetDesktopWindow()->spwndChild; 08282 } 08283 } 08284 } else { 08285 if (fEnumChildren) { 08286 wFlags |= BWL_ENUMCHILDREN; 08287 pwndNext = pwndNext->spwndChild; 08288 } 08289 } 08290 08291 if ((pbwl = BuildHwndList(pwndNext, wFlags, pti)) == NULL) { 08292 MSGERRORCLEANUP(ERROR_NOT_ENOUGH_MEMORY); 08293 } 08294 08295 cHwndNeeded = (UINT)(pbwl->phwndNext - pbwl->rghwnd) + 1; 08296 08297 /* 08298 * Probe arguments 08299 */ 08300 try { 08301 ProbeForWriteBuffer(phwndFirst, cHwndMax, sizeof(DWORD)); 08302 ProbeForWriteUlong(pcHwndNeeded); 08303 08304 /* 08305 * If we have enough space, copy out list of hwnds to user mode buffer. 08306 */ 08307 if (cHwndNeeded <= cHwndMax) { 08308 RtlCopyMemory(phwndFirst, pbwl->rghwnd, cHwndNeeded * sizeof(HWND)); 08309 retval = STATUS_SUCCESS; 08310 } else { 08311 retval = STATUS_BUFFER_TOO_SMALL; 08312 } 08313 *pcHwndNeeded = cHwndNeeded; 08314 } except (StubExceptionHandler(TRUE)) { 08315 MSGERRORCLEANUP(0); // phwndFirst/pcHwndNeeded are USER's, not app's 08316 } 08317 08318 CLEANUPRECV(); 08319 08320 if (pbwl != NULL) { 08321 FreeHwndList(pbwl); 08322 } 08323 08324 if (pdesk != NULL) { 08325 LogDesktop(pdesk, LD_DEREF_VALIDATE_HDESK4, FALSE, (ULONG_PTR)PtiCurrent()); 08326 ObDereferenceObject(pdesk); 08327 } 08328 08329 TRACE("NtUserBuildHwndList"); 08330 ENDATOMICRECV(); 08331 } 08332 08333 NTSTATUS NtUserBuildPropList( // worker for EnumProps etc. 08334 IN HWND hwnd, 08335 IN UINT cPropMax, 08336 OUT PPROPSET pPropSet, 08337 OUT PUINT pcPropNeeded) 08338 { 08339 BEGINRECV_HWNDLOCK(NTSTATUS, STATUS_INVALID_HANDLE, hwnd); 08340 08341 if (cPropMax == 0) { 08342 MSGERROR(0); 08343 } 08344 08345 /* 08346 * Probe arguments 08347 */ 08348 try { 08349 ProbeForWriteBuffer(pPropSet, cPropMax, sizeof(DWORD)); 08350 ProbeForWriteUlong(pcPropNeeded); 08351 08352 retval = _BuildPropList( 08353 pwnd, 08354 pPropSet, 08355 cPropMax, 08356 pcPropNeeded); 08357 } except (StubExceptionHandler(FALSE)) { 08358 MSGERROR(0); // pPropSet/pcPropNeed are USER's, not app's 08359 } 08360 08361 TRACE("NtUserBuildPropList"); 08362 ENDRECV_HWNDLOCK(); 08363 } 08364 08365 NTSTATUS NtUserBuildNameList( // worker for EnumWindowStations/EnumDesktops 08366 IN HWINSTA hwinsta, 08367 IN UINT cbNameList, 08368 OUT PNAMELIST pNameList, 08369 OUT PUINT pcbNeeded) 08370 { 08371 UINT cbNeeded; 08372 PWINDOWSTATION pwinsta = NULL; 08373 08374 BEGINRECV_SHARED(NTSTATUS, STATUS_INVALID_HANDLE); 08375 08376 if (cbNameList < sizeof(NAMELIST)) { 08377 MSGERROR(0); 08378 } 08379 08380 try { 08381 ProbeForWriteUlong(pcbNeeded); 08382 ProbeForWrite(pNameList, cbNameList, sizeof(DWORD)); 08383 } except (StubExceptionHandler(FALSE)) { 08384 MSGERROR(0); 08385 } 08386 08387 if (hwinsta != NULL) { 08388 retval = ValidateHwinsta(hwinsta, UserMode, WINSTA_ENUMDESKTOPS, &pwinsta); 08389 } else { 08390 retval = STATUS_SUCCESS; 08391 } 08392 08393 if (!NT_SUCCESS(retval)) { 08394 try { 08395 *pNameList->awchNames = 0; 08396 pNameList->cb = 1; 08397 } except (StubExceptionHandler(FALSE)) { 08398 MSGERROR(0); 08399 } 08400 08401 } else { 08402 /* 08403 * Note -- pNameList is a client-side pointers. 08404 * BuildNameList protects access with try blocks. 08405 */ 08406 08407 retval = _BuildNameList( 08408 pwinsta, 08409 pNameList, 08410 cbNameList, 08411 &cbNeeded); 08412 try { 08413 *pcbNeeded = cbNeeded; 08414 } except (StubExceptionHandler(FALSE)) { 08415 retval = STATUS_ACCESS_VIOLATION; 08416 } 08417 } 08418 08419 if (pwinsta != NULL) 08420 ObDereferenceObject(pwinsta); 08421 08422 TRACE("NtUserBuildNameList"); 08423 ENDRECV_SHARED(); 08424 } 08425 08426 HKL NtUserActivateKeyboardLayout( 08427 IN HKL hkl, 08428 IN UINT Flags) 08429 { 08430 BEGINRECV(HKL, NULL); 08431 08432 /* 08433 * Prevent restricted threads from setting the keyboard layout 08434 * for the entire system. 08435 */ 08436 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_HANDLES)) { 08437 MSGERROR(0); 08438 } 08439 08440 retval = (HKL)xxxActivateKeyboardLayout( 08441 _GetProcessWindowStation(NULL), 08442 hkl, 08443 Flags, NULL); 08444 08445 TRACE("NtUserActivateKeyboardLayout"); 08446 ENDRECV(); 08447 } 08448 08449 HKL NtUserLoadKeyboardLayoutEx( 08450 IN HANDLE hFile, 08451 IN DWORD offTable, 08452 IN HKL hkl, 08453 IN PUNICODE_STRING pstrKLID, 08454 IN UINT KbdInputLocale, 08455 IN UINT Flags) 08456 { 08457 UNICODE_STRING strKLID; 08458 PWINDOWSTATION pwinsta; 08459 WCHAR awchKF[sizeof(((PKL)0)->spkf->awchKF)]; 08460 UINT chMax; 08461 08462 BEGINRECV(HKL, NULL); 08463 08464 TESTFLAGS(Flags, KLF_VALID); 08465 08466 pwinsta = _GetProcessWindowStation(NULL); 08467 08468 /* 08469 * Probe arguments 08470 */ 08471 try { 08472 strKLID = ProbeAndReadUnicodeString(pstrKLID); 08473 ProbeForRead(strKLID.Buffer, strKLID.Length, CHARALIGN); 08474 chMax = min(sizeof(awchKF) - sizeof(WCHAR), strKLID.Length) / sizeof(WCHAR); 08475 wcsncpy(awchKF, strKLID.Buffer, chMax); 08476 awchKF[chMax] = 0; 08477 } except (StubExceptionHandler(TRUE)) { 08478 MSGERROR(0); 08479 } 08480 08481 retval = xxxLoadKeyboardLayoutEx( 08482 pwinsta, 08483 hFile, 08484 hkl, 08485 offTable, 08486 awchKF, 08487 KbdInputLocale, 08488 Flags); 08489 08490 TRACE("NtUserLoadKeyboardLayoutEx"); 08491 ENDRECV(); 08492 } 08493 08494 BOOL NtUserUnloadKeyboardLayout( 08495 IN HKL hkl) 08496 { 08497 BEGINRECV(BOOL, FALSE); 08498 08499 retval = xxxUnloadKeyboardLayout( 08500 _GetProcessWindowStation(NULL), 08501 hkl); 08502 08503 TRACE("NtUserUnloadKeyboardLayout"); 08504 ENDRECV(); 08505 } 08506 08507 BOOL NtUserSetSystemMenu( 08508 IN HWND hwnd, 08509 IN HMENU hmenu) 08510 { 08511 08512 // 08513 // N.B. This function has implicit window translation and thread locking 08514 // enabled. These operations are performed in the User server API 08515 // dispatcher. 08516 // 08517 08518 PMENU pmenu; 08519 TL tlpmenu; 08520 08521 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 08522 08523 ValidateHMENU(pmenu, hmenu); 08524 08525 ThreadLockAlwaysWithPti(ptiCurrent, pmenu, &tlpmenu); 08526 08527 retval = xxxSetSystemMenu(pwnd, pmenu); 08528 08529 ThreadUnlock(&tlpmenu); 08530 08531 TRACE("NtUserSetSystemMenu"); 08532 ENDRECV_HWNDLOCK(); 08533 } 08534 08535 BOOL NtUserDragDetect( 08536 IN HWND hwnd, 08537 IN POINT pt) 08538 { 08539 08540 // 08541 // N.B. This function has implicit window translation and thread locking 08542 // enabled. These operations are performed in the User server API 08543 // dispatcher. 08544 // 08545 08546 BEGINRECV_HWNDLOCK(DWORD, 0, hwnd); 08547 08548 retval = xxxDragDetect(pwnd, pt); 08549 08550 TRACE("NtUserDragDetect"); 08551 ENDRECV_HWNDLOCK(); 08552 } 08553 08554 UINT_PTR NtUserSetSystemTimer( 08555 IN HWND hwnd, 08556 IN UINT_PTR nIDEvent, 08557 IN DWORD dwElapse, 08558 IN WNDPROC pTimerFunc) 08559 { 08560 08561 // 08562 // N.B. This function has implicit window translation and thread locking 08563 // enabled. These operations are performed in the User server API 08564 // dispatcher. 08565 // 08566 08567 BEGINRECV_HWND(UINT_PTR, 0, hwnd); 08568 08569 UNREFERENCED_PARAMETER(pTimerFunc); 08570 08571 retval = _SetSystemTimer(pwnd, 08572 nIDEvent, 08573 dwElapse, 08574 NULL); 08575 08576 TRACE("NtUserSetSystemTimer"); 08577 ENDRECV_HWND(); 08578 } 08579 08580 BOOL NtUserQuerySendMessage( // private QuerySendMessage 08581 OUT PMSG pmsg OPTIONAL) 08582 { 08583 PSMS psms; 08584 BEGINRECV_SHARED(BOOL, FALSE); 08585 08586 /* 08587 * This function looks like dead code. If it's not, it can be optimized 08588 * by using the CTIF_INSENDMESSAGE flag from user mode. - JerrySh 08589 */ 08590 RIPMSG0(RIP_ERROR, "I don't think QuerySendMessage ever gets called. Remove this assert if it does."); 08591 08592 if ((psms = PtiCurrentShared()->psmsCurrent) == NULL) { 08593 MSGERROR(0); 08594 } 08595 08596 retval = TRUE; 08597 if (ARGUMENT_PRESENT(pmsg)) { 08598 try { 08599 ProbeForWriteMessage(pmsg); 08600 pmsg->hwnd = HW(psms->spwnd); 08601 pmsg->message = psms->message; 08602 pmsg->wParam = psms->wParam; 08603 pmsg->lParam = psms->lParam; 08604 pmsg->time = psms->tSent; 08605 pmsg->pt.x = 0; 08606 pmsg->pt.y = 0; 08607 retval = TRUE; 08608 } except (StubExceptionHandler(FALSE)) { 08609 MSGERROR(0); 08610 } 08611 } 08612 08613 TRACE("NtUserQuerySendMessage"); 08614 ENDRECV_SHARED(); 08615 } 08616 08617 UINT NtUserSendInput( 08618 IN UINT cInputs, 08619 IN CONST INPUT *pInputs, 08620 IN int cbSize) 08621 { 08622 LPINPUT pInput2 = NULL; 08623 PTHREADINFO ptiCurrent; 08624 TL tlInput; 08625 DWORD dwArgumentError = ERROR_INVALID_PARAMETER; 08626 08627 BEGINRECV(UINT, 0); 08628 08629 if (sizeof(INPUT) != cbSize || cInputs == 0) { 08630 MSGERROR(dwArgumentError); 08631 } 08632 08633 ptiCurrent = PtiCurrent(); 08634 08635 /* 08636 * Probe arguments 08637 */ 08638 try { 08639 ProbeForReadBuffer(pInputs, cInputs, DATAALIGN); 08640 08641 pInput2 = UserAllocPoolWithQuota(cInputs * sizeof(*pInputs), TAG_SENDINPUT); 08642 if (pInput2 == NULL) { 08643 ExRaiseStatus(STATUS_NO_MEMORY); 08644 } 08645 RtlCopyMemory(pInput2, pInputs, cInputs * sizeof(*pInputs)); 08646 } except (StubExceptionHandler(TRUE)) { 08647 MSGERRORCLEANUP(0); 08648 } 08649 08650 ThreadLockPool(ptiCurrent, pInput2, &tlInput); 08651 retval = xxxSendInput(cInputs, pInput2); 08652 ThreadUnlockPool(ptiCurrent, &tlInput); 08653 CLEANUPRECV(); 08654 if (pInput2) { 08655 UserFreePool(pInput2); 08656 } 08657 TRACE("NtUserSendInput"); 08658 ENDRECV(); 08659 } 08660 08661 UINT NtUserBlockInput( 08662 IN BOOL fBlockIt) 08663 { 08664 BEGINATOMICRECV(BOOL, FALSE); 08665 retval = _BlockInput(fBlockIt); 08666 TRACE("NtUserBlockInput"); 08667 ENDATOMICRECV(); 08668 } 08669 08670 BOOL NtUserImpersonateDdeClientWindow( 08671 IN HWND hwndClient, 08672 IN HWND hwndServer) 08673 { 08674 08675 // 08676 // N.B. This function has implicit window handle translation. This 08677 // operation is performed in the User server API dispatcher. 08678 // 08679 08680 PWND pwndServer; 08681 08682 BEGINATOMICRECV_HWND(BOOL, FALSE, hwndClient); 08683 08684 ValidateHWND(pwndServer, hwndServer); 08685 if (GETPTI(pwndServer) != PtiCurrent()) { 08686 RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, ""); 08687 MSGERROR(0); 08688 } 08689 08690 if (GETPWNDPPI(pwnd) == GETPWNDPPI(pwndServer)) { 08691 retval = TRUE; // impersonating self is a NOOP 08692 } else { 08693 retval = _ImpersonateDdeClientWindow(pwnd, pwndServer); 08694 } 08695 08696 TRACE("NtUserImpersonateDdeClientWindow"); 08697 ENDATOMICRECV_HWND(); 08698 } 08699 08700 ULONG_PTR NtUserGetCPD( 08701 IN HWND hwnd, 08702 IN DWORD options, 08703 IN ULONG_PTR dwData) 08704 { 08705 08706 // 08707 // N.B. This function has implicit window handle translation. This 08708 // operation is performed in the User server API dispatcher. 08709 // 08710 08711 BEGINRECV_HWND(ULONG_PTR, 0, hwnd); 08712 08713 switch (options & ~CPD_TRANSITION_TYPES) { 08714 case CPD_WND: 08715 case CPD_DIALOG: 08716 case CPD_WNDTOCLS: 08717 break; 08718 default: 08719 RIPMSG1(RIP_WARNING, "GetCPD: Invalid options %x", options); 08720 MSGERROR(0); 08721 } 08722 08723 retval = GetCPD(pwnd, options, dwData); 08724 08725 TRACE("NtUserGetCPD"); 08726 ENDRECV_HWND(); 08727 } 08728 08729 int NtUserCopyAcceleratorTable( // API CopyAcceleratorTableA/W 08730 IN HACCEL hAccelSrc, 08731 IN OUT LPACCEL lpAccelDst OPTIONAL, 08732 IN int cAccel) 08733 { 08734 LPACCELTABLE pat; 08735 int i; 08736 BEGINATOMICRECV(int, 0); 08737 08738 ValidateHACCEL(pat, hAccelSrc); 08739 08740 if (lpAccelDst == NULL) { 08741 retval = pat->cAccel; 08742 } else { 08743 08744 /* 08745 * Probe arguments 08746 */ 08747 try { 08748 ProbeForWriteBuffer(lpAccelDst, cAccel, DATAALIGN); 08749 08750 if (cAccel > (int)pat->cAccel) 08751 cAccel = pat->cAccel; 08752 08753 retval = cAccel; 08754 for (i = 0; i < cAccel; i++) { 08755 RtlCopyMemory(&lpAccelDst[i], &pat->accel[i], sizeof(ACCEL)); 08756 lpAccelDst[i].fVirt &= ~FLASTKEY; 08757 } 08758 } except (StubExceptionHandler(TRUE)) { 08759 MSGERROR(0); 08760 } 08761 } 08762 08763 TRACE("NtUserCopyAcceleratorTable"); 08764 ENDATOMICRECV(); 08765 } 08766 08767 HWND NtUserFindWindowEx( // API FindWindowA/W, FindWindowExA/W 08768 IN HWND hwndParent, 08769 IN HWND hwndChild, 08770 IN PUNICODE_STRING pstrClassName, 08771 IN PUNICODE_STRING pstrWindowName, 08772 DWORD dwType) 08773 { 08774 UNICODE_STRING strClassName; 08775 UNICODE_STRING strWindowName; 08776 PWND pwndParent, pwndChild; 08777 08778 BEGINATOMICRECV(HWND, NULL); 08779 08780 if (hwndParent != HWND_MESSAGE) { 08781 ValidateHWNDOPT(pwndParent, hwndParent); 08782 } else 08783 pwndParent = _GetMessageWindow(); 08784 08785 ValidateHWNDOPT(pwndChild, hwndChild); 08786 08787 /* 08788 * Probe arguments 08789 */ 08790 try { 08791 strClassName = ProbeAndReadUnicodeString(pstrClassName); 08792 strWindowName = ProbeAndReadUnicodeString(pstrWindowName); 08793 ProbeForReadUnicodeStringBufferOrId(strClassName); 08794 ProbeForReadUnicodeStringBuffer(strWindowName); 08795 } except (StubExceptionHandler(TRUE)) { 08796 MSGERRORCLEANUP(0); 08797 } 08798 08799 /* 08800 * Use of both buffers is protected by try/except clauses in the code. 08801 */ 08802 08803 retval = (HWND)_FindWindowEx( 08804 pwndParent, 08805 pwndChild, 08806 strClassName.Buffer, 08807 strWindowName.Buffer, 08808 dwType); 08809 retval = PtoH((PVOID)retval); 08810 08811 CLEANUPRECV(); 08812 08813 TRACE("NtUserFindWindowEx"); 08814 ENDATOMICRECV(); 08815 } 08816 08817 BOOL NtUserGetClassInfo( // API GetClassInfoA/W 08818 IN HINSTANCE hInstance OPTIONAL, 08819 IN PUNICODE_STRING pstrClassName, 08820 IN OUT LPWNDCLASSEXW lpWndClass, 08821 OUT LPWSTR *ppszMenuName, 08822 IN BOOL bAnsi) 08823 { 08824 UNICODE_STRING strClassName; 08825 08826 LPWSTR pszMenuName; 08827 WNDCLASSEXW wc; 08828 BEGINRECV(BOOL, FALSE); 08829 08830 /* 08831 * Probe arguments 08832 */ 08833 try { 08834 strClassName = ProbeAndReadUnicodeString(pstrClassName); 08835 08836 /* 08837 * The class name may either be a string or an atom. Only 08838 * probe strings. 08839 */ 08840 ProbeForReadUnicodeStringBufferOrId(strClassName); 08841 ProbeForWrite(lpWndClass, sizeof(*lpWndClass), DATAALIGN); 08842 ProbeForWriteUlong((PULONG)ppszMenuName); 08843 RtlCopyMemory(&wc, lpWndClass, sizeof(WNDCLASSEXW)); 08844 } except (StubExceptionHandler(TRUE)) { 08845 MSGERROR(0); 08846 } 08847 08848 /* 08849 * The class name buffer is client-side. 08850 */ 08851 retval = _GetClassInfoEx( 08852 hInstance, 08853 (LPTSTR)strClassName.Buffer, 08854 &wc, 08855 &pszMenuName, 08856 bAnsi); 08857 08858 try { 08859 RtlCopyMemory(lpWndClass, &wc, sizeof(WNDCLASSEXW)); 08860 *ppszMenuName = pszMenuName; 08861 } except (StubExceptionHandler(TRUE)) { 08862 MSGERROR(0); 08863 } 08864 TRACE("NtUserGetClassInfo"); 08865 ENDRECV(); 08866 } 08867 08868 /* 08869 * gaFNIDtoICLS is used only in NtUserGetClassName and should be in sync with 08870 * the values from user.h 08871 * ICLS_MAX is an unused value 08872 */ 08873 CONST BYTE gaFNIDtoICLS[] = { 08874 // FNID-START 08875 ICLS_SCROLLBAR, // FNID_SCROLLBAR 08876 ICLS_ICONTITLE, // FNID_ICONTITLE 08877 ICLS_MENU, // FNID_MENU 08878 ICLS_DESKTOP, // FNID_DESKTOP 08879 ICLS_MAX, // FNID_DEFWINDOWPROC 08880 ICLS_BUTTON, // FNID_BUTTON 08881 ICLS_COMBOBOX, // FNID_COMBOBOX 08882 ICLS_COMBOLISTBOX, // FNID_COMBOLISTBOX 08883 ICLS_DIALOG, // FNID_DIALOG 08884 ICLS_EDIT, // FNID_EDIT 08885 ICLS_LISTBOX, // FNID_LISTBOX 08886 ICLS_MDICLIENT, // FNID_MDICLIENT 08887 ICLS_STATIC, // FNID_STATIC 08888 ICLS_IME, // FNID_IME 08889 ICLS_MAX, // FNID_HKINLPCWPEXSTRUCT 08890 ICLS_MAX, // FNID_HKINLPCWPRETEXSTRUCT 08891 ICLS_MAX, // FNID_DEFFRAMEPROC 08892 ICLS_MAX, // FNID_DEFMDICHILDPROC 08893 ICLS_MAX, // FNID_MB_DLGPROC 08894 ICLS_MAX, // FNID_MDIACTIVATEDLGPROC 08895 ICLS_MAX, // FNID_SENDMESSAGE 08896 ICLS_MAX, // FNID_SENDMESSAGEFF 08897 ICLS_MAX, // FNID_SENDMESSAGEEX 08898 ICLS_MAX, // FNID_CALLWINDOWPROC 08899 ICLS_MAX, // FNID_SENDMESSAGEBSM 08900 ICLS_SWITCH, // FNID_SWITCH 08901 ICLS_TOOLTIP // FNID_TOOLTIP 08902 }; // FNID_END 08903 08904 int NtUserGetClassName( // API GetClassNameA/W 08905 IN HWND hwnd, 08906 IN BOOL bReal, 08907 IN OUT PUNICODE_STRING pstrClassName) 08908 { 08909 UNICODE_STRING strClassName; 08910 ATOM atom; 08911 08912 // 08913 // N.B. This function has implicit window handle translation. This 08914 // operation is performed in the User server API dispatcher. 08915 // 08916 08917 BEGINRECV_HWND_SHARED(DWORD, 0, hwnd); 08918 08919 /* 08920 * Probe arguments 08921 */ 08922 try { 08923 strClassName = ProbeAndReadUnicodeString(pstrClassName); 08924 #if defined(_X86_) 08925 ProbeForWrite(strClassName.Buffer, strClassName.MaximumLength, 08926 sizeof(BYTE)); 08927 #else 08928 ProbeForWrite(strClassName.Buffer, strClassName.MaximumLength, 08929 sizeof(WCHAR)); 08930 #endif 08931 08932 atom = pwnd->pcls->atomClassName; 08933 UserAssert(ARRAY_SIZE(gaFNIDtoICLS) == FNID_END - FNID_START + 1); 08934 08935 if (bReal) { 08936 DWORD dwFnid; 08937 DWORD dwClass; 08938 dwFnid = GETFNID(pwnd); 08939 if (dwFnid) { 08940 dwFnid -= FNID_START; 08941 if ((dwFnid < ARRAY_SIZE(gaFNIDtoICLS)) && (dwFnid >= 0)) { 08942 dwClass = gaFNIDtoICLS[dwFnid]; 08943 if (dwClass != ICLS_MAX) { 08944 atom = gpsi->atomSysClass[dwClass]; 08945 } 08946 } 08947 } 08948 } 08949 retval = UserGetAtomName( 08950 atom, 08951 strClassName.Buffer, 08952 strClassName.MaximumLength / sizeof(WCHAR)); 08953 08954 } except (StubExceptionHandler(TRUE)) { 08955 MSGERROR(0); 08956 } 08957 08958 TRACE("NtUserGetClassName"); 08959 ENDRECV_HWND_SHARED(); 08960 } 08961 08962 int NtUserGetClipboardFormatName( // API GetclipboardFormatNameA/W 08963 IN UINT format, 08964 OUT LPWSTR lpszFormatName, 08965 IN UINT chMax) 08966 { 08967 BEGINRECV_NOCRIT(int, 0); 08968 08969 /* 08970 * Probe arguments 08971 */ 08972 try { 08973 ProbeForWriteBuffer(lpszFormatName, chMax, CHARALIGN); 08974 } except (StubExceptionHandler(TRUE)) { 08975 MSGERROR(0); 08976 } 08977 08978 if ((ATOM)format < MAXINTATOM) { 08979 MSGERROR(ERROR_INVALID_PARAMETER); 08980 } else { 08981 /* 08982 * UserGetAtomName (actually RtlQueryAtomInAtomTable) protects access 08983 * within a try block, and sets last error appropriately. 08984 */ 08985 retval = UserGetAtomName((ATOM)format, lpszFormatName, chMax); 08986 } 08987 08988 TRACE("NtUserGetClipboardFormatName"); 08989 ENDRECV_NOCRIT(); 08990 } 08991 08992 int NtUserGetKeyNameText( 08993 IN LONG lParam, 08994 OUT LPWSTR lpszKeyName, 08995 IN UINT chMax) 08996 { 08997 BEGINRECV_SHARED(int, 0); 08998 08999 /* 09000 * Probe arguments 09001 */ 09002 try { 09003 ProbeForWriteBuffer(lpszKeyName, chMax, CHARALIGN); 09004 } except (StubExceptionHandler(TRUE)) { 09005 MSGERROR(0); 09006 } 09007 09008 /* 09009 * Note -- lpszKeyName is a client-side address. GetKeyNameText 09010 * protects uses with try blocks, and sets last error accordingly. 09011 */ 09012 09013 retval = _GetKeyNameText( 09014 lParam, 09015 lpszKeyName, 09016 chMax); 09017 09018 TRACE("NtUserGetKeyNameText"); 09019 ENDRECV_SHARED(); 09020 } 09021 09022 BOOL NtUserGetKeyboardLayoutName( 09023 IN OUT PUNICODE_STRING pstrKLID) 09024 { 09025 PTHREADINFO ptiCurrent; 09026 PKL pklActive; 09027 UNICODE_STRING strKLID; 09028 09029 BEGINRECV_SHARED(BOOL, FALSE); 09030 09031 ptiCurrent = PtiCurrentShared(); 09032 pklActive = ptiCurrent->spklActive; 09033 09034 if (pklActive == NULL) { 09035 MSGERROR(0); 09036 } 09037 /* 09038 * Probe arguments 09039 */ 09040 try { 09041 strKLID = ProbeAndReadUnicodeString(pstrKLID); 09042 ProbeForWrite(strKLID.Buffer, strKLID.MaximumLength, CHARALIGN); 09043 09044 wcsncpycch(strKLID.Buffer, 09045 pklActive->spkf->awchKF, 09046 strKLID.MaximumLength / sizeof(WCHAR)); 09047 09048 retval = TRUE; 09049 09050 } except (StubExceptionHandler(TRUE)) { 09051 MSGERROR(0); 09052 } 09053 09054 TRACE("NtUserGetKeyboardLayoutName"); 09055 ENDRECV_SHARED(); 09056 } 09057 09058 UINT NtUserGetKeyboardLayoutList( 09059 IN UINT nItems, 09060 OUT HKL *lpBuff) 09061 { 09062 PWINDOWSTATION pwinsta; 09063 09064 BEGINRECV_SHARED(UINT, 0); 09065 09066 /* 09067 * Probe arguments 09068 */ 09069 try { 09070 if (!lpBuff) { 09071 nItems = 0; 09072 } 09073 ProbeForWriteBuffer(lpBuff, nItems, DATAALIGN); 09074 pwinsta = _GetProcessWindowStation(NULL); 09075 09076 } except (StubExceptionHandler(TRUE)) { 09077 MSGERROR(0); 09078 } 09079 09080 /* 09081 * Access to the client-side buffer lpBuff is protected by try/except 09082 * inside _GetKeyboardLayoutList() 09083 */ 09084 retval = (DWORD)_GetKeyboardLayoutList(pwinsta, nItems, lpBuff); 09085 TRACE("NtUserGetKeyboardLayoutList"); 09086 ENDRECV_SHARED(); 09087 } 09088 09089 UINT NtUserMapVirtualKeyEx( 09090 IN UINT uCode, 09091 IN UINT uMapType, 09092 IN ULONG_PTR dwHKLorPKL, 09093 IN BOOL bHKL) 09094 { 09095 PKL pkl; 09096 09097 BEGINRECV_SHARED(UINT, 0); 09098 09099 /* 09100 * See if we need to convert an HKL to a PKL. MapVirtualKey passes a PKL and 09101 * MapVirtualKeyEx passes an HKL. The conversion must be done in the kernel. 09102 */ 09103 if (bHKL) { 09104 pkl = HKLtoPKL(PtiCurrentShared(), (HKL)dwHKLorPKL); 09105 } else { 09106 pkl = PtiCurrentShared()->spklActive; 09107 } 09108 09109 if (pkl == NULL) { 09110 retval = 0; 09111 } else { 09112 retval = InternalMapVirtualKeyEx(uCode, uMapType, pkl->spkf->pKbdTbl); 09113 } 09114 09115 TRACE("NtUserMapVirtualKeyEx"); 09116 ENDRECV_SHARED(); 09117 } 09118 09119 ATOM NtUserRegisterClassExWOW( 09120 IN WNDCLASSEX *lpWndClass, 09121 IN PUNICODE_STRING pstrClassName, 09122 IN PCLSMENUNAME pcmn, 09123 IN WORD fnid, 09124 IN DWORD dwFlags, 09125 IN LPDWORD pdwWOWstuff OPTIONAL) 09126 { 09127 UNICODE_STRING strClassName; 09128 UNICODE_STRING strMenuName; 09129 WNDCLASSEX WndClass; 09130 WC WowCls; 09131 CLSMENUNAME cmn; 09132 09133 BEGINRECV(ATOM, 0); 09134 09135 TESTFLAGS(dwFlags, CSF_VALID); 09136 09137 /* 09138 * Probe arguments 09139 */ 09140 try { 09141 strClassName = ProbeAndReadUnicodeString(pstrClassName); 09142 cmn = ProbeAndReadStructure(pcmn, CLSMENUNAME); 09143 strMenuName = ProbeAndReadUnicodeString(cmn.pusMenuName); 09144 WndClass = ProbeAndReadStructure(lpWndClass, WNDCLASSEX); 09145 ProbeForReadUnicodeStringBufferOrId(strClassName); 09146 ProbeForReadUnicodeStringBufferOrId(strMenuName); 09147 if (ARGUMENT_PRESENT(pdwWOWstuff)) { 09148 ProbeForRead(pdwWOWstuff, sizeof(WC), sizeof(BYTE)); 09149 RtlCopyMemory(&WowCls, pdwWOWstuff, sizeof(WC)); 09150 pdwWOWstuff = (PDWORD)&WowCls; 09151 } 09152 WndClass.lpszClassName = strClassName.Buffer; 09153 WndClass.lpszMenuName = strMenuName.Buffer; 09154 } except (StubExceptionHandler(TRUE)) { 09155 MSGERROR(0); 09156 } 09157 09158 /* 09159 * ClassName and MenuName in WndClass are client-side pointers. 09160 */ 09161 09162 retval = xxxRegisterClassEx( 09163 &WndClass, 09164 &cmn, 09165 fnid, 09166 dwFlags, 09167 pdwWOWstuff); 09168 09169 TRACE("NtUserRegisterClassExWOW"); 09170 ENDRECV(); 09171 } 09172 09173 UINT NtUserRegisterWindowMessage( 09174 IN PUNICODE_STRING pstrMessage) 09175 { 09176 UNICODE_STRING strMessage; 09177 09178 BEGINRECV_NOCRIT(UINT, 0); 09179 09180 /* 09181 * Probe arguments 09182 */ 09183 try { 09184 strMessage = ProbeAndReadUnicodeString(pstrMessage); 09185 ProbeForReadUnicodeStringBuffer(strMessage); 09186 } except (StubExceptionHandler(TRUE)) { 09187 MSGERROR(0); 09188 } 09189 09190 /* 09191 * The buffer is in client-side memory. 09192 * Rtl atom routines protect accesses to strings with their 09193 * own try/except blocks, UserAddAtom sets last error accordingly. 09194 */ 09195 retval = UserAddAtom( 09196 strMessage.Buffer, FALSE); 09197 09198 TRACE("NtUserRegisterWindowMessage"); 09199 ENDRECV_NOCRIT(); 09200 } 09201 09202 HANDLE NtUserRemoveProp( 09203 IN HWND hwnd, 09204 IN DWORD dwProp) 09205 { 09206 09207 // 09208 // N.B. This function has implicit window handle translation. This 09209 // operation is performed in the User server API dispatcher. 09210 // 09211 09212 BEGINRECV_HWND(HANDLE, NULL, hwnd); 09213 09214 retval = InternalRemoveProp(pwnd, (LPWSTR)LOWORD(dwProp), FALSE); 09215 09216 TRACE("NtUserRemoveProp"); 09217 ENDRECV_HWND(); 09218 } 09219 09220 BOOL NtUserSetProp( 09221 IN HWND hwnd, 09222 IN DWORD dwProp, 09223 IN HANDLE hData) 09224 { 09225 09226 // 09227 // N.B. This function has implicit window handle translation. This 09228 // operation is performed in the User server API dispatcher. 09229 // 09230 09231 BEGINRECV_HWND(DWORD, 0, hwnd); 09232 09233 retval = InternalSetProp( 09234 pwnd, 09235 (LPTSTR)LOWORD(dwProp), 09236 hData, 09237 HIWORD(dwProp) ? PROPF_STRING : 0); 09238 09239 TRACE("NtUserSetProp"); 09240 ENDRECV_HWND(); 09241 } 09242 09243 BOOL NtUserUnregisterClass( // API UnregisterClass 09244 IN PUNICODE_STRING pstrClassName, 09245 IN HINSTANCE hInstance, 09246 OUT PCLSMENUNAME pcmn) 09247 { 09248 UNICODE_STRING strClassName; 09249 CLSMENUNAME cmn; 09250 09251 BEGINRECV(BOOL, FALSE); 09252 09253 /* 09254 * Probe arguments 09255 */ 09256 try { 09257 strClassName = ProbeAndReadUnicodeString(pstrClassName); 09258 ProbeForReadUnicodeStringBufferOrId(strClassName); 09259 } except (StubExceptionHandler(TRUE)) { 09260 MSGERROR(0); 09261 } 09262 09263 /* 09264 * The buffer is in client-side memory. 09265 */ 09266 09267 retval = _UnregisterClass( 09268 strClassName.Buffer, 09269 hInstance, 09270 &cmn); 09271 09272 try { 09273 ProbeAndWriteStructure(pcmn, cmn, CLSMENUNAME); 09274 } except (StubExceptionHandler(FALSE)) { 09275 // no SetLastError, since pcmn is a USER address, not the application's 09276 } 09277 09278 TRACE("NtUserUnregisterClass"); 09279 ENDRECV(); 09280 } 09281 09282 SHORT NtUserVkKeyScanEx( 09283 IN WCHAR cChar, 09284 IN ULONG_PTR dwHKLorPKL, 09285 IN BOOL bHKL) 09286 { 09287 PKL pkl; 09288 09289 BEGINRECV_SHARED(SHORT, -1); 09290 09291 /* 09292 * See if we need to convert an HKL to a PKL. VkKeyScan passes a PKL and 09293 * VkKeyScanEx passes an HKL. The conversion must be done on the server side. 09294 */ 09295 if (bHKL) { 09296 pkl = HKLtoPKL(PtiCurrentShared(), (HKL)dwHKLorPKL); 09297 } else { 09298 pkl = PtiCurrentShared()->spklActive; 09299 } 09300 09301 if (pkl == NULL) { 09302 retval = (SHORT)-1; 09303 } else { 09304 retval = InternalVkKeyScanEx(cChar, pkl->spkf->pKbdTbl); 09305 } 09306 09307 TRACE("NtUserVkKeyScanEx"); 09308 ENDRECV_SHARED(); 09309 } 09310 09311 NTSTATUS 09312 NtUserEnumDisplayDevices( 09313 IN PUNICODE_STRING pstrDeviceName, 09314 IN DWORD iDevNum, 09315 IN OUT LPDISPLAY_DEVICEW lpDisplayDevice, 09316 IN DWORD dwFlags) 09317 { 09318 BEGINRECV(NTSTATUS, STATUS_UNSUCCESSFUL); 09319 09320 // 09321 // Update the list of devices. 09322 // If the function returns FALSE (retry update), then we must 09323 // disable the current hdev, call back, and reanable the hdev. 09324 // 09325 09326 if (DrvUpdateGraphicsDeviceList(FALSE, FALSE) == FALSE) { 09327 09328 if (DrvDisableMDEV(gpDispInfo->pmdev, TRUE)) { 09329 09330 DrvUpdateGraphicsDeviceList(TRUE, FALSE); 09331 09332 DrvEnableMDEV(gpDispInfo->pmdev, TRUE); 09333 09334 // 09335 // Repaint the screen 09336 // 09337 09338 xxxUserResetDisplayDevice(); 09339 } 09340 } 09341 09342 /* 09343 * Address checking, etc., occurs in GRE. 09344 */ 09345 09346 retval = DrvEnumDisplayDevices(pstrDeviceName, 09347 gpDispInfo->pMonitorPrimary->hDev, 09348 iDevNum, 09349 lpDisplayDevice, 09350 dwFlags, 09351 UserMode); 09352 TRACE("NtUserEnumDisplayDevices"); 09353 ENDRECV(); 09354 } 09355 09356 NTSTATUS 09357 NtUserEnumDisplaySettings( 09358 IN PUNICODE_STRING pstrDeviceName, 09359 IN DWORD iModeNum, 09360 OUT LPDEVMODEW lpDevMode, 09361 IN DWORD dwFlags) 09362 { 09363 BEGINRECV(NTSTATUS, STATUS_UNSUCCESSFUL); 09364 09365 /* 09366 * Address checking, etc., occurs in GRE. 09367 */ 09368 09369 retval = DrvEnumDisplaySettings(pstrDeviceName, 09370 gpDispInfo->pMonitorPrimary->hDev, 09371 iModeNum, 09372 lpDevMode, 09373 dwFlags); 09374 09375 TRACE("NtUserEnumDisplaySettings"); 09376 ENDRECV(); 09377 } 09378 09379 LONG 09380 NtUserChangeDisplaySettings( 09381 IN PUNICODE_STRING pstrDeviceName, 09382 IN LPDEVMODEW pDevMode, 09383 IN HWND hwnd, 09384 IN DWORD dwFlags, 09385 IN PVOID lParam) 09386 { 09387 BEGINRECV(LONG, DISP_CHANGE_FAILED); 09388 09389 /* 09390 * Prevent restricted threads from changing 09391 * display settings 09392 */ 09393 if (IS_CURRENT_THREAD_RESTRICTED(JOB_OBJECT_UILIMIT_DISPLAYSETTINGS)) { 09394 MSGERROR(0); 09395 } 09396 09397 /* 09398 * Address checking, etc., occurs in GRE. 09399 */ 09400 09401 retval = xxxUserChangeDisplaySettings(pstrDeviceName, 09402 pDevMode, 09403 hwnd, 09404 NULL, // pdesk 09405 dwFlags, 09406 lParam, 09407 UserMode); 09408 09409 TRACE("NtUserChangeDisplaySettings"); 09410 ENDRECV(); 09411 } 09412 09413 BOOL NtUserCallMsgFilter( // API CallMsgFilterA/W 09414 IN OUT LPMSG lpMsg, 09415 IN int nCode) 09416 { 09417 MSG msg; 09418 09419 BEGINRECV(BOOL, FALSE); 09420 09421 /* 09422 * Probe arguments 09423 */ 09424 try { 09425 ProbeForWriteMessage(lpMsg); 09426 msg = *lpMsg; 09427 } except (StubExceptionHandler(TRUE)) { 09428 MSGERROR(0); 09429 } 09430 09431 retval = _CallMsgFilter( 09432 &msg, 09433 nCode); 09434 try { 09435 *lpMsg = msg; 09436 } except (StubExceptionHandler(TRUE)) { 09437 MSGERROR(0); 09438 } 09439 09440 TRACE("NtUserCallMsgFilter"); 09441 ENDRECV(); 09442 } 09443 09444 int NtUserDrawMenuBarTemp( // private DrawMenuBarTemp 09445 IN HWND hwnd, 09446 IN HDC hdc, 09447 IN LPCRECT lprc, 09448 IN HMENU hMenu, 09449 IN HFONT hFont) 09450 { 09451 // 09452 // N.B. This function has implicit window translation and thread locking 09453 // enabled. These operations are performed in the User server API 09454 // dispatcher. 09455 // 09456 09457 PMENU pMenu; 09458 TL tlpMenu; 09459 RECT rc; 09460 09461 09462 BEGINRECV_HWNDLOCK(int, 0, hwnd); 09463 09464 /* 09465 * Probe and capture arguments. 09466 */ 09467 try { 09468 rc = ProbeAndReadRect(lprc); 09469 } except (StubExceptionHandler(FALSE)) { 09470 MSGERROR(0); 09471 } 09472 09473 ValidateHMENU(pMenu, hMenu); 09474 09475 ThreadLockAlwaysWithPti(ptiCurrent, pMenu, &tlpMenu); 09476 09477 retval = xxxDrawMenuBarTemp( 09478 pwnd, 09479 hdc, 09480 &rc, 09481 pMenu, 09482 hFont); 09483 09484 ThreadUnlock(&tlpMenu); 09485 09486 TRACE("NtUserDrawMenuBarTemp"); 09487 ENDRECV_HWNDLOCK(); 09488 } 09489 09490 BOOL NtUserDrawCaptionTemp( // private DrawCaptionTempA/W 09491 IN HWND hwnd, 09492 IN HDC hdc, 09493 IN LPCRECT lprc, 09494 IN HFONT hFont, 09495 IN HICON hIcon, 09496 IN PUNICODE_STRING pstrText, 09497 IN UINT flags) 09498 { 09499 PCURSOR pcur; 09500 TL tlpcur; 09501 RECT rc; 09502 UNICODE_STRING strCapture; 09503 PWND pwnd; 09504 TL tlpwnd; 09505 PTHREADINFO ptiCurrent; 09506 TL tlBuffer; 09507 BOOL fFreeBuffer = FALSE; 09508 09509 BEGINRECV(DWORD, FALSE); 09510 09511 ptiCurrent = PtiCurrent(); 09512 09513 ValidateHWNDOPT(pwnd, hwnd); 09514 ValidateHCURSOROPT(pcur, hIcon); 09515 09516 /* 09517 * Probe and capture arguments. Capturing the text is ugly, 09518 * but must be done because it is passed to GDI. 09519 */ 09520 try { 09521 rc = ProbeAndReadRect(lprc); 09522 strCapture = ProbeAndReadUnicodeString(pstrText); 09523 if (strCapture.Buffer != NULL) { 09524 PWSTR pszCapture = strCapture.Buffer; 09525 ProbeForRead(strCapture.Buffer, strCapture.Length, CHARALIGN); 09526 strCapture.Buffer = UserAllocPoolWithQuota(strCapture.Length+sizeof(UNICODE_NULL), TAG_TEXT); 09527 if (strCapture.Buffer != NULL) { 09528 fFreeBuffer = TRUE; 09529 ThreadLockPool(ptiCurrent, strCapture.Buffer, &tlBuffer); 09530 RtlCopyMemory(strCapture.Buffer, pszCapture, strCapture.Length); 09531 strCapture.Buffer[strCapture.Length/sizeof(WCHAR)]=0; // null-terminate string 09532 strCapture.MaximumLength = strCapture.Length+sizeof(UNICODE_NULL); 09533 pstrText = &strCapture; 09534 } else { 09535 ExRaiseStatus(STATUS_NO_MEMORY); 09536 } 09537 } 09538 } except (StubExceptionHandler(FALSE)) { 09539 MSGERRORCLEANUP(0); 09540 } 09541 09542 ThreadLockWithPti(ptiCurrent, pwnd, &tlpwnd); 09543 ThreadLockWithPti(ptiCurrent, pcur, &tlpcur); 09544 09545 retval = xxxDrawCaptionTemp( 09546 pwnd, 09547 hdc, 09548 &rc, 09549 hFont, 09550 pcur, 09551 strCapture.Buffer ? &strCapture : NULL, 09552 flags); 09553 09554 ThreadUnlock(&tlpcur); 09555 ThreadUnlock(&tlpwnd); 09556 09557 CLEANUPRECV(); 09558 if (fFreeBuffer) 09559 ThreadUnlockAndFreePool(ptiCurrent, &tlBuffer); 09560 09561 TRACE("NtUserDrawCaptionTemp"); 09562 ENDRECV(); 09563 } 09564 09565 BOOL NtUserGetKeyboardState( // API GetKeyboardState 09566 OUT PBYTE pb) 09567 { 09568 int i; 09569 PQ pq; 09570 BEGINRECV_SHARED(SHORT, 0) 09571 09572 /* 09573 * Probe arguments 09574 */ 09575 try { 09576 ProbeForWrite(pb, 256, sizeof(BYTE)); 09577 09578 pq = PtiCurrentShared()->pq; 09579 09580 for (i = 0; i < 256; i++, pb++) { 09581 *pb = 0; 09582 if (TestKeyStateDown(pq, i)) 09583 *pb |= 0x80; 09584 09585 if (TestKeyStateToggle(pq, i)) 09586 *pb |= 0x01; 09587 } 09588 retval = TRUE; 09589 } except (StubExceptionHandler(TRUE)) { 09590 MSGERROR(0); 09591 } 09592 09593 ENDRECV_SHARED(); 09594 } 09595 09596 SHORT NtUserGetKeyState( 09597 IN int vk) 09598 { 09599 PTHREADINFO ptiCurrent; 09600 BEGINRECV_SHARED(SHORT, 0) 09601 09602 ptiCurrent = PtiCurrentShared(); 09603 if (ptiCurrent->pq->QF_flags & QF_UPDATEKEYSTATE) { 09604 09605 /* 09606 * We are going to change the system state, so we 09607 * must have an exclusive lock 09608 */ 09609 ChangeAcquireResourceType(); 09610 09611 /* 09612 * If this thread needs a key state event, give one to it. There are 09613 * cases where any app may be looping looking at GetKeyState(), plus 09614 * calling PeekMessage(). Key state events don't get created unless 09615 * new hardware input comes along. If the app isn't receiving hardware 09616 * input, it won't get the new key state. So ResyncKeyState() will 09617 * ensure that if the app is looping on GetKeyState(), it'll get the 09618 * right key state. 09619 */ 09620 if (ptiCurrent->pq->QF_flags & QF_UPDATEKEYSTATE) { 09621 PostUpdateKeyStateEvent(ptiCurrent->pq); 09622 } 09623 } 09624 retval = _GetKeyState(vk); 09625 09626 /* 09627 * Update the client side key state cache. 09628 */ 09629 ptiCurrent->pClientInfo->dwKeyCache = gpsi->dwKeyCache; 09630 RtlCopyMemory(ptiCurrent->pClientInfo->afKeyState, 09631 ptiCurrent->pq->afKeyState, 09632 CBKEYCACHE); 09633 09634 ENDRECV_SHARED(); 09635 } 09636 09637 /**************************************************************************\ 09638 * NtUserQueryWindow 09639 * 09640 * 03-18-95 JimA Created. 09641 \**************************************************************************/ 09642 09643 HANDLE NtUserQueryWindow( 09644 IN HWND hwnd, 09645 IN WINDOWINFOCLASS WindowInfo) 09646 { 09647 PTHREADINFO ptiWnd; 09648 09649 BEGINRECV_HWND_SHARED(HANDLE, NULL, hwnd); 09650 09651 ptiWnd = GETPTI(pwnd); 09652 09653 switch (WindowInfo) { 09654 case WindowProcess: 09655 09656 /* 09657 * Special case console windows 09658 */ 09659 if (ptiWnd->TIF_flags & TIF_CSRSSTHREAD && 09660 pwnd->pcls->atomClassName == gatomConsoleClass) { 09661 retval = (HANDLE)LongToHandle( _GetWindowLong(pwnd, 0) ); 09662 } else { 09663 retval = (HANDLE)ptiWnd->pEThread->Cid.UniqueProcess; 09664 } 09665 break; 09666 case WindowThread: 09667 09668 /* 09669 * Special case console windows 09670 */ 09671 if (ptiWnd->TIF_flags & TIF_CSRSSTHREAD && 09672 pwnd->pcls->atomClassName == gatomConsoleClass) { 09673 retval = (HANDLE)LongToHandle( _GetWindowLong(pwnd, 4) ); 09674 } else { 09675 retval = (HANDLE)ptiWnd->pEThread->Cid.UniqueThread; 09676 } 09677 break; 09678 case WindowActiveWindow: 09679 retval = (HANDLE)HW(ptiWnd->pq->spwndActive); 09680 break; 09681 case WindowFocusWindow: 09682 retval = (HANDLE)HW(ptiWnd->pq->spwndFocus); 09683 break; 09684 case WindowIsHung: 09685 retval = (HANDLE)IntToPtr( FHungApp(ptiWnd, CMSHUNGAPPTIMEOUT) ); 09686 break; 09687 case WindowIsForegroundThread: 09688 retval = (HANDLE)IntToPtr( (ptiWnd->pq == gpqForeground) ); 09689 break; 09690 case WindowDefaultImeWindow: 09691 retval = (HANDLE)HW(ptiWnd->spwndDefaultIme); 09692 break; 09693 case WindowDefaultInputContext: 09694 retval = (HANDLE)PtoH(ptiWnd->spDefaultImc); 09695 break; 09696 case WindowActiveDefaultImeWindow: 09697 /* 09698 * Only return a window if there is a foreground queue and the 09699 * caller has access to the current desktop. 09700 */ 09701 retval = NULL; 09702 if (gpqForeground && gpqForeground->spwndActive && 09703 PtiCurrentShared()->rpdesk == gpqForeground->spwndActive->head.rpdesk) { 09704 PWND pwndFG = gpqForeground->spwndActive; 09705 09706 if (pwndFG && pwndFG->head.pti) { 09707 retval = (HANDLE)PtoHq(pwndFG->head.pti->spwndDefaultIme); 09708 } 09709 } 09710 break; 09711 default: 09712 retval = (HANDLE)NULL; 09713 break; 09714 } 09715 09716 ENDRECV_HWND_SHARED(); 09717 } 09718 09719 BOOL NtUserSBGetParms( // API GetScrollInfo, SBM_GETSCROLLINFO 09720 IN HWND hwnd, 09721 IN int code, 09722 IN PSBDATA pw, 09723 IN OUT LPSCROLLINFO lpsi) 09724 { 09725 SBDATA sbd; 09726 SCROLLINFO si; 09727 BEGINRECV_HWND_SHARED(BOOL, FALSE, hwnd); 09728 09729 /* 09730 * Probe arguments 09731 */ 09732 try { 09733 ProbeForWriteScrollInfo(lpsi); 09734 09735 /* 09736 * Probe the 4 DWORDS (MIN, MAX, PAGE, POS) 09737 */ 09738 ProbeForRead(pw, sizeof(SBDATA), sizeof(DWORD)); 09739 RtlCopyMemory(&sbd, pw, sizeof(sbd)); 09740 RtlCopyMemory(&si, lpsi, sizeof(SCROLLINFO)); 09741 } except (StubExceptionHandler(TRUE)) { 09742 MSGERROR(0); 09743 } 09744 09745 retval = _SBGetParms(pwnd, code, &sbd, &si); 09746 try { 09747 RtlCopyMemory(lpsi, &si, sizeof(SCROLLINFO)); 09748 } except (StubExceptionHandler(TRUE)) { 09749 MSGERROR(0); 09750 } 09751 09752 ENDRECV_HWND_SHARED(); 09753 } 09754 09755 BOOL NtUserBitBltSysBmp( 09756 IN HDC hdc, 09757 IN int xDest, 09758 IN int yDest, 09759 IN int cxDest, 09760 IN int cyDest, 09761 IN int xSrc, 09762 IN int ySrc, 09763 IN DWORD dwRop) 09764 { 09765 BEGINRECV(BOOL, FALSE); 09766 09767 /* 09768 * Note -- this interface requires exclusive ownership of 09769 * the User crit sect in order to serialize use 09770 * of HDCBITS. Only one thread at a time may use 09771 * a DC. 09772 */ 09773 09774 retval = GreBitBlt(hdc, 09775 xDest, 09776 yDest, 09777 cxDest, 09778 cyDest, 09779 HDCBITS(), 09780 xSrc, 09781 ySrc, 09782 dwRop, 09783 0); 09784 09785 ENDRECV(); 09786 } 09787 09788 HPALETTE NtUserSelectPalette( 09789 IN HDC hdc, 09790 IN HPALETTE hpalette, 09791 IN BOOL fForceBackground) 09792 { 09793 BEGINRECV(HPALETTE, NULL) 09794 09795 retval = _SelectPalette(hdc, hpalette, fForceBackground); 09796 09797 ENDRECV(); 09798 } 09799 09800 /* 09801 * Message thunks 09802 */ 09803 09804 LRESULT NtUserMessageCall( 09805 IN HWND hwnd, 09806 IN UINT msg, 09807 IN WPARAM wParam, 09808 IN LPARAM lParam, 09809 IN ULONG_PTR xParam, 09810 IN DWORD xpfnProc, 09811 IN BOOL bAnsi) 09812 { 09813 BEGINRECV_HWNDLOCK(LRESULT, 0, hwnd); 09814 09815 if ((msg & ~MSGFLAG_MASK) >= WM_USER) { 09816 retval = CALLPROC(xpfnProc)( 09817 pwnd, 09818 msg, 09819 wParam, 09820 lParam, 09821 xParam); 09822 } else { 09823 retval = gapfnMessageCall[MessageTable[(msg & ~MSGFLAG_MASK)].iFunction]( 09824 pwnd, 09825 msg, 09826 wParam, 09827 lParam, 09828 xParam, 09829 xpfnProc, 09830 bAnsi); 09831 } 09832 09833 TRACE("NtUserMessageCall"); 09834 ENDRECV_HWNDLOCK(); 09835 } 09836 09837 MESSAGECALL(DWORD) 09838 { 09839 BEGINRECV_MESSAGECALL(0); 09840 TRACETHUNK("fnDWORD"); 09841 09842 UNREFERENCED_PARAMETER(bAnsi); 09843 09844 retval = CALLPROC(xpfnProc)( 09845 pwnd, 09846 msg, 09847 wParam, 09848 lParam, 09849 xParam); 09850 09851 TRACE("fnDWORD"); 09852 ENDRECV_MESSAGECALL(); 09853 09854 } 09855 09856 MESSAGECALL(OPTOUTLPDWORDOPTOUTLPDWORD) 09857 { 09858 DWORD dwwParam, dwlParam; 09859 09860 // 09861 // N.B. This function has implicit window translation and thread locking 09862 // enabled. These operations are performed in the User server API 09863 // dispatcher. 09864 // 09865 09866 BEGINRECV_MESSAGECALL(0); 09867 TRACETHUNK("fnOPTOUTLPDWORDOPTOUTLPDWORD"); 09868 09869 UNREFERENCED_PARAMETER(bAnsi); 09870 09871 retval = CALLPROC(xpfnProc)( 09872 pwnd, 09873 msg, 09874 (WPARAM)&dwwParam, 09875 (LPARAM)&dwlParam, 09876 xParam); 09877 09878 /* 09879 * Probe arguments 09880 */ 09881 try { 09882 if (ARGUMENT_PRESENT(wParam)) { 09883 ProbeAndWriteUlong((PULONG)wParam, dwwParam); 09884 } 09885 if (ARGUMENT_PRESENT(lParam)) { 09886 ProbeAndWriteUlong((PULONG)lParam, dwlParam); 09887 } 09888 } except (StubExceptionHandler(TRUE)) { 09889 MSGERROR(0); // should messages with bad wParam/lParam SetLastError? 09890 } 09891 09892 TRACE("fnOPTOUTLPDWORDOPTOUTLPDWORD"); 09893 ENDRECV_MESSAGECALL(); 09894 09895 } 09896 09897 MESSAGECALL(INOUTNEXTMENU) 09898 { 09899 MDINEXTMENU mnm; 09900 09901 // 09902 // N.B. This function has implicit window translation and thread locking 09903 // enabled. These operations are performed in the User server API 09904 // dispatcher. 09905 // 09906 09907 BEGINRECV_MESSAGECALL(0); 09908 TRACETHUNK("fnINOUTNEXTMENU"); 09909 09910 UNREFERENCED_PARAMETER(bAnsi); 09911 09912 /* 09913 * Probe arguments 09914 */ 09915 try { 09916 ProbeForWriteMDINextMenu((PMDINEXTMENU)lParam); 09917 mnm = *(PMDINEXTMENU)lParam; 09918 09919 } except (StubExceptionHandler(FALSE)) { 09920 MSGERROR(0); 09921 } 09922 retval = CALLPROC(xpfnProc)( 09923 pwnd, 09924 msg, 09925 wParam, 09926 (LPARAM)&mnm, 09927 xParam); 09928 09929 try { 09930 *(PMDINEXTMENU)lParam = mnm; 09931 } except (StubExceptionHandler(FALSE)) { 09932 } 09933 09934 TRACE("fnINOUTNEXTMENU"); 09935 ENDRECV_MESSAGECALL(); 09936 } 09937 09938 MESSAGECALL(DWORDOPTINLPMSG) 09939 { 09940 MSG msgstruct; 09941 09942 // 09943 // N.B. This function has implicit window translation and thread locking 09944 // enabled. These operations are performed in the User server API 09945 // dispatcher. 09946 // 09947 09948 BEGINRECV_MESSAGECALL(0); 09949 TRACETHUNK("fnDWORDOPTINLPMSG"); 09950 09951 UNREFERENCED_PARAMETER(bAnsi); 09952 09953 /* 09954 * Probe arguments 09955 */ 09956 try { 09957 if (ARGUMENT_PRESENT(lParam)) { 09958 msgstruct = ProbeAndReadMessage((LPMSG)lParam); 09959 lParam = (LPARAM)&msgstruct; 09960 } 09961 } except (StubExceptionHandler(FALSE)) { 09962 MSGERROR(0); 09963 } 09964 09965 retval = CALLPROC(xpfnProc)( 09966 pwnd, 09967 msg, 09968 wParam, 09969 lParam, 09970 xParam); 09971 09972 TRACE("fnDWORDOPTINLPMSG"); 09973 ENDRECV_MESSAGECALL(); 09974 } 09975 09976 MESSAGECALL(COPYGLOBALDATA) 09977 { 09978 09979 // 09980 // N.B. This function has implicit window translation and thread locking 09981 // enabled. These operations are performed in the User server API 09982 // dispatcher. 09983 // 09984 09985 BEGINRECV_MESSAGECALL(0); 09986 TRACETHUNK("fnCOPYGLOBALDATA"); 09987 09988 UNREFERENCED_PARAMETER(bAnsi); 09989 09990 /* 09991 * Probe arguments 09992 */ 09993 try { 09994 ProbeForRead((PVOID)lParam, wParam, sizeof(BYTE)); 09995 } except (StubExceptionHandler(FALSE)) { 09996 MSGERROR(0); 09997 } 09998 09999 /* 10000 * !!! Data pointed to by lParam must be captured 10001 * in xxxInterSendMsgEx 10002 */ 10003 retval = CALLPROC(xpfnProc)( 10004 pwnd, 10005 msg, 10006 wParam, 10007 lParam, 10008 xParam); 10009 10010 TRACE("fnCOPYGLOBALDATA"); 10011 ENDRECV_MESSAGECALL(); 10012 } 10013 10014 MESSAGECALL(COPYDATA) 10015 { 10016 COPYDATASTRUCT cds; 10017 10018 // 10019 // N.B. This function has implicit window translation and thread locking 10020 // enabled. These operations are performed in the User server API 10021 // dispatcher. 10022 // 10023 10024 BEGINRECV_MESSAGECALL(0); 10025 TRACETHUNK("fnCOPYDATA"); 10026 10027 UNREFERENCED_PARAMETER(bAnsi); 10028 10029 /* 10030 * Probe arguments 10031 */ 10032 try { 10033 if (ARGUMENT_PRESENT(lParam)) { 10034 cds = ProbeAndReadCopyDataStruct((PCOPYDATASTRUCT)lParam); 10035 if (cds.lpData) 10036 ProbeForRead(cds.lpData, cds.cbData, sizeof(BYTE)); 10037 lParam = (LPARAM)&cds; 10038 } 10039 } except (StubExceptionHandler(FALSE)) { 10040 MSGERROR(0); 10041 } 10042 10043 /* 10044 * !!! Data pointed to by cds.lpData must be captured 10045 * in xxxInterSendMsgEx 10046 */ 10047 retval = CALLPROC(xpfnProc)( 10048 pwnd, 10049 msg, 10050 wParam, 10051 lParam, 10052 xParam); 10053 10054 TRACE("fnCOPYDATA"); 10055 ENDRECV_MESSAGECALL(); 10056 } 10057 10058 MESSAGECALL(SENTDDEMSG) 10059 { 10060 BEGINRECV_MESSAGECALL(0); 10061 TRACETHUNK("fnSENTDDEMSG"); 10062 10063 UNREFERENCED_PARAMETER(bAnsi); 10064 10065 if (xpfnProc == FNID_CALLWINDOWPROC) { 10066 retval = CALLPROC(xpfnProc)(pwnd, 10067 msg | MSGFLAG_DDE_SPECIAL_SEND, 10068 wParam, lParam, xParam); 10069 } else if ((ptiCurrent->TIF_flags & TIF_16BIT) && 10070 (ptiCurrent->ptdb) && 10071 (ptiCurrent->ptdb->hTaskWow)) { 10072 /* 10073 * Note that this function may modify msg by ORing in a bit in the 10074 * high word. This bit is ignored when thunking messages. 10075 * This allows the DdeTrackSendMessage() hook to be skipped - which 10076 * would cause an error - and instead allows this thunk to carry 10077 * the message all the way across. 10078 */ 10079 retval = xxxDDETrackPostHook(&msg, pwnd, wParam, &lParam, TRUE); 10080 switch (retval) { 10081 case DO_POST: 10082 /* 10083 * Or in the MSGFLAG_DDE_SPECIAL_SEND so that 10084 * xxxSendMessageTimeout() will not pass this on to 10085 * xxxDdeTrackSendMsg() which would think it was evil. 10086 * 10087 * Since the SendMessage() thunks ignore the reserved bits 10088 * it will still get maped to the fnSENTDDEMSG callback thunk. 10089 */ 10090 retval = CALLPROC(xpfnProc)(pwnd, 10091 msg | MSGFLAG_DDE_SPECIAL_SEND, 10092 wParam, lParam, xParam); 10093 break; 10094 10095 case FAKE_POST: 10096 case FAIL_POST: 10097 retval = 0; 10098 } 10099 } else { 10100 MSGERROR(0); 10101 } 10102 10103 TRACE("fnSENTDDEMSG"); 10104 ENDRECV_MESSAGECALL(); 10105 } 10106 10107 MESSAGECALL(DDEINIT) 10108 { 10109 10110 // 10111 // N.B. This function has implicit window translation and thread locking 10112 // enabled. These operations are performed in the User server API 10113 // dispatcher. 10114 // 10115 10116 PWND pwndFrom; 10117 TL tlpwndFrom; 10118 PDDEIMP pddei; 10119 PSECURITY_QUALITY_OF_SERVICE pqos; 10120 NTSTATUS Status; 10121 10122 BEGINRECV_MESSAGECALL(0); 10123 TRACETHUNK("fnDDEINIT"); 10124 10125 UNREFERENCED_PARAMETER(bAnsi); 10126 10127 ValidateHWND(pwndFrom, (HWND)wParam); 10128 ThreadLockAlwaysWithPti(ptiCurrent, pwndFrom, &tlpwndFrom); 10129 10130 /* 10131 * Create temporary DDEIMP property for client window - this stays around 10132 * only during the initiate phase. 10133 */ 10134 if ((pddei = (PDDEIMP)_GetProp(pwndFrom, PROP_DDEIMP, TRUE)) 10135 == NULL) { 10136 pddei = (PDDEIMP)UserAllocPoolWithQuota(sizeof(DDEIMP), TAG_DDEd); 10137 if (pddei == NULL) { 10138 RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_WARNING, "fnDDEINIT: LocalAlloc failed."); 10139 MSGERRORCLEANUP(0); 10140 } 10141 pqos = (PSECURITY_QUALITY_OF_SERVICE)_GetProp(pwndFrom, PROP_QOS, TRUE); 10142 if (pqos == NULL) { 10143 pqos = &gqosDefault; 10144 } 10145 pddei->qos = *pqos; 10146 Status = SeCreateClientSecurity(PsGetCurrentThread(), 10147 pqos, FALSE, &pddei->ClientContext); 10148 if (!NT_SUCCESS(Status)) { 10149 RIPMSG0(RIP_WARNING, "SeCreateClientContext failed."); 10150 UserFreePool(pddei); 10151 MSGERRORCLEANUP(0); 10152 } 10153 pddei->cRefInit = 1; 10154 pddei->cRefConv = 0; 10155 InternalSetProp(pwndFrom, PROP_DDEIMP, pddei, PROPF_INTERNAL); 10156 } else { 10157 pddei->cRefInit++; // cover broadcast case! 10158 } 10159 10160 retval = CALLPROC(xpfnProc)( 10161 pwnd, 10162 msg, 10163 wParam, 10164 lParam, 10165 xParam); 10166 10167 /* 10168 * Reaquire pddei incase pwndFrom was destroyed. 10169 */ 10170 pddei = (PDDEIMP)_GetProp(pwndFrom, PROP_DDEIMP, TRUE); 10171 if (pddei != NULL) { 10172 /* 10173 * Decrement reference count from DDEImpersonate property and remove property. 10174 */ 10175 pddei->cRefInit--; 10176 if (pddei->cRefInit == 0) { 10177 InternalRemoveProp(pwndFrom, PROP_DDEIMP, TRUE); 10178 if (pddei->cRefConv == 0) { 10179 SeDeleteClientSecurity(&pddei->ClientContext); 10180 UserFreePool(pddei); 10181 } 10182 } 10183 } 10184 10185 CLEANUPRECV(); 10186 ThreadUnlock(&tlpwndFrom); 10187 10188 TRACE("fnDDEINIT"); 10189 ENDRECV_MESSAGECALL(); 10190 } 10191 10192 MESSAGECALL(INPAINTCLIPBRD) 10193 { 10194 PAINTSTRUCT ps; 10195 10196 BEGINRECV_MESSAGECALL(0); 10197 TRACETHUNK("fnINPAINTCLIPBRD"); 10198 10199 UNREFERENCED_PARAMETER(bAnsi); 10200 10201 /* 10202 * Probe arguments 10203 */ 10204 try { 10205 ps = ProbeAndReadPaintStruct((PPAINTSTRUCT)lParam); 10206 } except (StubExceptionHandler(FALSE)) { 10207 MSGERROR(0); 10208 } 10209 10210 retval = CALLPROC(xpfnProc)( 10211 pwnd, 10212 msg, 10213 wParam, 10214 (LPARAM)&ps, 10215 xParam); 10216 10217 TRACE("fnINPAINTCLIPBRD"); 10218 ENDRECV_MESSAGECALL(); 10219 } 10220 10221 MESSAGECALL(INSIZECLIPBRD) 10222 { 10223 RECT rc; 10224 10225 BEGINRECV_MESSAGECALL(0); 10226 TRACETHUNK("fnINSIZECLIPBRD"); 10227 10228 UNREFERENCED_PARAMETER(bAnsi); 10229 10230 /* 10231 * Probe arguments 10232 */ 10233 try { 10234 rc = ProbeAndReadRect((PRECT)lParam); 10235 } except (StubExceptionHandler(FALSE)) { 10236 MSGERROR(0); 10237 } 10238 10239 retval = CALLPROC(xpfnProc)( 10240 pwnd, 10241 msg, 10242 wParam, 10243 (LPARAM)&rc, 10244 xParam); 10245 10246 TRACE("fnINSIZECLIPBRD"); 10247 ENDRECV_MESSAGECALL(); 10248 } 10249 10250 #if 0 10251 10252 // !!!LATER not needed until we support multiple screens 10253 10254 MESSAGECALL(FULLSCREEN) 10255 { 10256 TL tlpwnd; 10257 10258 BEGINRECV(LRESULT, FALSE); 10259 TRACETHUNK("fnFULLSCREEN"); 10260 10261 /* 10262 * Probe arguments 10263 */ 10264 try { 10265 } except (StubExceptionHandler(FALSE)) { 10266 MSGERROR(0); 10267 } 10268 10269 ValidateHWND(pwnd, hwnd); 10270 10271 ThreadLockAlways(pwnd, &tlpwnd); 10272 retval = CALLPROC(xpfnProc)( 10273 pwnd, 10274 pmsg->msg, 10275 pmsg->wParam, 10276 (LONG)pdeviceinfo, 10277 pmsg->xParam); 10278 ThreadUnlock(&tlpwnd); 10279 10280 TRACE("fnFULLSCREEN"); 10281 ENDRECV(); 10282 } 10283 10284 #endif // 0 10285 10286 MESSAGECALL(INOUTDRAG) 10287 { 10288 DROPSTRUCT ds; 10289 10290 // 10291 // N.B. This function has implicit window translation and thread locking 10292 // enabled. These operations are performed in the User server API 10293 // dispatcher. 10294 // 10295 10296 BEGINRECV_MESSAGECALL(0); 10297 TRACETHUNK("fnINOUTDRAG"); 10298 10299 UNREFERENCED_PARAMETER(bAnsi); 10300 10301 /* 10302 * Probe arguments 10303 */ 10304 try { 10305 ProbeForWriteDropStruct((PDROPSTRUCT)lParam); 10306 ds = *(PDROPSTRUCT)lParam; 10307 10308 } except (StubExceptionHandler(FALSE)) { 10309 MSGERROR(0); 10310 } 10311 retval = CALLPROC(xpfnProc)( 10312 pwnd, 10313 msg, 10314 wParam, 10315 (LPARAM)&ds, 10316 xParam); 10317 10318 try { 10319 *(PDROPSTRUCT)lParam = ds; 10320 } except (StubExceptionHandler(FALSE)) { 10321 } 10322 10323 TRACE("fnINOUTDRAG"); 10324 ENDRECV_MESSAGECALL(); 10325 } 10326 10327 MESSAGECALL(GETDBCSTEXTLENGTHS) 10328 { 10329 10330 // 10331 // N.B. This function has implicit window translation and thread locking 10332 // enabled. These operations are performed in the User server API 10333 // dispatcher. 10334 // 10335 10336 BEGINRECV_MESSAGECALL(0); 10337 TRACETHUNK("fnGETDBCSTEXTLENGTHS"); 10338 10339 UNREFERENCED_PARAMETER(lParam); 10340 10341 /* 10342 * This is used by L/CB_GETTEXTLEN which should return -1 (L/CB_ERR) 10343 * on error. If any error code path is introduced here, make sure we return the 10344 * proper value.This is also used by WM_GETTEXTLEN. 10345 */ 10346 10347 retval = CALLPROC(xpfnProc)( 10348 pwnd, 10349 msg, 10350 wParam, 10351 bAnsi, 10352 xParam); 10353 10354 TRACE("fnGETDBCSTEXTLENGTHS"); 10355 ENDRECV_MESSAGECALL(); 10356 } 10357 10358 MESSAGECALL(INLPCREATESTRUCT) 10359 { 10360 CREATESTRUCTEX csex; 10361 10362 // 10363 // N.B. This function has implicit window translation and thread locking 10364 // enabled. These operations are performed in the User server API 10365 // dispatcher. 10366 // 10367 10368 BEGINRECV_MESSAGECALL(0); 10369 TRACETHUNK("fnINLPCREATESTRUCT"); 10370 10371 if (ARGUMENT_PRESENT(lParam)) { 10372 try { 10373 csex.cs = ProbeAndReadCreateStruct((LPCREATESTRUCTW)lParam); 10374 if (bAnsi) { 10375 ProbeForRead(csex.cs.lpszName, sizeof(CHAR), sizeof(CHAR)); 10376 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&csex.strName, 10377 (LPSTR)csex.cs.lpszName, (UINT)-1); 10378 if (IS_PTR(csex.cs.lpszClass)) { 10379 ProbeForRead(csex.cs.lpszClass, sizeof(CHAR), sizeof(CHAR)); 10380 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&csex.strClass, 10381 (LPSTR)csex.cs.lpszClass, (UINT)-1); 10382 } 10383 } else { 10384 ProbeForRead(csex.cs.lpszName, sizeof(WCHAR), CHARALIGN); 10385 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&csex.strName, 10386 csex.cs.lpszName, (UINT)-1); 10387 if (IS_PTR(csex.cs.lpszClass)) { 10388 ProbeForRead(csex.cs.lpszClass, sizeof(WCHAR), CHARALIGN); 10389 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&csex.strClass, 10390 csex.cs.lpszClass, (UINT)-1); 10391 } 10392 } 10393 } except (StubExceptionHandler(FALSE)) { 10394 MSGERROR(0); 10395 } 10396 } 10397 10398 /* 10399 * Per Win95, do not allow NULL lpcreatestructs for WM_NCCREATE [51986] 10400 * Allowed for WM_CREATE in Win95 for ObjectVision 10401 */ 10402 else if (msg == WM_NCCREATE) { 10403 MSGERROR(0) ; 10404 } 10405 10406 /* 10407 * !!! Strings pointed to by cs.cs must be captured in xxxInterSendMsgEx 10408 */ 10409 retval = CALLPROC(xpfnProc)( 10410 pwnd, 10411 msg, 10412 wParam, 10413 lParam ? (LPARAM)&csex : 0, 10414 xParam); 10415 10416 TRACE("fnINLPCREATESTRUCT"); 10417 ENDRECV_MESSAGECALL(); 10418 } 10419 10420 MESSAGECALL(INLPMDICREATESTRUCT) 10421 { 10422 // 10423 // N.B. This function has implicit window translation and thread locking 10424 // enabled. These operations are performed in the User server API 10425 // dispatcher. 10426 // 10427 10428 MDICREATESTRUCTEX mdics; 10429 10430 BEGINRECV_MESSAGECALL(0); 10431 TRACETHUNK("fnINLPMDICREATESTRUCT"); 10432 10433 /* 10434 * Probe arguments 10435 */ 10436 try { 10437 mdics.mdics = ProbeAndReadMDICreateStruct((LPMDICREATESTRUCTW)lParam); 10438 10439 if (bAnsi) { 10440 ProbeForRead(mdics.mdics.szTitle, sizeof(CHAR), sizeof(CHAR)); 10441 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&mdics.strTitle, 10442 (LPSTR)mdics.mdics.szTitle, (UINT)-1); 10443 if (IS_PTR(mdics.mdics.szClass)) { 10444 ProbeForRead(mdics.mdics.szClass, sizeof(CHAR), sizeof(CHAR)); 10445 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&mdics.strClass, 10446 (LPSTR)mdics.mdics.szClass, (UINT)-1); 10447 } else { 10448 /* 10449 * mdics.mdics.szClass may be Atom. 10450 */ 10451 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&mdics.strClass, 10452 NULL, 0); 10453 } 10454 } else { 10455 ProbeForRead(mdics.mdics.szTitle, sizeof(WCHAR), CHARALIGN); 10456 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&mdics.strTitle, 10457 mdics.mdics.szTitle, (UINT)-1); 10458 if (IS_PTR(mdics.mdics.szClass)) { 10459 ProbeForRead(mdics.mdics.szClass, sizeof(WCHAR), CHARALIGN); 10460 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&mdics.strClass, 10461 mdics.mdics.szClass, (UINT)-1); 10462 } else { 10463 /* 10464 * mdics.mdics.szClass may be Atom. 10465 */ 10466 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&mdics.strClass, 10467 NULL, 0); 10468 } 10469 } 10470 } except (StubExceptionHandler(FALSE)) { 10471 MSGERROR(0); 10472 } 10473 10474 /* 10475 * !!! Strings pointed to by mdics must be captured in xxxInterSendMsgEx 10476 */ 10477 retval = CALLPROC(xpfnProc)( 10478 pwnd, 10479 msg, 10480 wParam, 10481 (LPARAM)&mdics, 10482 xParam); 10483 10484 TRACE("fnINLPMDICREATESTRUCT"); 10485 ENDRECV_MESSAGECALL(); 10486 } 10487 10488 MESSAGECALL(INOUTLPSCROLLINFO) 10489 { 10490 SCROLLINFO scrollinfo; 10491 10492 // 10493 // N.B. This function has implicit window translation and thread locking 10494 // enabled. These operations are performed in the User server API 10495 // dispatcher. 10496 // 10497 10498 BEGINRECV_MESSAGECALL(0); 10499 TRACETHUNK("fnINOUTLPSCROLLINFO"); 10500 10501 UNREFERENCED_PARAMETER(bAnsi); 10502 10503 /* 10504 * Probe arguments 10505 */ 10506 try { 10507 ProbeForWriteScrollInfo((LPSCROLLINFO)lParam); 10508 scrollinfo = *(LPSCROLLINFO)lParam; 10509 } except (StubExceptionHandler(FALSE)) { 10510 MSGERROR(0); 10511 } 10512 10513 retval = CALLPROC(xpfnProc)( 10514 pwnd, 10515 msg, 10516 wParam, 10517 (LPARAM)&scrollinfo, 10518 xParam); 10519 10520 try { 10521 *(LPSCROLLINFO)lParam = scrollinfo; 10522 } except (StubExceptionHandler(FALSE)) { 10523 } 10524 10525 TRACE("fnINOUTLPSCROLLINFO"); 10526 ENDRECV_MESSAGECALL(); 10527 } 10528 10529 MESSAGECALL(INOUTLPPOINT5) 10530 { 10531 POINT5 pt5; 10532 10533 // 10534 // N.B. This function has implicit window translation and thread locking 10535 // enabled. These operations are performed in the User server API 10536 // dispatcher. 10537 // 10538 10539 BEGINRECV_MESSAGECALL(0); 10540 TRACETHUNK("fnINOUTLPPOINT5"); 10541 10542 UNREFERENCED_PARAMETER(bAnsi); 10543 10544 /* 10545 * Probe arguments 10546 */ 10547 try { 10548 ProbeForWritePoint5((LPPOINT5)lParam); 10549 pt5 = *(LPPOINT5)lParam; 10550 } except (StubExceptionHandler(FALSE)) { 10551 MSGERROR(0); 10552 } 10553 10554 retval = CALLPROC(xpfnProc)( 10555 pwnd, 10556 msg, 10557 wParam, 10558 (LPARAM)&pt5, 10559 xParam); 10560 10561 try { 10562 *(LPPOINT5)lParam = pt5; 10563 } except (StubExceptionHandler(FALSE)) { 10564 } 10565 10566 TRACE("fnINOUTLPPOINT5"); 10567 ENDRECV_MESSAGECALL(); 10568 } 10569 10570 MESSAGECALL(INSTRING) 10571 { 10572 LARGE_STRING str; 10573 10574 // 10575 // N.B. This function has implicit window translation and thread locking 10576 // enabled. These operations are performed in the User server API 10577 // dispatcher. 10578 // 10579 10580 BEGINRECV_MESSAGECALL(0); 10581 TRACETHUNK("fnINSTRING"); 10582 10583 /* 10584 * Don't allow any app to send a LB_DIR or CB_DIR with the postmsgs bit 10585 * set (ObjectVision does this). This is because there is actually a legal 10586 * case that we need to thunk of user posting a LB_DIR or CB_DIR 10587 * (DlgDirListHelper()). In the post case, we thunk the lParam (pointer 10588 * to a string) differently, and we track that post case with the 10589 * DDL_POSTMSGS bit. If an app sends a message with this bit, then our 10590 * thunking gets confused, so clear it here. Let's hope that no app 10591 * depends on this bit set when either of these messages are sent. 10592 * 10593 * These messages should return -1 on failure 10594 */ 10595 switch (msg) { 10596 case LB_DIR: 10597 case CB_DIR: 10598 wParam &= ~DDL_POSTMSGS; 10599 /* Fall through */ 10600 10601 case LB_ADDFILE: 10602 #if (LB_ERR != CB_ERR) 10603 #error LB_ERR/CB_ERR conflict 10604 #endif 10605 errret = LB_ERR; 10606 break; 10607 } 10608 10609 /* 10610 * Probe arguments 10611 */ 10612 try { 10613 if (bAnsi) { 10614 ProbeForRead((LPSTR)lParam, sizeof(CHAR), sizeof(CHAR)); 10615 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&str, 10616 (LPSTR)lParam, (UINT)-1); 10617 } else { 10618 ProbeForRead((LPWSTR)lParam, sizeof(WCHAR), CHARALIGN); 10619 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&str, 10620 (LPWSTR)lParam, (UINT)-1); 10621 } 10622 } except (StubExceptionHandler(FALSE)) { 10623 MSGERROR(0); 10624 } 10625 10626 /* 10627 * !!! str.Buffer must be captured in xxxInterSendMsgEx 10628 */ 10629 retval = CALLPROC(xpfnProc)( 10630 pwnd, 10631 msg, 10632 wParam, 10633 (LPARAM)&str, 10634 xParam); 10635 10636 TRACE("fnINSTRING"); 10637 ENDRECV_MESSAGECALL(); 10638 } 10639 10640 MESSAGECALL(INSTRINGNULL) 10641 { 10642 LARGE_STRING str; 10643 10644 // 10645 // N.B. This function has implicit window translation and thread locking 10646 // enabled. These operations are performed in the User server API 10647 // dispatcher. 10648 // 10649 10650 BEGINRECV_MESSAGECALL(0); 10651 TRACETHUNK("fnINSTRINGNULL"); 10652 10653 /* 10654 * Probe arguments 10655 */ 10656 if (ARGUMENT_PRESENT(lParam)) { 10657 try { 10658 if (bAnsi) { 10659 ProbeForRead((LPSTR)lParam, sizeof(CHAR), sizeof(CHAR)); 10660 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&str, 10661 (LPSTR)lParam, (UINT)-1); 10662 } else { 10663 ProbeForRead((LPWSTR)lParam, sizeof(WCHAR), CHARALIGN); 10664 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&str, 10665 (LPWSTR)lParam, (UINT)-1); 10666 } 10667 lParam = (LPARAM)&str; 10668 } except (StubExceptionHandler(FALSE)) { 10669 MSGERROR(0); 10670 } 10671 } 10672 10673 /* 10674 * !!! str.Buffer must be captured in xxxInterSendMsgEx 10675 */ 10676 retval = CALLPROC(xpfnProc)( 10677 pwnd, 10678 msg, 10679 wParam, 10680 lParam, 10681 xParam); 10682 10683 TRACE("fnINSTRINGNULL"); 10684 ENDRECV_MESSAGECALL(); 10685 } 10686 10687 MESSAGECALL(INDEVICECHANGE) 10688 { 10689 BOOL fPtr = (BOOL)((wParam & 0x8000) == 0x8000); 10690 DWORD cbSize; 10691 PBYTE bfr = NULL; 10692 TL tlBuffer; 10693 10694 // 10695 // N.B. This function has implicit window translation and thread locking 10696 // enabled. These operations are performed in the User server API 10697 // dispatcher. 10698 // 10699 10700 BEGINRECV_MESSAGECALL(0); 10701 TRACETHUNK("fnINDEVICECHANGE"); 10702 10703 UNREFERENCED_PARAMETER(bAnsi); 10704 10705 /* 10706 * Probe arguments 10707 */ 10708 if (fPtr && lParam) { 10709 struct _DEV_BROADCAST_HEADER *pHdr; 10710 PDEV_BROADCAST_DEVICEINTERFACE_W pInterfaceW; 10711 PDEV_BROADCAST_PORT_W pPortW; 10712 PDEV_BROADCAST_HANDLE pHandleW; 10713 try { 10714 pHdr = (struct _DEV_BROADCAST_HEADER *)lParam; 10715 cbSize = ProbeAndReadUlong(&(pHdr->dbcd_size)); 10716 if (cbSize < sizeof(*pHdr)) { 10717 MSGERROR(ERROR_INVALID_PARAMETER); 10718 } 10719 ProbeForRead(pHdr, cbSize, sizeof(BYTE)); 10720 10721 bfr = UserAllocPoolWithQuota(cbSize+2, TAG_DEVICECHANGE); // add space for trailing NULL for test 10722 if (bfr == NULL) { 10723 RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_WARNING, "fnINDEVICECHANGE: LocalAlloc failed."); 10724 MSGERRORCLEANUP(0); 10725 } 10726 10727 ThreadLockPool(ptiCurrent, bfr, &tlBuffer); 10728 10729 RtlCopyMemory(bfr, (PBYTE)lParam, 10730 cbSize); 10731 ((PWSTR)bfr)[cbSize/sizeof(WCHAR)] = 0; // trailing null to halt wcslen scan 10732 lParam = (LPARAM)bfr; 10733 pHdr = (struct _DEV_BROADCAST_HEADER *)lParam; 10734 if (pHdr->dbcd_size != cbSize) { 10735 MSGERRORCLEANUP(0); 10736 } 10737 switch(pHdr->dbcd_devicetype) { 10738 case DBT_DEVTYP_PORT: 10739 pPortW = (PDEV_BROADCAST_PORT_W)lParam; 10740 if ((1+wcslen(pPortW->dbcp_name))*sizeof(WCHAR) + FIELD_OFFSET(DEV_BROADCAST_PORT_W, dbcp_name) > cbSize) { 10741 MSGERRORCLEANUP(0); 10742 } 10743 break; 10744 case DBT_DEVTYP_DEVICEINTERFACE: 10745 pInterfaceW = (PDEV_BROADCAST_DEVICEINTERFACE_W)lParam; 10746 if ((1+wcslen(pInterfaceW->dbcc_name))*sizeof(WCHAR) + FIELD_OFFSET(DEV_BROADCAST_DEVICEINTERFACE_W, dbcc_name) > cbSize) { 10747 MSGERRORCLEANUP(0); 10748 } 10749 break; 10750 case DBT_DEVTYP_HANDLE: 10751 pHandleW = (PDEV_BROADCAST_HANDLE)lParam; 10752 /* 10753 * Check if there is any text. 10754 */ 10755 10756 if (wParam != DBT_CUSTOMEVENT) { 10757 if (FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_eventguid) > cbSize) { 10758 MSGERRORCLEANUP(0); 10759 } 10760 break; 10761 } 10762 if (pHandleW->dbch_nameoffset < 0) { 10763 if (FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_data) > cbSize) { 10764 MSGERRORCLEANUP(0); 10765 } 10766 break; 10767 } 10768 if (pHandleW->dbch_nameoffset & (CHARALIGN - 1)) { 10769 ExRaiseDatatypeMisalignment(); \ 10770 } 10771 if ((DWORD)(FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_data) + pHandleW->dbch_nameoffset) > cbSize) { 10772 MSGERRORCLEANUP(0); 10773 } 10774 if (FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_data) + pHandleW->dbch_nameoffset + 10775 (1+wcslen((LPWSTR)(pHandleW->dbch_data+pHandleW->dbch_nameoffset)))*sizeof(WCHAR) > 10776 cbSize) { 10777 MSGERRORCLEANUP(0); 10778 } 10779 break; 10780 10781 } 10782 10783 } except (StubExceptionHandler(FALSE)) { 10784 MSGERRORCLEANUP(0); 10785 } 10786 10787 } 10788 10789 retval = CALLPROC(xpfnProc)( 10790 pwnd, 10791 msg, 10792 wParam, 10793 lParam, 10794 xParam); 10795 10796 CLEANUPRECV(); 10797 if (bfr) 10798 ThreadUnlockAndFreePool(ptiCurrent, &tlBuffer); 10799 10800 TRACE("fnINDEVICECHANGE"); 10801 ENDRECV_MESSAGECALL(); 10802 } 10803 10804 MESSAGECALL(INOUTNCCALCSIZE) 10805 { 10806 NCCALCSIZE_PARAMS params; 10807 WINDOWPOS pos; 10808 PWINDOWPOS pposClient; 10809 RECT rc; 10810 LPARAM lParamLocal; 10811 10812 // 10813 // N.B. This function has implicit window translation and thread locking 10814 // enabled. These operations are performed in the User server API 10815 // dispatcher. 10816 // 10817 10818 BEGINRECV_MESSAGECALL(0); 10819 TRACETHUNK("fnINOUTNCCALCSIZE"); 10820 10821 UNREFERENCED_PARAMETER(bAnsi); 10822 10823 /* 10824 * Probe arguments 10825 */ 10826 try { 10827 if (wParam != 0) { 10828 ProbeForWriteNCCalcSize((LPNCCALCSIZE_PARAMS)lParam); 10829 params = *(LPNCCALCSIZE_PARAMS)lParam; 10830 ProbeForWriteWindowPos(params.lppos); 10831 pposClient = params.lppos; 10832 pos = *params.lppos; 10833 params.lppos = &pos; 10834 lParamLocal = (LPARAM)&params; 10835 } else { 10836 ProbeForWriteRect((LPRECT)lParam); 10837 rc = *(LPRECT)lParam; 10838 lParamLocal = (LPARAM)&rc; 10839 } 10840 } except (StubExceptionHandler(FALSE)) { 10841 MSGERROR(0); 10842 } 10843 retval = CALLPROC(xpfnProc)( 10844 pwnd, 10845 msg, 10846 wParam, 10847 lParamLocal, 10848 xParam); 10849 10850 try { 10851 if (wParam != 0) { 10852 *(LPNCCALCSIZE_PARAMS)lParam = params; 10853 ((LPNCCALCSIZE_PARAMS)lParam)->lppos = pposClient; 10854 *pposClient = pos; 10855 } else { 10856 *(LPRECT)lParam = rc; 10857 } 10858 } except (StubExceptionHandler(FALSE)) { 10859 } 10860 10861 TRACE("fnINOUTNCCALCSIZE"); 10862 ENDRECV_MESSAGECALL(); 10863 } 10864 10865 MESSAGECALL(INOUTSTYLECHANGE) 10866 { 10867 STYLESTRUCT ss; 10868 10869 // 10870 // N.B. This function has implicit window translation and thread locking 10871 // enabled. These operations are performed in the User server API 10872 // dispatcher. 10873 // 10874 10875 BEGINRECV_MESSAGECALL(0); 10876 TRACETHUNK("fnINOUTSTYLECHANGE"); 10877 10878 UNREFERENCED_PARAMETER(bAnsi); 10879 10880 /* 10881 * Probe arguments 10882 */ 10883 try { 10884 ProbeForWriteStyleStruct((LPSTYLESTRUCT)lParam); 10885 ss = *(LPSTYLESTRUCT)lParam; 10886 } except (StubExceptionHandler(FALSE)) { 10887 MSGERROR(0); 10888 } 10889 10890 retval = CALLPROC(xpfnProc)( 10891 pwnd, 10892 msg, 10893 wParam, 10894 (LPARAM)&ss, 10895 xParam); 10896 10897 try { 10898 *(LPSTYLESTRUCT)lParam = ss; 10899 } except (StubExceptionHandler(FALSE)) { 10900 } 10901 10902 TRACE("fnINOUTSTYLECHANGE"); 10903 ENDRECV_MESSAGECALL(); 10904 } 10905 10906 MESSAGECALL(INOUTLPRECT) 10907 { 10908 RECT rc; 10909 10910 // 10911 // N.B. This function has implicit window translation and thread locking 10912 // enabled. These operations are performed in the User server API 10913 // dispatcher. 10914 // 10915 10916 BEGINRECV_MESSAGECALL((msg == LB_GETITEMRECT ? LB_ERR : 0)); 10917 TRACETHUNK("fnINOUTLPRECT"); 10918 10919 UNREFERENCED_PARAMETER(bAnsi); 10920 10921 /* 10922 * Probe arguments 10923 */ 10924 try { 10925 ProbeForWriteRect((PRECT)lParam); 10926 rc = *(PRECT)lParam; 10927 } except (StubExceptionHandler(FALSE)) { 10928 MSGERROR(0); 10929 } 10930 10931 retval = CALLPROC(xpfnProc)( 10932 pwnd, 10933 msg, 10934 wParam, 10935 (LPARAM)&rc, 10936 xParam); 10937 10938 try { 10939 *(PRECT)lParam = rc; 10940 } except (StubExceptionHandler(FALSE)) { 10941 } 10942 10943 TRACE("fnINOUTLPRECT"); 10944 ENDRECV_MESSAGECALL(); 10945 } 10946 10947 MESSAGECALL(OUTLPSCROLLINFO) 10948 { 10949 SCROLLINFO scrollinfo; 10950 10951 // 10952 // N.B. This function has implicit window translation and thread locking 10953 // enabled. These operations are performed in the User server API 10954 // dispatcher. 10955 // 10956 10957 BEGINRECV_MESSAGECALL(0); 10958 TRACETHUNK("fnOUTLPSCROLLINFO"); 10959 10960 UNREFERENCED_PARAMETER(bAnsi); 10961 10962 retval = CALLPROC(xpfnProc)( 10963 pwnd, 10964 msg, 10965 wParam, 10966 (LPARAM)&scrollinfo, 10967 xParam); 10968 10969 /* 10970 * Probe arguments 10971 */ 10972 try { 10973 ProbeAndWriteStructure((LPSCROLLINFO)lParam, scrollinfo, SCROLLINFO); 10974 } except (StubExceptionHandler(FALSE)) { 10975 MSGERROR(0); 10976 } 10977 10978 TRACE("fnOUTLPSCROLLINFO"); 10979 ENDRECV_MESSAGECALL(); 10980 } 10981 10982 MESSAGECALL(OUTLPRECT) 10983 { 10984 RECT rc; 10985 10986 // 10987 // N.B. This function has implicit window translation and thread locking 10988 // enabled. These operations are performed in the User server API 10989 // dispatcher. 10990 // 10991 10992 BEGINRECV_MESSAGECALL(0); 10993 TRACETHUNK("fnOUTLPRECT"); 10994 10995 UNREFERENCED_PARAMETER(bAnsi); 10996 10997 retval = CALLPROC(xpfnProc)( 10998 pwnd, 10999 msg, 11000 wParam, 11001 (LPARAM)&rc, 11002 xParam); 11003 11004 /* 11005 * Probe arguments 11006 */ 11007 try { 11008 ProbeAndWriteStructure((PRECT)lParam, rc, RECT); 11009 } except (StubExceptionHandler(FALSE)) { 11010 MSGERROR(0); 11011 } 11012 11013 TRACE("fnOUTLPRECT"); 11014 ENDRECV_MESSAGECALL(); 11015 } 11016 11017 MESSAGECALL(INLPCOMPAREITEMSTRUCT) 11018 { 11019 COMPAREITEMSTRUCT compareitemstruct; 11020 11021 // 11022 // N.B. This function has implicit window translation and thread locking 11023 // enabled. These operations are performed in the User server API 11024 // dispatcher. 11025 // 11026 11027 BEGINRECV_MESSAGECALL(0); 11028 TRACETHUNK("fnINLPCOMPAREITEMSTRUCT"); 11029 11030 UNREFERENCED_PARAMETER(bAnsi); 11031 11032 /* 11033 * Probe arguments 11034 */ 11035 try { 11036 compareitemstruct = ProbeAndReadCompareItemStruct((PCOMPAREITEMSTRUCT)lParam); 11037 } except (StubExceptionHandler(FALSE)) { 11038 MSGERROR(0); 11039 } 11040 11041 retval = CALLPROC(xpfnProc)( 11042 pwnd, 11043 msg, 11044 wParam, 11045 (LPARAM)&compareitemstruct, 11046 xParam); 11047 11048 TRACE("fnINLPCOMPAREITEMSTRUCT"); 11049 ENDRECV_MESSAGECALL(); 11050 } 11051 11052 MESSAGECALL(INLPDELETEITEMSTRUCT) 11053 { 11054 DELETEITEMSTRUCT deleteitemstruct; 11055 11056 // 11057 // N.B. This function has implicit window translation and thread locking 11058 // enabled. These operations are performed in the User server API 11059 // dispatcher. 11060 // 11061 11062 BEGINRECV_MESSAGECALL(0); 11063 TRACETHUNK("fnINLPDELETEITEMSTRUCT"); 11064 11065 UNREFERENCED_PARAMETER(bAnsi); 11066 11067 /* 11068 * Probe arguments 11069 */ 11070 try { 11071 deleteitemstruct = ProbeAndReadDeleteItemStruct((PDELETEITEMSTRUCT)lParam); 11072 } except (StubExceptionHandler(FALSE)) { 11073 MSGERROR(0); 11074 } 11075 11076 retval = CALLPROC(xpfnProc)( 11077 pwnd, 11078 msg, 11079 wParam, 11080 (LPARAM)&deleteitemstruct, 11081 xParam); 11082 11083 TRACE("fnINLPDELETEITEMSTRUCT"); 11084 ENDRECV_MESSAGECALL(); 11085 } 11086 11087 MESSAGECALL(INLPHLPSTRUCT) 11088 { 11089 HLP hlp; 11090 LPHLP phlp = NULL; 11091 TL tlBuffer; 11092 11093 // 11094 // N.B. This function has implicit window translation and thread locking 11095 // enabled. These operations are performed in the User server API 11096 // dispatcher. 11097 // 11098 11099 BEGINRECV_MESSAGECALL(0); 11100 TRACETHUNK("fnINLPHLPSTRUCT"); 11101 11102 UNREFERENCED_PARAMETER(bAnsi); 11103 11104 /* 11105 * Probe arguments 11106 */ 11107 try { 11108 hlp = ProbeAndReadHelp((LPHLP)lParam); 11109 if (hlp.cbData < sizeof(HLP)) { 11110 MSGERROR(0); 11111 } 11112 phlp = UserAllocPoolWithQuota(hlp.cbData, TAG_SYSTEM); 11113 if (phlp == NULL) { 11114 ExRaiseStatus(STATUS_NO_MEMORY); 11115 } 11116 ThreadLockPool(ptiCurrent, phlp, &tlBuffer); 11117 RtlCopyMemory(phlp, (PVOID)lParam, hlp.cbData); 11118 } except (StubExceptionHandler(FALSE)) { 11119 MSGERRORCLEANUP(0); 11120 } 11121 11122 retval = CALLPROC(xpfnProc)( 11123 pwnd, 11124 msg, 11125 wParam, 11126 (LPARAM)phlp, 11127 xParam); 11128 11129 CLEANUPRECV(); 11130 if (phlp) { 11131 ThreadUnlockAndFreePool(ptiCurrent, &tlBuffer); 11132 } 11133 11134 TRACE("fnINLPHLPSTRUCT"); 11135 ENDRECV_MESSAGECALL(); 11136 } 11137 11138 MESSAGECALL(INLPHELPINFOSTRUCT) 11139 { 11140 HELPINFO helpinfo; 11141 11142 // 11143 // N.B. This function has implicit window translation and thread locking 11144 // enabled. These operations are performed in the User server API 11145 // dispatcher. 11146 // 11147 11148 BEGINRECV_MESSAGECALL(0); 11149 TRACETHUNK("fnINLPHELPINFOSTRUCT"); 11150 11151 UNREFERENCED_PARAMETER(bAnsi); 11152 11153 /* 11154 * Probe arguments 11155 */ 11156 try { 11157 helpinfo = ProbeAndReadHelpInfo((LPHELPINFO)lParam); 11158 if (helpinfo.cbSize != sizeof(HELPINFO)) { 11159 RIPMSG1(RIP_WARNING, "HELPINFO.cbSize %d is wrong", helpinfo.cbSize); 11160 MSGERROR(ERROR_INVALID_PARAMETER); 11161 } 11162 } except (StubExceptionHandler(FALSE)) { 11163 MSGERROR(0); 11164 } 11165 11166 retval = CALLPROC(xpfnProc)( 11167 pwnd, 11168 msg, 11169 wParam, 11170 (LPARAM)&helpinfo, 11171 xParam); 11172 11173 TRACE("fnINLPHELPINFOSTRUCT"); 11174 ENDRECV_MESSAGECALL(); 11175 } 11176 11177 MESSAGECALL(INLPDRAWITEMSTRUCT) 11178 { 11179 DRAWITEMSTRUCT drawitemstruct; 11180 11181 // 11182 // N.B. This function has implicit window translation and thread locking 11183 // enabled. These operations are performed in the User server API 11184 // dispatcher. 11185 // 11186 11187 BEGINRECV_MESSAGECALL(0); 11188 TRACETHUNK("fnINLPDRAWITEMSTRUCT"); 11189 11190 UNREFERENCED_PARAMETER(bAnsi); 11191 11192 /* 11193 * Probe arguments 11194 */ 11195 try { 11196 drawitemstruct = ProbeAndReadDrawItemStruct((PDRAWITEMSTRUCT)lParam); 11197 } except (StubExceptionHandler(FALSE)) { 11198 MSGERROR(0); 11199 } 11200 11201 retval = CALLPROC(xpfnProc)( 11202 pwnd, 11203 msg, 11204 wParam, 11205 (LPARAM)&drawitemstruct, 11206 xParam); 11207 11208 TRACE("fnINLPDRAWITEMSTRUCT"); 11209 ENDRECV_MESSAGECALL(); 11210 } 11211 11212 MESSAGECALL(INOUTLPMEASUREITEMSTRUCT) 11213 { 11214 MEASUREITEMSTRUCT measureitemstruct; 11215 11216 // 11217 // N.B. This function has implicit window translation and thread locking 11218 // enabled. These operations are performed in the User server API 11219 // dispatcher. 11220 // 11221 11222 BEGINRECV_MESSAGECALL(0); 11223 TRACETHUNK("fnINOUTLPMEASUREITEMSTRUCT"); 11224 11225 UNREFERENCED_PARAMETER(bAnsi); 11226 11227 /* 11228 * Probe arguments 11229 */ 11230 try { 11231 ProbeForWriteMeasureItemStruct((PMEASUREITEMSTRUCT)lParam); 11232 measureitemstruct = *(PMEASUREITEMSTRUCT)lParam; 11233 } except (StubExceptionHandler(FALSE)) { 11234 MSGERROR(0); 11235 } 11236 11237 retval = CALLPROC(xpfnProc)( 11238 pwnd, 11239 msg, 11240 wParam, 11241 (LPARAM)&measureitemstruct, 11242 xParam); 11243 11244 try { 11245 *(PMEASUREITEMSTRUCT)lParam = measureitemstruct; 11246 } except (StubExceptionHandler(FALSE)) { 11247 } 11248 11249 TRACE("fnINOUTLPMEASUREITEMSTRUCT"); 11250 ENDRECV_MESSAGECALL(); 11251 } 11252 11253 MESSAGECALL(OUTSTRING) 11254 { 11255 LARGE_STRING str; 11256 11257 // 11258 // N.B. This function has implicit window translation and thread locking 11259 // enabled. These operations are performed in the User server API 11260 // dispatcher. 11261 // 11262 11263 BEGINRECV_MESSAGECALL(0); 11264 TRACETHUNK("fnOUTSTRING"); 11265 11266 /* 11267 * Probe all arguments 11268 */ 11269 try { 11270 str.bAnsi = bAnsi; 11271 str.MaximumLength = (ULONG)wParam; 11272 if (!bAnsi) { 11273 str.MaximumLength *= sizeof(WCHAR); 11274 } 11275 str.Length = 0; 11276 str.Buffer = (PVOID)lParam; 11277 #if defined(_X86_) 11278 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE)); 11279 #else 11280 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, 11281 str.bAnsi ? sizeof(BYTE) : sizeof(WORD)); 11282 #endif 11283 } except (StubExceptionHandler(FALSE)) { 11284 MSGERROR(0); 11285 } 11286 11287 /* 11288 * !!! String buffer must be created in xxxInterSendMsgEx and 11289 * lParam probed for write again upon return. 11290 */ 11291 retval = CALLPROC(xpfnProc)( 11292 pwnd, 11293 msg, 11294 wParam, 11295 (LPARAM)&str, 11296 xParam); 11297 11298 /* 11299 * A dialog function returning FALSE means no text to copy out, 11300 * but an empty string also has retval == 0: put a null char in 11301 * pstr for the latter case. 11302 */ 11303 if (!retval && wParam != 0) { 11304 try { 11305 NullTerminateString((PVOID)lParam, bAnsi); 11306 } except (StubExceptionHandler(FALSE)) { 11307 MSGERROR(0); 11308 } 11309 } 11310 11311 TRACE("fnOUTSTRING"); 11312 ENDRECV_MESSAGECALL(); 11313 } 11314 11315 MESSAGECALL(OUTDWORDINDWORD) 11316 { 11317 DWORD dw; 11318 11319 BEGINRECV_MESSAGECALL(0); 11320 TRACETHUNK("fnOUTDWORDINDWORD"); 11321 11322 UNREFERENCED_PARAMETER(bAnsi); 11323 11324 retval = CALLPROC(xpfnProc)( 11325 pwnd, 11326 msg, 11327 (WPARAM)&dw, 11328 lParam, 11329 xParam); 11330 11331 /* 11332 * Probe wParam 11333 */ 11334 try { 11335 ProbeAndWriteUlong((PULONG)wParam, dw); 11336 } except (StubExceptionHandler(FALSE)) { 11337 MSGERROR(0); 11338 } 11339 11340 TRACE("fnOUTDWORDINDWORD"); 11341 ENDRECV_MESSAGECALL(); 11342 } 11343 11344 MESSAGECALL(INCNTOUTSTRING) 11345 { 11346 LARGE_STRING str; 11347 11348 BEGINRECV_MESSAGECALL(0); 11349 TRACETHUNK("fnINCNTOUTSTRING"); 11350 11351 /* 11352 * Probe arguments 11353 */ 11354 try { 11355 str.bAnsi = bAnsi; 11356 str.MaximumLength = ProbeAndReadUshort((LPWORD)lParam); 11357 if (str.MaximumLength == 0) { 11358 RIPMSG0(RIP_WARNING, "fnINCNTOUTSTRING asking for 0 characters back\n"); 11359 MSGERROR(0); 11360 } 11361 if (!bAnsi) { 11362 str.MaximumLength *= sizeof(WCHAR); 11363 } 11364 str.Length = 0; 11365 str.Buffer = (LPBYTE)lParam; 11366 #if defined(_X86_) 11367 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE)); 11368 #else 11369 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, 11370 str.bAnsi ? sizeof(BYTE) : sizeof(WORD)); 11371 #endif 11372 } except (StubExceptionHandler(FALSE)) { 11373 MSGERROR(0); 11374 } 11375 11376 /* 11377 * !!! String buffer must be created in xxxInterSendMsgEx and 11378 * lParam probed for write again upon return. 11379 */ 11380 retval = CALLPROC(xpfnProc)( 11381 pwnd, 11382 msg, 11383 wParam, 11384 (LPARAM)&str, 11385 xParam); 11386 11387 /* 11388 * A dialog function returning FALSE means no text to copy out, 11389 * but an empty string also has retval == 0: put a null char in 11390 * pstr for the latter case. 11391 */ 11392 if (!retval) { 11393 try { 11394 NullTerminateString((PVOID)lParam, bAnsi); 11395 } except (StubExceptionHandler(FALSE)) { 11396 MSGERROR(0); 11397 } 11398 } 11399 11400 TRACE("fnINCNTOUTSTRING"); 11401 ENDRECV_MESSAGECALL(); 11402 } 11403 11404 MESSAGECALL(INCNTOUTSTRINGNULL) 11405 { 11406 LARGE_STRING str; 11407 11408 // 11409 // N.B. This function has implicit window translation and thread locking 11410 // enabled. These operations are performed in the User server API 11411 // dispatcher. 11412 // 11413 11414 BEGINRECV_MESSAGECALL(0); 11415 TRACETHUNK("fnINCNTOUTSTRINGNULL"); 11416 11417 /* 11418 * Probe arguments 11419 */ 11420 try { 11421 if (wParam < 2) { // This prevents a possible GP 11422 MSGERROR(0); 11423 } 11424 11425 str.bAnsi = bAnsi; 11426 str.MaximumLength = (ULONG)wParam; 11427 if (!bAnsi) { 11428 str.MaximumLength *= sizeof(WCHAR); 11429 } 11430 str.Length = 0; 11431 str.Buffer = (LPBYTE)lParam; 11432 #if defined(_X86_) 11433 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE)); 11434 #else 11435 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, 11436 str.bAnsi ? sizeof(BYTE) : sizeof(WORD)); 11437 #endif 11438 *((LPWSTR)str.Buffer) = 0; // mark incase message is not handled 11439 } except (StubExceptionHandler(FALSE)) { 11440 MSGERROR(0); 11441 } 11442 11443 /* 11444 * !!! String buffer must be created in xxxInterSendMsgEx and 11445 * lParam probed for write again upon return. 11446 */ 11447 retval = CALLPROC(xpfnProc)( 11448 pwnd, 11449 msg, 11450 wParam, 11451 (LPARAM)&str, 11452 xParam); 11453 11454 TRACE("fnINCNTOUTSTRINGNULL"); 11455 ENDRECV_MESSAGECALL(); 11456 } 11457 11458 MESSAGECALL(POUTLPINT) 11459 { 11460 11461 // 11462 // N.B. This function has implicit window translation and thread locking 11463 // enabled. These operations are performed in the User server API 11464 // dispatcher. 11465 // 11466 11467 BEGINRECV_MESSAGECALL(LB_ERR); 11468 /* 11469 * If we use this for other messages, then that return value might not be appropriate. 11470 */ 11471 UserAssert(msg == LB_GETSELITEMS); 11472 TRACETHUNK("fnPOUTLPINT"); 11473 11474 UNREFERENCED_PARAMETER(bAnsi); 11475 11476 /* 11477 * Probe arguments 11478 */ 11479 try { 11480 #if defined(_X86_) 11481 ProbeForWriteBuffer((LPINT)lParam, wParam, sizeof(BYTE)); 11482 #else 11483 ProbeForWriteBuffer((LPINT)lParam, wParam, sizeof(INT)); 11484 #endif 11485 } except (StubExceptionHandler(FALSE)) { 11486 MSGERROR(0); 11487 } 11488 11489 /* 11490 * !!! Buffer must be created in xxxInterSendMsgEx and 11491 * lParam probed for write again upon return. 11492 */ 11493 retval = CALLPROC(xpfnProc)( 11494 pwnd, 11495 msg, 11496 wParam, 11497 lParam, 11498 xParam); 11499 11500 TRACE("fnPOUTLPINT"); 11501 ENDRECV_MESSAGECALL(); 11502 } 11503 11504 MESSAGECALL(POPTINLPUINT) 11505 { 11506 11507 // 11508 // N.B. This function has implicit window translation and thread locking 11509 // enabled. These operations are performed in the User server API 11510 // dispatcher. 11511 // 11512 11513 BEGINRECV_MESSAGECALL(0); 11514 TRACETHUNK("fnPOPTINLPUINT"); 11515 11516 UNREFERENCED_PARAMETER(bAnsi); 11517 11518 /* 11519 * Probe arguments 11520 */ 11521 try { 11522 #if defined(_X86_) 11523 if (lParam) 11524 ProbeForReadBuffer((LPUINT)lParam, wParam, sizeof(BYTE)); 11525 #else 11526 if (lParam) 11527 ProbeForReadBuffer((LPUINT)lParam, wParam, sizeof(DWORD)); 11528 #endif 11529 } except (StubExceptionHandler(FALSE)) { 11530 MSGERROR(0); 11531 } 11532 11533 /* 11534 * !!! Data pointed to by lParam must be captured in xxxInterSendMsgEx 11535 */ 11536 retval = CALLPROC(xpfnProc)( 11537 pwnd, 11538 msg, 11539 wParam, 11540 lParam, 11541 xParam); 11542 11543 TRACE("fnPOPTINLPUINT"); 11544 ENDRECV_MESSAGECALL(); 11545 } 11546 11547 MESSAGECALL(INOUTLPWINDOWPOS) 11548 { 11549 WINDOWPOS pos; 11550 11551 // 11552 // N.B. This function has implicit window translation and thread locking 11553 // enabled. These operations are performed in the User server API 11554 // dispatcher. 11555 // 11556 11557 BEGINRECV_MESSAGECALL(0); 11558 TRACETHUNK("fnINOUTLPWINDOWPOS"); 11559 11560 UNREFERENCED_PARAMETER(bAnsi); 11561 11562 /* 11563 * Probe arguments 11564 */ 11565 try { 11566 ProbeForWriteWindowPos((PWINDOWPOS)lParam); 11567 pos = *(PWINDOWPOS)lParam; 11568 } except (StubExceptionHandler(FALSE)) { 11569 MSGERROR(0); 11570 } 11571 11572 retval = CALLPROC(xpfnProc)( 11573 pwnd, 11574 msg, 11575 wParam, 11576 (LPARAM)&pos, 11577 xParam); 11578 11579 try { 11580 *(PWINDOWPOS)lParam = pos; 11581 } except (StubExceptionHandler(FALSE)) { 11582 } 11583 11584 TRACE("fnINOUTLPWINDOWPOS"); 11585 ENDRECV_MESSAGECALL(); 11586 } 11587 11588 MESSAGECALL(INLPWINDOWPOS) 11589 { 11590 WINDOWPOS pos; 11591 11592 // 11593 // N.B. This function has implicit window translation and thread locking 11594 // enabled. These operations are performed in the User server API 11595 // dispatcher. 11596 // 11597 11598 BEGINRECV_MESSAGECALL(0); 11599 TRACETHUNK("fnINLPWINDOWPOS"); 11600 11601 UNREFERENCED_PARAMETER(bAnsi); 11602 11603 /* 11604 * Probe arguments 11605 */ 11606 try { 11607 pos = ProbeAndReadWindowPos((PWINDOWPOS)lParam); 11608 } except (StubExceptionHandler(FALSE)) { 11609 MSGERROR(0); 11610 } 11611 11612 retval = CALLPROC(xpfnProc)( 11613 pwnd, 11614 msg, 11615 wParam, 11616 (LPARAM)&pos, 11617 xParam); 11618 11619 TRACE("fnINLPWINDOWPOS"); 11620 ENDRECV_MESSAGECALL(); 11621 } 11622 11623 MESSAGECALL(INLBOXSTRING) 11624 { 11625 BEGINRECV_MESSAGECALL(LB_ERR); 11626 TRACETHUNK("fnINLBOXSTRING"); 11627 11628 if (!(pwnd->style & LBS_HASSTRINGS) && 11629 (pwnd->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))) { 11630 retval = CALLPROC(xpfnProc)( 11631 pwnd, 11632 msg, 11633 wParam, 11634 lParam, 11635 xParam); 11636 } else if (msg == LB_FINDSTRING) { 11637 retval = NtUserfnINSTRINGNULL( 11638 pwnd, 11639 msg, 11640 wParam, 11641 lParam, 11642 xParam, 11643 xpfnProc, 11644 bAnsi); 11645 } else { 11646 retval = NtUserfnINSTRING( 11647 pwnd, 11648 msg, 11649 wParam, 11650 lParam, 11651 xParam, 11652 xpfnProc, 11653 bAnsi); 11654 } 11655 11656 TRACE("fnINLBOXSTRING"); 11657 ENDRECV_MESSAGECALL(); 11658 } 11659 11660 MESSAGECALL(OUTLBOXSTRING) 11661 { 11662 LARGE_STRING str; 11663 11664 BEGINRECV_MESSAGECALL(LB_ERR); 11665 TRACETHUNK("fnOUTLBOXSTRING"); 11666 11667 /* 11668 * Need to get the string length ahead of time. This isn't passed in 11669 * with this message. Code assumes app already knows the size of 11670 * the string and has passed a pointer to a buffer of adequate size. 11671 * To do client/server copying of this string, we need to ahead of 11672 * time the Unicode size of this string. We add one character because 11673 * GETTEXTLEN excludes the null terminator. 11674 */ 11675 retval = NtUserfnGETDBCSTEXTLENGTHS( 11676 pwnd, 11677 LB_GETTEXTLEN, 11678 wParam, 11679 lParam, 11680 xParam, 11681 xpfnProc, 11682 /*IS_DBCS_ENABLED() &&*/ bAnsi); // HiroYama: LATER 11683 if (retval == LB_ERR) 11684 MSGERROR(0); 11685 retval++; 11686 11687 /* 11688 * Probe all arguments 11689 */ 11690 try { 11691 str.bAnsi = bAnsi; 11692 if (bAnsi) 11693 str.MaximumLength = (ULONG)retval; 11694 else 11695 str.MaximumLength = (ULONG)retval * sizeof(WCHAR); 11696 str.Length = 0; 11697 str.Buffer = (PVOID)lParam; 11698 #if defined(_X86_) 11699 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE)); 11700 #else 11701 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, 11702 str.bAnsi ? sizeof(BYTE) : sizeof(WORD)); 11703 #endif 11704 } except (StubExceptionHandler(FALSE)) { 11705 MSGERROR(0); 11706 } 11707 11708 retval = CALLPROC(xpfnProc)( 11709 pwnd, 11710 msg, 11711 wParam, 11712 (LPARAM)&str, 11713 xParam); 11714 11715 /* 11716 * If the control is ownerdraw and does not have the LBS_HASSTRINGS 11717 * style, then a 32-bits of application data has been obtained, 11718 * not a string. 11719 */ 11720 if (!(pwnd->style & LBS_HASSTRINGS) && 11721 (pwnd->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))) { 11722 if (bAnsi) { 11723 retval = sizeof(ULONG_PTR)/sizeof(CHAR); // 4 CHARs just like win3.1 11724 } else { 11725 retval = sizeof(ULONG_PTR)/sizeof(WCHAR); // 2 WCHARs 11726 } 11727 } 11728 11729 TRACE("fnOUTLBOXSTRING"); 11730 ENDRECV_MESSAGECALL(); 11731 } 11732 11733 MESSAGECALL(INCBOXSTRING) 11734 { 11735 BEGINRECV_MESSAGECALL(CB_ERR); 11736 TRACETHUNK("fnINCBOXSTRING"); 11737 11738 if (!(pwnd->style & CBS_HASSTRINGS) && 11739 (pwnd->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))) { 11740 retval = CALLPROC(xpfnProc)( 11741 pwnd, 11742 msg, 11743 wParam, 11744 lParam, 11745 xParam); 11746 } else if (msg == CB_FINDSTRING) { 11747 retval = NtUserfnINSTRINGNULL( 11748 pwnd, 11749 msg, 11750 wParam, 11751 lParam, 11752 xParam, 11753 xpfnProc, 11754 bAnsi); 11755 } else { 11756 retval = NtUserfnINSTRING( 11757 pwnd, 11758 msg, 11759 wParam, 11760 lParam, 11761 xParam, 11762 xpfnProc, 11763 bAnsi); 11764 } 11765 11766 TRACE("fnINCBOXSTRING"); 11767 ENDRECV_MESSAGECALL(); 11768 } 11769 11770 MESSAGECALL(OUTCBOXSTRING) 11771 { 11772 LARGE_STRING str; 11773 11774 BEGINRECV_MESSAGECALL(CB_ERR); 11775 TRACETHUNK("fnOUTCBOXSTRING"); 11776 11777 /* 11778 * Need to get the string length ahead of time. This isn't passed in 11779 * with this message. Code assumes app already knows the size of 11780 * the string and has passed a pointer to a buffer of adequate size. 11781 * To do client/server copying of this string, we need to ahead of 11782 * time the size of this string. We add one character because 11783 * GETTEXTLEN excludes the null terminator. 11784 */ 11785 retval = NtUserfnGETDBCSTEXTLENGTHS( 11786 pwnd, 11787 CB_GETLBTEXTLEN, 11788 wParam, 11789 lParam, 11790 xParam, 11791 xpfnProc, 11792 /*IS_DBCS_ENABLED() &&*/ bAnsi); // HiroYama: LATER 11793 if (retval == CB_ERR) 11794 MSGERROR(0); 11795 retval++; 11796 11797 /* 11798 * Probe all arguments 11799 */ 11800 try { 11801 str.bAnsi = bAnsi; 11802 if (bAnsi) 11803 str.MaximumLength = (ULONG)retval; 11804 else 11805 str.MaximumLength = (ULONG)retval * sizeof(WCHAR); 11806 str.Length = 0; 11807 str.Buffer = (PVOID)lParam; 11808 #if defined(_X86_) 11809 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, sizeof(BYTE)); 11810 #else 11811 ProbeForWrite((PVOID)str.Buffer, str.MaximumLength, 11812 str.bAnsi ? sizeof(BYTE) : sizeof(WORD)); 11813 #endif 11814 } except (StubExceptionHandler(FALSE)) { 11815 MSGERROR(0); 11816 } 11817 11818 retval = CALLPROC(xpfnProc)( 11819 pwnd, 11820 msg, 11821 wParam, 11822 (LPARAM)&str, 11823 xParam); 11824 11825 /* 11826 * If the control is ownerdraw and does not have the CBS_HASSTRINGS 11827 * style, then a 32-bits of application data has been obtained, 11828 * not a string. 11829 */ 11830 if (!(pwnd->style & CBS_HASSTRINGS) && 11831 (pwnd->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))) { 11832 if (bAnsi) { 11833 retval = sizeof(ULONG_PTR)/sizeof(CHAR); // 4 CHARs just like win3.1 11834 } else { 11835 retval = sizeof(ULONG_PTR)/sizeof(WCHAR); // 2 WCHARs 11836 } 11837 } 11838 11839 TRACE("fnOUTCBOXSTRING"); 11840 ENDRECV_MESSAGECALL(); 11841 } 11842 11843 MESSAGECALL(INWPARAMCHAR) 11844 { 11845 BEGINRECV_MESSAGECALL(0); 11846 TRACETHUNK("fnINWPARAMCHAR"); 11847 11848 /* 11849 * The server always expects the characters to be unicode so 11850 * if this was generated from an ANSI routine convert it to Unicode 11851 */ 11852 if (bAnsi) { 11853 if (msg == WM_CHARTOITEM || msg == WM_MENUCHAR) { 11854 WPARAM dwT = wParam & 0xFFFF; // mask of caret pos 11855 RtlMBMessageWParamCharToWCS(msg, &dwT); // convert key portion 11856 wParam = MAKELONG(LOWORD(dwT),HIWORD(wParam)); // rebuild pos & key wParam 11857 } else { 11858 RtlMBMessageWParamCharToWCS(msg, &wParam); 11859 } 11860 } 11861 11862 retval = CALLPROC(xpfnProc)( 11863 pwnd, 11864 msg, 11865 wParam, 11866 lParam, 11867 xParam); 11868 11869 TRACE("fnINWPARAMCHAR"); 11870 ENDRECV_MESSAGECALL(); 11871 } 11872 11873 MESSAGECALL(KERNELONLY) 11874 { 11875 BEGINRECV_MESSAGECALL(0); 11876 TRACETHUNK("fnKERNELONLY"); 11877 11878 UNREFERENCED_PARAMETER(pwnd); 11879 UNREFERENCED_PARAMETER(msg); 11880 UNREFERENCED_PARAMETER(wParam); 11881 UNREFERENCED_PARAMETER(lParam); 11882 UNREFERENCED_PARAMETER(xParam); 11883 UNREFERENCED_PARAMETER(xpfnProc); 11884 UNREFERENCED_PARAMETER(bAnsi); 11885 11886 RIPMSG0(RIP_WARNING, 11887 "Message sent from client to kernel for a process which has only kernel side\n" ); 11888 11889 retval = 0; 11890 11891 TRACE("fnKERNELONLY"); 11892 ENDRECV_MESSAGECALL(); 11893 } 11894 11895 MESSAGECALL(IMECONTROL) 11896 { 11897 CANDIDATEFORM CandForm; 11898 COMPOSITIONFORM CompForm; 11899 LOGFONTW LogFontW; 11900 LPARAM lData = lParam; 11901 PSOFTKBDDATA pSoftKbdData = NULL; 11902 11903 // 11904 // N.B. This function has implicit window translation and thread locking 11905 // enabled. These operations are performed in the User server API 11906 // dispatcher. 11907 // 11908 11909 BEGINRECV_MESSAGECALL(0); 11910 TRACETHUNK("fnIMECONTROL"); 11911 11912 UNREFERENCED_PARAMETER(bAnsi); 11913 11914 /* 11915 * wParam range validation: 11916 * No need to check lower limit, 'cause we assume IMC_FIRST == 0 11917 * and wParam is unsigned. 11918 */ 11919 #if (IMC_FIRST != 0) 11920 #error IMC_FIRST: unexpected value 11921 #endif 11922 if (msg != WM_IME_CONTROL || wParam > IMC_LAST) { 11923 MSGERROR(0); 11924 } 11925 11926 /* 11927 * Probe arguments 11928 */ 11929 try { 11930 switch (wParam) { 11931 case IMC_GETCANDIDATEPOS: 11932 ProbeForWriteCandidateForm((PCANDIDATEFORM)lParam); 11933 break; 11934 11935 case IMC_GETCOMPOSITIONWINDOW: 11936 ProbeForWriteCompositionForm((PCOMPOSITIONFORM)lParam); 11937 break; 11938 11939 case IMC_GETCOMPOSITIONFONT: 11940 case IMC_GETSOFTKBDFONT: 11941 ProbeForWriteLogFontW((PLOGFONTW)lParam); 11942 break; 11943 11944 case IMC_SETCANDIDATEPOS: 11945 CandForm = ProbeAndReadCandidateForm((PCANDIDATEFORM)lParam); 11946 lData = (LPARAM)&CandForm; 11947 break; 11948 11949 case IMC_SETCOMPOSITIONWINDOW: 11950 CompForm = ProbeAndReadCompositionForm((PCOMPOSITIONFORM)lParam); 11951 lData = (LPARAM)&CompForm; 11952 break; 11953 11954 case IMC_SETCOMPOSITIONFONT: 11955 LogFontW = ProbeAndReadLogFontW((PLOGFONTW)lParam); 11956 lData = (LPARAM)&LogFontW; 11957 break; 11958 11959 case IMC_SETSOFTKBDDATA: 11960 pSoftKbdData = ProbeAndCaptureSoftKbdData((PSOFTKBDDATA)lParam); 11961 if (pSoftKbdData == NULL) 11962 MSGERROR(0); 11963 lData = (LPARAM)pSoftKbdData; 11964 break; 11965 11966 default: 11967 break; 11968 } 11969 11970 } except (StubExceptionHandler(FALSE)) { 11971 MSGERRORCLEANUP(0); 11972 } 11973 retval = CALLPROC(xpfnProc)( 11974 pwnd, 11975 msg, 11976 wParam, 11977 lData, 11978 xParam); 11979 11980 CLEANUPRECV(); 11981 if (pSoftKbdData != NULL) { 11982 UserFreePool(pSoftKbdData); 11983 } 11984 11985 TRACE("fnIMECONTROL"); 11986 ENDRECV_MESSAGECALL(); 11987 } 11988 11989 #ifdef LATER 11990 MESSAGECALL(IMEREQUEST) 11991 { 11992 LPARAM lData = lParam; 11993 11994 // 11995 // N.B. This function has implicit window translation and thread locking 11996 // enabled. These operations are performed in the User server API 11997 // dispatcher. 11998 // 11999 12000 BEGINRECV_MESSAGECALL(0); 12001 TRACETHUNK("fnIMEREQUEST"); 12002 12003 UNREFERENCED_PARAMETER(bAnsi); 12004 12005 // RIPMSG0(RIP_ERROR, "MESSAGECALL(IMEREQUEST) called.\n"); 12006 12007 if (GETPTI(pwnd) != PtiCurrent()) { 12008 /* 12009 * Does not allow to send WM_IME_REQUEST to 12010 * the different thread. 12011 */ 12012 MSGERROR(ERROR_WINDOW_OF_OTHER_THREAD); 12013 } 12014 12015 /* 12016 * Probe arguments 12017 */ 12018 try { 12019 switch (wParam) { 12020 case IMR_COMPOSITIONWINDOW: 12021 ProbeForWriteCompositionForm((PCOMPOSITIONFORM)lParam); 12022 break; 12023 12024 case IMR_CANDIDATEWINDOW: 12025 ProbeForWriteCandidateForm((PCANDIDATEFORM)lParam); 12026 break; 12027 12028 case IMR_COMPOSITIONFONT: 12029 ProbeForWriteLogFontW((PLOGFONTW)lParam); 12030 break; 12031 12032 case IMR_RECONVERTSTRING: 12033 case IMR_DOCUMENTFEED: 12034 if (lParam) { 12035 ProbeForWriteReconvertString((LPRECONVERTSTRING)lParam); 12036 } 12037 break; 12038 12039 case IMR_CONFIRMRECONVERTSTRING: 12040 //ProbeAndCaptureReconvertString((LPRECONVERTSTRING)lParam); 12041 //ProbeForWriteReconvertString((LPRECONVERTSTRING)lParam); 12042 ProbeForReadReconvertString((LPRECONVERTSTRING)lParam); 12043 break; 12044 12045 case IMR_QUERYCHARPOSITION: 12046 ProbeForWriteImeCharPosition((LPPrivateIMECHARPOSITION)lParam); 12047 break; 12048 12049 default: 12050 MSGERROR(0); 12051 } 12052 12053 } except (StubExceptionHandler(FALSE)) { 12054 MSGERRORCLEANUP(0); 12055 } 12056 12057 retval = CALLPROC(xpfnProc)( 12058 pwnd, 12059 msg, 12060 wParam, 12061 lData, 12062 xParam); 12063 12064 CLEANUPRECV(); 12065 12066 TRACE("fnIMEREQUEST"); 12067 ENDRECV_MESSAGECALL(); 12068 } 12069 #endif 12070 12071 /* 12072 * Hook stubs 12073 */ 12074 12075 LRESULT NtUserfnHkINLPCBTCREATESTRUCT( 12076 IN UINT msg, 12077 IN WPARAM wParam, 12078 IN LPCBT_CREATEWND pcbt, 12079 IN BOOL bAnsi) 12080 { 12081 CBT_CREATEWND cbt; 12082 CREATESTRUCTEX csex; 12083 LPCREATESTRUCT lpcsSave; 12084 12085 BEGINRECV_HOOKCALL(); 12086 12087 /* 12088 * Probe arguments 12089 */ 12090 try { 12091 cbt = ProbeAndReadCBTCreateStruct(pcbt); 12092 ProbeForWriteCreateStruct(cbt.lpcs); 12093 lpcsSave = cbt.lpcs; 12094 csex.cs = *cbt.lpcs; 12095 cbt.lpcs = (LPCREATESTRUCT)&csex; 12096 if (bAnsi) { 12097 ProbeForRead(csex.cs.lpszName, sizeof(CHAR), sizeof(CHAR)); 12098 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&csex.strName, 12099 (LPSTR)csex.cs.lpszName, (UINT)-1); 12100 if (IS_PTR(csex.cs.lpszClass)) { 12101 ProbeForRead(csex.cs.lpszClass, sizeof(CHAR), sizeof(CHAR)); 12102 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&csex.strClass, 12103 (LPSTR)csex.cs.lpszClass, (UINT)-1); 12104 } 12105 } else { 12106 ProbeForRead(csex.cs.lpszName, sizeof(WCHAR), CHARALIGN); 12107 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&csex.strName, 12108 csex.cs.lpszName, (UINT)-1); 12109 if (IS_PTR(csex.cs.lpszClass)) { 12110 ProbeForRead(csex.cs.lpszClass, sizeof(WCHAR), CHARALIGN); 12111 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&csex.strClass, 12112 csex.cs.lpszClass, (UINT)-1); 12113 } 12114 } 12115 } except (StubExceptionHandler(FALSE)) { 12116 MSGERROR(0); 12117 } 12118 12119 retval = xxxCallNextHookEx( 12120 msg, 12121 wParam, 12122 (LPARAM)&cbt); 12123 12124 try { 12125 pcbt->hwndInsertAfter = cbt.hwndInsertAfter; 12126 lpcsSave->x = cbt.lpcs->x; 12127 lpcsSave->y = cbt.lpcs->y; 12128 lpcsSave->cx = cbt.lpcs->cx; 12129 lpcsSave->cy = cbt.lpcs->cy; 12130 } except (StubExceptionHandler(FALSE)) { 12131 MSGERROR(0); 12132 } 12133 12134 TRACE("NtUserfnHkINLPCBTCREATESTRUCT"); 12135 ENDRECV_HOOKCALL(); 12136 } 12137 12138 LRESULT NtUserfnHkINLPRECT( 12139 IN DWORD nCode, 12140 IN WPARAM wParam, 12141 IN LPRECT lParam) 12142 { 12143 RECT rc; 12144 12145 BEGINRECV_HOOKCALL(); 12146 12147 /* 12148 * Probe arguments 12149 */ 12150 try { 12151 rc = ProbeAndReadRect((PRECT)lParam); 12152 } except (StubExceptionHandler(FALSE)) { 12153 MSGERROR(0); 12154 } 12155 12156 retval = xxxCallNextHookEx( 12157 nCode, 12158 wParam, 12159 (LPARAM)&rc); 12160 12161 TRACE("NtUserfnHkINLPRECT"); 12162 ENDRECV_HOOKCALL(); 12163 } 12164 12165 #ifdef REDIRECTION 12166 12167 LRESULT NtUserfnHkINLPPOINT( 12168 IN DWORD nCode, 12169 IN WPARAM wParam, 12170 IN LPPOINT lParam) 12171 { 12172 POINT pt; 12173 12174 BEGINRECV_HOOKCALL(); 12175 12176 /* 12177 * Probe arguments 12178 */ 12179 try { 12180 pt = ProbeAndReadPoint((LPPOINT)lParam); 12181 } except (StubExceptionHandler(FALSE)) { 12182 MSGERROR(0); 12183 } 12184 12185 retval = xxxCallNextHookEx( 12186 nCode, 12187 wParam, 12188 (LPARAM)&pt); 12189 12190 TRACE("NtUserfnHkINLPPOINT"); 12191 ENDRECV_HOOKCALL(); 12192 } 12193 #endif // REDIRECTION 12194 12195 LRESULT NtUserfnHkINLPMSG( 12196 IN int iHook, 12197 IN DWORD nCode, 12198 IN WPARAM wParam, 12199 IN LPMSG lParam) 12200 { 12201 MSG msg; 12202 12203 BEGINRECV_HOOKCALL(); 12204 12205 /* 12206 * Probe arguments 12207 */ 12208 try { 12209 msg = ProbeAndReadMessage((PMSG)lParam); 12210 } except (StubExceptionHandler(FALSE)) { 12211 MSGERROR(0); 12212 } 12213 12214 retval = xxxCallNextHookEx( 12215 nCode, 12216 wParam, 12217 (LPARAM)&msg); 12218 12219 /* 12220 * If this is GetMessageHook, the hook should be 12221 * able to change the message, as stated in SDK document. 12222 */ 12223 if (iHook == WH_GETMESSAGE) { 12224 try { 12225 *(PMSG)lParam = msg; 12226 } except (StubExceptionHandler(FALSE)) { 12227 MSGERROR(0); 12228 } 12229 } 12230 12231 TRACE("NtUserfnHkINLPMSG"); 12232 ENDRECV_HOOKCALL(); 12233 } 12234 12235 LRESULT NtUserfnHkINLPDEBUGHOOKSTRUCT( 12236 IN DWORD nCode, 12237 IN WPARAM wParam, 12238 IN LPDEBUGHOOKINFO lParam) 12239 { 12240 DEBUGHOOKINFO hookinfo; 12241 DWORD cbDbgLParam; 12242 12243 BEGINRECV_HOOKCALL(); 12244 12245 /* 12246 * Probe arguments 12247 */ 12248 try { 12249 hookinfo = ProbeAndReadHookInfo((PDEBUGHOOKINFO)lParam); 12250 12251 cbDbgLParam = GetDebugHookLParamSize(wParam, &hookinfo); 12252 ProbeForRead(hookinfo.lParam, cbDbgLParam, DATAALIGN); 12253 } except (StubExceptionHandler(FALSE)) { 12254 MSGERROR(0); 12255 } 12256 12257 retval = xxxCallNextHookEx( 12258 nCode, 12259 wParam, 12260 (LPARAM)&hookinfo); 12261 12262 TRACE("NtUserfnHkINLPDEBUGHOOKSTRUCT"); 12263 ENDRECV_HOOKCALL(); 12264 } 12265 12266 LRESULT NtUserfnHkOPTINLPEVENTMSG( 12267 IN DWORD nCode, 12268 IN WPARAM wParam, 12269 IN OUT LPEVENTMSGMSG lParam OPTIONAL) 12270 { 12271 EVENTMSG event; 12272 12273 BEGINRECV_HOOKCALL(); 12274 12275 /* 12276 * Probe arguments 12277 */ 12278 if (ARGUMENT_PRESENT(lParam)) { 12279 try { 12280 ProbeForWriteEvent((LPEVENTMSGMSG)lParam); 12281 event = *(LPEVENTMSGMSG)lParam; 12282 } except (StubExceptionHandler(FALSE)) { 12283 MSGERROR(0); 12284 } 12285 } 12286 12287 retval = xxxCallNextHookEx( 12288 nCode, 12289 wParam, 12290 (LPARAM)(lParam ? &event : NULL)); 12291 12292 if (ARGUMENT_PRESENT(lParam)) { 12293 try { 12294 *(LPEVENTMSGMSG)lParam = event; 12295 } except (StubExceptionHandler(FALSE)) { 12296 MSGERROR(0); 12297 } 12298 } 12299 12300 TRACE("NtUserfnHkINLPEVENTMSG"); 12301 ENDRECV_HOOKCALL(); 12302 } 12303 12304 LRESULT NtUserfnHkINLPMOUSEHOOKSTRUCTEX( 12305 IN DWORD nCode, 12306 IN WPARAM wParam, 12307 IN LPMOUSEHOOKSTRUCTEX lParam) 12308 { 12309 MOUSEHOOKSTRUCTEX mousehook; 12310 12311 BEGINRECV_HOOKCALL(); 12312 12313 /* 12314 * Probe arguments 12315 */ 12316 try { 12317 mousehook = ProbeAndReadMouseHook((PMOUSEHOOKSTRUCTEX)lParam); 12318 } except (StubExceptionHandler(FALSE)) { 12319 MSGERROR(0); 12320 } 12321 12322 retval = xxxCallNextHookEx( 12323 nCode, 12324 wParam, 12325 (LPARAM)&mousehook); 12326 12327 TRACE("NtUserfnHkINLPMOUSEHOOKSTRUCTEX"); 12328 ENDRECV_HOOKCALL(); 12329 } 12330 12331 LRESULT NtUserfnHkINLPKBDLLHOOKSTRUCT( 12332 IN DWORD nCode, 12333 IN WPARAM wParam, 12334 IN LPKBDLLHOOKSTRUCT lParam) 12335 { 12336 KBDLLHOOKSTRUCT kbdhook; 12337 12338 BEGINRECV_HOOKCALL(); 12339 12340 /* 12341 * Probe arguments 12342 */ 12343 try { 12344 kbdhook = ProbeAndReadKbdHook((PKBDLLHOOKSTRUCT)lParam); 12345 } except (StubExceptionHandler(FALSE)) { 12346 MSGERROR(0); 12347 } 12348 12349 retval = xxxCallNextHookEx( 12350 nCode, 12351 wParam, 12352 (LPARAM)&kbdhook); 12353 12354 TRACE("NtUserfnHkINLPKBDLLHOOKSTRUCT"); 12355 ENDRECV_HOOKCALL(); 12356 } 12357 12358 LRESULT NtUserfnHkINLPMSLLHOOKSTRUCT( 12359 IN DWORD nCode, 12360 IN WPARAM wParam, 12361 IN LPMSLLHOOKSTRUCT lParam) 12362 { 12363 MSLLHOOKSTRUCT msllhook; 12364 12365 BEGINRECV_HOOKCALL(); 12366 12367 /* 12368 * Probe arguments 12369 */ 12370 try { 12371 msllhook = ProbeAndReadMsllHook((PMSLLHOOKSTRUCT)lParam); 12372 } except (StubExceptionHandler(FALSE)) { 12373 MSGERROR(0); 12374 } 12375 12376 retval = xxxCallNextHookEx( 12377 nCode, 12378 wParam, 12379 (LPARAM)&msllhook); 12380 12381 TRACE("NtUserfnHkINLPMSLLHOOKSTRUCT"); 12382 ENDRECV_HOOKCALL(); 12383 } 12384 12385 #ifdef REDIRECTION 12386 LRESULT NtUserfnHkINLPHTHOOKSTRUCT( 12387 IN DWORD nCode, 12388 IN WPARAM wParam, 12389 IN LPHTHOOKSTRUCT lParam) 12390 { 12391 HTHOOKSTRUCT hthook; 12392 12393 BEGINRECV_HOOKCALL(); 12394 12395 /* 12396 * Probe arguments 12397 */ 12398 try { 12399 hthook = ProbeAndReadHTHook((PHTHOOKSTRUCT)lParam); 12400 } except (StubExceptionHandler(FALSE)) { 12401 MSGERROR(0); 12402 } 12403 12404 retval = xxxCallNextHookEx( 12405 nCode, 12406 wParam, 12407 (LPARAM)&hthook); 12408 12409 TRACE("NtUserfnHkINLPHTHOOKSTRUCT"); 12410 ENDRECV_HOOKCALL(); 12411 } 12412 #endif // REDIRECTION 12413 12414 LRESULT NtUserfnHkINLPCBTACTIVATESTRUCT( 12415 IN DWORD nCode, 12416 IN WPARAM wParam, 12417 IN LPCBTACTIVATESTRUCT lParam) 12418 { 12419 CBTACTIVATESTRUCT cbtactivate; 12420 12421 BEGINRECV_HOOKCALL(); 12422 12423 /* 12424 * Probe arguments 12425 */ 12426 try { 12427 cbtactivate = ProbeAndReadCBTActivateStruct((LPCBTACTIVATESTRUCT)lParam); 12428 } except (StubExceptionHandler(FALSE)) { 12429 MSGERROR(0); 12430 } 12431 12432 retval = xxxCallNextHookEx( 12433 nCode, 12434 wParam, 12435 (LPARAM)&cbtactivate); 12436 12437 TRACE("NtUserfnHkINLPCBTACTIVATESTRUCT"); 12438 ENDRECV_HOOKCALL(); 12439 } 12440 12441 LRESULT NtUserCallNextHookEx( 12442 int nCode, 12443 WPARAM wParam, 12444 LPARAM lParam, 12445 BOOL bAnsi) 12446 { 12447 BEGINRECV(LRESULT, 0); 12448 12449 if (PtiCurrent()->sphkCurrent == NULL) { 12450 MSGERROR(0); 12451 } 12452 12453 switch (PtiCurrent()->sphkCurrent->iHook) { 12454 case WH_CBT: 12455 /* 12456 * There are many different types of CBT hooks! 12457 */ 12458 switch (nCode) { 12459 case HCBT_CLICKSKIPPED: 12460 goto MouseHook; 12461 break; 12462 12463 case HCBT_CREATEWND: 12464 /* 12465 * This hook type points to a CREATESTRUCT, so we need to 12466 * be fancy it's thunking, because a CREATESTRUCT contains 12467 * a pointer to CREATEPARAMS which can be anything... so 12468 * funnel this through our message thunks. 12469 */ 12470 retval = NtUserfnHkINLPCBTCREATESTRUCT( 12471 nCode, 12472 wParam, 12473 (LPCBT_CREATEWND)lParam, 12474 bAnsi); 12475 break; 12476 12477 #ifdef REDIRECTION 12478 case HCBT_GETCURSORPOS: 12479 12480 /* 12481 * This hook type points to a POINT structure. 12482 */ 12483 retval = NtUserfnHkINLPPOINT(nCode, wParam, (LPPOINT)lParam); 12484 break; 12485 #endif // REDIRECTION 12486 12487 case HCBT_MOVESIZE: 12488 12489 /* 12490 * This hook type points to a RECT structure. 12491 */ 12492 retval = NtUserfnHkINLPRECT(nCode, wParam, (LPRECT)lParam); 12493 break; 12494 12495 case HCBT_ACTIVATE: 12496 /* 12497 * This hook type points to a CBTACTIVATESTRUCT 12498 */ 12499 retval = NtUserfnHkINLPCBTACTIVATESTRUCT(nCode, wParam, 12500 (LPCBTACTIVATESTRUCT)lParam); 12501 break; 12502 12503 default: 12504 /* 12505 * The rest of the cbt hooks are all dword parameters. 12506 */ 12507 retval = xxxCallNextHookEx( 12508 nCode, 12509 wParam, 12510 lParam); 12511 break; 12512 } 12513 break; 12514 12515 case WH_FOREGROUNDIDLE: 12516 case WH_KEYBOARD: 12517 case WH_SHELL: 12518 /* 12519 * These are dword parameters and are therefore real easy. 12520 */ 12521 retval = xxxCallNextHookEx( 12522 nCode, 12523 wParam, 12524 lParam); 12525 break; 12526 12527 case WH_MSGFILTER: 12528 case WH_SYSMSGFILTER: 12529 case WH_GETMESSAGE: 12530 /* 12531 * These take an lpMsg as their last parameter. Since these are 12532 * exclusively posted parameters, and since nowhere on the server 12533 * do we post a message with a pointer to some other structure in 12534 * it, the lpMsg structure contents can all be treated verbatim. 12535 */ 12536 retval = NtUserfnHkINLPMSG(PtiCurrent()->sphkCurrent->iHook, nCode, wParam, (LPMSG)lParam); 12537 break; 12538 12539 case WH_JOURNALPLAYBACK: 12540 case WH_JOURNALRECORD: 12541 /* 12542 * These take an OPTIONAL lpEventMsg. 12543 */ 12544 retval = NtUserfnHkOPTINLPEVENTMSG(nCode, wParam, (LPEVENTMSGMSG)lParam); 12545 break; 12546 12547 case WH_DEBUG: 12548 /* 12549 * This takes an lpDebugHookStruct. 12550 */ 12551 retval = NtUserfnHkINLPDEBUGHOOKSTRUCT(nCode, wParam, (LPDEBUGHOOKINFO)lParam); 12552 break; 12553 12554 case WH_KEYBOARD_LL: 12555 /* 12556 * This takes an lpKbdllHookStruct. 12557 */ 12558 retval = NtUserfnHkINLPKBDLLHOOKSTRUCT(nCode, wParam, (LPKBDLLHOOKSTRUCT)lParam); 12559 break; 12560 12561 case WH_MOUSE_LL: 12562 /* 12563 * This takes an lpMsllHookStruct. 12564 */ 12565 retval = NtUserfnHkINLPMSLLHOOKSTRUCT(nCode, wParam, (LPMSLLHOOKSTRUCT)lParam); 12566 break; 12567 12568 case WH_MOUSE: 12569 /* 12570 * This takes an lpMouseHookStructEx. 12571 */ 12572 MouseHook: 12573 retval = NtUserfnHkINLPMOUSEHOOKSTRUCTEX(nCode, wParam, (LPMOUSEHOOKSTRUCTEX)lParam); 12574 break; 12575 12576 #ifdef REDIRECTION 12577 case WH_HITTEST: 12578 /* 12579 * This takes an lpHTHookStruct. 12580 */ 12581 retval = NtUserfnHkINLPHTHOOKSTRUCT(nCode, wParam, (LPHTHOOKSTRUCT)lParam); 12582 break; 12583 #endif // REDIRECTION 12584 12585 default: 12586 RIPMSG1(RIP_WARNING, "NtUserCallNextHookEx: Invalid hook type %x", 12587 PtiCurrent()->sphkCurrent->iHook); 12588 MSGERROR(0); 12589 } 12590 12591 TRACE("NtUserCallNextHookEx"); 12592 ENDRECV(); 12593 } 12594 12595 12596 HIMC NtUserCreateInputContext( 12597 IN ULONG_PTR dwClientImcData) 12598 { 12599 BEGINRECV(HIMC, (HIMC)NULL); 12600 12601 ValidateIMMEnabled(); 12602 12603 if (dwClientImcData == 0) { 12604 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid hMemClientIC parameter"); 12605 MSGERROR(0); 12606 } 12607 12608 retval = (HIMC)CreateInputContext(dwClientImcData); 12609 12610 retval = (HIMC)PtoH((PVOID)retval); 12611 12612 TRACE("NtUserCreateInputContext"); 12613 ENDRECV(); 12614 } 12615 12616 12617 BOOL NtUserDestroyInputContext( 12618 IN HIMC hImc) 12619 { 12620 PIMC pImc; 12621 12622 BEGINATOMICRECV(BOOL, FALSE); 12623 12624 ValidateIMMEnabled(); 12625 12626 ValidateHIMC(pImc, hImc); 12627 12628 retval = DestroyInputContext(pImc); 12629 12630 TRACE("NtUserDestroyInputContext"); 12631 ENDATOMICRECV(); 12632 } 12633 12634 12635 AIC_STATUS NtUserAssociateInputContext( 12636 IN HWND hwnd, 12637 IN HIMC hImc, 12638 IN DWORD dwFlag) 12639 { 12640 PIMC pImc; 12641 12642 BEGINATOMICRECV_HWND(AIC_STATUS, AIC_ERROR, hwnd); 12643 12644 ValidateIMMEnabled(); 12645 12646 ValidateHIMCOPT(pImc, hImc); 12647 12648 retval = AssociateInputContextEx(pwnd, pImc, dwFlag); 12649 12650 TRACE("NtUserAssociateInputContext"); 12651 ENDATOMICRECV_HWND(); 12652 } 12653 12654 BOOL NtUserUpdateInputContext( 12655 IN HIMC hImc, 12656 IN UPDATEINPUTCONTEXTCLASS UpdateType, 12657 IN ULONG_PTR UpdateValue) 12658 { 12659 PIMC pImc; 12660 12661 BEGINATOMICRECV(BOOL, FALSE); 12662 12663 ValidateIMMEnabled(); 12664 12665 ValidateHIMC(pImc, hImc); 12666 12667 retval = UpdateInputContext(pImc, UpdateType, UpdateValue); 12668 12669 TRACE("NtUserUpdateInputContext"); 12670 ENDATOMICRECV(); 12671 } 12672 12673 12674 ULONG_PTR NtUserQueryInputContext( 12675 IN HIMC hImc, 12676 IN INPUTCONTEXTINFOCLASS InputContextInfo) 12677 { 12678 PTHREADINFO ptiImc; 12679 PIMC pImc; 12680 12681 BEGINRECV_SHARED(ULONG_PTR, 0); 12682 12683 ValidateIMMEnabled(); 12684 12685 ValidateHIMC(pImc, hImc); 12686 12687 ptiImc = GETPTI(pImc); 12688 12689 switch (InputContextInfo) { 12690 case InputContextProcess: 12691 retval = (ULONG_PTR)ptiImc->pEThread->Cid.UniqueProcess; 12692 break; 12693 12694 case InputContextThread: 12695 retval = (ULONG_PTR)ptiImc->pEThread->Cid.UniqueThread; 12696 break; 12697 12698 case InputContextDefaultImeWindow: 12699 retval = (ULONG_PTR)HW(ptiImc->spwndDefaultIme); 12700 break; 12701 12702 case InputContextDefaultInputContext: 12703 retval = (ULONG_PTR)PtoH(ptiImc->spDefaultImc); 12704 break; 12705 } 12706 12707 ENDRECV_SHARED(); 12708 } 12709 12710 NTSTATUS NtUserBuildHimcList( // private IMM BuildHimcList 12711 IN DWORD idThread, 12712 IN UINT cHimcMax, 12713 OUT HIMC *phimcFirst, 12714 OUT PUINT pcHimcNeeded) 12715 { 12716 PTHREADINFO pti; 12717 UINT cHimcNeeded; 12718 12719 BEGINATOMICRECV(NTSTATUS, STATUS_UNSUCCESSFUL); 12720 12721 ValidateIMMEnabled(); 12722 12723 switch (idThread) { 12724 case 0: 12725 pti = PtiCurrent(); 12726 break; 12727 case (DWORD)-1: 12728 pti = NULL; 12729 break; 12730 default: 12731 pti = PtiFromThreadId(idThread); 12732 if (pti == NULL || pti->rpdesk == NULL) { 12733 MSGERROR(0); 12734 } 12735 break; 12736 } 12737 12738 /* 12739 * Probe arguments 12740 */ 12741 try { 12742 ProbeForWriteBuffer(phimcFirst, cHimcMax, sizeof(DWORD)); 12743 ProbeForWriteUlong(pcHimcNeeded); 12744 } except (StubExceptionHandler(FALSE)) { 12745 MSGERROR(0); 12746 } 12747 12748 /* 12749 * phimcFirst is client-side. 12750 */ 12751 12752 cHimcNeeded = BuildHimcList(pti, cHimcMax, phimcFirst); 12753 12754 if (cHimcNeeded <= cHimcMax) { 12755 retval = STATUS_SUCCESS; 12756 } else { 12757 retval = STATUS_BUFFER_TOO_SMALL; 12758 } 12759 try { 12760 *pcHimcNeeded = cHimcNeeded; 12761 } except (StubExceptionHandler(FALSE)) { 12762 } 12763 12764 TRACE("NtUserBuildHimcList"); 12765 ENDATOMICRECV(); 12766 } 12767 12768 12769 BOOL NtUserGetImeInfoEx( // private ImmGetImeInfoEx 12770 IN OUT PIMEINFOEX piiex, 12771 IN IMEINFOEXCLASS SearchType) 12772 { 12773 IMEINFOEX iiex; 12774 BEGINRECV_SHARED(BOOL, FALSE); 12775 12776 ValidateIMMEnabled(); 12777 12778 try { 12779 ProbeForWrite(piiex, sizeof(*piiex), sizeof(BYTE)); 12780 RtlCopyMemory(&iiex, piiex, sizeof(IMEINFOEX)); 12781 } except (StubExceptionHandler(FALSE)) { 12782 MSGERROR(0); 12783 } 12784 12785 retval = GetImeInfoEx( 12786 _GetProcessWindowStation(NULL), 12787 &iiex, 12788 SearchType); 12789 12790 try { 12791 RtlCopyMemory(piiex, &iiex, sizeof(IMEINFOEX)); 12792 } except (StubExceptionHandler(FALSE)) { 12793 } 12794 12795 TRACE("NtUserGetImeInfoEx"); 12796 ENDRECV_SHARED(); 12797 } 12798 12799 12800 BOOL NtUserSetImeInfoEx( 12801 IN PIMEINFOEX piiex) 12802 { 12803 IMEINFOEX iiex; 12804 BEGINRECV(BOOL, FALSE); 12805 12806 ValidateIMMEnabled(); 12807 12808 /* 12809 * Probe arguments 12810 */ 12811 try { 12812 ProbeForRead(piiex, sizeof(*piiex), sizeof(BYTE)); 12813 RtlCopyMemory(&iiex, piiex, sizeof(IMEINFOEX)); 12814 } except (StubExceptionHandler(FALSE)) { 12815 MSGERROR(0); 12816 } 12817 12818 retval = SetImeInfoEx( 12819 _GetProcessWindowStation(NULL), 12820 &iiex); 12821 12822 TRACE("NtUserSetImeInfoEx"); 12823 ENDRECV(); 12824 } 12825 12826 BOOL NtUserGetImeHotKey( 12827 IN DWORD dwID, 12828 OUT PUINT puModifiers, 12829 OUT PUINT puVKey, 12830 OUT LPHKL phkl) 12831 { 12832 UINT uModifiers; 12833 UINT uVKey; 12834 HKL hkl; 12835 LPHKL phklIn = NULL; 12836 BEGINRECV(BOOL, FALSE); 12837 12838 try { 12839 ProbeForWriteUlong(((PULONG)puModifiers)); 12840 ProbeForWriteUlong(((PULONG)puVKey)); 12841 if (ARGUMENT_PRESENT(phkl)) { 12842 ProbeForWriteHandle((PHANDLE)phkl); 12843 phklIn = &hkl; 12844 } 12845 } except (StubExceptionHandler(FALSE)) { 12846 MSGERROR(0); 12847 } 12848 retval = GetImeHotKey( dwID, &uModifiers, &uVKey, phklIn); 12849 12850 try { 12851 *puModifiers = uModifiers; 12852 *puVKey = uVKey; 12853 if (ARGUMENT_PRESENT(phkl)) { 12854 *phkl = *phklIn; 12855 } 12856 } except (StubExceptionHandler(FALSE)) { 12857 MSGERROR(0); 12858 } 12859 TRACE("NtUserGetImeHotKey"); 12860 ENDRECV(); 12861 } 12862 12863 BOOL NtUserSetImeHotKey( 12864 IN DWORD dwID, 12865 IN UINT uModifiers, 12866 IN UINT uVKey, 12867 IN HKL hkl, 12868 IN DWORD dwFlags) 12869 { 12870 BEGINRECV(BOOL, FALSE); 12871 12872 retval = SetImeHotKey( dwID, uModifiers, uVKey, hkl, dwFlags ); 12873 TRACE("NtUserSetImeHotKey"); 12874 ENDRECV(); 12875 } 12876 12877 /* 12878 * Set per-window application level for IME control. 12879 * Used only for Korean 3.x ( both 16 bit and 32 bit) 12880 * applications. 12881 * 12882 * return value 12883 * 12884 * TRUE : success 12885 * FALSE: error 12886 */ 12887 BOOL NtUserSetAppImeLevel( 12888 IN HWND hwnd, 12889 IN DWORD dwLevel) 12890 { 12891 BEGINRECV_HWND(BOOL, FALSE, hwnd); 12892 12893 ValidateIMMEnabled(); 12894 12895 if ( GETPTI(pwnd)->ppi == PpiCurrent() ) { 12896 InternalSetProp(pwnd, PROP_IMELEVEL, (HANDLE)LongToHandle( dwLevel ), PROPF_INTERNAL | PROPF_NOPOOL); 12897 retval = TRUE; 12898 } else { 12899 MSGERROR(0); 12900 } 12901 TRACE("NtUserSetAppImeLevel"); 12902 ENDRECV_HWND(); 12903 } 12904 12905 /* 12906 * Get per-window application level for IME control. 12907 * Used only for Korean 3.x ( both 16 bit and 32 bit) 12908 * applications. 12909 * 12910 * return value 12911 * 12912 * 0 : error 12913 * non zero value : level 12914 */ 12915 DWORD NtUserGetAppImeLevel( 12916 IN HWND hwnd) 12917 { 12918 BEGINRECV_HWND_SHARED(DWORD, 0, hwnd); 12919 12920 ValidateIMMEnabled(); 12921 12922 if ( GETPTI(pwnd)->ppi == PtiCurrentShared()->ppi ) { 12923 retval = (DWORD)(ULONG_PTR)_GetProp(pwnd, PROP_IMELEVEL, TRUE); 12924 } else { 12925 MSGERROR(0); 12926 } 12927 TRACE("NtUserGetAppImeLevel"); 12928 ENDRECV_HWND_SHARED(); 12929 } 12930 12931 12932 DWORD NtUserCheckImeHotKey( 12933 UINT uVKey, 12934 LPARAM lParam) 12935 { 12936 PIMEHOTKEYOBJ pImeHotKeyObj; 12937 BEGINRECV(DWORD, IME_INVALID_HOTKEY); 12938 12939 if (gpqForeground == NULL) 12940 MSGERROR(0); 12941 12942 ValidateIMMEnabled(); 12943 12944 pImeHotKeyObj = CheckImeHotKey(gpqForeground, uVKey, lParam); 12945 if (pImeHotKeyObj) { 12946 retval = pImeHotKeyObj->hk.dwHotKeyID; 12947 } 12948 else { 12949 retval = IME_INVALID_HOTKEY; 12950 } 12951 12952 TRACE("NtUserCheckImeHotKey"); 12953 ENDRECV(); 12954 } 12955 12956 BOOL NtUserSetImeOwnerWindow( 12957 IN HWND hwndIme, 12958 IN HWND hwndFocus) 12959 { 12960 PWND pwndFocus; 12961 12962 BEGINATOMICRECV_HWND(BOOL, FALSE, hwndIme); 12963 12964 ValidateIMMEnabled(); 12965 12966 /* 12967 * Make sure this really is an IME window. 12968 */ 12969 if (GETFNID(pwnd) != FNID_IME) 12970 MSGERROR(0); 12971 12972 ValidateHWNDOPT(pwndFocus, hwndFocus); 12973 12974 if (pwndFocus != NULL) { 12975 PWND pwndTopLevel; 12976 PWND pwndT; 12977 12978 if (TestCF(pwndFocus, CFIME) || 12979 pwndFocus->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]) { 12980 RIPMSG0(RIP_WARNING, "Focus window should not be an IME/UI window!!"); 12981 MSGERROR(0); 12982 } 12983 12984 /* 12985 * Child window cannot be an owner window. 12986 */ 12987 pwndTopLevel = pwndT = GetTopLevelWindow(pwndFocus); 12988 12989 /* 12990 * To prevent the IME window becomes the onwer (HY?) 12991 */ 12992 while (pwndT != NULL) { 12993 if (pwndT->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]) { 12994 RIPMSG0(RIP_WARNING, 12995 "The owner of focus window should not be an IME window!!"); 12996 pwndTopLevel = NULL; 12997 break; 12998 } 12999 pwndT = pwndT->spwndOwner; 13000 } 13001 13002 UserAssert(pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]); 13003 UserAssert(pwndTopLevel == NULL || !TestCF(pwndTopLevel, CFIME)); 13004 Lock(&pwnd->spwndOwner, pwndTopLevel); 13005 ImeCheckTopmost(pwnd); 13006 } 13007 else { 13008 PTHREADINFO ptiImeWnd = GETPTI(pwnd); 13009 PWND pwndActive = ptiImeWnd->pq->spwndActive; 13010 13011 /* 13012 * If pwndFocus == NULL, active window in the queue should become the 13013 * owner window of the IME window, except: if IME related windows 13014 * somehow got a focus, or the active window belongs to the other thread. 13015 */ 13016 if (pwndActive == NULL || pwndActive != pwnd->spwndOwner) { 13017 if (pwndActive == NULL || IsWndImeRelated(pwndActive) || ptiImeWnd != GETPTI(pwndActive)) { 13018 /* 13019 * We should avoid improper window to be an owner of IME window. 13020 */ 13021 ImeSetFutureOwner(pwnd, pwnd->spwndOwner); 13022 } 13023 else { 13024 Lock(&pwnd->spwndOwner, pwndActive); 13025 } 13026 ImeCheckTopmost(pwnd); 13027 } 13028 } 13029 13030 retval = TRUE; 13031 13032 TRACE("NtUserSetImeNewOwner"); 13033 ENDATOMICRECV_HWND(); 13034 } 13035 13036 13037 VOID NtUserSetThreadLayoutHandles( 13038 IN HKL hklNew, 13039 IN HKL hklOld) 13040 { 13041 PTHREADINFO ptiCurrent; 13042 PKL pklNew; 13043 13044 BEGINRECV_VOID(); 13045 13046 ptiCurrent = PtiCurrent(); 13047 13048 if (ptiCurrent->spklActive != NULL && ptiCurrent->spklActive->hkl != hklOld) 13049 MSGERROR_VOID(); 13050 13051 if ((pklNew = HKLtoPKL(ptiCurrent, hklNew)) == NULL) 13052 MSGERROR_VOID(); 13053 13054 /* 13055 * hklPrev is only used for IME, non-IME toggle hotkey. 13056 * The purpose we remember hklPrev is to jump from 13057 * non-IME keyboard layout to the most recently used 13058 * IME layout, or to jump from an IME layout to 13059 * the most recently used non-IME layout. Therefore 13060 * piti->hklPrev is updated only when [ IME -> non-IME ] 13061 * or [ non-IME -> IME ] transition is happened. 13062 */ 13063 if (IS_IME_KBDLAYOUT(hklNew) ^ IS_IME_KBDLAYOUT(hklOld)) 13064 ptiCurrent->hklPrev = hklOld; 13065 13066 Lock(&ptiCurrent->spklActive, pklNew); 13067 13068 TRACEVOID("NtUserSetThreadLayoutHandles"); 13069 ENDRECV_VOID(); 13070 } 13071 13072 VOID NtUserNotifyIMEStatus( 13073 IN HWND hwnd, 13074 IN DWORD dwOpen, 13075 IN DWORD dwConversion) 13076 { 13077 BEGINRECV_HWNDLOCK_VOID(hwnd); 13078 13079 ValidateIMMEnabledVOID(); 13080 13081 xxxNotifyIMEStatus( pwnd, dwOpen, dwConversion ); 13082 13083 TRACEVOID("NtUserNotifyIMEStatus"); 13084 ENDRECV_HWNDLOCK_VOID() 13085 } 13086 13087 BOOL NtUserDisableThreadIme( 13088 IN DWORD dwThreadId) 13089 { 13090 PTHREADINFO ptiCurrent, pti; 13091 13092 BEGINRECV(BOOL, FALSE); 13093 13094 ValidateIMMEnabled(); 13095 13096 ptiCurrent = PtiCurrent(); 13097 13098 if (dwThreadId == -1) { 13099 // IME processing is disabled for all the thread in the current process 13100 ptiCurrent->ppi->W32PF_Flags |= W32PF_DISABLEIME; 13101 // destory IME stuff 13102 pti = ptiCurrent->ppi->ptiList; 13103 while (pti) { 13104 pti->TIF_flags |= TIF_DISABLEIME; 13105 if (pti->spwndDefaultIme != NULL) { 13106 xxxDestroyWindow(pti->spwndDefaultIme); 13107 // Start the search over from beginning 13108 // Since the ptilist may be updated 13109 pti = ptiCurrent->ppi->ptiList; 13110 continue; 13111 } 13112 pti = pti->ptiSibling; 13113 } 13114 } else { 13115 if (dwThreadId == 0) { 13116 pti = ptiCurrent; 13117 } 13118 else { 13119 pti = PtiFromThreadId(dwThreadId); 13120 if (pti == NULL || pti->ppi != ptiCurrent->ppi) 13121 MSGERROR(0); 13122 } 13123 pti->TIF_flags |= TIF_DISABLEIME; 13124 if (pti->spwndDefaultIme != NULL) { 13125 xxxDestroyWindow(pti->spwndDefaultIme); 13126 } 13127 13128 } 13129 13130 retval = TRUE; 13131 13132 TRACE("NtUserDisableThreadIme"); 13133 ENDRECV(); 13134 } 13135 13136 13137 BOOL 13138 NtUserEnumDisplayMonitors( // API EnumDisplayMonitors 13139 IN HDC hdc, 13140 IN LPCRECT lprcClip, 13141 IN MONITORENUMPROC lpfnEnum, 13142 IN LPARAM dwData) 13143 { 13144 RECT rc; 13145 LPRECT lprc = (LPRECT) lprcClip; 13146 13147 BEGINRECV(BOOL, FALSE); 13148 13149 /* 13150 * Probe arguments 13151 */ 13152 if (ARGUMENT_PRESENT(lprc)) { 13153 try { 13154 rc = ProbeAndReadRect(lprc); 13155 lprc = &rc; 13156 } except (StubExceptionHandler(TRUE)) { 13157 MSGERROR(0); 13158 } 13159 } 13160 13161 retval = xxxEnumDisplayMonitors( 13162 hdc, 13163 lprc, 13164 lpfnEnum, 13165 dwData, 13166 FALSE); 13167 13168 TRACE("NtUserEnumDisplayMonitors"); 13169 ENDRECV(); 13170 } 13171 13172 /* 13173 * NtUserQueryUserCounters() retrieves statistics on win32k 13174 * QUERYUSER_TYPE_USER retrieves the handle counters 13175 * QUERYUSER_TYPE_CS will fill the result buffer with USER critical section usage data 13176 */ 13177 13178 BOOL 13179 NtUserQueryUserCounters( // private QueryUserCounters 13180 IN DWORD dwQueryType, 13181 IN LPVOID pvIn, 13182 IN DWORD dwInSize, 13183 OUT LPVOID pvResult, 13184 IN DWORD dwOutSize) 13185 { 13186 PDWORD pdwInternalIn = NULL; 13187 PDWORD pdwInternalResult = NULL; 13188 13189 BEGINRECV(BOOL, FALSE); 13190 13191 #if defined (USER_PERFORMANCE) 13192 if (dwQueryType == QUERYUSER_CS) { 13193 CSSTATISTICS* pcsData; 13194 13195 if (dwOutSize != sizeof(CSSTATISTICS)) { 13196 MSGERROR(0); 13197 } 13198 try { 13199 ProbeForWrite((PDWORD)pvResult, dwOutSize, sizeof(DWORD)); 13200 13201 /* 13202 * Checking for overflow on these counters is caller responsability 13203 */ 13204 pcsData = (CSSTATISTICS*)pvResult; 13205 pcsData->cExclusive = gCSStatistics.cExclusive; 13206 pcsData->cShared = gCSStatistics.cShared; 13207 pcsData->i64TimeExclusive = gCSStatistics.i64TimeExclusive; 13208 13209 } except (StubExceptionHandler(FALSE)) { 13210 MSGERROR(0); 13211 } 13212 retval = TRUE; 13213 MSGERROR_VOID(); 13214 } 13215 else 13216 #endif // USER_PERFORMANCE 13217 13218 if (dwQueryType == QUERYUSER_HANDLES) { 13219 13220 /* 13221 * Probe arguments, dwInSize should be multiple of 4 13222 */ 13223 if (dwInSize & (sizeof(DWORD)-1) || 13224 dwOutSize != TYPE_CTYPES*dwInSize) { 13225 13226 MSGERROR(0) 13227 } 13228 13229 try { 13230 ProbeForRead((PDWORD)pvIn, dwInSize, sizeof(DWORD)); 13231 pdwInternalIn = UserAllocPoolWithQuota(dwInSize, TAG_SYSTEM); 13232 if (!pdwInternalIn) { 13233 ExRaiseStatus(STATUS_NO_MEMORY); 13234 } 13235 RtlCopyMemory(pdwInternalIn, pvIn, dwInSize); 13236 13237 ProbeForWrite(pvResult, dwOutSize, sizeof(DWORD)); 13238 pdwInternalResult = UserAllocPoolWithQuota(dwOutSize, TAG_SYSTEM); 13239 if (!pdwInternalResult) { 13240 ExRaiseStatus(STATUS_NO_MEMORY); 13241 } 13242 13243 } except (StubExceptionHandler(FALSE)) { 13244 MSGERRORCLEANUP(0); 13245 } 13246 13247 _QueryUserHandles(pdwInternalIn, 13248 dwInSize/sizeof(DWORD), 13249 (DWORD (*)[TYPE_CTYPES])pdwInternalResult); 13250 retval = TRUE; 13251 13252 try { 13253 RtlCopyMemory(pvResult, pdwInternalResult, dwOutSize); 13254 13255 } except (StubExceptionHandler(FALSE)) { 13256 MSGERRORCLEANUP(0); 13257 } 13258 } 13259 13260 else { 13261 13262 MSGERROR(0); 13263 } 13264 13265 CLEANUPRECV(); 13266 if (pdwInternalIn) { 13267 UserFreePool(pdwInternalIn); 13268 } 13269 if (pdwInternalResult) { 13270 UserFreePool(pdwInternalResult); 13271 } 13272 13273 TRACE("NtUserQueryCounters"); 13274 ENDRECV(); 13275 } 13276 13277 13278 /***************************************************************************\ 13279 * NtUserINOUTGETMENUINFO 13280 * 13281 * History: 13282 * 11-12-96 GerardoB - Created 13283 \***************************************************************************/ 13284 MESSAGECALL(INOUTMENUGETOBJECT) 13285 { 13286 MENUGETOBJECTINFO mgoi; 13287 BEGINRECV_MESSAGECALL(0); 13288 TRACETHUNK("fnINOUTMENUGETOBJECT"); 13289 13290 UNREFERENCED_PARAMETER(bAnsi); 13291 13292 try { 13293 /* 13294 * Capture now so xxxInterSendMsgEx won't have to. 13295 */ 13296 mgoi = ProbeAndReadMenuGetObjectInfo((PMENUGETOBJECTINFO)lParam); 13297 13298 } except (StubExceptionHandler(FALSE)) { 13299 MSGERROR(0); 13300 } 13301 retval = CALLPROC(xpfnProc)( 13302 pwnd, 13303 msg, 13304 wParam, 13305 (LPARAM)&mgoi, 13306 xParam); 13307 13308 try { 13309 *((PMENUGETOBJECTINFO)lParam) = mgoi; 13310 13311 } except (StubExceptionHandler(FALSE)) { 13312 } 13313 13314 TRACE("fnINOUTMENUGETOBJECT"); 13315 ENDRECV_MESSAGECALL(); 13316 } 13317 13318 /***************************************************************************\ 13319 * NtUserFlashWindowEx 13320 * 13321 * History: 13322 * 11-16-96 MCostea - Created 13323 \***************************************************************************/ 13324 BOOL 13325 NtUserFlashWindowEx( // API FlashWindowEx 13326 IN PFLASHWINFO pfwi) 13327 { 13328 FLASHWINFO fwiInternal; 13329 TL tlpwnd; 13330 PWND pwnd; 13331 13332 BEGINRECV(BOOL, FALSE); 13333 DBG_THREADLOCK_START(FlashWindowEx); 13334 13335 /* 13336 * Probe arguments 13337 */ 13338 try { 13339 fwiInternal = ProbeAndReadStructure(pfwi, FLASHWINFO); 13340 13341 } except (StubExceptionHandler(TRUE)) { 13342 MSGERROR(0); 13343 } 13344 13345 if ((pwnd = ValidateHwnd(fwiInternal.hwnd)) == NULL || 13346 fwiInternal.cbSize != sizeof(FLASHWINFO) || 13347 fwiInternal.dwFlags & ~FLASHW_VALID) { 13348 13349 RIPMSG0(RIP_WARNING, "NtUserFlashWindowEx: Invalid Parameter"); 13350 MSGERROR(ERROR_INVALID_PARAMETER); 13351 } 13352 else { 13353 ThreadLockAlwaysWithPti(PtiCurrent(), pwnd, &tlpwnd); 13354 retval = xxxFlashWindow(pwnd, 13355 MAKELONG(fwiInternal.dwFlags, fwiInternal.uCount), 13356 fwiInternal.dwTimeout); 13357 ThreadUnlock(&tlpwnd); 13358 } 13359 13360 DBG_THREADLOCK_END(FlashWindowEx); 13361 13362 TRACE("NtUserFlashWindowEx"); 13363 ENDRECV(); 13364 } 13365 13366 BOOL NtUserUpdateLayeredWindow( // API UpdateLayeredWindow 13367 IN HWND hwnd, 13368 IN HDC hdcDst, 13369 IN POINT *pptDst, 13370 IN SIZE *psize, 13371 IN HDC hdcSrc, 13372 IN POINT *pptSrc, 13373 IN COLORREF crKey, 13374 IN BLENDFUNCTION *pblend, 13375 IN DWORD dwFlags) 13376 { 13377 PWND pwnd; 13378 POINT ptSrc; 13379 SIZE size; 13380 POINT ptDst; 13381 BLENDFUNCTION blend; 13382 13383 BEGINATOMICRECV(BOOL, FALSE); 13384 13385 ValidateHWND(pwnd, hwnd); 13386 13387 /* 13388 * Probe and validate arguments. 13389 */ 13390 try { 13391 if (ARGUMENT_PRESENT(pptSrc)) { 13392 ptSrc = ProbeAndReadPoint(pptSrc); 13393 pptSrc = &ptSrc; 13394 } 13395 if (ARGUMENT_PRESENT(psize)) { 13396 size = ProbeAndReadSize(psize); 13397 psize = &size; 13398 if (psize->cx < 0 || psize->cy < 0) { 13399 MSGERROR(ERROR_INVALID_PARAMETER); // this is a jump out of try! 13400 } 13401 } 13402 if (ARGUMENT_PRESENT(pptDst)) { 13403 ptDst = ProbeAndReadPoint(pptDst); 13404 pptDst = &ptDst; 13405 } 13406 13407 if (ARGUMENT_PRESENT(pblend)) { 13408 blend = ProbeAndReadBlendfunction(pblend); 13409 pblend = &blend; 13410 } 13411 } except (StubExceptionHandler(TRUE)) { 13412 MSGERROR(0); 13413 } 13414 13415 if (dwFlags & ~ULW_VALID) { 13416 RIPMSG0(RIP_WARNING, "UpdateLayeredWindow: Invalid Parameter"); 13417 MSGERROR(ERROR_INVALID_PARAMETER); 13418 } else { 13419 retval = _UpdateLayeredWindow( 13420 pwnd, 13421 hdcDst, 13422 pptDst, 13423 psize, 13424 hdcSrc, 13425 pptSrc, 13426 crKey, 13427 pblend, 13428 dwFlags); 13429 } 13430 13431 TRACE("NtUserUpdateLayeredWindow"); 13432 ENDATOMICRECV(); 13433 } 13434 13435 BOOL NtUserSetLayeredWindowAttributes( 13436 IN HWND hwnd, 13437 IN COLORREF crKey, 13438 IN BYTE bAlpha, 13439 IN DWORD dwFlags) 13440 { 13441 PWND pwnd; 13442 13443 BEGINATOMICRECV(BOOL, FALSE); 13444 13445 ValidateHWND(pwnd, hwnd); 13446 13447 if (dwFlags & ~LWA_VALID) { 13448 RIPMSG0(RIP_WARNING, "SetLayeredWindowAttributes: Invalid Parameter"); 13449 MSGERROR(ERROR_INVALID_PARAMETER); 13450 } else { 13451 retval = _SetLayeredWindowAttributes(pwnd, crKey, bAlpha, dwFlags); 13452 } 13453 13454 TRACE("NtUserSetLayeredWindowAttributes"); 13455 ENDATOMICRECV(); 13456 } 13457 13458 /***************************************************************************\ 13459 * GetHDevName 13460 * Called by NtUserCallTwoParam in GetMonitorInfo to query 13461 * gre about the HDev name 13462 * 13463 * 1-July-1998 MCostea created 13464 \***************************************************************************/ 13465 BOOL GetHDevName(HMONITOR hMon, PWCHAR pName) 13466 { 13467 PMONITOR pMonitor; 13468 13469 CheckCritIn(); 13470 13471 pMonitor = ValidateHmonitor(hMon); 13472 if (!pMonitor) { 13473 return FALSE; 13474 } 13475 13476 try { 13477 ProbeForWrite(pName, CCHDEVICENAME*sizeof(WCHAR), sizeof(DWORD)); 13478 } except (StubExceptionHandler(TRUE)) { 13479 return FALSE; 13480 } 13481 return DrvGetHdevName(pMonitor->hDev, pName); 13482 }

Generated on Sat May 15 19:41:04 2004 for test by doxygen 1.3.7