Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2182 lines
69 KiB

  1. /**************************************************************************\
  2. * Module Name: cltxt.h
  3. *
  4. * Neutral Client/Server call related routines involving text.
  5. *
  6. * Copyright (c) 1985 - 1999, Microsoft Corporation
  7. *
  8. * Created: 04-Dec-90
  9. *
  10. * History:
  11. * 04-Dec-90 created by SMeans
  12. *
  13. \**************************************************************************/
  14. #ifdef UNICODE
  15. #define IS_ANSI FALSE
  16. #else
  17. #define IS_ANSI TRUE
  18. #if IS_ANSI != CW_FLAGS_ANSI
  19. # error("IS_ANSI != CW_FLAGS_ANSI)
  20. #endif
  21. #endif
  22. #include "ntsend.h"
  23. #include "powrprof.h"
  24. /***************************************************************************\
  25. * CreateWindowEx (API)
  26. *
  27. * A complete Thank cannot be generated for CreateWindowEx because its last
  28. * parameter (lpParam) is polymorphic depending on the window's class. If
  29. * the window class is "MDIClient" then lpParam points to a CLIENTCREATESTRUCT.
  30. *
  31. * History:
  32. * 04-23-91 DarrinM Created.
  33. * 04-Feb-92 IanJa Unicode/ANSI neutral
  34. \***************************************************************************/
  35. #ifdef UNICODE
  36. FUNCLOG12(LOG_GENERAL, HWND, WINAPI, CreateWindowExW, DWORD, dwExStyle, LPCTSTR, lpClassName, LPCTSTR, lpWindowName, DWORD, dwStyle, int, X, int, Y, int, nWidth, int, nHeight, HWND, hWndParent, HMENU, hMenu, HINSTANCE, hModule, LPVOID, lpParam)
  37. #else
  38. FUNCLOG12(LOG_GENERAL, HWND, WINAPI, CreateWindowExA, DWORD, dwExStyle, LPCTSTR, lpClassName, LPCTSTR, lpWindowName, DWORD, dwStyle, int, X, int, Y, int, nWidth, int, nHeight, HWND, hWndParent, HMENU, hMenu, HINSTANCE, hModule, LPVOID, lpParam)
  39. #endif // UNICODE
  40. HWND WINAPI CreateWindowEx(
  41. DWORD dwExStyle,
  42. LPCTSTR lpClassName,
  43. LPCTSTR lpWindowName,
  44. DWORD dwStyle,
  45. int X,
  46. int Y,
  47. int nWidth,
  48. int nHeight,
  49. HWND hWndParent,
  50. HMENU hMenu,
  51. HINSTANCE hModule,
  52. LPVOID lpParam)
  53. {
  54. return _CreateWindowEx(dwExStyle,
  55. lpClassName,
  56. lpWindowName,
  57. dwStyle,
  58. X,
  59. Y,
  60. nWidth,
  61. nHeight,
  62. hWndParent,
  63. hMenu,
  64. hModule,
  65. lpParam,
  66. IS_ANSI | CW_FLAGS_VERSIONCLASS);
  67. }
  68. /***************************************************************************\
  69. * fnHkINLPCWPSTRUCT
  70. *
  71. * This gets thunked through the message thunks, so it has the format
  72. * of a c/s message thunk call.
  73. *
  74. * 05-09-91 ScottLu Created.
  75. * 04-Feb-92 IanJa Unicode/ANSI neutral
  76. \***************************************************************************/
  77. LRESULT TEXT_FN(fnHkINLPCWPSTRUCT)(
  78. PWND pwnd,
  79. UINT message,
  80. WPARAM wParam,
  81. LPARAM lParam,
  82. ULONG_PTR xParam)
  83. {
  84. CWPSTRUCT cwp;
  85. cwp.hwnd = HW(pwnd);
  86. cwp.message = message;
  87. cwp.wParam = wParam;
  88. cwp.lParam = lParam;
  89. return TEXT_FN(DispatchHook)(MAKELONG(HC_ACTION, WH_CALLWNDPROC),
  90. (GetClientInfo()->CI_flags & CI_INTERTHREAD_HOOK) != 0,
  91. (LPARAM)&cwp, (HOOKPROC)xParam);
  92. }
  93. LRESULT TEXT_FN(fnHkINLPCWPRETSTRUCT)(
  94. PWND pwnd,
  95. UINT message,
  96. WPARAM wParam,
  97. LPARAM lParam,
  98. ULONG_PTR xParam)
  99. {
  100. CWPRETSTRUCT cwp;
  101. PCLIENTINFO pci = GetClientInfo();
  102. cwp.hwnd = HW(pwnd);
  103. cwp.message = message;
  104. cwp.wParam = wParam;
  105. cwp.lParam = lParam;
  106. cwp.lResult = KERNEL_LRESULT_TO_LRESULT(pci->dwHookData);
  107. return TEXT_FN(DispatchHook)(MAKELONG(HC_ACTION, WH_CALLWNDPROCRET),
  108. (GetClientInfo()->CI_flags & CI_INTERTHREAD_HOOK) != 0,
  109. (LPARAM)&cwp, (HOOKPROC)xParam);
  110. }
  111. /***************************************************************************\
  112. * DispatchHook
  113. *
  114. * This routine exists simply to remember the hook type in the CTI structure
  115. * so that later inside of CallNextHookEx we know how to thunk the hook
  116. * call.
  117. *
  118. * 05-09-91 ScottLu Created.
  119. * 04-Feb-92 IanJa Unicode/ANSI neutral
  120. \***************************************************************************/
  121. LRESULT TEXT_FN(DispatchHook)(
  122. int dw,
  123. WPARAM wParam,
  124. LPARAM lParam,
  125. HOOKPROC pfn)
  126. {
  127. int dwHookSave;
  128. LRESULT nRet;
  129. PCLIENTINFO pci;
  130. #if IS_ANSI
  131. WPARAM wParamSave;
  132. #endif
  133. /* -FE-
  134. * * THIS VARIABLE SHOULD BE THREAD AWARE *
  135. */
  136. static EVENTMSG CachedEvent = {0,0,0,(DWORD)0,(HWND)0};
  137. /*
  138. * First save the current hook stored in the CTI structure in case we're
  139. * being recursed into. dw contains MAKELONG(nCode, nFilterType).
  140. */
  141. pci = GetClientInfo();
  142. dwHookSave = pci->dwHookCurrent;
  143. pci->dwHookCurrent = (dw & 0xFFFF0000) | IS_ANSI;
  144. #if IS_ANSI // TEXT_FN(DispatchHook)()
  145. if (IS_DBCS_ENABLED()) {
  146. PMSG pMsg;
  147. PEVENTMSG pEMsg;
  148. switch (HIWORD(dw)) {
  149. case WH_JOURNALPLAYBACK:
  150. switch (LOWORD(dw)) {
  151. case HC_SKIP:
  152. CachedEvent.message = 0;
  153. break;
  154. case HC_GETNEXT:
  155. case HC_NOREMOVE:
  156. pEMsg = (PEVENTMSG)lParam;
  157. if (CachedEvent.message != 0 && pEMsg != NULL) {
  158. RtlCopyMemory((PEVENTMSG)lParam,&CachedEvent,sizeof(EVENTMSG));
  159. return 0;
  160. }
  161. break;
  162. }
  163. break;
  164. case WH_MSGFILTER:
  165. case WH_SYSMSGFILTER:
  166. case WH_GETMESSAGE:
  167. pMsg = (PMSG)lParam;
  168. if (pMsg) {
  169. /*
  170. * Save original message.
  171. */
  172. wParamSave = pMsg->wParam;
  173. switch (pMsg->message) {
  174. case WM_CHAR:
  175. case EM_SETPASSWORDCHAR:
  176. /*
  177. * Here... pMsg->wParam contains..
  178. *
  179. * HIWORD(wParam) = Information for DBCS messgaing.
  180. * HIBYTE(LOWORD(wParam)) = Dbcs LeadingByte Byte.
  181. * LOBYTE(LOWORD(wParam)) = Dbcs TrailingByte or Sbcs character.
  182. *
  183. */
  184. if (pMsg->wParam & WMCR_IR_DBCSCHAR) {
  185. /*
  186. * Mask off DBCS messaging infomation area.
  187. * (Look up only DBCS character code data).
  188. */
  189. pMsg->wParam &= 0x0000FFFF;
  190. } else {
  191. if (IS_DBCS_MESSAGE(LOWORD(pMsg->wParam))) {
  192. PKERNEL_MSG pDbcsMsg = GetCallBackDbcsInfo();
  193. /*
  194. * Copy this message to CLIENTINFO for next GetMessage
  195. * or PeekMesssage() call.
  196. */
  197. COPY_MSG_TO_KERNELMSG(pDbcsMsg,pMsg);
  198. /*
  199. * Only Dbcs Trailingbyte is nessesary for pushed message. we'll
  200. * pass this message when GetMessage/PeekMessage is called at next.
  201. */
  202. pDbcsMsg->wParam = (WPARAM)((pMsg->wParam & 0x0000FF00) >> 8);
  203. /*
  204. * Return DbcsLeading byte to Apps.
  205. */
  206. pMsg->wParam = (WPARAM)(pMsg->wParam & 0x000000FF);
  207. } else {
  208. /*
  209. * This is SBCS char, make sure it.
  210. */
  211. pMsg->wParam &= 0x000000FF;
  212. }
  213. }
  214. }
  215. }
  216. }
  217. GetNextHookData:
  218. ;
  219. }
  220. #endif
  221. /*
  222. * Call the hook. dw contains MAKELONG(nCode, nFilterType).
  223. */
  224. nRet = pfn(LOWORD(dw), wParam, lParam);
  225. #if IS_ANSI
  226. if (IS_DBCS_ENABLED()) {
  227. PMSG pMsg;
  228. PEVENTMSG pEMsg;
  229. switch (HIWORD(dw)) {
  230. case WH_JOURNALPLAYBACK:
  231. switch (LOWORD(dw)) {
  232. case HC_GETNEXT:
  233. case HC_NOREMOVE:
  234. pEMsg = (PEVENTMSG)lParam;
  235. if ((nRet == 0) && pEMsg) {
  236. WPARAM dwAnsi = LOWORD(pEMsg->paramL);
  237. switch(pEMsg->message) {
  238. case WM_CHAR:
  239. case EM_SETPASSWORDCHAR:
  240. /*
  241. * Chech wParam is DBCS character or not.
  242. */
  243. if (IS_DBCS_MESSAGE((dwAnsi))) {
  244. /*
  245. * DO NOT NEED TO MARK FOR IR_DBCSCHAR
  246. */
  247. } else {
  248. PBYTE pchDbcsCF = GetDispatchDbcsInfo();
  249. /*
  250. * If we have cached Dbcs LeadingByte character,
  251. * build a DBCS character with the TrailingByte
  252. * in wParam.
  253. */
  254. if (*pchDbcsCF) {
  255. WORD DbcsLeadChar = (WORD)(*pchDbcsCF);
  256. /*
  257. * HIBYTE(LOWORD(dwAnsi)) = Dbcs LeadingByte.
  258. * LOBYTE(LOWORD(dwAnsi)) = Dbcs TrailingByte.
  259. */
  260. dwAnsi |= (DbcsLeadChar << 8);
  261. /*
  262. * Invalidate cached data.
  263. */
  264. *pchDbcsCF = 0;
  265. } else if (IsDBCSLeadByteEx(THREAD_CODEPAGE(),LOBYTE(dwAnsi))) {
  266. /*
  267. * If this is DBCS LeadByte character, we
  268. * should wait DBCS TrailingByte to convert
  269. * this to Unicode. then we cache it here.
  270. */
  271. *pchDbcsCF = LOBYTE(dwAnsi);
  272. /*
  273. * Get DBCS TrailByte.
  274. */
  275. pfn(HC_SKIP,0,0);
  276. goto GetNextHookData;
  277. }
  278. }
  279. /*
  280. * Convert to Unicode.
  281. */
  282. RtlMBMessageWParamCharToWCS(pEMsg->message, &dwAnsi);
  283. /*
  284. * Restore converted Unicode to EVENTMSG.
  285. */
  286. pEMsg->paramL = (UINT)dwAnsi;
  287. /*
  288. * Keep this EVENTMSG to local buffer.
  289. */
  290. RtlCopyMemory(&CachedEvent, pEMsg, sizeof(EVENTMSG));
  291. }
  292. }
  293. }
  294. break;
  295. case WH_MSGFILTER:
  296. case WH_SYSMSGFILTER:
  297. case WH_GETMESSAGE:
  298. pMsg = (PMSG)lParam;
  299. if (pMsg) {
  300. switch (pMsg->message) {
  301. case WM_CHAR:
  302. case EM_SETPASSWORDCHAR:
  303. if (GetCallBackDbcsInfo()->wParam) {
  304. PKERNEL_MSG pmsgDbcs = GetCallBackDbcsInfo();
  305. /*
  306. * Get pushed message.
  307. *
  308. * Backup current message. this backupped message will be used
  309. * when Apps peek (or get) message from thier WndProc.
  310. * (see GetMessageA(), PeekMessageA()...)
  311. *
  312. * pmsg->hwnd = pmsgDbcs->hwnd;
  313. * pmsg->message = pmsgDbcs->message;
  314. * pmsg->wParam = pmsgDbcs->wParam;
  315. * pmsg->lParam = pmsgDbcs->lParam;
  316. * pmsg->time = pmsgDbcs->time;
  317. * pmsg->pt = pmsgDbcs->pt;
  318. */
  319. COPY_KERNELMSG_TO_MSG(pMsg,pmsgDbcs);
  320. /*
  321. * Invalidate pushed message in CLIENTINFO.
  322. */
  323. pmsgDbcs->wParam = 0;
  324. /*
  325. * Call the hook with DBCS TrailByte..
  326. */
  327. nRet = pfn(LOWORD(dw), wParam, lParam);
  328. }
  329. /*
  330. * Restore original message..
  331. * #96571 [hiroyama]
  332. * Other messages than WM_CHAR and EM_SETPASSWORDCHAR can be
  333. * modifed by a hooker.
  334. * Wparam for WM_CHAR and EM_SETPASSWORDCHAR must be restored.
  335. * *by design*
  336. */
  337. pMsg->wParam = wParamSave;
  338. }
  339. }
  340. }
  341. }
  342. #endif
  343. /*
  344. * Restore the hook number and return the return code.
  345. */
  346. pci->dwHookCurrent = dwHookSave;
  347. return nRet;
  348. }
  349. /***************************************************************************\
  350. * GetWindowLong, SetWindowLong, GetClassLong
  351. *
  352. * History:
  353. * 02-Feb-92 IanJa Neutral version.
  354. \***************************************************************************/
  355. #ifdef UNICODE
  356. FUNCLOG2(LOG_GENERAL, LONG_PTR, APIENTRY, GetWindowLongPtrW, HWND, hwnd, int, nIndex)
  357. #else
  358. FUNCLOG2(LOG_GENERAL, LONG_PTR, APIENTRY, GetWindowLongPtrA, HWND, hwnd, int, nIndex)
  359. #endif // UNICODE
  360. LONG_PTR APIENTRY GetWindowLongPtr(
  361. HWND hwnd,
  362. int nIndex)
  363. {
  364. PWND pwnd;
  365. pwnd = ValidateHwnd(hwnd);
  366. if (pwnd == NULL) {
  367. return 0;
  368. }
  369. try {
  370. return _GetWindowLongPtr(pwnd, nIndex, IS_ANSI);
  371. } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
  372. RIPERR1(ERROR_INVALID_WINDOW_HANDLE,
  373. RIP_WARNING,
  374. "Window %x no longer valid",
  375. hwnd);
  376. return 0;
  377. }
  378. }
  379. #ifdef UNICODE
  380. FUNCLOG3(LOG_GENERAL, LONG_PTR, APIENTRY, SetWindowLongPtrW, HWND, hWnd, int, nIndex, LONG_PTR, dwNewLong)
  381. #else
  382. FUNCLOG3(LOG_GENERAL, LONG_PTR, APIENTRY, SetWindowLongPtrA, HWND, hWnd, int, nIndex, LONG_PTR, dwNewLong)
  383. #endif // UNICODE
  384. LONG_PTR APIENTRY SetWindowLongPtr(
  385. HWND hWnd,
  386. int nIndex,
  387. LONG_PTR dwNewLong)
  388. {
  389. return _SetWindowLongPtr(hWnd, nIndex, dwNewLong, IS_ANSI);
  390. }
  391. #ifdef _WIN64
  392. LONG APIENTRY GetWindowLong(
  393. HWND hwnd,
  394. int nIndex)
  395. {
  396. PWND pwnd;
  397. pwnd = ValidateHwnd(hwnd);
  398. if (pwnd == NULL) {
  399. return 0;
  400. }
  401. try {
  402. return _GetWindowLong(pwnd, nIndex, IS_ANSI);
  403. } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
  404. RIPERR1(ERROR_INVALID_WINDOW_HANDLE,
  405. RIP_WARNING,
  406. "Window %x no longer valid",
  407. hwnd);
  408. return 0;
  409. }
  410. }
  411. LONG APIENTRY SetWindowLong(
  412. HWND hWnd,
  413. int nIndex,
  414. LONG dwNewLong)
  415. {
  416. return _SetWindowLong(hWnd, nIndex, dwNewLong, IS_ANSI);
  417. }
  418. #endif
  419. #ifdef UNICODE
  420. FUNCLOG2(LOG_GENERAL, ULONG_PTR, APIENTRY, GetClassLongPtrW, HWND, hWnd, int, nIndex)
  421. #else
  422. FUNCLOG2(LOG_GENERAL, ULONG_PTR, APIENTRY, GetClassLongPtrA, HWND, hWnd, int, nIndex)
  423. #endif // UNICODE
  424. ULONG_PTR APIENTRY GetClassLongPtr(
  425. HWND hWnd,
  426. int nIndex)
  427. {
  428. PWND pwnd;
  429. pwnd = ValidateHwnd(hWnd);
  430. if (pwnd == NULL) {
  431. return 0;
  432. }
  433. try {
  434. return _GetClassLongPtr(pwnd, nIndex, IS_ANSI);
  435. } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
  436. RIPERR1(ERROR_INVALID_WINDOW_HANDLE,
  437. RIP_WARNING,
  438. "Window %x no longer valid",
  439. hWnd);
  440. return 0;
  441. }
  442. }
  443. #ifdef _WIN64
  444. DWORD APIENTRY GetClassLong(HWND hWnd, int nIndex)
  445. {
  446. PWND pwnd;
  447. pwnd = ValidateHwnd(hWnd);
  448. if (pwnd == NULL)
  449. return 0;
  450. try {
  451. return _GetClassLong(pwnd, nIndex, IS_ANSI);
  452. } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
  453. RIPERR1(ERROR_INVALID_WINDOW_HANDLE,
  454. RIP_WARNING,
  455. "Window %x no longer valid",
  456. hWnd);
  457. return 0;
  458. }
  459. }
  460. #endif
  461. #ifdef UNICODE
  462. FUNCLOG5(LOG_GENERAL, BOOL, APIENTRY, PeekMessageW, LPMSG, lpMsg, HWND, hWnd, UINT, wMsgFilterMin, UINT, wMsgFilterMax, UINT, wRemoveMsg)
  463. #else
  464. FUNCLOG5(LOG_GENERAL, BOOL, APIENTRY, PeekMessageA, LPMSG, lpMsg, HWND, hWnd, UINT, wMsgFilterMin, UINT, wMsgFilterMax, UINT, wRemoveMsg)
  465. #endif // UNICODE
  466. BOOL APIENTRY PeekMessage(
  467. LPMSG lpMsg,
  468. HWND hWnd,
  469. UINT wMsgFilterMin,
  470. UINT wMsgFilterMax,
  471. UINT wRemoveMsg)
  472. {
  473. CLIENTTHREADINFO *pcti;
  474. PCLIENTINFO pci;
  475. UINT fsWakeMaskFilter;
  476. UINT fsWakeMask;
  477. UINT cSpinLimit;
  478. pci = GetClientInfo();
  479. if (hWnd != NULL) {
  480. goto lbCallServer;
  481. }
  482. #if IS_ANSI
  483. /*
  484. * If we have a DBCS TrailingByte that should be returned to App,
  485. * we should pass it, never can fail....
  486. */
  487. UserAssert(IS_DBCS_ENABLED() || GetCallBackDbcsInfo()->wParam == 0);
  488. if (GetCallBackDbcsInfo()->wParam) { // accesses fs:xxx, but no speed penalty
  489. /*
  490. * Check message filter... WM_CHAR should be in the Range...
  491. */
  492. if ((!wMsgFilterMin && !wMsgFilterMax) ||
  493. (wMsgFilterMin <= WM_CHAR && wMsgFilterMax >=WM_CHAR)) {
  494. goto lbCallServer;
  495. }
  496. }
  497. #endif
  498. if ( (pci->dwTIFlags & TIF_16BIT)
  499. && !(wRemoveMsg & PM_NOYIELD)
  500. && ((gpsi->nEvents != 0) || (pci->dwTIFlags & (TIF_FIRSTIDLE | TIF_DELAYEDEVENT)))) {
  501. goto lbCallServer;
  502. }
  503. /*
  504. * If we can't see the client thread info, we need to go to the kernel.
  505. */
  506. if ((pcti = CLIENTTHREADINFO(pci)) == NULL) {
  507. goto lbCallServer;
  508. }
  509. fsWakeMaskFilter = HIWORD(wRemoveMsg);
  510. #if DBG
  511. /*
  512. * New for NT5: HIWORD(wRemoveMsg) contains a QS_ mask. This is
  513. * validated for real in the kernel side.
  514. */
  515. if (fsWakeMaskFilter & ~QS_VALID) {
  516. RIPMSG1(RIP_WARNING,
  517. "PeekMessage: Invalid QS_ bits: 0x%x",
  518. fsWakeMaskFilter);
  519. }
  520. #endif
  521. /*
  522. * If any appropriate input is available, we need to go to the kernel.
  523. */
  524. if (wMsgFilterMax == 0 && fsWakeMaskFilter == 0) {
  525. fsWakeMask = (QS_ALLINPUT | QS_EVENT | QS_ALLPOSTMESSAGE);
  526. } else {
  527. fsWakeMask = CalcWakeMask(wMsgFilterMin, wMsgFilterMax, fsWakeMaskFilter);
  528. }
  529. if ((pcti->fsChangeBits | pcti->fsWakeBits) & fsWakeMask) {
  530. goto lbCallServer;
  531. }
  532. /*
  533. * If this thread has the queue locked, we have to go to the kernel or
  534. * other threads on the same queue may be prevented from getting input
  535. * messages.
  536. */
  537. if (pcti->CTIF_flags & CTIF_SYSQUEUELOCKED) {
  538. goto lbCallServer;
  539. }
  540. /*
  541. * This is the peek message count (not going idle count). If it gets
  542. * to be 100 or greater, call the server. This'll cause this app to be
  543. * put at background priority until it sleeps. This is really important
  544. * for compatibility because win3.1 peek/getmessage usually takes a trip
  545. * through the win3.1 scheduler and runs the next task.
  546. */
  547. pci->cSpins++;
  548. if ((pci->cSpins >= CSPINBACKGROUND) && !(pci->dwTIFlags & TIF_SPINNING)) {
  549. goto lbCallServer;
  550. }
  551. /*
  552. * We have to go to the server if someone is waiting on this event.
  553. * We used to just wait until the spin cound got large but for some
  554. * apps like terminal. They always just call PeekMessage and after
  555. * just a few calls they would blink their caret which bonks the spincount
  556. */
  557. if (pci->dwTIFlags & TIF_WAITFORINPUTIDLE) {
  558. goto lbCallServer;
  559. }
  560. /*
  561. * Make sure we go to the kernel at least once a second so that
  562. * hung app painting won't occur.
  563. */
  564. if ((NtGetTickCount() - pcti->timeLastRead) > 1000) {
  565. NtUserGetThreadState(UserThreadStatePeekMessage);
  566. }
  567. /*
  568. * Determine the maximum number of spins before we yield. Yields
  569. * are performed more frequently for 16 bit apps.
  570. */
  571. if ((pci->dwTIFlags & TIF_16BIT) && !(wRemoveMsg & PM_NOYIELD)) {
  572. cSpinLimit = CSPINBACKGROUND / 10;
  573. } else {
  574. cSpinLimit = CSPINBACKGROUND;
  575. }
  576. /*
  577. * If the PeekMessage() is just spinning, then we should sleep
  578. * just enough so that we allow other processes to gain CPU time.
  579. * A problem was found when an OLE app tries to communicate to a
  580. * background app (via SendMessage) running at the same priority as a
  581. * background/spinning process. This will starve the CPU from those
  582. * processes. Sleep on every re-cycle of the spin-count. This will
  583. * assure that apps doing peeks are degraded.
  584. *
  585. */
  586. if ((pci->dwTIFlags & TIF_SPINNING) && (pci->cSpins >= cSpinLimit)) {
  587. pci->cSpins = 0;
  588. NtYieldExecution();
  589. }
  590. return FALSE;
  591. lbCallServer:
  592. return _PeekMessage(lpMsg,
  593. hWnd,
  594. wMsgFilterMin,
  595. wMsgFilterMax,
  596. wRemoveMsg,
  597. IS_ANSI);
  598. }
  599. #ifdef UNICODE
  600. FUNCLOG4(LOG_GENERAL, LRESULT, APIENTRY, DefWindowProcW, HWND, hwnd, UINT, message, WPARAM, wParam, LPARAM, lParam)
  601. #else
  602. FUNCLOG4(LOG_GENERAL, LRESULT, APIENTRY, DefWindowProcA, HWND, hwnd, UINT, message, WPARAM, wParam, LPARAM, lParam)
  603. #endif // UNICODE
  604. LRESULT APIENTRY DefWindowProc(
  605. HWND hwnd,
  606. UINT message,
  607. WPARAM wParam,
  608. LPARAM lParam)
  609. {
  610. LRESULT lRet;
  611. BEGIN_USERAPIHOOK()
  612. BOOL fOverride = IsMsgOverride(message, &guah.mmDWP);
  613. if (fOverride) {
  614. /*
  615. * This message is being overridden, so we need to callback to
  616. * the process. During this callback, the override may call the
  617. * real DWP for processing.
  618. */
  619. #ifdef UNICODE
  620. lRet = guah.pfnDefWindowProcW(hwnd, message, wParam, lParam);
  621. #else
  622. lRet = guah.pfnDefWindowProcA(hwnd, message, wParam, lParam);
  623. #endif
  624. } else {
  625. /*
  626. * This message is not being overridden, so we can just call the
  627. * real DWP for processing.
  628. */
  629. #ifdef UNICODE
  630. lRet = RealDefWindowProcW(hwnd, message, wParam, lParam);
  631. #else
  632. lRet = RealDefWindowProcA(hwnd, message, wParam, lParam);
  633. #endif
  634. }
  635. END_USERAPIHOOK()
  636. return lRet;
  637. }
  638. LRESULT APIENTRY TEXT_FN(RealDefWindowProc)(
  639. HWND hwnd,
  640. UINT message,
  641. WPARAM wParam,
  642. LPARAM lParam)
  643. {
  644. PWND pwnd;
  645. if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
  646. switch (message) {
  647. case WM_CTLCOLORBTN:
  648. case WM_CTLCOLORSTATIC:
  649. case WM_CTLCOLORDLG:
  650. case WM_CTLCOLORMSGBOX:
  651. /*
  652. * Draw default colors
  653. */
  654. break;
  655. default:
  656. return 0;
  657. }
  658. }
  659. return RealDefWindowProcWorker(pwnd, message, wParam, lParam, IS_ANSI);
  660. }
  661. LRESULT APIENTRY TEXT_FN(DispatchDefWindowProc)(
  662. PWND pwnd,
  663. UINT message,
  664. WPARAM wParam,
  665. LPARAM lParam,
  666. ULONG_PTR pfn)
  667. {
  668. HWND hwnd = KHWND_TO_HWND(GetClientInfo()->CallbackWnd.hwnd);
  669. UNREFERENCED_PARAMETER(pwnd);
  670. UNREFERENCED_PARAMETER(pfn);
  671. return DefWindowProc(hwnd, message, wParam, lParam);
  672. }
  673. #ifdef UNICODE
  674. FUNCLOG4(LOG_GENERAL, LRESULT, APIENTRY, SendMessageW, HWND, hwnd, UINT, message, WPARAM, wParam, LPARAM, lParam)
  675. #else
  676. FUNCLOG4(LOG_GENERAL, LRESULT, APIENTRY, SendMessageA, HWND, hwnd, UINT, message, WPARAM, wParam, LPARAM, lParam)
  677. #endif // UNICODE
  678. LRESULT APIENTRY SendMessage(
  679. HWND hwnd,
  680. UINT message,
  681. WPARAM wParam,
  682. LPARAM lParam)
  683. {
  684. PWND pwnd;
  685. /*
  686. * Prevent apps from setting hi 16 bits so we can use them internally.
  687. */
  688. if (message & RESERVED_MSG_BITS) {
  689. RIPERR1(ERROR_INVALID_PARAMETER,
  690. RIP_WARNING,
  691. "Invalid parameter \"message\" (%ld) to SendMessage",
  692. message);
  693. return 0;
  694. }
  695. /*
  696. * Thunk through a special sendmessage for -1 hwnd's so that the general
  697. * purpose thunks don't allow -1 hwnd's.
  698. */
  699. if (hwnd == (HWND)-1 || hwnd == (HWND)0x0000FFFF) {
  700. /*
  701. * Get a real hwnd so the thunks will validation ok. Note that since
  702. * -1 hwnd is really rare, calling GetDesktopWindow() here is not a
  703. * big deal.
  704. */
  705. hwnd = GetDesktopWindow();
  706. /*
  707. * Always send broadcast requests straight to the server. Note: if
  708. * the xParam needs to be used, must update SendMsgTimeout,
  709. * FNID_SENDMESSAGEFF uses it to id who it is from.
  710. */
  711. return CsSendMessage(hwnd,
  712. message,
  713. wParam,
  714. lParam,
  715. 0L,
  716. FNID_SENDMESSAGEFF,
  717. IS_ANSI);
  718. }
  719. if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
  720. return 0;
  721. }
  722. return SendMessageWorker(pwnd, message, wParam, lParam, IS_ANSI);
  723. }
  724. #ifdef UNICODE
  725. FUNCLOG7(LOG_GENERAL, LRESULT, APIENTRY, SendMessageTimeoutW, HWND, hwnd, UINT, message, WPARAM, wParam, LPARAM, lParam, UINT, fuFlags, UINT, uTimeout, PULONG_PTR, lpdwResult)
  726. #else
  727. FUNCLOG7(LOG_GENERAL, LRESULT, APIENTRY, SendMessageTimeoutA, HWND, hwnd, UINT, message, WPARAM, wParam, LPARAM, lParam, UINT, fuFlags, UINT, uTimeout, PULONG_PTR, lpdwResult)
  728. #endif // UNICODE
  729. LRESULT APIENTRY SendMessageTimeout(
  730. HWND hwnd,
  731. UINT message,
  732. WPARAM wParam,
  733. LPARAM lParam,
  734. UINT fuFlags,
  735. UINT uTimeout,
  736. PULONG_PTR lpdwResult)
  737. {
  738. return SendMessageTimeoutWorker(hwnd,
  739. message,
  740. wParam,
  741. lParam,
  742. fuFlags,
  743. uTimeout,
  744. lpdwResult,
  745. IS_ANSI);
  746. }
  747. /***************************************************************************\
  748. * SendDlgItemMessage
  749. *
  750. * Translates the message, calls SendDlgItemMessage on server side. The
  751. * dialog item's ID is passed as the xParam. On the server side, a stub
  752. * rearranges the parameters to put the ID where it belongs and calls
  753. * xxxSendDlgItemMessage.
  754. *
  755. * 04-17-91 DarrinM Created.
  756. \***************************************************************************/
  757. #ifdef UNICODE
  758. FUNCLOG5(LOG_GENERAL, LRESULT, WINAPI, SendDlgItemMessageW, HWND, hwnd, int, id, UINT, message, WPARAM, wParam, LPARAM, lParam)
  759. #else
  760. FUNCLOG5(LOG_GENERAL, LRESULT, WINAPI, SendDlgItemMessageA, HWND, hwnd, int, id, UINT, message, WPARAM, wParam, LPARAM, lParam)
  761. #endif // UNICODE
  762. LRESULT WINAPI SendDlgItemMessage(
  763. HWND hwnd,
  764. int id,
  765. UINT message,
  766. WPARAM wParam,
  767. LPARAM lParam)
  768. {
  769. if (hwnd == (HWND)-1 || hwnd == (HWND)0x0000FFFF) {
  770. return 0;
  771. }
  772. if (hwnd = GetDlgItem(hwnd, id)) {
  773. return SendMessage(hwnd, message, wParam, lParam);
  774. }
  775. return 0L;
  776. }
  777. /***************************************************************************\
  778. * GetDlgItemText
  779. *
  780. * History:
  781. * 04 Feb 1992 GregoryW Neutral ANSI/Unicode version
  782. \***************************************************************************/
  783. #ifdef UNICODE
  784. FUNCLOG4(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, GetDlgItemTextW, HWND, hwnd, int, id, LPTSTR, lpch, int, cchMax)
  785. #else
  786. FUNCLOG4(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, GetDlgItemTextA, HWND, hwnd, int, id, LPTSTR, lpch, int, cchMax)
  787. #endif // UNICODE
  788. UINT GetDlgItemText(
  789. HWND hwnd,
  790. int id,
  791. LPTSTR lpch,
  792. int cchMax)
  793. {
  794. if ((hwnd = GetDlgItem(hwnd, id)) != NULL) {
  795. return GetWindowText(hwnd, lpch, cchMax);
  796. }
  797. /*
  798. * If we couldn't find the window, just null terminate lpch so that the
  799. * app doesn't AV if it tries to run through the text.
  800. */
  801. if (cchMax) {
  802. *lpch = (TCHAR)0;
  803. }
  804. return 0;
  805. }
  806. /***************************************************************************\
  807. * SetDlgItemText
  808. *
  809. * History:
  810. * 04 Feb 1992 GregoryW Neutral ANSI/Unicode version
  811. \***************************************************************************/
  812. #ifdef UNICODE
  813. FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetDlgItemTextW , HWND, hwnd, int, id, LPCTSTR, lpch)
  814. #else
  815. FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetDlgItemTextA , HWND, hwnd, int, id, LPCTSTR, lpch)
  816. #endif // UNICODE
  817. BOOL SetDlgItemText(
  818. HWND hwnd,
  819. int id,
  820. LPCTSTR lpch)
  821. {
  822. if ((hwnd = GetDlgItem(hwnd, id)) != NULL) {
  823. return SetWindowText(hwnd, lpch);
  824. }
  825. return FALSE;
  826. }
  827. #ifdef UNICODE
  828. FUNCLOG3(LOG_GENERAL, int, WINAPI, GetWindowTextW, HWND, hwnd, LPTSTR, lpName, int, nMaxCount)
  829. #else
  830. FUNCLOG3(LOG_GENERAL, int, WINAPI, GetWindowTextA, HWND, hwnd, LPTSTR, lpName, int, nMaxCount)
  831. #endif // UNICODE
  832. int WINAPI GetWindowText(
  833. HWND hwnd,
  834. LPTSTR lpName,
  835. int nMaxCount)
  836. {
  837. PWND pwnd;
  838. /*
  839. * Don't try to fill a non-existent buffer
  840. */
  841. if (lpName == NULL || nMaxCount == 0) {
  842. return 0;
  843. }
  844. try {
  845. /*
  846. * Initialize string empty, in case SendMessage aborts validation
  847. */
  848. *lpName = TEXT('\0');
  849. /*
  850. * Make sure we have a valid window.
  851. */
  852. if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
  853. return 0;
  854. }
  855. /*
  856. * This process comparison is bogus, but it is what win3.1 does.
  857. */
  858. if (TestWindowProcess(pwnd)) {
  859. return (int)SendMessageWorker(pwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpName, IS_ANSI);
  860. } else {
  861. return (int)DefWindowProcWorker(pwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpName, IS_ANSI);
  862. }
  863. } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
  864. RIPERR1(ERROR_INVALID_WINDOW_HANDLE,
  865. RIP_WARNING,
  866. "Window %x no longer valid",
  867. hwnd);
  868. return 0;
  869. }
  870. }
  871. #ifdef UNICODE
  872. FUNCLOG1(LOG_GENERAL, int, WINAPI, GetWindowTextLengthW, HWND, hwnd)
  873. #else
  874. FUNCLOG1(LOG_GENERAL, int, WINAPI, GetWindowTextLengthA, HWND, hwnd)
  875. #endif // UNICODE
  876. int WINAPI GetWindowTextLength(
  877. HWND hwnd)
  878. {
  879. PWND pwnd;
  880. /*
  881. * Make sure we have a valid window.
  882. */
  883. if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
  884. return 0;
  885. }
  886. /*
  887. * This process comparison is bogus, but it is what win3.1 does.
  888. */
  889. if (TestWindowProcess(pwnd)) {
  890. return (int)SendMessageWorker(pwnd, WM_GETTEXTLENGTH, 0, 0, IS_ANSI);
  891. } else {
  892. return (int)DefWindowProcWorker(pwnd, WM_GETTEXTLENGTH, 0, 0, IS_ANSI);
  893. }
  894. }
  895. #ifdef UNICODE
  896. FUNCLOG2(LOG_GENERAL, BOOL, WINAPI, SetWindowTextW , HWND, hwnd, LPCTSTR, pString)
  897. #else
  898. FUNCLOG2(LOG_GENERAL, BOOL, WINAPI, SetWindowTextA , HWND, hwnd, LPCTSTR, pString)
  899. #endif // UNICODE
  900. BOOL WINAPI SetWindowText(
  901. HWND hwnd,
  902. LPCTSTR pString)
  903. {
  904. LRESULT lReturn;
  905. PWND pwnd;
  906. /*
  907. * Make sure we have a valid window.
  908. */
  909. if ((pwnd = ValidateHwnd(hwnd)) == NULL) {
  910. return FALSE;
  911. }
  912. /*
  913. * This process comparison is bogus, but it is what win3.1 does.
  914. */
  915. if (TestWindowProcess(pwnd)) {
  916. lReturn = SendMessageWorker(pwnd, WM_SETTEXT, 0, (LPARAM)pString, IS_ANSI);
  917. } else {
  918. lReturn = DefWindowProcWorker(pwnd, WM_SETTEXT, 0, (LPARAM)pString, IS_ANSI);
  919. }
  920. return (lReturn >= 0);
  921. }
  922. LRESULT APIENTRY DispatchMessage(CONST MSG *lpMsg)
  923. {
  924. extern LRESULT DispatchMessageWorker(CONST MSG *lpMsg, BOOL fAnsi);
  925. return DispatchMessageWorker(lpMsg, IS_ANSI);
  926. }
  927. #if IS_ANSI
  928. VOID CopyLogFontAtoW(
  929. PLOGFONTW pdest,
  930. PLOGFONTA psrc)
  931. {
  932. LPSTR lpstrFont = (LPSTR)(&psrc->lfFaceName);
  933. LPWSTR lpstrFontW = (LPWSTR)(&pdest->lfFaceName);
  934. RtlCopyMemory((LPBYTE)pdest, psrc, sizeof(LOGFONTA) - LF_FACESIZE);
  935. RtlZeroMemory(pdest->lfFaceName, LF_FACESIZE * sizeof(WCHAR));
  936. MBToWCS(lpstrFont, -1, &lpstrFontW, LF_FACESIZE, FALSE);
  937. }
  938. VOID CopyLogFontWtoA(
  939. PLOGFONTA pdest,
  940. PLOGFONTW psrc)
  941. {
  942. LPSTR lpstrFont = (LPSTR)(&pdest->lfFaceName);
  943. RtlCopyMemory((LPBYTE)pdest, (LPBYTE)psrc, sizeof(LOGFONTA) - LF_FACESIZE);
  944. RtlZeroMemory(pdest->lfFaceName, LF_FACESIZE);
  945. WCSToMB(psrc->lfFaceName, -1, &lpstrFont, LF_FACESIZE, FALSE);
  946. }
  947. #else
  948. /**************************************************************************\
  949. * SetVideoTimeout
  950. *
  951. * Updates the video timeout values in the current power profile.
  952. *
  953. * 15-Apr-1999 JerrySh Created.
  954. \**************************************************************************/
  955. typedef BOOLEAN (*PFNGETACTIVEPWRSCHEME)(PUINT);
  956. typedef BOOLEAN (*PFNSETACTIVEPWRSCHEME)(UINT, PGLOBAL_POWER_POLICY, PPOWER_POLICY);
  957. typedef BOOLEAN (*PFNREADPWRSCHEME)(UINT, PPOWER_POLICY);
  958. BOOL SetVideoTimeout(
  959. DWORD dwVideoTimeout)
  960. {
  961. POWER_POLICY pp;
  962. UINT uiID;
  963. BOOL fRet = FALSE;
  964. if (GetActivePwrScheme(&uiID)) {
  965. if (ReadPwrScheme(uiID, &pp)) {
  966. pp.user.VideoTimeoutDc = dwVideoTimeout;
  967. pp.user.VideoTimeoutAc = dwVideoTimeout;
  968. fRet = SetActivePwrScheme(uiID, NULL, &pp);
  969. }
  970. }
  971. return fRet;
  972. }
  973. #endif
  974. /***************************************************************************\
  975. * SystemParametersInfo
  976. *
  977. *
  978. \***************************************************************************/
  979. #ifdef UNICODE
  980. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, SystemParametersInfoW, UINT, wFlag, UINT, wParam, PVOID, lParam, UINT, flags)
  981. #else
  982. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, SystemParametersInfoA, UINT, wFlag, UINT, wParam, PVOID, lParam, UINT, flags)
  983. #endif // UINCODE
  984. BOOL APIENTRY SystemParametersInfo(
  985. UINT wFlag,
  986. UINT wParam,
  987. PVOID lParam,
  988. UINT flags)
  989. {
  990. BOOL bRet;
  991. BEGIN_USERAPIHOOK()
  992. #ifdef UNICODE
  993. bRet = guah.pfnSystemParametersInfoW(wFlag, wParam, lParam, flags);
  994. #else
  995. bRet = guah.pfnSystemParametersInfoA(wFlag, wParam, lParam, flags);
  996. #endif
  997. END_USERAPIHOOK()
  998. return bRet;
  999. }
  1000. BOOL APIENTRY TEXT_FN(RealSystemParametersInfo)(
  1001. UINT wFlag,
  1002. UINT wParam,
  1003. PVOID lParam,
  1004. UINT flags)
  1005. {
  1006. #if IS_ANSI
  1007. NONCLIENTMETRICSW ClientMetricsW;
  1008. ICONMETRICSW IconMetricsW;
  1009. LOGFONTW LogFontW;
  1010. WCHAR szTemp[MAX_PATH];
  1011. UINT oldwParam = wParam;
  1012. #endif
  1013. INTERNALSETHIGHCONTRAST ihc;
  1014. IN_STRING strlParam;
  1015. PVOID oldlParam = lParam;
  1016. /*
  1017. * Make sure cleanup will work successfully
  1018. */
  1019. strlParam.fAllocated = FALSE;
  1020. BEGINCALL();
  1021. switch (wFlag) {
  1022. case SPI_SETSCREENSAVERRUNNING: // same as SPI_SCREENSAVERRUNNING
  1023. MSGERROR();
  1024. case SPI_SETDESKPATTERN:
  1025. if (wParam == 0x0000FFFF) {
  1026. wParam = (UINT)-1;
  1027. }
  1028. /*
  1029. * lParam not a string (and already copied).
  1030. */
  1031. if (wParam == (UINT)-1) {
  1032. break;
  1033. }
  1034. /*
  1035. * lParam is possibly 0 or -1 (filled in already) or a string.
  1036. */
  1037. if (lParam != (PVOID)0 && lParam != (PVOID)-1) {
  1038. COPYLPTSTR(&strlParam, (LPTSTR)lParam);
  1039. lParam = strlParam.pstr;
  1040. }
  1041. break;
  1042. case SPI_SETDESKWALLPAPER: {
  1043. /*
  1044. * lParam is possibly 0, -1 or -2 (filled in already) or a string.
  1045. * Get a pointer to the string so we can use it later. We're
  1046. * going to a bit of normalizing here for consistency.
  1047. *
  1048. * If the caller passes in 0, -1 or -2, we're going to set
  1049. * the wParam to -1, and use the lParam to pass the string
  1050. * representation of the wallpaper.
  1051. */
  1052. if ((lParam != (PVOID) 0) &&
  1053. (lParam != (PVOID)-1) &&
  1054. (lParam != (PVOID)-2)) {
  1055. COPYLPTSTR(&strlParam, (LPTSTR)lParam);
  1056. lParam = strlParam.pstr;
  1057. wParam = 0;
  1058. } else {
  1059. wParam = (UINT)-1;
  1060. }
  1061. }
  1062. break;
  1063. /*
  1064. * Bug 257718 - joejo
  1065. * Add SPI_GETDESKWALLPAPER to SystemParametersInfo
  1066. */
  1067. case SPI_GETDESKWALLPAPER:
  1068. if ((lParam == NULL) || (wParam == 0))
  1069. MSGERROR();
  1070. #if IS_ANSI
  1071. lParam = szTemp;
  1072. wParam = ARRAY_SIZE(szTemp);
  1073. #else
  1074. /*
  1075. * Bug 283318 - joejo
  1076. * Leave space for a null termination
  1077. */
  1078. wParam--;
  1079. #endif
  1080. break;
  1081. case SPI_GETANIMATION:
  1082. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(ANIMATIONINFO)) {
  1083. MSGERROR();
  1084. }
  1085. break;
  1086. case SPI_GETNONCLIENTMETRICS:
  1087. #if IS_ANSI
  1088. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(NONCLIENTMETRICSA)) {
  1089. MSGERROR();
  1090. }
  1091. lParam = &ClientMetricsW;
  1092. #else
  1093. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(NONCLIENTMETRICSW)) {
  1094. MSGERROR();
  1095. }
  1096. #endif
  1097. break;
  1098. case SPI_GETMINIMIZEDMETRICS:
  1099. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(MINIMIZEDMETRICS)) {
  1100. MSGERROR();
  1101. }
  1102. break;
  1103. case SPI_GETICONMETRICS:
  1104. #if IS_ANSI
  1105. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(ICONMETRICSA)) {
  1106. MSGERROR();
  1107. }
  1108. lParam = &IconMetricsW;
  1109. #else
  1110. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(ICONMETRICSW)) {
  1111. MSGERROR();
  1112. }
  1113. #endif
  1114. break;
  1115. case SPI_GETHIGHCONTRAST:
  1116. #if IS_ANSI
  1117. {
  1118. LPHIGHCONTRASTA pHC = (HIGHCONTRASTA *)lParam;
  1119. if (!pHC || pHC->cbSize != sizeof(HIGHCONTRASTA)) {
  1120. MSGERROR();
  1121. }
  1122. if (!pcHighContrastScheme) {
  1123. pcHighContrastScheme = UserLocalAlloc(HEAP_ZERO_MEMORY,
  1124. MAX_SCHEME_NAME_SIZE * sizeof(WCHAR));
  1125. if (!pcHighContrastScheme) {
  1126. MSGERROR();
  1127. }
  1128. }
  1129. if (!pwcHighContrastScheme) {
  1130. pwcHighContrastScheme = UserLocalAlloc(HEAP_ZERO_MEMORY,
  1131. MAX_SCHEME_NAME_SIZE * sizeof(WCHAR));
  1132. if (!pwcHighContrastScheme) {
  1133. MSGERROR();
  1134. }
  1135. }
  1136. ((LPHIGHCONTRASTW)(lParam))->lpszDefaultScheme = pwcHighContrastScheme;
  1137. }
  1138. #else
  1139. {
  1140. LPHIGHCONTRASTW pHC = (HIGHCONTRASTW *)lParam;
  1141. if (!pHC || (pHC->cbSize != sizeof(HIGHCONTRASTW))) {
  1142. MSGERROR();
  1143. }
  1144. if (!pwcHighContrastScheme) {
  1145. pwcHighContrastScheme = UserLocalAlloc(HEAP_ZERO_MEMORY,
  1146. MAX_SCHEME_NAME_SIZE * sizeof(WCHAR));
  1147. if (!pwcHighContrastScheme) {
  1148. MSGERROR();
  1149. }
  1150. }
  1151. pHC->lpszDefaultScheme = pwcHighContrastScheme;
  1152. }
  1153. #endif
  1154. break;
  1155. #if IS_ANSI
  1156. case SPI_GETICONTITLELOGFONT:
  1157. lParam = &LogFontW;
  1158. break;
  1159. #endif
  1160. case SPI_SETANIMATION:
  1161. if (lParam == NULL || *((DWORD *)lParam) != sizeof(ANIMATIONINFO)) {
  1162. MSGERROR();
  1163. }
  1164. break;
  1165. case SPI_SETHIGHCONTRAST:
  1166. ihc.cbSize = sizeof (HIGHCONTRASTW);
  1167. {
  1168. LPHIGHCONTRAST pHC = (HIGHCONTRAST *)lParam;
  1169. if (lParam == NULL || pHC->cbSize != sizeof(HIGHCONTRAST)) {
  1170. MSGERROR();
  1171. }
  1172. lParam = &ihc;
  1173. ihc.dwFlags = pHC->dwFlags;
  1174. COPYLPTSTR(&strlParam, pHC->lpszDefaultScheme);
  1175. ihc.usDefaultScheme = *strlParam.pstr;
  1176. }
  1177. break;
  1178. case SPI_SETNONCLIENTMETRICS:
  1179. {
  1180. PNONCLIENTMETRICS psrc = (PNONCLIENTMETRICS)lParam;
  1181. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(NONCLIENTMETRICS)) {
  1182. MSGERROR();
  1183. }
  1184. if (psrc->iCaptionWidth > 256) {
  1185. psrc->iCaptionWidth = 256;
  1186. }
  1187. if (psrc->iCaptionHeight > 256) {
  1188. psrc->iCaptionHeight = 256;
  1189. }
  1190. #if IS_ANSI
  1191. ClientMetricsW.cbSize = psrc->cbSize;
  1192. ClientMetricsW.iBorderWidth = psrc->iBorderWidth;
  1193. ClientMetricsW.iScrollWidth = psrc->iScrollWidth;
  1194. ClientMetricsW.iScrollHeight = psrc->iScrollHeight;
  1195. ClientMetricsW.iCaptionWidth = psrc->iCaptionWidth;
  1196. ClientMetricsW.iCaptionHeight = psrc->iCaptionHeight;
  1197. ClientMetricsW.iSmCaptionWidth = psrc->iSmCaptionWidth;
  1198. ClientMetricsW.iSmCaptionHeight = psrc->iSmCaptionHeight;
  1199. ClientMetricsW.iMenuWidth = psrc->iMenuWidth;
  1200. ClientMetricsW.iMenuHeight = psrc->iMenuHeight;
  1201. CopyLogFontAtoW(&(ClientMetricsW.lfCaptionFont), &(psrc->lfCaptionFont));
  1202. CopyLogFontAtoW(&(ClientMetricsW.lfSmCaptionFont), &(psrc->lfSmCaptionFont));
  1203. CopyLogFontAtoW(&(ClientMetricsW.lfMenuFont), &(psrc->lfMenuFont));
  1204. CopyLogFontAtoW(&(ClientMetricsW.lfStatusFont), &(psrc->lfStatusFont));
  1205. CopyLogFontAtoW(&(ClientMetricsW.lfMessageFont), &(psrc->lfMessageFont));
  1206. lParam = &ClientMetricsW;
  1207. #endif
  1208. wParam = sizeof(NONCLIENTMETRICSW);
  1209. }
  1210. break;
  1211. case SPI_SETMINIMIZEDMETRICS:
  1212. if ((lParam == NULL) || (*((DWORD *)(lParam)) != sizeof(MINIMIZEDMETRICS)))
  1213. MSGERROR();
  1214. wParam = sizeof(MINIMIZEDMETRICS);
  1215. break;
  1216. case SPI_SETICONMETRICS:
  1217. #if IS_ANSI
  1218. {
  1219. PICONMETRICSA psrc = (PICONMETRICSA)lParam;
  1220. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(ICONMETRICSA)) {
  1221. MSGERROR();
  1222. }
  1223. RtlCopyMemory(&IconMetricsW, psrc, sizeof(ICONMETRICSA) - sizeof(LOGFONTA));
  1224. CopyLogFontAtoW(&(IconMetricsW.lfFont), &(psrc->lfFont));
  1225. lParam = &IconMetricsW;
  1226. }
  1227. #else
  1228. if (lParam == NULL || *((DWORD *)(lParam)) != sizeof(ICONMETRICSW)) {
  1229. MSGERROR();
  1230. }
  1231. #endif
  1232. wParam = sizeof(ICONMETRICSW);
  1233. break;
  1234. case SPI_SETICONTITLELOGFONT:
  1235. #if IS_ANSI
  1236. CopyLogFontAtoW(&LogFontW, lParam);
  1237. lParam = &LogFontW;
  1238. #endif
  1239. wParam = sizeof(LOGFONTW);
  1240. break;
  1241. case SPI_GETFILTERKEYS:
  1242. {
  1243. if ((((LPFILTERKEYS)lParam)->cbSize == 0) ||
  1244. (((LPFILTERKEYS)lParam)->cbSize) > sizeof(FILTERKEYS)) {
  1245. MSGERROR();
  1246. }
  1247. }
  1248. break;
  1249. case SPI_GETSTICKYKEYS:
  1250. {
  1251. if ((((LPSTICKYKEYS)lParam)->cbSize == 0) ||
  1252. (((LPSTICKYKEYS)lParam)->cbSize) > sizeof(STICKYKEYS)) {
  1253. MSGERROR();
  1254. }
  1255. }
  1256. break;
  1257. case SPI_GETTOGGLEKEYS:
  1258. {
  1259. if ((((LPTOGGLEKEYS)lParam)->cbSize == 0) ||
  1260. (((LPTOGGLEKEYS)lParam)->cbSize) > sizeof(TOGGLEKEYS)) {
  1261. MSGERROR();
  1262. }
  1263. }
  1264. break;
  1265. case SPI_GETMOUSEKEYS:
  1266. {
  1267. if ((((LPMOUSEKEYS)lParam)->cbSize == 0) ||
  1268. (((LPMOUSEKEYS)lParam)->cbSize) > sizeof(MOUSEKEYS)) {
  1269. MSGERROR();
  1270. }
  1271. }
  1272. break;
  1273. case SPI_GETACCESSTIMEOUT:
  1274. {
  1275. if ((((LPACCESSTIMEOUT)lParam)->cbSize == 0) ||
  1276. (((LPACCESSTIMEOUT)lParam)->cbSize) > sizeof(ACCESSTIMEOUT)) {
  1277. MSGERROR();
  1278. }
  1279. }
  1280. break;
  1281. case SPI_GETSOUNDSENTRY:
  1282. if ((((LPSOUNDSENTRY)lParam)->cbSize == 0) ||
  1283. (((LPSOUNDSENTRY)lParam)->cbSize) > sizeof(SOUNDSENTRY)) {
  1284. MSGERROR();
  1285. }
  1286. break;
  1287. }
  1288. retval = NtUserSystemParametersInfo(wFlag, wParam, lParam, flags);
  1289. switch (wFlag) {
  1290. #if IS_ANSI
  1291. case SPI_GETNONCLIENTMETRICS:
  1292. {
  1293. PNONCLIENTMETRICSA pdst = (PNONCLIENTMETRICSA)oldlParam;
  1294. pdst->cbSize = sizeof(NONCLIENTMETRICSA);
  1295. pdst->iBorderWidth = ClientMetricsW.iBorderWidth;
  1296. pdst->iScrollWidth = ClientMetricsW.iScrollWidth;
  1297. pdst->iScrollHeight = ClientMetricsW.iScrollHeight;
  1298. pdst->iCaptionWidth = ClientMetricsW.iCaptionWidth;
  1299. pdst->iCaptionHeight = ClientMetricsW.iCaptionHeight;
  1300. pdst->iSmCaptionWidth = ClientMetricsW.iSmCaptionWidth;
  1301. pdst->iSmCaptionHeight = ClientMetricsW.iSmCaptionHeight;
  1302. pdst->iMenuWidth = ClientMetricsW.iMenuWidth;
  1303. pdst->iMenuHeight = ClientMetricsW.iMenuHeight;
  1304. CopyLogFontWtoA(&(pdst->lfCaptionFont), &(ClientMetricsW.lfCaptionFont));
  1305. CopyLogFontWtoA(&(pdst->lfSmCaptionFont), &(ClientMetricsW.lfSmCaptionFont));
  1306. CopyLogFontWtoA(&(pdst->lfMenuFont), &(ClientMetricsW.lfMenuFont));
  1307. CopyLogFontWtoA(&(pdst->lfStatusFont), &(ClientMetricsW.lfStatusFont));
  1308. CopyLogFontWtoA(&(pdst->lfMessageFont), &(ClientMetricsW.lfMessageFont));
  1309. }
  1310. break;
  1311. case SPI_GETICONMETRICS:
  1312. {
  1313. PICONMETRICSA pdst = (PICONMETRICSA)oldlParam;
  1314. RtlCopyMemory(pdst, &IconMetricsW, sizeof(ICONMETRICSA) - sizeof(LOGFONTA));
  1315. pdst->cbSize = sizeof(ICONMETRICSA);
  1316. CopyLogFontWtoA(&(pdst->lfFont), &(IconMetricsW.lfFont));
  1317. }
  1318. break;
  1319. case SPI_GETICONTITLELOGFONT:
  1320. CopyLogFontWtoA((PLOGFONTA)oldlParam, &LogFontW);
  1321. break;
  1322. case SPI_GETHIGHCONTRAST:
  1323. WCSToMB(pwcHighContrastScheme, -1, &pcHighContrastScheme, MAX_SCHEME_NAME_SIZE, FALSE);
  1324. ((LPHIGHCONTRASTA)(lParam))->lpszDefaultScheme = pcHighContrastScheme;
  1325. break;
  1326. #endif
  1327. case SPI_GETDESKWALLPAPER:
  1328. {
  1329. #if IS_ANSI
  1330. INT cchAnsiCopy = WCSToMB(lParam,
  1331. -1,
  1332. (LPSTR*)&oldlParam,
  1333. oldwParam - 1,
  1334. FALSE);
  1335. cchAnsiCopy = min(cchAnsiCopy, (INT)(oldwParam - 1));
  1336. ((LPSTR)oldlParam)[cchAnsiCopy] = 0;
  1337. #else
  1338. ((LPWSTR)oldlParam)[wParam] = (WCHAR)0;
  1339. #endif
  1340. break;
  1341. }
  1342. case SPI_SETLOWPOWERTIMEOUT:
  1343. case SPI_SETPOWEROFFTIMEOUT:
  1344. if (retval && (flags & SPIF_UPDATEINIFILE)) {
  1345. retval = SetVideoTimeout(wParam);
  1346. }
  1347. break;
  1348. }
  1349. ERRORTRAP(FALSE);
  1350. CLEANUPLPTSTR(strlParam);
  1351. ENDCALL(BOOL);
  1352. }
  1353. #ifdef UNICODE
  1354. FUNCLOG2(LOG_GENERAL, HANDLE, APIENTRY, GetPropW, HWND, hwnd, LPCTSTR, pString)
  1355. #else
  1356. FUNCLOG2(LOG_GENERAL, HANDLE, APIENTRY, GetPropA, HWND, hwnd, LPCTSTR, pString)
  1357. #endif // UNICODE
  1358. HANDLE APIENTRY GetProp(HWND hwnd, LPCTSTR pString)
  1359. {
  1360. PWND pwnd;
  1361. int iString;
  1362. if (IS_PTR(pString)) {
  1363. iString = (int)GlobalFindAtom(pString);
  1364. if (iString == 0)
  1365. return NULL;
  1366. } else
  1367. iString = PTR_TO_ID(pString);
  1368. pwnd = ValidateHwnd(hwnd);
  1369. if (pwnd == NULL)
  1370. return NULL;
  1371. return _GetProp(pwnd, (LPWSTR)UIntToPtr( iString ), FALSE);
  1372. }
  1373. /***************************************************************************\
  1374. * RegisterClassW(API)
  1375. *
  1376. * History:
  1377. * 28-Jul-1992 ChandanC Created.
  1378. \***************************************************************************/
  1379. ATOM
  1380. WINAPI
  1381. TEXT_FN(RegisterClass)(
  1382. CONST WNDCLASS *lpWndClass )
  1383. {
  1384. WNDCLASSEX wc;
  1385. /*
  1386. * On 64-bit plaforms we'll have 32-bits of padding between style and
  1387. * lpfnWndProc in WNDCLASS, so start the copy from the first 64-bit
  1388. * aligned field and hand copy the rest.
  1389. */
  1390. RtlCopyMemory(&(wc.lpfnWndProc), &(lpWndClass->lpfnWndProc), sizeof(WNDCLASS) - FIELD_OFFSET(WNDCLASS, lpfnWndProc));
  1391. wc.style = lpWndClass->style;
  1392. wc.hIconSm = NULL;
  1393. wc.cbSize = sizeof(WNDCLASSEX);
  1394. return TEXT_FN(RegisterClassExWOW)(&wc, NULL, 0, CSF_VERSIONCLASS);
  1395. }
  1396. /***************************************************************************\
  1397. * RegisterClassExW(API)
  1398. *
  1399. * History:
  1400. * 28-Jul-1992 ChandanC Created.
  1401. \***************************************************************************/
  1402. ATOM
  1403. WINAPI
  1404. TEXT_FN(RegisterClassEx)(
  1405. CONST WNDCLASSEX *lpWndClass)
  1406. {
  1407. if (lpWndClass->cbSize != sizeof(WNDCLASSEX)) {
  1408. RIPERR1(ERROR_INVALID_PARAMETER,
  1409. RIP_WARNING,
  1410. "RegisterClassEx: cbsize is wrong %lX",
  1411. lpWndClass->cbSize);
  1412. return 0;
  1413. } else {
  1414. return TEXT_FN(RegisterClassExWOW)((LPWNDCLASSEX)lpWndClass,
  1415. NULL, 0, CSF_VERSIONCLASS);
  1416. }
  1417. }
  1418. /***************************************************************************\
  1419. * GetMenuItemInfoInternal
  1420. *
  1421. * History:
  1422. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  1423. \***************************************************************************/
  1424. BOOL TEXT_FN(GetMenuItemInfoInternal) (HMENU hMenu, UINT uID, BOOL fByPosition,
  1425. LPMENUITEMINFOW lpInfo)
  1426. {
  1427. PITEM pItem;
  1428. PMENU pMenu;
  1429. PMENU pMenuT;
  1430. pMenu = VALIDATEHMENU(hMenu);
  1431. if (pMenu == NULL) {
  1432. VALIDATIONFAIL(hMenu);
  1433. }
  1434. pMenuT = pMenu; // need to check the ORIGINAL menu if popup
  1435. pItem = MNLookUpItem(pMenu, uID, fByPosition, &pMenu);
  1436. if (pItem == NULL) {
  1437. /*
  1438. * Don't display a warning. The explorer makes a lot of calls
  1439. * that fail here.
  1440. * VALIDATIONFAIL(uID);
  1441. */
  1442. SetLastError(ERROR_MENU_ITEM_NOT_FOUND);
  1443. return FALSE;
  1444. }
  1445. if (lpInfo->fMask & MIIM_STATE) {
  1446. lpInfo->fState = pItem->fState & MFS_MASK;
  1447. }
  1448. if (lpInfo->fMask & MIIM_ID) {
  1449. lpInfo->wID = pItem->wID;
  1450. }
  1451. if ((lpInfo->fMask & MIIM_SUBMENU) && (pItem->spSubMenu != NULL)) {
  1452. lpInfo->hSubMenu = PtoH(REBASEPTR(pMenu, pItem->spSubMenu));
  1453. } else {
  1454. lpInfo->hSubMenu = NULL;
  1455. }
  1456. if (lpInfo->fMask & MIIM_CHECKMARKS) {
  1457. lpInfo->hbmpChecked = KHBITMAP_TO_HBITMAP(pItem->hbmpChecked);
  1458. lpInfo->hbmpUnchecked= KHBITMAP_TO_HBITMAP(pItem->hbmpUnchecked);
  1459. }
  1460. if (lpInfo->fMask & MIIM_DATA) {
  1461. lpInfo->dwItemData = KERNEL_ULONG_PTR_TO_ULONG_PTR(pItem->dwItemData);
  1462. }
  1463. if (lpInfo->fMask & MIIM_FTYPE) {
  1464. lpInfo->fType = pItem->fType & MFT_MASK;
  1465. if (TestMF(pMenuT,MFRTL))
  1466. lpInfo->fType |= MFT_RIGHTORDER;
  1467. }
  1468. if ( lpInfo->fMask & MIIM_BITMAP) {
  1469. lpInfo->hbmpItem = KHBITMAP_TO_HBITMAP(pItem->hbmp);
  1470. }
  1471. if (lpInfo->fMask & MIIM_STRING) {
  1472. if ((lpInfo->cch == 0)
  1473. || (lpInfo->dwTypeData == NULL)
  1474. /*
  1475. * If this is an old caller (MIIM_TYPE set), and this item
  1476. * has a bitmap or it's ownerdraw, then don't attempt to
  1477. * copy a string since they probably didn't pass a pointer
  1478. */
  1479. || ((lpInfo->fMask & MIIM_TYPE)
  1480. && ((lpInfo->fType & MFT_OWNERDRAW)
  1481. /*
  1482. * Bug 278750 - jojoe
  1483. *
  1484. * Soemone forgot to check for separator in the list
  1485. * of menuitems that do NOT return string data!
  1486. */
  1487. || (lpInfo->fType & MFT_SEPARATOR)
  1488. || ((pItem->hbmp != NULL) && ((pItem->hbmp < HBMMENU_POPUPFIRST) || (pItem->hbmp > HBMMENU_POPUPLAST)))))) {
  1489. /*
  1490. * When DBCS is enabled, one UNICODE character may occupy two bytes.
  1491. * GetMenuItemInfoA should return the byte count, rather than the character count.
  1492. * On NT5, pItem->lpstr is guaranteed to be a valid string, if it is not NULL.
  1493. */
  1494. if (IS_ANSI && IS_DBCS_ENABLED() && pItem->lpstr != NULL) {
  1495. NTSTATUS Status;
  1496. ULONG cch;
  1497. Status = RtlUnicodeToMultiByteSize(&cch, REBASEPTR(pMenu, pItem->lpstr), pItem->cch * sizeof(WCHAR));
  1498. UserAssert(NT_SUCCESS(Status)); // RtlUnicodeToMultiByteSize is not expected to fail
  1499. lpInfo->cch = cch;
  1500. } else {
  1501. lpInfo->cch = pItem->cch;
  1502. }
  1503. lpInfo->dwTypeData = NULL;
  1504. } else {
  1505. int cch = 0;
  1506. if (pItem->lpstr != NULL) {
  1507. // originally:
  1508. // cch = min(lpInfo->cch - 1, (pItem->cch * sizeof(WORD)));
  1509. cch = pItem->cch;
  1510. UserAssert(cch >= 0);
  1511. if (IS_DBCS_ENABLED()) {
  1512. /* pItem->cch contains Unicode character counts,
  1513. * we guess max DBCS string size for the Unicode string.
  1514. */
  1515. cch *= DBCS_CHARSIZE;
  1516. }
  1517. cch = min(lpInfo->cch - 1, (DWORD)cch);
  1518. #if IS_ANSI
  1519. cch = WCSToMB(REBASEPTR(pMenu, pItem->lpstr), pItem->cch,
  1520. (LPSTR *)&(lpInfo->dwTypeData), cch, FALSE);
  1521. #else
  1522. wcsncpy(lpInfo->dwTypeData, (LPWSTR)REBASEPTR(pMenu, pItem->lpstr),
  1523. cch);
  1524. #endif
  1525. }
  1526. #if IS_ANSI
  1527. *((LPSTR)lpInfo->dwTypeData + cch) = (CHAR)0;
  1528. #else
  1529. *(lpInfo->dwTypeData + cch) = (WCHAR)0;
  1530. #endif
  1531. lpInfo->cch = cch;
  1532. }
  1533. }
  1534. return TRUE;
  1535. VALIDATIONERROR(FALSE);
  1536. }
  1537. /***************************************************************************\
  1538. * GetMenuString()
  1539. *
  1540. * History:
  1541. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  1542. \***************************************************************************/
  1543. #ifdef UNICODE
  1544. FUNCLOG5(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetMenuStringW, HMENU, hMenu, UINT, wID, LPTSTR, lpsz, int, cchMax, UINT, flags)
  1545. #else
  1546. FUNCLOG5(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetMenuStringA, HMENU, hMenu, UINT, wID, LPTSTR, lpsz, int, cchMax, UINT, flags)
  1547. #endif // UNICODE
  1548. int GetMenuString(HMENU hMenu, UINT wID, LPTSTR lpsz, int cchMax, UINT flags)
  1549. {
  1550. MENUITEMINFOW miiLocal;
  1551. miiLocal.fMask = MIIM_STRING;
  1552. miiLocal.dwTypeData = (LPWSTR)lpsz;
  1553. miiLocal.cch = cchMax;
  1554. if (cchMax != 0) {
  1555. *lpsz = (TCHAR)0;
  1556. }
  1557. if (TEXT_FN(GetMenuItemInfoInternal)(hMenu, wID, (BOOL)(flags & MF_BYPOSITION), &miiLocal)) {
  1558. return miiLocal.cch;
  1559. } else {
  1560. return 0;
  1561. }
  1562. }
  1563. /***************************************************************************\
  1564. * GetMenuItemInfo
  1565. *
  1566. * 1) converts a MENUITEMINFO95 or a new-MENUITEMINFO-with-old-flags to a new
  1567. * MENUITEMINFO -- this way all internal code can assume one look for the
  1568. * structure
  1569. * 2) calls the internal GetMenuItemInfo which performs validation and work
  1570. * 3) converts the new MENUITEMINFO back to the original MENUITEMINFO
  1571. *
  1572. * History:
  1573. * 07-22-96 GerardoB - Fixed up for 5.0
  1574. \***************************************************************************/
  1575. #ifdef UNICODE
  1576. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetMenuItemInfoW, HMENU, hMenu, UINT, wID, BOOL, fByPos, LPMENUITEMINFO, lpmii)
  1577. #else
  1578. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetMenuItemInfoA, HMENU, hMenu, UINT, wID, BOOL, fByPos, LPMENUITEMINFO, lpmii)
  1579. #endif // UNICODE
  1580. BOOL GetMenuItemInfo(HMENU hMenu, UINT wID, BOOL fByPos, LPMENUITEMINFO lpmii)
  1581. {
  1582. UINT cbCallercbSize = lpmii->cbSize;
  1583. MENUITEMINFOW miiLocal;
  1584. if (!ValidateMENUITEMINFO((LPMENUITEMINFOW)lpmii, &miiLocal, MENUAPI_GET)) {
  1585. return FALSE;
  1586. }
  1587. if (!TEXT_FN(GetMenuItemInfoInternal)(hMenu, wID, fByPos, &miiLocal)) {
  1588. return FALSE;
  1589. }
  1590. /*
  1591. * Copy the structure and map old flags back. Only requested fields were
  1592. * modified, so it's OK to copy all fields back.
  1593. */
  1594. RtlCopyMemory(lpmii, &miiLocal, SIZEOFMENUITEMINFO95);
  1595. lpmii->cbSize = cbCallercbSize;
  1596. if (cbCallercbSize > SIZEOFMENUITEMINFO95) {
  1597. lpmii->hbmpItem = miiLocal.hbmpItem;
  1598. }
  1599. if (lpmii->fMask & MIIM_TYPE) {
  1600. if ((miiLocal.hbmpItem != NULL) && (miiLocal.dwTypeData == NULL)) {
  1601. lpmii->fType |= MFT_BITMAP;
  1602. lpmii->dwTypeData = (LPTSTR)miiLocal.hbmpItem;
  1603. } else if (miiLocal.cch == 0) {
  1604. lpmii->dwTypeData = NULL;
  1605. }
  1606. lpmii->fMask &= ~(MIIM_FTYPE | MIIM_BITMAP | MIIM_STRING);
  1607. }
  1608. return TRUE;
  1609. }
  1610. /***************************************************************************\
  1611. * SetMenuItemInfo
  1612. *
  1613. * History:
  1614. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  1615. \***************************************************************************/
  1616. #ifdef UNICODE
  1617. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetMenuItemInfoW, HMENU, hMenu, UINT, uID, BOOL, fByPosition, LPCMENUITEMINFO, lpmii)
  1618. #else
  1619. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetMenuItemInfoA, HMENU, hMenu, UINT, uID, BOOL, fByPosition, LPCMENUITEMINFO, lpmii)
  1620. #endif // UNICODE
  1621. BOOL SetMenuItemInfo(HMENU hMenu, UINT uID, BOOL fByPosition, LPCMENUITEMINFO lpmii)
  1622. {
  1623. MENUITEMINFOW miiLocal;
  1624. if (!ValidateMENUITEMINFO((LPMENUITEMINFOW)lpmii, &miiLocal, MENUAPI_SET)) {
  1625. return FALSE;
  1626. }
  1627. return (ThunkedMenuItemInfo(hMenu, uID, fByPosition, FALSE, &miiLocal, IS_ANSI));
  1628. }
  1629. /***************************************************************************\
  1630. * InsertMenuItem
  1631. *
  1632. * History:
  1633. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  1634. \***************************************************************************/
  1635. BOOL InsertMenuItem (HMENU hMenu, UINT uID, BOOL fByPosition, LPCMENUITEMINFO lpmii)
  1636. {
  1637. MENUITEMINFOW miiLocal;
  1638. if (!ValidateMENUITEMINFO((LPMENUITEMINFOW)lpmii, &miiLocal, MENUAPI_SET)) {
  1639. return FALSE;
  1640. }
  1641. return (ThunkedMenuItemInfo(hMenu, uID, fByPosition, TRUE, &miiLocal, IS_ANSI));
  1642. }
  1643. /***************************************************************************\
  1644. * InsertMenu
  1645. *
  1646. * History:
  1647. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  1648. \***************************************************************************/
  1649. #ifdef UNICODE
  1650. FUNCLOG5(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, InsertMenuW, HMENU, hMenu, UINT, uPosition, UINT, uFlags, UINT_PTR, uIDNewItem, LPCTSTR, lpNewItem)
  1651. #else
  1652. FUNCLOG5(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, InsertMenuA, HMENU, hMenu, UINT, uPosition, UINT, uFlags, UINT_PTR, uIDNewItem, LPCTSTR, lpNewItem)
  1653. #endif // UNICODE
  1654. BOOL InsertMenu(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR lpNewItem)
  1655. {
  1656. MENUITEMINFOW miiLocal;
  1657. SetMenuItemInfoStruct(hMenu, uFlags, uIDNewItem, (LPWSTR)lpNewItem, &miiLocal);
  1658. return ThunkedMenuItemInfo(hMenu, uPosition, (BOOL) (uFlags & MF_BYPOSITION), TRUE, (LPMENUITEMINFOW)&miiLocal, IS_ANSI);
  1659. }
  1660. /***************************************************************************\
  1661. * AppendMenu
  1662. *
  1663. * History:
  1664. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  1665. \***************************************************************************/
  1666. #ifdef UNICODE
  1667. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, AppendMenuW, HMENU, hMenu, UINT, uFlags, UINT_PTR, uIDNewItem, LPCTSTR, lpNewItem)
  1668. #else
  1669. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, AppendMenuA, HMENU, hMenu, UINT, uFlags, UINT_PTR, uIDNewItem, LPCTSTR, lpNewItem)
  1670. #endif // UNICODE
  1671. BOOL AppendMenu(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR lpNewItem)
  1672. {
  1673. MENUITEMINFOW miiLocal;
  1674. SetMenuItemInfoStruct(hMenu, uFlags, uIDNewItem, (LPWSTR)lpNewItem, &miiLocal);
  1675. return ThunkedMenuItemInfo(hMenu, MFMWFP_NOITEM, MF_BYPOSITION, TRUE, (LPMENUITEMINFOW)&miiLocal, IS_ANSI);
  1676. }
  1677. /***************************************************************************\
  1678. * ModifyMenu
  1679. *
  1680. * History:
  1681. * 07-22-96 GerardoB - Added header and Fixed up for 5.0
  1682. \***************************************************************************/
  1683. #ifdef UNICODE
  1684. FUNCLOG5(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, ModifyMenuW, HMENU, hMenu, UINT, uPosition, UINT, uFlags, UINT_PTR, uIDNewItem, LPCTSTR, lpNewItem)
  1685. #else
  1686. FUNCLOG5(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, ModifyMenuA, HMENU, hMenu, UINT, uPosition, UINT, uFlags, UINT_PTR, uIDNewItem, LPCTSTR, lpNewItem)
  1687. #endif // UNICODE
  1688. BOOL ModifyMenu(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR lpNewItem)
  1689. {
  1690. MENUITEMINFOW miiLocal;
  1691. SetMenuItemInfoStruct(hMenu, uFlags, uIDNewItem, (LPWSTR)lpNewItem, &miiLocal);
  1692. return ThunkedMenuItemInfo(hMenu, uPosition, (BOOL) (uFlags & MF_BYPOSITION), FALSE, (LPMENUITEMINFOW)&miiLocal, IS_ANSI);
  1693. }
  1694. #ifdef UNICODE
  1695. FUNCLOG6(LOG_GENERAL, LONG, WINUSERAPI, BroadcastSystemMessageExW, DWORD, dwFlags, LPDWORD, lpdwRecipients, UINT, uiMessage, WPARAM, wParam, LPARAM, lParam, PBSMINFO, pBSMInfo)
  1696. #else
  1697. FUNCLOG6(LOG_GENERAL, LONG, WINUSERAPI, BroadcastSystemMessageExA, DWORD, dwFlags, LPDWORD, lpdwRecipients, UINT, uiMessage, WPARAM, wParam, LPARAM, lParam, PBSMINFO, pBSMInfo)
  1698. #endif // UNICODE
  1699. /***************************************************************************\
  1700. * BroadcastSystemMessageEx
  1701. *
  1702. * History:
  1703. *
  1704. \***************************************************************************/
  1705. WINUSERAPI LONG BroadcastSystemMessageEx(
  1706. DWORD dwFlags,
  1707. LPDWORD lpdwRecipients,
  1708. UINT uiMessage,
  1709. WPARAM wParam,
  1710. LPARAM lParam,
  1711. PBSMINFO pBSMInfo)
  1712. {
  1713. return BroadcastSystemMessageWorker(dwFlags,
  1714. lpdwRecipients,
  1715. uiMessage,
  1716. wParam,
  1717. lParam,
  1718. pBSMInfo,
  1719. IS_ANSI);
  1720. }
  1721. #ifdef UNICODE
  1722. FUNCLOG5(LOG_GENERAL, LONG, WINUSERAPI, BroadcastSystemMessageW, DWORD, dwFlags, LPDWORD, lpdwRecipients, UINT, uiMessage, WPARAM, wParam, LPARAM, lParam)
  1723. #else
  1724. FUNCLOG5(LOG_GENERAL, LONG, WINUSERAPI, BroadcastSystemMessageA, DWORD, dwFlags, LPDWORD, lpdwRecipients, UINT, uiMessage, WPARAM, wParam, LPARAM, lParam)
  1725. #endif // UNICODE
  1726. /***************************************************************************\
  1727. * BroadcastSystemMessage
  1728. *
  1729. * History:
  1730. * 07-22-96 GerardoB - Added header
  1731. \***************************************************************************/
  1732. WINUSERAPI LONG BroadcastSystemMessage(
  1733. DWORD dwFlags,
  1734. LPDWORD lpdwRecipients,
  1735. UINT uiMessage,
  1736. WPARAM wParam,
  1737. LPARAM lParam)
  1738. {
  1739. return BroadcastSystemMessageWorker(dwFlags,
  1740. lpdwRecipients,
  1741. uiMessage,
  1742. wParam,
  1743. lParam,
  1744. NULL,
  1745. IS_ANSI);
  1746. }
  1747. #ifdef UNICODE
  1748. FUNCLOG3(LOG_GENERAL, UINT, WINUSERAPI, GetWindowModuleFileNameW, HWND, hwnd, LPTSTR, pszFileName, UINT, cchFileNameMax)
  1749. #else
  1750. FUNCLOG3(LOG_GENERAL, UINT, WINUSERAPI, GetWindowModuleFileNameA, HWND, hwnd, LPTSTR, pszFileName, UINT, cchFileNameMax)
  1751. #endif // UNICODE
  1752. WINUSERAPI UINT WINAPI
  1753. GetWindowModuleFileName(
  1754. HWND hwnd,
  1755. LPTSTR pszFileName,
  1756. UINT cchFileNameMax)
  1757. {
  1758. PWND pwnd;
  1759. pwnd = ValidateHwnd(hwnd);
  1760. if (pwnd == NULL) {
  1761. return 0;
  1762. }
  1763. return GetModuleFileName(KHANDLE_TO_HANDLE(pwnd->hModule),
  1764. pszFileName,
  1765. cchFileNameMax);
  1766. }
  1767. /***************************************************************************\
  1768. * RegisterDeviceNotification
  1769. *
  1770. * History:
  1771. * 01-23-97 PaulaT - Added header
  1772. \***************************************************************************/
  1773. WINUSERAPI HDEVNOTIFY WINAPI
  1774. RegisterDeviceNotification(
  1775. IN HANDLE hRecipient,
  1776. IN LPVOID NotificationFilter,
  1777. IN DWORD Flags)
  1778. {
  1779. extern HDEVNOTIFY RegisterDeviceNotificationWorker(IN HANDLE hRecipient,
  1780. IN LPVOID NotificationFilter,
  1781. IN DWORD Flags);
  1782. // translate strings in NotificationFilter (if any)
  1783. return RegisterDeviceNotificationWorker(hRecipient,
  1784. NotificationFilter,
  1785. Flags);
  1786. }
  1787. /***************************************************************************\
  1788. * GetMonitorInfo
  1789. *
  1790. * History:
  1791. * 31-Mar-1997 adams Doesn't call into kernel.
  1792. * 06-Jul-1998 MCostea Has to call into kernel #190510
  1793. \***************************************************************************/
  1794. #ifdef UNICODE
  1795. FUNCLOG2(LOG_GENERAL, BOOL, WINUSERAPI, GetMonitorInfoW, HMONITOR, hMonitor, LPMONITORINFO, lpmi)
  1796. #else
  1797. FUNCLOG2(LOG_GENERAL, BOOL, WINUSERAPI, GetMonitorInfoA, HMONITOR, hMonitor, LPMONITORINFO, lpmi)
  1798. #endif // UNICODE
  1799. BOOL WINUSERAPI
  1800. GetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
  1801. {
  1802. PMONITOR pMonitor;
  1803. BOOL bRetVal;
  1804. int cbSize;
  1805. pMonitor = VALIDATEHMONITOR(hMonitor);
  1806. if (!pMonitor) {
  1807. return FALSE;
  1808. }
  1809. cbSize = lpmi->cbSize;
  1810. if (cbSize == sizeof(MONITORINFO)) {
  1811. /*
  1812. * Check for this first, since it is the most
  1813. * common size. All the work for filling in
  1814. * MONITORINFO fields is done after the else-if
  1815. * statements.
  1816. */
  1817. } else if (cbSize == sizeof(MONITORINFOEX)) {
  1818. /*
  1819. * The ANSI version has to translate the szDevice field
  1820. */
  1821. ULONG_PTR pName;
  1822. #if IS_ANSI
  1823. WCHAR szDevice[CCHDEVICENAME];
  1824. pName = (ULONG_PTR)szDevice;
  1825. #else
  1826. pName = (ULONG_PTR)(((LPMONITORINFOEX)lpmi)->szDevice);
  1827. #endif
  1828. bRetVal = (BOOL)NtUserCallTwoParam((ULONG_PTR)(hMonitor),
  1829. pName,
  1830. SFI_GETHDEVNAME);
  1831. if (!bRetVal) {
  1832. return FALSE;
  1833. }
  1834. #if IS_ANSI
  1835. WideCharToMultiByte(
  1836. CP_ACP, 0, // ANSI -> Unicode
  1837. (LPWSTR)pName, -1, // source & length
  1838. (LPSTR)((LPMONITORINFOEX)lpmi)->szDevice, // destination & length
  1839. ARRAY_SIZE(((LPMONITORINFOEX)lpmi)->szDevice),
  1840. NULL, NULL);
  1841. #endif
  1842. } else {
  1843. RIPERR1(ERROR_INVALID_PARAMETER,
  1844. RIP_WARNING,
  1845. "Invalid lpmi->cbSize, %d", lpmi->cbSize);
  1846. return FALSE;
  1847. }
  1848. lpmi->dwFlags = (pMonitor == GetPrimaryMonitor()) ? MONITORINFOF_PRIMARY : 0;
  1849. lpmi->rcMonitor = pMonitor->rcMonitor;
  1850. lpmi->rcWork = pMonitor->rcWork;
  1851. return TRUE;
  1852. }
  1853. #ifdef GENERIC_INPUT
  1854. #ifdef UNICODE
  1855. FUNCLOG4(LOG_GENERAL, UINT, WINUSERAPI, GetRawInputDeviceInfoW, HANDLE, hDevice, UINT, uiCommand, LPVOID, pData, PUINT, pcbSize)
  1856. #else
  1857. FUNCLOG4(LOG_GENERAL, UINT, WINUSERAPI, GetRawInputDeviceInfoA, HANDLE, hDevice, UINT, uiCommand, LPVOID, pData, PUINT, pcbSize)
  1858. #endif // UNICODE
  1859. UINT WINUSERAPI
  1860. GetRawInputDeviceInfo(
  1861. HANDLE hDevice,
  1862. UINT uiCommand,
  1863. LPVOID pData,
  1864. PUINT pcbSize)
  1865. {
  1866. #if IS_ANSI
  1867. UINT uiRet;
  1868. LPVOID lpParam = pData;
  1869. WCHAR wszPath[MAX_PATH];
  1870. UINT cbBufferSize = 0;
  1871. if (uiCommand == RIDI_DEVICENAME) {
  1872. if (pData) {
  1873. lpParam = wszPath;
  1874. cbBufferSize = *pcbSize;
  1875. }
  1876. }
  1877. uiRet = NtUserGetRawInputDeviceInfo(hDevice, uiCommand, lpParam, pcbSize);
  1878. if (uiCommand == RIDI_DEVICENAME) {
  1879. if (uiRet == (UINT)-1 && pData != NULL) {
  1880. /* Insufficient buffer */
  1881. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  1882. *pcbSize *= DBCS_CHARSIZE;
  1883. }
  1884. } else if (uiRet == 0 && pData == NULL) {
  1885. /* The app wants the buffer size for the device name */
  1886. *pcbSize *= DBCS_CHARSIZE;
  1887. } else {
  1888. uiRet = WCSToMB(lpParam, uiRet, (LPSTR*)&pData, cbBufferSize, FALSE);
  1889. /* TODO:
  1890. * Handle the case if cbBufferSize was not enough.
  1891. */
  1892. }
  1893. }
  1894. return uiRet;
  1895. #else
  1896. return NtUserGetRawInputDeviceInfo(hDevice, uiCommand, pData, pcbSize);
  1897. #endif
  1898. }
  1899. #endif