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.

1781 lines
51 KiB

  1. /***************************** Module Header ******************************\
  2. * Module Name: ntcftxt.h
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Kernel call forward stubs with text arguments
  7. *
  8. * Each function will be created with two flavors Ansi and Unicode
  9. *
  10. * 06-Jan-1992 IanJa Moved from cf.h
  11. * 18-Mar-1995 JimA Ported from cftxt.h
  12. \**************************************************************************/
  13. #ifdef UNICODE
  14. #define IS_ANSI FALSE
  15. #ifndef _UNICODE
  16. #define _UNICODE
  17. #endif
  18. #else
  19. #define IS_ANSI TRUE
  20. #undef _UNICODE
  21. #endif
  22. #include <tchar.h>
  23. #include "ntsend.h"
  24. HWND TEXT_FN(InternalFindWindowEx)(
  25. HWND hwndParent,
  26. HWND hwndChild,
  27. LPCTSTR pClassName,
  28. LPCTSTR pWindowName,
  29. DWORD dwFlag)
  30. {
  31. IN_STRING strClass;
  32. IN_STRING strWindow;
  33. /*
  34. * Make sure cleanup will work successfully
  35. */
  36. strClass.fAllocated = FALSE;
  37. strWindow.fAllocated = FALSE;
  38. BEGINCALL()
  39. FIRSTCOPYLPTSTRIDOPT(&strClass, pClassName);
  40. COPYLPTSTROPT(&strWindow, pWindowName);
  41. retval = (ULONG_PTR)NtUserFindWindowEx(
  42. hwndParent,
  43. hwndChild,
  44. strClass.pstr,
  45. strWindow.pstr,
  46. dwFlag);
  47. ERRORTRAP(0);
  48. CLEANUPLPTSTR(strClass);
  49. CLEANUPLPTSTR(strWindow);
  50. ENDCALL(HWND);
  51. }
  52. #ifdef UNICODE
  53. FUNCLOG4(LOG_GENERAL, HWND, WINUSERAPI, FindWindowExW, HWND, hwndParent, HWND, hwndChild, LPCTSTR, pClassName, LPCTSTR, pWindowName)
  54. #else
  55. FUNCLOG4(LOG_GENERAL, HWND, WINUSERAPI, FindWindowExA, HWND, hwndParent, HWND, hwndChild, LPCTSTR, pClassName, LPCTSTR, pWindowName)
  56. #endif // UNICODE
  57. HWND FindWindowEx(
  58. HWND hwndParent,
  59. HWND hwndChild,
  60. LPCTSTR pClassName,
  61. LPCTSTR pWindowName)
  62. {
  63. return TEXT_FN(InternalFindWindowEx)(hwndParent, hwndChild, pClassName, pWindowName, FW_BOTH);
  64. }
  65. #ifdef UNICODE
  66. FUNCLOG2(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, FindWindowW, LPCTSTR, pClassName, LPCTSTR, pWindowName)
  67. #else
  68. FUNCLOG2(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, FindWindowA, LPCTSTR, pClassName, LPCTSTR, pWindowName)
  69. #endif // UNICODE
  70. HWND FindWindow(
  71. LPCTSTR pClassName,
  72. LPCTSTR pWindowName)
  73. {
  74. return TEXT_FN(InternalFindWindowEx)(NULL, NULL, pClassName, pWindowName, FW_BOTH);
  75. }
  76. BOOL GetClassInfoEx(
  77. HINSTANCE hmod,
  78. LPCTSTR pszClassName,
  79. LPWNDCLASSEX pwc)
  80. {
  81. IN_STRING strClassName;
  82. LPWSTR pszMenuName;
  83. DWORD Error;
  84. HMODULE hDllMod = NULL;
  85. #ifdef LAZY_CLASS_INIT
  86. LazyInitClasses();
  87. #endif
  88. /*
  89. * Make sure cleanup will work successfully.
  90. */
  91. strClassName.fAllocated = FALSE;
  92. BEGINCALL_CLASSV()
  93. FIRSTCOPYLPTSTRID(&strClassName, lpClassNameVer);
  94. TryAgain:
  95. retval = (DWORD)NtUserGetClassInfoEx(hmod,
  96. strClassName.pstr,
  97. (LPWNDCLASSEXW)pwc,
  98. &pszMenuName,
  99. IS_ANSI);
  100. /*
  101. * If we failed to find the class specified, let's register it and
  102. * try again.
  103. */
  104. if (!retval &&
  105. !bRegistered &&
  106. lpDllName != NULL &&
  107. ((Error = NtCurrentTeb()->LastErrorValue) == ERROR_CANNOT_FIND_WND_CLASS
  108. || Error == ERROR_CLASS_DOES_NOT_EXIST)) {
  109. IN_STRING strClassNameNoVer;
  110. FIRSTCOPYLPTSTRID(&strClassNameNoVer, pszClassName);
  111. bRegistered = VersionRegisterClass(strClassNameNoVer.pstr->Buffer, lpDllName, lpActivationContext, &hDllMod);
  112. CLEANUPLPTSTR(strClassNameNoVer);
  113. if (bRegistered) {
  114. goto TryAgain;
  115. }
  116. }
  117. if (!retval && hDllMod != NULL) {
  118. FREE_LIBRARY_SAVE_ERROR(hDllMod);
  119. hDllMod = NULL;
  120. }
  121. if (lpActivationContext != NULL) {
  122. RtlReleaseActivationContext(lpActivationContext);
  123. lpActivationContext = NULL;
  124. }
  125. if (retval) {
  126. /*
  127. * Update these pointers so they point to something real.
  128. * pszMenuName is actually just the pointer the app originally
  129. * passed to us.
  130. */
  131. pwc->lpszMenuName = (LPTSTR)pszMenuName;
  132. pwc->lpszClassName = pszClassName;
  133. }
  134. ERRORTRAP(0);
  135. CLEANUPLPTSTR(strClassName);
  136. ENDCALL(BOOL);
  137. }
  138. BOOL GetClassInfo(
  139. HINSTANCE hmod,
  140. LPCTSTR pszClassName,
  141. LPWNDCLASS pwc)
  142. {
  143. WNDCLASSEX WndClass;
  144. BOOL retval;
  145. retval = GetClassInfoEx(hmod, pszClassName, &WndClass);
  146. if (retval) {
  147. /*
  148. * Move the info from the WNDCLASSEX to the WNDCLASS structure. On
  149. * 64-bit plaforms we'll have 32 bits of padding between style and
  150. * lpfnWndProc in WNDCLASS, so start the copy from the first 64-bit
  151. * aligned field and hand copy the rest.
  152. */
  153. RtlCopyMemory(&(pwc->lpfnWndProc),
  154. &(WndClass.lpfnWndProc),
  155. sizeof(WNDCLASS) - FIELD_OFFSET(WNDCLASS, lpfnWndProc));
  156. pwc->style = WndClass.style;
  157. }
  158. return retval;
  159. }
  160. #ifdef UNICODE
  161. FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetClipboardFormatNameW, UINT, wFormat, LPTSTR, pFormatName, int, chMaxCount)
  162. #else
  163. FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetClipboardFormatNameA, UINT, wFormat, LPTSTR, pFormatName, int, chMaxCount)
  164. #endif // UNICODE
  165. int GetClipboardFormatName(
  166. UINT wFormat,
  167. LPTSTR pFormatName,
  168. int chMaxCount)
  169. {
  170. LPWSTR lpszReserve;
  171. BEGINCALL()
  172. #ifdef UNICODE
  173. lpszReserve = pFormatName;
  174. #else
  175. lpszReserve = UserLocalAlloc(0, chMaxCount * sizeof(WCHAR));
  176. if (!lpszReserve) {
  177. return 0;
  178. }
  179. #endif
  180. retval = (DWORD)NtUserGetClipboardFormatName(wFormat,
  181. lpszReserve,
  182. chMaxCount);
  183. #ifndef UNICODE
  184. if (retval) {
  185. /*
  186. * Do not copy out more than the requested byte count 'chMaxCount'.
  187. * Set retval to reflect the number of ANSI bytes.
  188. */
  189. retval = WCSToMB(lpszReserve,
  190. (UINT)retval,
  191. &pFormatName,
  192. chMaxCount - 1,
  193. FALSE);
  194. pFormatName[retval] = '\0';
  195. }
  196. UserLocalFree(lpszReserve);
  197. #endif
  198. ERRORTRAP(0);
  199. ENDCALL(int);
  200. }
  201. #ifdef UNICODE
  202. FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetKeyNameTextW, LONG, lParam, LPTSTR, pString, int, cchSize)
  203. #else
  204. FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetKeyNameTextA, LONG, lParam, LPTSTR, pString, int, cchSize)
  205. #endif // UNICODE
  206. int GetKeyNameText(
  207. LONG lParam,
  208. LPTSTR pString,
  209. int cchSize)
  210. {
  211. LPWSTR lpszReserve;
  212. BEGINCALL()
  213. #ifdef UNICODE
  214. lpszReserve = pString;
  215. #else
  216. lpszReserve = UserLocalAlloc(0, cchSize * sizeof(WCHAR));
  217. if (!lpszReserve) {
  218. return 0;
  219. }
  220. #endif
  221. retval = (DWORD)NtUserGetKeyNameText(
  222. lParam,
  223. lpszReserve,
  224. cchSize);
  225. #ifndef UNICODE
  226. if (retval) {
  227. /*
  228. * Do not copy out more than the requested byte count 'nSize'.
  229. * Set retval to reflect the number of ANSI bytes.
  230. */
  231. retval = WCSToMB(lpszReserve,
  232. (UINT)retval,
  233. &pString,
  234. cchSize - 1,
  235. FALSE);
  236. }
  237. UserLocalFree(lpszReserve);
  238. ((LPSTR)pString)[retval] = '\0';
  239. #endif
  240. ERRORTRAP(0);
  241. ENDCALL(int);
  242. }
  243. #ifdef UNICODE
  244. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, GetMessageW, LPMSG, pmsg, HWND, hwnd, UINT, wMsgFilterMin, UINT, wMsgFilterMax)
  245. #else
  246. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, GetMessageA, LPMSG, pmsg, HWND, hwnd, UINT, wMsgFilterMin, UINT, wMsgFilterMax)
  247. #endif // UNICODE
  248. BOOL APIENTRY GetMessage(
  249. LPMSG pmsg,
  250. HWND hwnd,
  251. UINT wMsgFilterMin,
  252. UINT wMsgFilterMax)
  253. {
  254. BEGINCALL()
  255. /*
  256. * Prevent apps from setting hi 16 bits so we can use them internally.
  257. */
  258. if ((wMsgFilterMin | wMsgFilterMax) & RESERVED_MSG_BITS) {
  259. /*
  260. * Backward compatability with Win9x where someone is setting
  261. * wMsgFilterMax to -1 to get all the messages.
  262. */
  263. if (wMsgFilterMax == (UINT)-1 && !(wMsgFilterMin & RESERVED_MSG_BITS)) {
  264. wMsgFilterMax = 0;
  265. } else {
  266. MSGERRORCODE(ERROR_INVALID_PARAMETER);
  267. }
  268. }
  269. #ifndef UNICODE
  270. /*
  271. * If we have pushed message for DBCS messaging, we should pass this one
  272. * to Apps at first...
  273. */
  274. GET_DBCS_MESSAGE_IF_EXIST(GetMessage, pmsg, wMsgFilterMin, wMsgFilterMax, TRUE);
  275. #endif
  276. retval = (DWORD)NtUserGetMessage(
  277. pmsg,
  278. hwnd,
  279. wMsgFilterMin,
  280. wMsgFilterMax);
  281. #ifndef UNICODE
  282. // May have a bit more work to do if this MSG is for an ANSI app
  283. // !!! LATER if the unichar translates into multiple ANSI chars
  284. // !!! then what??? Divide into two messages?? WM_SYSDEADCHAR??
  285. if (RtlWCSMessageWParamCharToMB(pmsg->message, &(pmsg->wParam))) {
  286. WPARAM dwAnsi = pmsg->wParam;
  287. /*
  288. * Build DBCS-ware wParam. (for EM_SETPASSWORDCHAR...)
  289. */
  290. BUILD_DBCS_MESSAGE_TO_CLIENTA_FROM_SERVER(pmsg, dwAnsi, TRUE, TRUE);
  291. } else {
  292. retval = 0;
  293. }
  294. ExitGetMessage:
  295. #else
  296. /*
  297. * Only LOWORD of WPARAM is valid for WM_CHAR (Unicode)....
  298. * (Mask off DBCS messaging information.)
  299. */
  300. BUILD_DBCS_MESSAGE_TO_CLIENTW_FROM_SERVER(pmsg->message,pmsg->wParam);
  301. #endif // UNICODE
  302. #if DBG && defined(GENERIC_INPUT)
  303. // TEST PURPOSE ONLY
  304. if (pmsg->message == WM_INPUT) {
  305. TAGMSG3(DBGTAG_PNP, "GetMessage: WM_INPUT, hwnd=%p, wp=%04x, lp=%08x", pmsg->hwnd, pmsg->wParam, pmsg->lParam);
  306. }
  307. #endif // GENERIC_INPUT
  308. ERRORTRAP(0);
  309. ENDCALL(BOOL);
  310. }
  311. #ifdef UNICODE
  312. FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetKeyboardLayoutNameW, LPTSTR, pwszKL)
  313. #else
  314. FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetKeyboardLayoutNameA, LPTSTR, pwszKL)
  315. #endif // UNICODE
  316. BOOL GetKeyboardLayoutName(
  317. LPTSTR pwszKL)
  318. {
  319. #ifdef UNICODE
  320. UNICODE_STRING str;
  321. PUNICODE_STRING pstr = &str;
  322. #else
  323. PUNICODE_STRING pstr = &NtCurrentTeb()->StaticUnicodeString;
  324. #endif
  325. BEGINCALL()
  326. #ifdef UNICODE
  327. str.MaximumLength = KL_NAMELENGTH * sizeof(WCHAR);
  328. str.Buffer = pwszKL;
  329. #endif
  330. retval = (DWORD)NtUserGetKeyboardLayoutName(pstr);
  331. #ifndef UNICODE
  332. if (retval) {
  333. /*
  334. * Non-zero retval means some text to copy out. Do not copy out
  335. * more than the requested byte count 'chMaxCount'.
  336. */
  337. WCSToMB(pstr->Buffer, -1, &pwszKL, KL_NAMELENGTH, FALSE);
  338. }
  339. #endif
  340. ERRORTRAP(0);
  341. ENDCALL(BOOL);
  342. }
  343. #ifdef UNICODE
  344. FUNCLOG2(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyW, UINT, wCode, UINT, wMapType)
  345. #else
  346. FUNCLOG2(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyA, UINT, wCode, UINT, wMapType)
  347. #endif // UNICODE
  348. UINT MapVirtualKey(
  349. UINT wCode,
  350. UINT wMapType)
  351. {
  352. BEGINCALL()
  353. retval = (DWORD)NtUserMapVirtualKeyEx(
  354. wCode,
  355. wMapType,
  356. 0,
  357. FALSE);
  358. #ifndef UNICODE
  359. if ((wMapType == 2) && (retval != 0)) {
  360. WCHAR wch = LOWORD(retval);
  361. retval &= ~0xFFFF;
  362. RtlUnicodeToMultiByteN((LPSTR)&(retval), sizeof(CHAR),
  363. NULL, &wch, sizeof(WCHAR));
  364. }
  365. #endif
  366. ERRORTRAP(0);
  367. ENDCALL(UINT);
  368. }
  369. /**************************************************************************\
  370. * MapVirtualKeyEx
  371. *
  372. * 21-Feb-1995 GregoryW Created
  373. \**************************************************************************/
  374. #ifndef UNICODE
  375. static HKL hMVKCachedHKL = 0;
  376. static UINT uMVKCachedCP = 0;
  377. #endif
  378. #ifdef UNICODE
  379. FUNCLOG3(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyExW, UINT, wCode, UINT, wMapType, HKL, hkl)
  380. #else
  381. FUNCLOG3(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyExA, UINT, wCode, UINT, wMapType, HKL, hkl)
  382. #endif // UNICODE
  383. UINT MapVirtualKeyEx(
  384. UINT wCode,
  385. UINT wMapType,
  386. HKL hkl)
  387. {
  388. BEGINCALL()
  389. retval = (DWORD)NtUserMapVirtualKeyEx(
  390. wCode,
  391. wMapType,
  392. (ULONG_PTR)hkl,
  393. TRUE);
  394. #ifndef UNICODE
  395. if ((wMapType == 2) && (retval != 0)) {
  396. WCHAR wch = LOWORD(retval);
  397. if (hkl != hMVKCachedHKL) {
  398. DWORD dwCodePage;
  399. if (!GetLocaleInfoW(
  400. HandleToUlong(hkl) & 0xffff,
  401. LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
  402. (LPWSTR)&dwCodePage,
  403. sizeof(dwCodePage) / sizeof(WCHAR)
  404. )) {
  405. MSGERROR();
  406. }
  407. uMVKCachedCP = dwCodePage;
  408. hMVKCachedHKL = hkl;
  409. }
  410. /*
  411. * Clear low word which contains Unicode character returned from server.
  412. * This preserves the high word which is used to indicate dead key status.
  413. */
  414. retval = retval & 0xffff0000;
  415. if (!WideCharToMultiByte(
  416. uMVKCachedCP,
  417. 0,
  418. &wch,
  419. 1,
  420. (LPSTR)&(retval),
  421. 1,
  422. NULL,
  423. NULL)) {
  424. MSGERROR();
  425. }
  426. }
  427. #endif
  428. ERRORTRAP(0);
  429. ENDCALL(UINT);
  430. }
  431. #ifdef UNICODE
  432. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostMessageW , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
  433. #else
  434. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostMessageA , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
  435. #endif // UNICODE
  436. BOOL APIENTRY PostMessage(
  437. HWND hwnd,
  438. UINT wMsg,
  439. WPARAM wParam,
  440. LPARAM lParam)
  441. {
  442. BEGINCALL()
  443. switch (wMsg) {
  444. case WM_DROPFILES:
  445. if (GetWindowProcess(hwnd) != GETPROCESSID()) {
  446. /*
  447. * We first send a WM_COPYGLOBALDATA message to get the data into the proper
  448. * context.
  449. */
  450. HGLOBAL hg;
  451. hg = (HGLOBAL)SendMessage(hwnd, WM_COPYGLOBALDATA,
  452. GlobalSize((HGLOBAL)wParam), wParam);
  453. if (!hg) {
  454. MSGERROR();
  455. }
  456. wParam = (WPARAM)hg;
  457. }
  458. break;
  459. case LB_DIR:
  460. case CB_DIR:
  461. /*
  462. * Make sure this bit is set so the client side string gets
  463. * successfully copied over.
  464. */
  465. wParam |= DDL_POSTMSGS;
  466. break;
  467. }
  468. #ifndef UNICODE
  469. /*
  470. * Setup DBCS Messaging for WM_CHAR...
  471. */
  472. BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(wMsg,wParam,TRUE);
  473. RtlMBMessageWParamCharToWCS(wMsg, &wParam);
  474. #endif
  475. retval = (DWORD)NtUserPostMessage(
  476. hwnd,
  477. wMsg,
  478. wParam,
  479. lParam);
  480. ERRORTRAP(0);
  481. ENDCALL(BOOL);
  482. }
  483. #ifdef UNICODE
  484. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostThreadMessageW, DWORD, idThread, UINT, msg, WPARAM, wParam, LPARAM, lParam)
  485. #else
  486. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostThreadMessageA, DWORD, idThread, UINT, msg, WPARAM, wParam, LPARAM, lParam)
  487. #endif // UNICODE
  488. BOOL APIENTRY PostThreadMessage(
  489. DWORD idThread,
  490. UINT msg,
  491. WPARAM wParam,
  492. LPARAM lParam)
  493. {
  494. BEGINCALL()
  495. #ifndef UNICODE
  496. #ifdef FE_SB // PostThreadMessage()
  497. /*
  498. * The server always expects the characters to be unicode so
  499. * if this was generated from an ANSI routine convert it to Unicode
  500. */
  501. BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(msg,wParam,TRUE);
  502. #endif // FE_SB
  503. RtlMBMessageWParamCharToWCS(msg, &wParam);
  504. #endif
  505. retval = (DWORD)NtUserPostThreadMessage(
  506. idThread,
  507. msg,
  508. wParam,
  509. lParam);
  510. ERRORTRAP(0);
  511. ENDCALL(BOOL);
  512. }
  513. /**************************************************************************\
  514. * StringDuplicate
  515. *
  516. * 03-25-96 GerardoB Added Header.
  517. \**************************************************************************/
  518. #define StringDuplicate TEXT_FN(StringDuplicate)
  519. LPTSTR StringDuplicate(LPCTSTR ptszDup) {
  520. LPTSTR ptsz;
  521. ULONG cb;
  522. cb = (_tcslen(ptszDup) + 1) * sizeof(TCHAR);
  523. ptsz = UserLocalAlloc(0, cb);
  524. if (ptsz != NULL) {
  525. RtlCopyMemory(ptsz, ptszDup, cb);
  526. }
  527. return ptsz;
  528. }
  529. /**************************************************************************\
  530. * InitClsMenuName
  531. *
  532. * 03-22-96 GerardoB Created.
  533. \**************************************************************************/
  534. #define InitClsMenuName TEXT_FN(InitClsMenuName)
  535. BOOL InitClsMenuName (PCLSMENUNAME pcmn, LPCTSTR lpszMenuName, PIN_STRING pstrMenuName)
  536. {
  537. /*
  538. * We check the high-word because this may be a resource-ID.
  539. */
  540. if (IS_PTR(lpszMenuName)) {
  541. #ifdef UNICODE
  542. if ((pcmn->pwszClientUnicodeMenuName = StringDuplicate(lpszMenuName)) == NULL) {
  543. return FALSE;
  544. }
  545. if (!WCSToMB(lpszMenuName, -1, &(pcmn->pszClientAnsiMenuName), -1, TRUE)) {
  546. pcmn->pszClientAnsiMenuName = NULL;
  547. }
  548. #else
  549. if ((pcmn->pszClientAnsiMenuName = StringDuplicate(lpszMenuName)) == NULL) {
  550. return FALSE;
  551. }
  552. if (!MBToWCS(lpszMenuName, -1, &(pcmn->pwszClientUnicodeMenuName), -1, TRUE)) {
  553. pcmn->pwszClientUnicodeMenuName = NULL;
  554. }
  555. #endif // UNICODE
  556. } else {
  557. /* Copy the ID */
  558. pcmn->pszClientAnsiMenuName = (LPSTR)lpszMenuName;
  559. pcmn->pwszClientUnicodeMenuName = (LPWSTR)lpszMenuName;
  560. }
  561. COPYLPTSTRID(pstrMenuName, lpszMenuName);
  562. pcmn->pusMenuName = pstrMenuName->pstr;
  563. return TRUE;
  564. goto errorexit; /* Keep the compiler happy */
  565. errorexit: /* Used by COPYLPTSTRID */
  566. #ifdef UNICODE
  567. UserLocalFree(pcmn->pwszClientUnicodeMenuName);
  568. pcmn->pwszClientUnicodeMenuName = NULL;
  569. #else
  570. UserLocalFree(pcmn->pszClientAnsiMenuName);
  571. pcmn->pszClientAnsiMenuName = NULL;
  572. #endif
  573. return FALSE;
  574. }
  575. /**************************************************************************\
  576. * SetClassLong
  577. *
  578. * 03-22-96 GerardoB Moved from client\cltxt.h & client\ntstubs.c
  579. \**************************************************************************/
  580. #ifdef UNICODE
  581. FUNCLOG3(LOG_GENERAL, ULONG_PTR, APIENTRY, SetClassLongPtrW, HWND, hwnd, int, nIndex, LONG_PTR, dwNewLong)
  582. #else
  583. FUNCLOG3(LOG_GENERAL, ULONG_PTR, APIENTRY, SetClassLongPtrA, HWND, hwnd, int, nIndex, LONG_PTR, dwNewLong)
  584. #endif // UNICODE
  585. ULONG_PTR APIENTRY SetClassLongPtr(HWND hwnd, int nIndex, LONG_PTR dwNewLong)
  586. {
  587. CLSMENUNAME cmn;
  588. IN_STRING strMenuName;
  589. switch (nIndex) {
  590. case GCLP_MENUNAME:
  591. if (!InitClsMenuName(&cmn, (LPCTSTR) dwNewLong, &strMenuName)) {
  592. RIPERR0(ERROR_INVALID_HANDLE, RIP_WARNING, "SetClassLong: InitClsMenuName failed");
  593. return 0;
  594. }
  595. dwNewLong = (ULONG_PTR) &cmn;
  596. break;
  597. case GCLP_HBRBACKGROUND:
  598. if ((DWORD)dwNewLong > COLOR_ENDCOLORS) {
  599. /*
  600. * Let gdi validate the brush. If it's invalid, then gdi
  601. * will log a warning. No need to rip twice so we'll just
  602. * set the last error.
  603. */
  604. if (GdiValidateHandle((HBRUSH)dwNewLong) == FALSE) {
  605. RIPERR0(ERROR_INVALID_HANDLE, RIP_VERBOSE, "");
  606. return 0;
  607. }
  608. }
  609. break;
  610. }
  611. BEGINCALL()
  612. retval = (ULONG_PTR)NtUserSetClassLongPtr(hwnd, nIndex, dwNewLong, IS_ANSI);
  613. ERRORTRAP(0);
  614. /* Clean up */
  615. switch (nIndex) {
  616. case GCLP_MENUNAME:
  617. CLEANUPLPTSTR(strMenuName); /* Initialized by InitClsMenuName */
  618. /*
  619. * We free either the old strings (returned by the kernel),
  620. * or the new ones if the kernel call failed
  621. */
  622. if (IS_PTR(cmn.pszClientAnsiMenuName)) {
  623. UserLocalFree(KPVOID_TO_PVOID(cmn.pszClientAnsiMenuName));
  624. }
  625. if (IS_PTR(cmn.pwszClientUnicodeMenuName)) {
  626. UserLocalFree(KPVOID_TO_PVOID(cmn.pwszClientUnicodeMenuName));
  627. }
  628. break;
  629. }
  630. ENDCALL(ULONG_PTR);
  631. }
  632. #ifdef _WIN64
  633. DWORD APIENTRY SetClassLong(HWND hwnd, int nIndex, LONG dwNewLong)
  634. {
  635. BEGINCALL()
  636. retval = (DWORD)NtUserSetClassLong(hwnd, nIndex, dwNewLong, IS_ANSI);
  637. ERRORTRAP(0);
  638. ENDCALL(DWORD);
  639. }
  640. #endif
  641. /**************************************************************************\
  642. * RegisterClassExWOW
  643. *
  644. * 03-22-96 GerardoB Added Header
  645. \**************************************************************************/
  646. ATOM TEXT_FN(RegisterClassExWOW)(
  647. WNDCLASSEX *lpWndClass,
  648. LPDWORD pdwWOWstuff,
  649. WORD fnid,
  650. DWORD dwFlags)
  651. {
  652. WNDCLASSEX WndClass;
  653. IN_STRING strClassName;
  654. IN_STRING strClassNameVer;
  655. IN_STRING strMenuName;
  656. DWORD dwExpWinVer;
  657. CLSMENUNAME cmn;
  658. TCHAR ClassNameVer[MAX_ATOM_LEN];
  659. LPTSTR lpClassNameVer;
  660. PACTIVATION_CONTEXT lpActivationContext = NULL;
  661. #ifdef LAZY_CLASS_INIT
  662. LazyInitClasses();
  663. #endif
  664. strClassName.fAllocated = 0;
  665. strClassNameVer.fAllocated = 0;
  666. strMenuName.fAllocated = 0;
  667. /*
  668. * Skip validation for our classes
  669. */
  670. if (fnid != 0) {
  671. /*
  672. * This is a hack to bypass validation for DDE classes
  673. * specifically, allow them to use hmodUser.
  674. */
  675. if (fnid == FNID_DDE_BIT) {
  676. fnid = 0;
  677. }
  678. dwExpWinVer = VER40;
  679. } else {
  680. if (lpWndClass->cbSize != sizeof(WNDCLASSEX)) {
  681. RIPMSG0(RIP_WARNING, "RegisterClass: Invalid cbSize");
  682. }
  683. if (lpWndClass->cbClsExtra < 0 || lpWndClass->cbWndExtra < 0) {
  684. RIPMSG0(RIP_WARNING, "RegisterClass: invalid cb*Extra");
  685. goto BadParameter;
  686. }
  687. /*
  688. * Validate hInstance
  689. * Don't allow 4.0 apps to use hmodUser
  690. */
  691. if ((lpWndClass->hInstance == hmodUser)
  692. && (GetClientInfo()->dwExpWinVer >= VER40)) {
  693. RIPMSG0(RIP_WARNING, "RegisterClass: Cannot use USER's hInstance");
  694. goto BadParameter;
  695. } else if (lpWndClass->hInstance == NULL) {
  696. /*
  697. * For 32 bit apps we need to fix up the hInstance because Win 95 does
  698. * this in their thunk MapHInstLS
  699. */
  700. lpWndClass->hInstance = GetModuleHandle(NULL);
  701. RIPMSG1(RIP_VERBOSE, "RegisterClass: fixing up NULL hmodule to %#p",
  702. lpWndClass->hInstance);
  703. }
  704. dwExpWinVer = GETEXPWINVER(lpWndClass->hInstance);
  705. /*
  706. * Check for valid style bits and strip if appropriate
  707. */
  708. if (lpWndClass->style & ~CS_VALID40) {
  709. if (dwExpWinVer > VER31) {
  710. RIPMSG0(RIP_WARNING, "RegisterClass: Invalid class style");
  711. goto BadParameter;
  712. }
  713. /*
  714. * Old application - strip bogus bits and pass through
  715. */
  716. RIPMSG0(RIP_WARNING, "RegisterClass: Invalid class style, stripping bad styles");
  717. lpWndClass->style &= CS_VALID40;
  718. }
  719. /*
  720. * Validate hbrBackground
  721. */
  722. if (lpWndClass->hbrBackground > (HBRUSH)COLOR_MAX
  723. && !GdiValidateHandle(lpWndClass->hbrBackground)) {
  724. RIPMSG1(RIP_WARNING, "RegisterClass: Invalid class brush:%#p", lpWndClass->hbrBackground);
  725. if (dwExpWinVer > VER30) {
  726. goto BadParameter;
  727. }
  728. lpWndClass->hbrBackground = NULL;
  729. }
  730. }
  731. if (!InitClsMenuName(&cmn, lpWndClass->lpszMenuName, &strMenuName)) {
  732. return FALSE;
  733. }
  734. BEGINCALL()
  735. WndClass = *lpWndClass;
  736. #ifndef UNICODE
  737. dwFlags |= CSF_ANSIPROC;
  738. #endif // UNICODE
  739. if (dwExpWinVer > VER31) {
  740. dwFlags |= CSF_WIN40COMPAT;
  741. }
  742. if (GetClientInfo()->dwTIFlags & TIF_16BIT) {
  743. /*
  744. * No Fusion redirection for 16BIT apps.
  745. */
  746. if (!(GetAppCompatFlags2(VERMAX) & GACF2_FORCEFUSION)) {
  747. dwFlags &= ~CW_FLAGS_VERSIONCLASS;
  748. }
  749. }
  750. if (dwFlags & CSF_VERSIONCLASS) {
  751. lpClassNameVer = (LPTSTR)ClassNameToVersion((LPCWSTR)lpWndClass->lpszClassName, (LPWSTR)ClassNameVer, NULL, NULL, IS_ANSI);
  752. if (lpClassNameVer == NULL) {
  753. RIPMSG0(RIP_WARNING, "RegisterClass: Couldn't resolve class name");
  754. MSGERROR();
  755. }
  756. } else {
  757. lpClassNameVer = (LPTSTR)lpWndClass->lpszClassName;
  758. }
  759. COPYLPTSTRID(&strClassName, (LPTSTR)lpWndClass->lpszClassName);
  760. COPYLPTSTRID(&strClassNameVer, (LPTSTR)lpClassNameVer);
  761. retval = NtUserRegisterClassExWOW(
  762. &WndClass,
  763. strClassName.pstr,
  764. strClassNameVer.pstr,
  765. &cmn,
  766. fnid,
  767. dwFlags,
  768. pdwWOWstuff);
  769. /*
  770. * Return the atom associated with this class or if earlier
  771. * than Win 3.1 convert it to a strict BOOL (some apps check)
  772. */
  773. if (GETEXPWINVER(lpWndClass->hInstance) < VER31)
  774. retval = !!retval;
  775. ERRORTRAP(0);
  776. CLEANUPLPTSTR(strMenuName); /* Initialized by InitClsMenuName */
  777. CLEANUPLPTSTR(strClassName);
  778. CLEANUPLPTSTR(strClassNameVer);
  779. if (lpActivationContext != NULL) {
  780. RtlReleaseActivationContext(lpActivationContext);
  781. lpActivationContext = NULL;
  782. }
  783. if (!retval) {
  784. if (IS_PTR(cmn.pszClientAnsiMenuName)) {
  785. UserLocalFree(KPVOID_TO_PVOID(cmn.pszClientAnsiMenuName));
  786. }
  787. if (IS_PTR(cmn.pwszClientUnicodeMenuName)) {
  788. UserLocalFree(KPVOID_TO_PVOID(cmn.pwszClientUnicodeMenuName));
  789. }
  790. }
  791. ENDCALL(BOOL);
  792. BadParameter:
  793. RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "RegisterClass: Invalid Parameter");
  794. return FALSE;
  795. }
  796. #ifdef UNICODE
  797. FUNCLOG1(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, RegisterWindowMessageW , LPCTSTR, pString)
  798. #else
  799. FUNCLOG1(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, RegisterWindowMessageA , LPCTSTR, pString)
  800. #endif // UNICODE
  801. UINT RegisterWindowMessage(
  802. LPCTSTR pString)
  803. {
  804. IN_STRING str;
  805. /*
  806. * Make sure cleanup will work successfully
  807. */
  808. str.fAllocated = FALSE;
  809. BEGINCALL()
  810. FIRSTCOPYLPTSTR(&str, (LPTSTR)pString);
  811. retval = (DWORD)NtUserRegisterWindowMessage(
  812. str.pstr);
  813. ERRORTRAP(0);
  814. CLEANUPLPTSTR(str);
  815. ENDCALL(UINT);
  816. }
  817. #ifdef UNICODE
  818. FUNCLOG2(LOG_GENERAL, HANDLE, DUMMYCALLINGTYPE, RemovePropW , HWND, hwnd, LPCTSTR, pString)
  819. #else
  820. FUNCLOG2(LOG_GENERAL, HANDLE, DUMMYCALLINGTYPE, RemovePropA , HWND, hwnd, LPCTSTR, pString)
  821. #endif // UNICODE
  822. HANDLE RemoveProp(
  823. HWND hwnd,
  824. LPCTSTR pString)
  825. {
  826. ATOM atomProp;
  827. DWORD dwProp;
  828. BEGINCALL()
  829. if (IS_PTR(pString)) {
  830. atomProp = GlobalFindAtom(pString);
  831. if (atomProp == 0)
  832. MSGERROR();
  833. dwProp = MAKELONG(atomProp, TRUE);
  834. } else
  835. dwProp = MAKELONG(PTR_TO_ID(pString), FALSE);
  836. retval = (ULONG_PTR)NtUserRemoveProp(
  837. hwnd,
  838. dwProp);
  839. if (retval != 0 && IS_PTR(pString))
  840. GlobalDeleteAtom(atomProp);
  841. ERRORTRAP(0);
  842. ENDCALL(HANDLE);
  843. }
  844. #ifdef UNICODE
  845. FUNCLOG6(LOG_GENERAL, BOOL, APIENTRY, SendMessageCallbackW, HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam, SENDASYNCPROC, lpResultCallBack, ULONG_PTR, dwData)
  846. #else
  847. FUNCLOG6(LOG_GENERAL, BOOL, APIENTRY, SendMessageCallbackA, HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam, SENDASYNCPROC, lpResultCallBack, ULONG_PTR, dwData)
  848. #endif // UNICODE
  849. BOOL APIENTRY SendMessageCallback(
  850. HWND hwnd,
  851. UINT wMsg,
  852. WPARAM wParam,
  853. LPARAM lParam,
  854. SENDASYNCPROC lpResultCallBack,
  855. ULONG_PTR dwData)
  856. {
  857. SNDMSGCALLBACK smcb;
  858. BEGINCALL()
  859. smcb.dwData = dwData;
  860. smcb.lpResultCallBack = lpResultCallBack;
  861. retval = (DWORD)CsSendMessage(hwnd, wMsg, wParam, lParam,
  862. (ULONG_PTR)&smcb, FNID_SENDMESSAGECALLBACK, IS_ANSI);
  863. ERRORTRAP(0);
  864. ENDCALL(BOOL);
  865. }
  866. #ifdef UNICODE
  867. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, SendNotifyMessageW , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
  868. #else
  869. FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, SendNotifyMessageA , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
  870. #endif // UNICODE
  871. BOOL APIENTRY SendNotifyMessage(
  872. HWND hwnd,
  873. UINT wMsg,
  874. WPARAM wParam,
  875. LPARAM lParam)
  876. {
  877. BEGINCALL()
  878. retval = (DWORD)CsSendMessage(hwnd, wMsg, wParam, lParam,
  879. 0L, FNID_SENDNOTIFYMESSAGE, IS_ANSI);
  880. ERRORTRAP(0);
  881. ENDCALL(BOOL);
  882. }
  883. #ifdef UNICODE
  884. FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetPropW , HWND, hwnd, LPCTSTR, pString, HANDLE, hData)
  885. #else
  886. FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetPropA , HWND, hwnd, LPCTSTR, pString, HANDLE, hData)
  887. #endif // UNICODE
  888. BOOL SetProp(
  889. HWND hwnd,
  890. LPCTSTR pString,
  891. HANDLE hData)
  892. {
  893. ATOM atomProp;
  894. DWORD dwProp;
  895. BEGINCALL()
  896. if (IS_PTR(pString)) {
  897. atomProp = GlobalAddAtom(pString);
  898. if (atomProp == 0)
  899. MSGERROR();
  900. dwProp = MAKELONG(atomProp, TRUE);
  901. } else
  902. dwProp = MAKELONG(PTR_TO_ID(pString), FALSE);
  903. retval = (DWORD)NtUserSetProp(
  904. hwnd,
  905. dwProp,
  906. hData);
  907. /*
  908. * If it failed, get rid of the atom
  909. */
  910. if (retval == FALSE && IS_PTR(pString))
  911. GlobalDeleteAtom(atomProp);
  912. ERRORTRAP(0);
  913. ENDCALL(BOOL);
  914. }
  915. #ifdef UNICODE
  916. FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, UnregisterClassW, LPCTSTR, pszClassName, HINSTANCE, hModule)
  917. #else
  918. FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, UnregisterClassA, LPCTSTR, pszClassName, HINSTANCE, hModule)
  919. #endif // UNICODE
  920. BOOL UnregisterClass(
  921. LPCTSTR pszClassName,
  922. HINSTANCE hModule)
  923. {
  924. IN_STRING strClassName;
  925. CLSMENUNAME cmn;
  926. /*
  927. * Make sure cleanup will work successfully
  928. */
  929. strClassName.fAllocated = FALSE;
  930. BEGINCALL_CLASSV()
  931. FIRSTCOPYLPTSTRID(&strClassName, lpClassNameVer);
  932. retval = (DWORD)NtUserUnregisterClass(
  933. strClassName.pstr,
  934. hModule,
  935. &cmn);
  936. /*
  937. * Check explicity for TRUE so we don't get a !FALSE when
  938. * converttogui fails and the NtUser returns a status code intead of bool.
  939. */
  940. if (retval == TRUE) {
  941. /*
  942. * Free the menu strings if they are not resource IDs
  943. */
  944. if (IS_PTR(cmn.pszClientAnsiMenuName)) {
  945. UserLocalFree(KPVOID_TO_PVOID(cmn.pszClientAnsiMenuName));
  946. }
  947. if (IS_PTR(cmn.pwszClientUnicodeMenuName)) {
  948. UserLocalFree(KPVOID_TO_PVOID(cmn.pwszClientUnicodeMenuName));
  949. }
  950. }
  951. ERRORTRAP(0);
  952. CLEANUPLPTSTR(strClassName);
  953. ENDCALL(BOOL);
  954. }
  955. #ifdef UNICODE
  956. FUNCLOG1(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanW , TCHAR, cChar)
  957. #else
  958. FUNCLOG1(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanA , TCHAR, cChar)
  959. #endif // UNICODE
  960. SHORT VkKeyScan(
  961. TCHAR cChar)
  962. {
  963. WCHAR wChar;
  964. BEGINCALL()
  965. #ifdef UNICODE
  966. wChar = cChar;
  967. #else
  968. #ifdef FE_SB // VkKeyScan()
  969. /*
  970. * Return 0xFFFFFFFF for DBCS LeadByte character.
  971. */
  972. if (IsDBCSLeadByte(cChar)) {
  973. MSGERROR();
  974. }
  975. #endif // FE_SB
  976. RtlMultiByteToUnicodeN((LPWSTR)&(wChar), sizeof(WCHAR), NULL, &cChar, sizeof(CHAR));
  977. #endif // UNICODE
  978. retval = (DWORD)NtUserVkKeyScanEx(
  979. wChar,
  980. 0,
  981. FALSE);
  982. ERRORTRAP(-1);
  983. ENDCALL(SHORT);
  984. }
  985. #ifndef UNICODE
  986. static HKL hVKSCachedHKL = 0;
  987. static UINT uVKSCachedCP = 0;
  988. #endif
  989. #ifdef UNICODE
  990. FUNCLOG2(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanExW, TCHAR, cChar, HKL, hkl)
  991. #else
  992. FUNCLOG2(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanExA, TCHAR, cChar, HKL, hkl)
  993. #endif // UNICODE
  994. SHORT VkKeyScanEx(
  995. TCHAR cChar,
  996. HKL hkl)
  997. {
  998. WCHAR wChar;
  999. BEGINCALL()
  1000. #ifdef UNICODE
  1001. wChar = cChar;
  1002. #else
  1003. if (hkl != hVKSCachedHKL) {
  1004. DWORD dwCodePage;
  1005. if (!GetLocaleInfoW(
  1006. HandleToUlong(hkl) & 0xffff,
  1007. LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
  1008. (LPWSTR)&dwCodePage,
  1009. sizeof(dwCodePage) / sizeof(WCHAR)
  1010. )) {
  1011. MSGERROR();
  1012. }
  1013. uVKSCachedCP = dwCodePage;
  1014. hVKSCachedHKL = hkl;
  1015. }
  1016. #ifdef FE_SB // VkKeyScanEx()
  1017. /*
  1018. * Return 0xFFFFFFFF for DBCS LeadByte character.
  1019. */
  1020. if (IsDBCSLeadByteEx(uVKSCachedCP,cChar)) {
  1021. MSGERROR();
  1022. }
  1023. #endif // FE_SB
  1024. if (!MultiByteToWideChar(
  1025. uVKSCachedCP,
  1026. 0,
  1027. &cChar,
  1028. 1,
  1029. &wChar,
  1030. 1)) {
  1031. MSGERROR();
  1032. }
  1033. #endif // UNICODE
  1034. retval = (DWORD)NtUserVkKeyScanEx(
  1035. wChar,
  1036. (ULONG_PTR)hkl,
  1037. TRUE);
  1038. ERRORTRAP(-1);
  1039. ENDCALL(SHORT);
  1040. }
  1041. #ifdef UNICODE
  1042. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplayDevicesW, LPCTSTR, lpszDevice, DWORD, iDevNum, PDISPLAY_DEVICE, lpDisplayDevice, DWORD, dwFlags)
  1043. #else
  1044. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplayDevicesA, LPCTSTR, lpszDevice, DWORD, iDevNum, PDISPLAY_DEVICE, lpDisplayDevice, DWORD, dwFlags)
  1045. #endif // UNICODE
  1046. BOOL
  1047. EnumDisplayDevices(
  1048. LPCTSTR lpszDevice,
  1049. DWORD iDevNum,
  1050. PDISPLAY_DEVICE lpDisplayDevice,
  1051. DWORD dwFlags)
  1052. {
  1053. UNICODE_STRING UnicodeString;
  1054. PUNICODE_STRING pUnicodeString = NULL;
  1055. NTSTATUS Status;
  1056. DISPLAY_DEVICEW tmpDisplayDevice;
  1057. //
  1058. // Clear out things to make sure the caller passes in appropriate
  1059. // parameters
  1060. //
  1061. ZeroMemory(((PUCHAR)lpDisplayDevice) + sizeof(DWORD),
  1062. lpDisplayDevice->cb - sizeof(DWORD));
  1063. tmpDisplayDevice.cb = sizeof(DISPLAY_DEVICEW);
  1064. if (lpszDevice) {
  1065. #ifdef UNICODE
  1066. RtlInitUnicodeString(&UnicodeString, lpszDevice);
  1067. #else
  1068. ANSI_STRING AnsiString;
  1069. UnicodeString = NtCurrentTeb()->StaticUnicodeString;
  1070. RtlInitAnsiString(&AnsiString, (LPSTR)lpszDevice);
  1071. if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
  1072. &AnsiString,
  1073. FALSE))) {
  1074. return FALSE;
  1075. }
  1076. #endif
  1077. pUnicodeString = &UnicodeString;
  1078. }
  1079. Status = NtUserEnumDisplayDevices(
  1080. pUnicodeString,
  1081. iDevNum,
  1082. &tmpDisplayDevice,
  1083. dwFlags);
  1084. if (NT_SUCCESS(Status))
  1085. {
  1086. #ifndef UNICODE
  1087. LPSTR psz;
  1088. if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, DeviceString)) {
  1089. psz = (LPSTR)&(lpDisplayDevice->DeviceName[0]);
  1090. WCSToMB(&(tmpDisplayDevice.DeviceName[0]), -1, &psz, 32, FALSE);
  1091. }
  1092. if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, StateFlags)) {
  1093. psz = (LPSTR)&(lpDisplayDevice->DeviceString[0]);
  1094. WCSToMB(&(tmpDisplayDevice.DeviceString[0]), -1, &psz, 128, FALSE);
  1095. }
  1096. if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, DeviceID)) {
  1097. lpDisplayDevice->StateFlags = tmpDisplayDevice.StateFlags;
  1098. }
  1099. if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, DeviceKey)) {
  1100. psz = (LPSTR)&(lpDisplayDevice->DeviceID[0]);
  1101. WCSToMB(&(tmpDisplayDevice.DeviceID[0]), -1, &psz, 128, FALSE);
  1102. }
  1103. if (lpDisplayDevice->cb >= sizeof(DISPLAY_DEVICE)) {
  1104. psz = (LPSTR)&(lpDisplayDevice->DeviceKey[0]);
  1105. WCSToMB(&(tmpDisplayDevice.DeviceKey[0]), -1, &psz, 128, FALSE);
  1106. }
  1107. #else
  1108. //
  1109. // Copy the contents of the tmpDisplayDevice back to the
  1110. // user supplied buffer. Make sure not to overwrite the original
  1111. // size field.
  1112. //
  1113. RtlMoveMemory((PUCHAR)lpDisplayDevice + sizeof(DWORD),
  1114. ((PUCHAR)&tmpDisplayDevice + sizeof(DWORD)),
  1115. lpDisplayDevice->cb - sizeof(DWORD));
  1116. #endif
  1117. return TRUE;
  1118. }
  1119. return FALSE;
  1120. }
  1121. #ifdef UNICODE
  1122. FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsW , LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode)
  1123. #else
  1124. FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsA, LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode)
  1125. #endif // UNICODE
  1126. BOOL EnumDisplaySettings(
  1127. LPCTSTR lpszDeviceName,
  1128. DWORD iModeNum,
  1129. LPDEVMODE lpDevMode)
  1130. {
  1131. //
  1132. // Work-around Win95 problem which does not require the caller
  1133. // to initialize these two fields.
  1134. //
  1135. lpDevMode->dmDriverExtra = 0;
  1136. lpDevMode->dmSize = FIELD_OFFSET(DEVMODE, dmICMMethod);
  1137. return EnumDisplaySettingsEx(lpszDeviceName, iModeNum, lpDevMode, 0);
  1138. }
  1139. #ifdef UNICODE
  1140. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsExW, LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode, DWORD, dwFlags)
  1141. #else
  1142. FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsExA, LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode, DWORD, dwFlags)
  1143. #endif // UNICODE
  1144. BOOL EnumDisplaySettingsEx(
  1145. LPCTSTR lpszDeviceName,
  1146. DWORD iModeNum,
  1147. LPDEVMODE lpDevMode,
  1148. DWORD dwFlags)
  1149. {
  1150. UNICODE_STRING UnicodeString;
  1151. PUNICODE_STRING pUnicodeString = NULL;
  1152. LPDEVMODEW lpDevModeReserve;
  1153. BOOL retval = FALSE;
  1154. WORD size = lpDevMode->dmSize;
  1155. if (lpszDeviceName) {
  1156. #ifdef UNICODE
  1157. RtlInitUnicodeString(&UnicodeString, lpszDeviceName);
  1158. #else
  1159. ANSI_STRING AnsiString;
  1160. UnicodeString = NtCurrentTeb()->StaticUnicodeString;
  1161. RtlInitAnsiString(&AnsiString, (LPSTR)lpszDeviceName);
  1162. if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
  1163. &AnsiString,
  1164. FALSE))) {
  1165. return FALSE;
  1166. }
  1167. #endif
  1168. pUnicodeString = &UnicodeString;
  1169. }
  1170. /*
  1171. * Currently -2 is reserved (undocumented function of the NT api.
  1172. * remove the check is win95 implements this.
  1173. * -> -1 returns the content of the registry at the time of the call
  1174. *
  1175. *
  1176. * if (iModeNum == (DWORD) -2)
  1177. * {
  1178. * return FALSE;
  1179. * }
  1180. *
  1181. *
  1182. * -1 should return the current DEVMODE for the device.
  1183. * This is handled in the kernel part of the function, so we pass it on.
  1184. *
  1185. *
  1186. *
  1187. * We will always request a full DEVMODE from the kernel.
  1188. * So allocate the space needed
  1189. *
  1190. */
  1191. lpDevModeReserve = UserLocalAlloc(HEAP_ZERO_MEMORY,
  1192. sizeof(DEVMODEW) + lpDevMode->dmDriverExtra);
  1193. if (lpDevModeReserve) {
  1194. lpDevModeReserve->dmSize = sizeof(DEVMODEW);
  1195. lpDevModeReserve->dmDriverExtra = lpDevMode->dmDriverExtra;
  1196. /*
  1197. * Get the information
  1198. */
  1199. retval = (NT_SUCCESS(NtUserEnumDisplaySettings(pUnicodeString,
  1200. iModeNum,
  1201. lpDevModeReserve,
  1202. dwFlags)));
  1203. if (retval) {
  1204. #ifndef UNICODE
  1205. LPSTR psz;
  1206. #endif
  1207. /*
  1208. * return only the amount of information requested.
  1209. * For ANSI, this requires a conversion.
  1210. */
  1211. /*
  1212. * First, copy the driver extra information
  1213. */
  1214. if (lpDevMode->dmDriverExtra && lpDevModeReserve->dmDriverExtra) {
  1215. RtlMoveMemory(((PUCHAR)lpDevMode) + size,
  1216. lpDevModeReserve + 1,
  1217. min(lpDevMode->dmDriverExtra,
  1218. lpDevModeReserve->dmDriverExtra));
  1219. }
  1220. #ifndef UNICODE
  1221. psz = (LPSTR)&(lpDevMode->dmDeviceName[0]);
  1222. retval = WCSToMB(lpDevModeReserve->dmDeviceName,
  1223. -1,
  1224. &psz,
  1225. 32,
  1226. FALSE);
  1227. RtlMoveMemory(&lpDevMode->dmSpecVersion,
  1228. &lpDevModeReserve->dmSpecVersion,
  1229. min(size, FIELD_OFFSET(DEVMODE,dmFormName)) -
  1230. FIELD_OFFSET(DEVMODE,dmSpecVersion));
  1231. lpDevMode->dmSize = size;
  1232. if (size >= FIELD_OFFSET(DEVMODE,dmFormName)) {
  1233. psz = (LPSTR)&(lpDevMode->dmFormName[0]);
  1234. retval = WCSToMB(lpDevModeReserve->dmFormName, -1, &psz, 32, FALSE);
  1235. }
  1236. if (size > FIELD_OFFSET(DEVMODE,dmBitsPerPel)) {
  1237. RtlMoveMemory(&lpDevMode->dmBitsPerPel,
  1238. &lpDevModeReserve->dmBitsPerPel,
  1239. lpDevMode->dmSize +
  1240. lpDevMode->dmDriverExtra -
  1241. FIELD_OFFSET(DEVMODE,dmBitsPerPel));
  1242. }
  1243. #else
  1244. RtlMoveMemory(lpDevMode, lpDevModeReserve, size);
  1245. lpDevMode->dmSize = size;
  1246. #endif
  1247. if (size != lpDevMode->dmSize) {
  1248. RIPMSG0(RIP_WARNING, "EnumDisplaySettings : Error in dmSize");
  1249. }
  1250. /*
  1251. * Don't return invalid field flags to the application
  1252. * Add any other new ones here.
  1253. *
  1254. * We assume apps at least have up to dmDisplayFrenquency for
  1255. * now ...
  1256. */
  1257. if (size < FIELD_OFFSET(DEVMODE,dmPanningWidth))
  1258. lpDevMode->dmFields &= ~DM_PANNINGWIDTH;
  1259. if (size < FIELD_OFFSET(DEVMODE,dmPanningHeight))
  1260. lpDevMode->dmFields &= ~DM_PANNINGHEIGHT;
  1261. }
  1262. UserLocalFree(lpDevModeReserve);
  1263. }
  1264. return retval;
  1265. }
  1266. #ifdef UNICODE
  1267. FUNCLOG2(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsW, LPDEVMODE, lpDevMode, DWORD, dwFlags)
  1268. #else
  1269. FUNCLOG2(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsA, LPDEVMODE, lpDevMode, DWORD, dwFlags)
  1270. #endif // UNICODE
  1271. LONG ChangeDisplaySettings(
  1272. LPDEVMODE lpDevMode,
  1273. DWORD dwFlags)
  1274. {
  1275. /*
  1276. * Compatibility.
  1277. */
  1278. if (lpDevMode) {
  1279. lpDevMode->dmDriverExtra = 0;
  1280. }
  1281. return ChangeDisplaySettingsEx(NULL, lpDevMode, NULL, dwFlags, NULL);
  1282. }
  1283. #ifdef UNICODE
  1284. FUNCLOG5(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsExW, LPCTSTR, lpszDeviceName, LPDEVMODE, lpDevMode, HWND, hwnd, DWORD, dwFlags, LPVOID, lParam)
  1285. #else
  1286. FUNCLOG5(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsExA, LPCTSTR, lpszDeviceName, LPDEVMODE, lpDevMode, HWND, hwnd, DWORD, dwFlags, LPVOID, lParam)
  1287. #endif // UNICODE
  1288. LONG ChangeDisplaySettingsEx(
  1289. LPCTSTR lpszDeviceName,
  1290. LPDEVMODE lpDevMode,
  1291. HWND hwnd,
  1292. DWORD dwFlags,
  1293. LPVOID lParam)
  1294. {
  1295. #ifndef UNICODE
  1296. ANSI_STRING AnsiString;
  1297. #endif
  1298. UNICODE_STRING UnicodeString;
  1299. PUNICODE_STRING pUnicodeString = NULL;
  1300. LONG status = DISP_CHANGE_FAILED;
  1301. LPDEVMODEW lpDevModeW;
  1302. if (hwnd != NULL) {
  1303. return DISP_CHANGE_BADPARAM;
  1304. }
  1305. if (lpszDeviceName) {
  1306. #ifdef UNICODE
  1307. RtlInitUnicodeString(&UnicodeString, lpszDeviceName);
  1308. #else
  1309. UnicodeString = NtCurrentTeb()->StaticUnicodeString;
  1310. RtlInitAnsiString(&AnsiString, (LPSTR)lpszDeviceName);
  1311. if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
  1312. &AnsiString,
  1313. FALSE))) {
  1314. return FALSE;
  1315. }
  1316. #endif
  1317. pUnicodeString = &UnicodeString;
  1318. }
  1319. #ifdef UNICODE
  1320. lpDevModeW = lpDevMode;
  1321. #else
  1322. lpDevModeW = NULL;
  1323. if (lpDevMode) {
  1324. lpDevModeW = GdiConvertToDevmodeW(lpDevMode);
  1325. if (lpDevModeW == NULL) {
  1326. return FALSE;
  1327. }
  1328. }
  1329. #endif
  1330. status = NtUserChangeDisplaySettings(pUnicodeString,
  1331. lpDevModeW,
  1332. dwFlags,
  1333. lParam);
  1334. #ifndef UNICODE
  1335. if (lpDevMode) {
  1336. UserLocalFree(lpDevModeW);
  1337. }
  1338. #endif
  1339. return status;
  1340. }
  1341. #ifdef UNICODE
  1342. FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, CallMsgFilterW , LPMSG, pmsg, int, nCode)
  1343. #else
  1344. FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, CallMsgFilterA , LPMSG, pmsg, int, nCode)
  1345. #endif // UNICODE
  1346. BOOL CallMsgFilter(
  1347. LPMSG pmsg,
  1348. int nCode)
  1349. {
  1350. PCLIENTINFO pci;
  1351. MSG msg;
  1352. BEGINCALLCONNECT()
  1353. /*
  1354. * If we're not hooked, don't bother going to the server
  1355. */
  1356. pci = GetClientInfo();
  1357. if (!IsHooked(pci, (WH_MSGFILTER | WH_SYSMSGFILTER))) {
  1358. return FALSE;
  1359. }
  1360. /*
  1361. * Don't allow apps to use the hiword of the message parameter.
  1362. */
  1363. if (pmsg->message & RESERVED_MSG_BITS) {
  1364. MSGERRORCODE(ERROR_INVALID_PARAMETER);
  1365. }
  1366. msg = *pmsg;
  1367. #ifndef UNICODE
  1368. switch (pmsg->message) {
  1369. #ifdef FE_SB // CallMsgFilter()
  1370. case WM_CHAR:
  1371. case EM_SETPASSWORDCHAR:
  1372. #ifndef LATER
  1373. /*
  1374. * we should not return "TRUE" everytime for DBCS leadbyte character...
  1375. * but should convert DBCS character to Unicode correctly.. How I can do ??
  1376. * then ,finally, we just take what we did in NT 3.51, it means do nothing..
  1377. */
  1378. #else
  1379. /*
  1380. * Build DBCS-aware message.
  1381. */
  1382. BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(pmsg->message,pmsg->wParam,TRUE);
  1383. /*
  1384. * Fall through.....
  1385. */
  1386. #endif // LATER
  1387. #else
  1388. case WM_CHAR:
  1389. case EM_SETPASSWORDCHAR:
  1390. #endif // FE_SB
  1391. case WM_CHARTOITEM:
  1392. case WM_DEADCHAR:
  1393. case WM_SYSCHAR:
  1394. case WM_SYSDEADCHAR:
  1395. case WM_MENUCHAR:
  1396. #ifdef FE_IME // CallMsgFilter()
  1397. case WM_IME_CHAR:
  1398. case WM_IME_COMPOSITION:
  1399. #endif // FE_IME
  1400. RtlMBMessageWParamCharToWCS( msg.message, &(msg.wParam));
  1401. break;
  1402. }
  1403. #endif //!UNICODE
  1404. retval = (DWORD)NtUserCallMsgFilter(
  1405. &msg,
  1406. nCode);
  1407. ERRORTRAP(0);
  1408. ENDCALL(BOOL);
  1409. }
  1410. #ifdef UNICODE
  1411. FUNCLOG7(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, DrawCaptionTempW, HWND, hwnd, HDC, hdc, LPCRECT, lprc, HFONT, hFont, HICON, hicon, LPCTSTR, lpText, UINT, flags)
  1412. #else
  1413. FUNCLOG7(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, DrawCaptionTempA, HWND, hwnd, HDC, hdc, LPCRECT, lprc, HFONT, hFont, HICON, hicon, LPCTSTR, lpText, UINT, flags)
  1414. #endif // UNICODE
  1415. BOOL DrawCaptionTemp(
  1416. HWND hwnd,
  1417. HDC hdc,
  1418. LPCRECT lprc,
  1419. HFONT hFont,
  1420. HICON hicon,
  1421. LPCTSTR lpText,
  1422. UINT flags)
  1423. {
  1424. HDC hdcr;
  1425. IN_STRING strText;
  1426. /*
  1427. * Make sure cleanup will work successfully
  1428. */
  1429. strText.fAllocated = FALSE;
  1430. BEGINCALL()
  1431. if (IsMetaFile(hdc)) return FALSE;
  1432. hdcr = GdiConvertAndCheckDC(hdc);
  1433. if (hdcr == (HDC)0)
  1434. return FALSE;
  1435. FIRSTCOPYLPTSTRIDOPT(&strText, lpText);
  1436. retval = (DWORD)NtUserDrawCaptionTemp(
  1437. hwnd,
  1438. hdc,
  1439. lprc,
  1440. hFont,
  1441. hicon,
  1442. strText.pstr,
  1443. flags);
  1444. ERRORTRAP(0);
  1445. CLEANUPLPTSTR(strText);
  1446. ENDCALL(BOOL);
  1447. }
  1448. #ifdef UNICODE
  1449. FUNCLOG3(LOG_GENERAL, UINT, WINUSERAPI, RealGetWindowClassW, HWND, hwnd, LPTSTR, ptszClassName, UINT, cchClassNameMax)
  1450. #else
  1451. FUNCLOG3(LOG_GENERAL, UINT, WINUSERAPI, RealGetWindowClassA, HWND, hwnd, LPTSTR, ptszClassName, UINT, cchClassNameMax)
  1452. #endif // UNICODE
  1453. WINUSERAPI UINT WINAPI
  1454. RealGetWindowClass(
  1455. HWND hwnd,
  1456. LPTSTR ptszClassName,
  1457. UINT cchClassNameMax)
  1458. {
  1459. UNICODE_STRING strClassName;
  1460. int retval;
  1461. strClassName.MaximumLength = (USHORT)(cchClassNameMax * sizeof(WCHAR));
  1462. #ifndef UNICODE
  1463. strClassName.Buffer = UserLocalAlloc(0, strClassName.MaximumLength);
  1464. if (!strClassName.Buffer) {
  1465. return 0;
  1466. }
  1467. #else
  1468. strClassName.Buffer = ptszClassName;
  1469. #endif
  1470. retval = NtUserGetClassName(hwnd, TRUE, &strClassName);
  1471. #ifndef UNICODE
  1472. if (retval || (cchClassNameMax == 1)) {
  1473. /*
  1474. * Copy the result
  1475. */
  1476. retval = WCSToMB(strClassName.Buffer,
  1477. retval,
  1478. &ptszClassName,
  1479. cchClassNameMax - 1,
  1480. FALSE);
  1481. ptszClassName[retval] = '\0';
  1482. }
  1483. UserLocalFree(strClassName.Buffer);
  1484. #endif
  1485. return retval;
  1486. }
  1487. WINUSERAPI BOOL WINAPI GetAltTabInfo(
  1488. HWND hwnd,
  1489. int iItem,
  1490. PALTTABINFO pati,
  1491. LPTSTR pszItemText,
  1492. UINT cchItemText OPTIONAL)
  1493. {
  1494. BEGINCALL()
  1495. retval = (DWORD)NtUserGetAltTabInfo(hwnd,
  1496. iItem,
  1497. pati,
  1498. (LPWSTR)pszItemText,
  1499. cchItemText,
  1500. IS_ANSI);
  1501. ERRORTRAP(0);
  1502. ENDCALL(BOOL);
  1503. }