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.

7039 lines
194 KiB

  1. //
  2. // uniwrap.cpp
  3. //
  4. // Unicode wrappers
  5. //
  6. // Copyright(C) Microsoft Corporation 2000
  7. //
  8. // Heavily based on code from shell\shlwapi\unicwrap.*
  9. // Modifications/additions - Nadim Abdo (nadima)
  10. //
  11. #include "stdafx.h"
  12. #include "uniwrap.h"
  13. #include "cstrinout.h"
  14. //Just include wrap function prototypes
  15. //no wrappers (it would be silly to wrap wrappers)
  16. #define DONOT_REPLACE_WITH_WRAPPERS
  17. #include "uwrap.h"
  18. #ifdef InRange
  19. #undef InRange
  20. #endif
  21. #define InRange(id, idFirst, idLast) ((UINT)(id-idFirst) <= (UINT)(idLast-idFirst))
  22. //
  23. // Do this in every wrapper function to make sure the wrapper
  24. // prototype matches the function it is intending to replace.
  25. //
  26. #define VALIDATE_PROTOTYPE(f) if (f##W == f##WrapW) 0
  27. #define VALIDATE_PROTOTYPE_DELAYLOAD(fWrap, fDelay) if (fDelay##W == fWrap##WrapW) 0
  28. #define VALIDATE_OUTBUF(s, cch)
  29. #define UseUnicodeShell32() ( g_bRunningOnNT )
  30. // compiler should do this opt for us (call-thunk => jmp), but it doesn't
  31. // so we do it ourselves (i raided it and they're adding it to vc6.x so
  32. // hopefully we'll get it someday)
  33. #if _X86_
  34. #define PERF_ASM 1 // turn on inline-asm opts
  35. #endif
  36. // todo??? #ifdef SUNDOWN #undef PERF_ASM
  37. #if PERF_ASM // {
  38. // BUGBUG workaround compiler bug
  39. // compiler should know this, but doesn't, so we make it explicit
  40. #define IMPORT_PTR dword ptr // BUGBUG sundown
  41. //*** FORWARD_AW, THUNK_AW -- simple forwarders and thunks
  42. // ENTRY/EXIT
  43. // - declare function w/ FORWARD_API
  44. // - if you're using THUNK_AW, create the 'A' thunk helper
  45. // - make the body FORWARD_AW or THUNK_AW.
  46. // - make sure there's *no* other code in the func. o.w. you'll get bogus
  47. // code.
  48. // EXAMPLE
  49. // int FORWARD_API WINAPI FooWrapW(int i, void *p)
  50. // {
  51. // VALIDATE_PROTOTYPE(Foo);
  52. //
  53. // FORWARD_AW(Foo, (i, p));
  54. // }
  55. //
  56. // int WINAPI BarAThunk(HWND hwnd, WPARAM wParam)
  57. // {
  58. // ... ansi thunk helper ...
  59. // }
  60. //
  61. // int FORWARD_API WINAPI BarWrapW(HWND hwnd, WPARAM wParam)
  62. // {
  63. // VALIDATE_PROTOTYPE(Bar);
  64. //
  65. // THUNK_AW(Bar, (hwnd, wParam));
  66. // }
  67. // NOTES
  68. // - WARNING: can only be used for 'simple' thunks (NAKED => no non-global
  69. // vars, etc.).
  70. // - WARNING: calling func must be declared FORWARD_API. if not you'll
  71. // get bogus code. happily if you forget you get the (obscure) error
  72. // message "error C4035: 'FooW': no return value"
  73. // - note that the macro ends up w/ an extra ";" from the caller, oh well...
  74. // - TODO: perf: better still would be to have a g_pfnCallWndProc, init
  75. // it 1x, and then jmp indirect w/o the test. it would cost us a ptr but
  76. // we only do it for the top-2 funcs (CallWindowProc and SendMessage)
  77. #define FORWARD_API _declspec(naked)
  78. #define FORWARD_AW(_fn, _args) \
  79. if (g_bRunningOnNT) { \
  80. _asm { jmp IMPORT_PTR _fn##W } \
  81. } \
  82. _asm { jmp IMPORT_PTR _fn##A }
  83. #define THUNK_AW(_fn, _args) \
  84. if (g_bRunningOnNT) { \
  85. _asm { jmp IMPORT_PTR _fn##W } \
  86. } \
  87. _asm { jmp _fn##AThunk } // n.b. no IMPORT_PTR
  88. #else // }{
  89. #define FORWARD_API /*NOTHING*/
  90. #define FORWARD_AW(_fn, _args) \
  91. if (g_bRunningOnNT) { \
  92. return _fn##W _args; \
  93. } \
  94. return _fn##A _args;
  95. #define THUNK_AW(_fn, _args) \
  96. if (g_bRunningOnNT) { \
  97. return _fn##W _args; \
  98. } \
  99. return _fn##AThunk _args;
  100. #endif // }
  101. //
  102. // Windows 95 and NT5 do not have the hbmpItem field in their MENUITEMINFO
  103. // structure.
  104. //
  105. #if (WINVER >= 0x0500)
  106. #define MENUITEMINFOSIZE_WIN95 FIELD_OFFSET(MENUITEMINFOW, hbmpItem)
  107. #else
  108. #define MENUITEMINFOSIZE_WIN95 sizeof(MENUITEMINFOW)
  109. #endif
  110. //
  111. // Some W functions are implemented on Win95, so complain if anybody
  112. // writes thunks for them.
  113. //
  114. // Though Win95's implementation of TextOutW is incomplete for FE languages.
  115. // Remove this section when we implement FE-aware TextOutW for Win95.
  116. //
  117. #if defined(TextOutWrap)
  118. #error Do not write thunks for TextOutW; Win95 supports it.
  119. #endif
  120. #define SEE_MASK_FILEANDURL 0x00400000 // defined in private\inc\shlapip.h !
  121. #define MFT_NONSTRING 0x00000904 // defined in private\inc\winuserp.h !
  122. #ifdef FUS9xWRAPAPI
  123. #undef FUS9xWRAPAPI
  124. #endif
  125. #define FUS9xWRAPAPI(type) STDAPI_(type)
  126. #include "strtype.cpp"
  127. //+------------------------------------------------------------------------
  128. //
  129. // Implementation of the wrapped functions
  130. // This part courtesy of shlwapi's unicwrap.c
  131. //
  132. //-------------------------------------------------------------------------
  133. #define NEED_COMDLG32_WRAPPER
  134. #define NEED_USER32_WRAPPER
  135. #define NEED_KERNEL32_WRAPPER
  136. #define NEED_ADVAPI32_WRAPPER
  137. #define NEED_GDI32_WRAPPER
  138. #ifdef NEED_USER32_WRAPPER
  139. BOOL WINAPI
  140. AppendMenuWrapW(
  141. HMENU hMenu,
  142. UINT uFlags,
  143. UINT_PTR uIDnewItem,
  144. LPCWSTR lpnewItem)
  145. {
  146. VALIDATE_PROTOTYPE(AppendMenu);
  147. // Make the InsertMenu wrapper do all the work
  148. return InsertMenuWrapW(hMenu, (UINT)-1,
  149. uFlags | MF_BYPOSITION, uIDnewItem, lpnewItem);
  150. }
  151. #endif // NEED_USER32_WRAPPER
  152. #ifdef NEED_USER32_WRAPPER
  153. LRESULT FORWARD_API WINAPI
  154. CallWindowProcWrapW(
  155. WNDPROC lpPrevWndFunc,
  156. HWND hWnd,
  157. UINT Msg,
  158. WPARAM wParam,
  159. LPARAM lParam)
  160. {
  161. VALIDATE_PROTOTYPE(CallWindowProc);
  162. // perf: better still would be to have a g_pfnCallWndProc, init it 1x,
  163. // and then jmp indirect w/o the test. it would cost us a ptr but we
  164. // only do it for the top-2 funcs (CallWindowProc and SendMessage)
  165. FORWARD_AW(CallWindowProc, (lpPrevWndFunc, hWnd, Msg, wParam, lParam));
  166. }
  167. #endif // NEED_USER32_WRAPPER
  168. #ifdef NEED_USER32_WRAPPER
  169. STDAPI_(BOOL FORWARD_API) CallMsgFilterWrapW(LPMSG lpMsg, int nCode)
  170. {
  171. VALIDATE_PROTOTYPE(CallMsgFilter);
  172. FORWARD_AW(CallMsgFilter, (lpMsg, nCode));
  173. }
  174. #endif // NEED_USER32_WRAPPER
  175. //----------------------------------------------------------------------
  176. //
  177. // function: CharLowerWrapW( LPWSTR pch )
  178. //
  179. // purpose: Converts character to lowercase. Takes either a pointer
  180. // to a string, or a character masquerading as a pointer.
  181. // In the later case, the HIWORD must be zero. This is
  182. // as spec'd for Win32.
  183. //
  184. // returns: Lowercased character or string. In the string case,
  185. // the lowercasing is done inplace.
  186. //
  187. //----------------------------------------------------------------------
  188. #ifdef NEED_USER32_WRAPPER
  189. LPWSTR WINAPI
  190. CharLowerWrapW( LPWSTR pch )
  191. {
  192. VALIDATE_PROTOTYPE(CharLower);
  193. if (g_bRunningOnNT)
  194. {
  195. return CharLowerW( pch );
  196. }
  197. if (!HIWORD64(pch))
  198. {
  199. WCHAR ch = (WCHAR)(LONG_PTR)pch;
  200. CharLowerBuffWrapW( &ch, 1 );
  201. pch = (LPWSTR)MAKEINTATOM(ch);
  202. }
  203. else
  204. {
  205. CharLowerBuffWrapW( pch, lstrlenW(pch) );
  206. }
  207. return pch;
  208. }
  209. #endif // NEED_USER32_WRAPPER
  210. //----------------------------------------------------------------------
  211. //
  212. // function: CharLowerBuffWrapW( LPWSTR pch, DWORD cch )
  213. //
  214. // purpose: Converts a string to lowercase. String must be cch
  215. // characters in length.
  216. //
  217. // returns: Character count (cch). The lowercasing is done inplace.
  218. //
  219. //----------------------------------------------------------------------
  220. #ifdef NEED_USER32_WRAPPER
  221. DWORD WINAPI
  222. CharLowerBuffWrapW( LPWSTR pch, DWORD cchLength )
  223. {
  224. VALIDATE_PROTOTYPE(CharLowerBuff);
  225. if (g_bRunningOnNT)
  226. {
  227. return CharLowerBuffW( pch, cchLength );
  228. }
  229. DWORD cch;
  230. for ( cch = cchLength; cch-- ; pch++ )
  231. {
  232. WCHAR ch = *pch;
  233. if (IsCharUpperWrapW(ch))
  234. {
  235. if (ch < 0x0100)
  236. {
  237. *pch += 32; // Get Latin-1 out of the way first
  238. }
  239. else if (ch < 0x0531)
  240. {
  241. if (ch < 0x0391)
  242. {
  243. if (ch < 0x01cd)
  244. {
  245. if (ch <= 0x178)
  246. {
  247. if (ch < 0x0178)
  248. {
  249. *pch += (ch == 0x0130) ? 0 : 1;
  250. }
  251. else
  252. {
  253. *pch -= 121;
  254. }
  255. }
  256. else
  257. {
  258. static const BYTE abLookup[] =
  259. { // 0/8 1/9 2/a 3/b 4/c 5/d 6/e 7/f
  260. /* 0x0179-0x17f */1, 0, 1, 0, 1, 0, 0,
  261. /* 0x0180-0x187 */ 0, 210, 1, 0, 1, 0, 206, 1,
  262. /* 0x0188-0x18f */ 0, 205, 205, 1, 0, 0, 79, 202,
  263. /* 0x0190-0x197 */ 203, 1, 0, 205, 207, 0, 211, 209,
  264. /* 0x0198-0x19f */ 1, 0, 0, 0, 211, 213, 0, 214,
  265. /* 0x01a0-0x1a7 */ 1, 0, 1, 0, 1, 0, 0, 1,
  266. /* 0x01a8-0x1af */ 0, 218, 0, 0, 1, 0, 218, 1,
  267. /* 0x01b0-0x1b7 */ 0, 217, 217, 1, 0, 1, 0, 219,
  268. /* 0x01b8-0x1bf */ 1, 0, 0, 0, 1, 0, 0, 0,
  269. /* 0x01c0-0x1c7 */ 0, 0, 0, 0, 2, 0, 0, 2,
  270. /* 0x01c8-0x1cb */ 0, 0, 2, 0
  271. };
  272. *pch += abLookup[ch-0x0179];
  273. }
  274. }
  275. else if (ch < 0x0386)
  276. {
  277. switch (ch)
  278. {
  279. case 0x01f1: *pch += 2; break;
  280. case 0x01f2: break;
  281. default: *pch += 1;
  282. }
  283. }
  284. else
  285. {
  286. static const BYTE abLookup[] =
  287. { 38, 0, 37, 37, 37, 0, 64, 0, 63, 63};
  288. *pch += abLookup[ch-0x0386];
  289. }
  290. }
  291. else
  292. {
  293. if (ch < 0x0410)
  294. {
  295. if (ch < 0x0401)
  296. {
  297. if (ch < 0x03e2)
  298. {
  299. if (!InRange(ch, 0x03d2, 0x03d4) &&
  300. !(InRange(ch, 0x3da, 0x03e0) & !(ch & 1)))
  301. {
  302. *pch += 32;
  303. }
  304. }
  305. else
  306. {
  307. *pch += 1;
  308. }
  309. }
  310. else
  311. {
  312. *pch += 80;
  313. }
  314. }
  315. else
  316. {
  317. if (ch < 0x0460)
  318. {
  319. *pch += 32;
  320. }
  321. else
  322. {
  323. *pch += 1;
  324. }
  325. }
  326. }
  327. }
  328. else
  329. {
  330. if (ch < 0x2160)
  331. {
  332. if (ch < 0x1fba)
  333. {
  334. if (ch < 0x1f08)
  335. {
  336. if (ch < 0x1e00)
  337. {
  338. *pch += 48;
  339. }
  340. else
  341. {
  342. *pch += 1;
  343. }
  344. }
  345. else if (!(InRange(ch, 0x1f88, 0x1faf) && (ch & 15)>7))
  346. {
  347. *pch -= 8;
  348. }
  349. }
  350. else
  351. {
  352. static const BYTE abLookup[] =
  353. { // 8 9 a b c d e f
  354. 0, 0, 74, 74, 0, 0, 0, 0,
  355. 86, 86, 86, 86, 0, 0, 0, 0,
  356. 8, 8, 100, 100, 0, 0, 0, 0,
  357. 8, 8, 112, 112, 7, 0, 0, 0,
  358. 128, 128, 126, 126, 0, 0, 0, 0
  359. };
  360. int i = (ch-0x1fb0);
  361. *pch -= (int)abLookup[((i>>1) & ~7) | (i & 7)];
  362. }
  363. }
  364. else
  365. {
  366. if (ch < 0xff21)
  367. {
  368. if (ch < 0x24b6)
  369. {
  370. *pch += 16;
  371. }
  372. else
  373. {
  374. *pch += 26;
  375. }
  376. }
  377. else
  378. {
  379. *pch += 32;
  380. }
  381. }
  382. }
  383. }
  384. else
  385. {
  386. // These are Unicode Number Forms. They have lowercase counter-
  387. // parts, but are not considered uppercase. Why, I don't know.
  388. if (InRange(ch, 0x2160, 0x216f))
  389. {
  390. *pch += 16;
  391. }
  392. }
  393. }
  394. return cchLength;
  395. }
  396. #endif // NEED_USER32_WRAPPER
  397. //
  398. // BUGBUG - Do CharNextWrap and CharPrevWrap need to call the
  399. // CharNextW, CharPrevW on WinNT? Couldn't these be MACROS?
  400. //
  401. LPWSTR WINAPI
  402. CharNextWrapW(LPCWSTR lpszCurrent)
  403. {
  404. VALIDATE_PROTOTYPE(CharNext);
  405. if (*lpszCurrent)
  406. {
  407. return(LPWSTR) lpszCurrent + 1;
  408. }
  409. else
  410. {
  411. return(LPWSTR) lpszCurrent;
  412. }
  413. }
  414. LPWSTR WINAPI
  415. CharPrevWrapW(LPCWSTR lpszStart, LPCWSTR lpszCurrent)
  416. {
  417. VALIDATE_PROTOTYPE(CharPrev);
  418. if (lpszCurrent == lpszStart)
  419. {
  420. return(LPWSTR) lpszStart;
  421. }
  422. else
  423. {
  424. return(LPWSTR) lpszCurrent - 1;
  425. }
  426. }
  427. //----------------------------------------------------------------------
  428. //
  429. // function: CharUpperWrapW( LPWSTR pch )
  430. //
  431. // purpose: Converts character to uppercase. Takes either a pointer
  432. // to a string, or a character masquerading as a pointer.
  433. // In the later case, the HIWORD must be zero. This is
  434. // as spec'd for Win32.
  435. //
  436. // returns: Uppercased character or string. In the string case,
  437. // the uppercasing is done inplace.
  438. //
  439. //----------------------------------------------------------------------
  440. #ifdef NEED_USER32_WRAPPER
  441. LPWSTR WINAPI
  442. CharUpperWrapW( LPWSTR pch )
  443. {
  444. VALIDATE_PROTOTYPE(CharUpper);
  445. if (g_bRunningOnNT)
  446. {
  447. return CharUpperW( pch );
  448. }
  449. if (!HIWORD64(pch))
  450. {
  451. WCHAR ch = (WCHAR)(LONG_PTR)pch;
  452. CharUpperBuffWrapW( &ch, 1 );
  453. pch = (LPWSTR)MAKEINTATOM(ch);
  454. }
  455. else
  456. {
  457. CharUpperBuffWrapW( pch, lstrlenW(pch) );
  458. }
  459. return pch;
  460. }
  461. #endif // NEED_USER32_WRAPPER
  462. //----------------------------------------------------------------------
  463. //
  464. // function: CharUpperBuffWrapW( LPWSTR pch, DWORD cch )
  465. //
  466. // purpose: Converts a string to uppercase. String must be cch
  467. // characters in length. Note that this function is
  468. // is messier that CharLowerBuffWrap, and the reason for
  469. // this is many Unicode characters are considered uppercase,
  470. // even when they don't have an uppercase counterpart.
  471. //
  472. // returns: Character count (cch). The uppercasing is done inplace.
  473. //
  474. //----------------------------------------------------------------------
  475. #ifdef NEED_USER32_WRAPPER
  476. DWORD WINAPI
  477. CharUpperBuffWrapW( LPWSTR pch, DWORD cchLength )
  478. {
  479. VALIDATE_PROTOTYPE(CharUpperBuff);
  480. if (g_bRunningOnNT)
  481. {
  482. return CharUpperBuffW( pch, cchLength );
  483. }
  484. DWORD cch;
  485. for ( cch = cchLength; cch-- ; pch++ )
  486. {
  487. WCHAR ch = *pch;
  488. if (IsCharLowerWrapW(ch))
  489. {
  490. if (ch < 0x00ff)
  491. {
  492. *pch -= ((ch != 0xdf) << 5);
  493. }
  494. else if (ch < 0x03b1)
  495. {
  496. if (ch < 0x01f5)
  497. {
  498. if (ch < 0x01ce)
  499. {
  500. if (ch < 0x017f)
  501. {
  502. if (ch < 0x0101)
  503. {
  504. *pch += 121;
  505. }
  506. else
  507. {
  508. *pch -= (ch != 0x0131 &&
  509. ch != 0x0138 &&
  510. ch != 0x0149);
  511. }
  512. }
  513. else if (ch < 0x01c9)
  514. {
  515. static const BYTE abMask[] =
  516. { // 6543210f edcba987
  517. 0xfc, 0xbf, // 11111100 10111111
  518. 0xbf, 0x67, // 10111111 01100111
  519. 0xff, 0xef, // 11111111 11101111
  520. 0xff, 0xf7, // 11111111 11110111
  521. 0xbf, 0xfd // 10111111 11111101
  522. };
  523. int i = ch - 0x017f;
  524. *pch -= ((abMask[i>>3] >> (i&7)) & 1) +
  525. (ch == 0x01c6);
  526. }
  527. else
  528. {
  529. *pch -= ((ch != 0x01cb)<<1);
  530. }
  531. }
  532. else
  533. {
  534. if (ch < 0x01df)
  535. {
  536. if (ch < 0x01dd)
  537. {
  538. *pch -= 1;
  539. }
  540. else
  541. {
  542. *pch -= 79;
  543. }
  544. }
  545. else
  546. {
  547. *pch -= 1 + (ch == 0x01f3) -
  548. InRange(ch,0x01f0,0x01f2);
  549. }
  550. }
  551. }
  552. else if (ch < 0x0253)
  553. {
  554. *pch -= (ch < 0x0250);
  555. }
  556. else if (ch < 0x03ac)
  557. {
  558. static const BYTE abLookup[] =
  559. { // 0/8 1/9 2/a 3/b 4/c 5/d 6/e 7/f
  560. /* 0x0253-0x0257 */210, 206, 0, 205, 205,
  561. /* 0x0258-0x025f */ 0, 202, 0, 203, 0, 0, 0, 0,
  562. /* 0x0260-0x0267 */ 205, 0, 0, 207, 0, 0, 0, 0,
  563. /* 0x0268-0x026f */ 209, 211, 0, 0, 0, 0, 0, 211,
  564. /* 0x0270-0x0277 */ 0, 0, 213, 0, 0, 214, 0, 0,
  565. /* 0x0278-0x027f */ 0, 0, 0, 0, 0, 0, 0, 0,
  566. /* 0x0280-0x0287 */ 0, 0, 0, 218, 0, 0, 0, 0,
  567. /* 0x0288-0x028f */ 218, 0, 217, 217, 0, 0, 0, 0,
  568. /* 0x0290-0x0297 */ 0, 0, 219
  569. };
  570. if (ch <= 0x0292)
  571. {
  572. *pch -= abLookup[ch - 0x0253];
  573. }
  574. }
  575. else
  576. {
  577. *pch -= (ch == 0x03b0) ? 0 : (37 + (ch == 0x03ac));
  578. }
  579. }
  580. else
  581. {
  582. if (ch < 0x0561)
  583. {
  584. if (ch < 0x0451)
  585. {
  586. if (ch < 0x03e3)
  587. {
  588. if (ch < 0x03cc)
  589. {
  590. *pch -= 32 - (ch == 0x03c2);
  591. }
  592. else
  593. {
  594. int i = (ch < 0x03d0);
  595. *pch -= (i<<6) - i + (ch == 0x03cc);
  596. }
  597. }
  598. else if (ch < 0x0430)
  599. {
  600. *pch -= (ch < 0x03f0);
  601. }
  602. else
  603. {
  604. *pch -= 32;
  605. }
  606. }
  607. else if (ch < 0x0461)
  608. {
  609. *pch -= 80;
  610. }
  611. else
  612. {
  613. *pch -= 1;
  614. }
  615. }
  616. else
  617. {
  618. if (ch < 0x1fb0)
  619. {
  620. if (ch < 0x1f70)
  621. {
  622. if (ch < 0x1e01)
  623. {
  624. int i = ch != 0x0587 && ch < 0x10d0;
  625. *pch -= ((i<<5)+(i<<4)); /* 48 */
  626. }
  627. else if (ch < 0x1f00)
  628. {
  629. *pch -= !InRange(ch, 0x1e96, 0x1e9a);
  630. }
  631. else
  632. {
  633. int i = !InRange(ch, 0x1f50, 0x1f56)||(ch & 1);
  634. *pch += (i<<3);
  635. }
  636. }
  637. else
  638. {
  639. static const BYTE abLookup[] =
  640. { 74, 86, 86, 100, 128, 112, 126};
  641. if ( ch <= 0x1f7d )
  642. {
  643. *pch += abLookup[(ch-0x1f70)>>1];
  644. }
  645. }
  646. }
  647. else
  648. {
  649. if (ch < 0x24d0)
  650. {
  651. if (ch < 0x1fe5)
  652. {
  653. *pch += (0x0023 & (1<<(ch&15))) ? 8 : 0;
  654. }
  655. else if (ch < 0x2170)
  656. {
  657. *pch += (0x0023 & (1<<(ch&15))) ? 7 : 0;
  658. }
  659. else
  660. {
  661. *pch -= ((ch > 0x24b5)<<4);
  662. }
  663. }
  664. else if (ch < 0xff41)
  665. {
  666. int i = !InRange(ch, 0xfb00, 0xfb17);
  667. *pch -= (i<<4)+(i<<3)+(i<<1); /* 26 */
  668. }
  669. else
  670. {
  671. *pch -= 32;
  672. }
  673. }
  674. }
  675. }
  676. }
  677. else
  678. {
  679. int i = InRange(ch, 0x2170, 0x217f);
  680. *pch -= (i<<4);
  681. }
  682. }
  683. return cchLength;
  684. }
  685. #endif // NEED_USER32_WRAPPER
  686. #ifdef NEED_USER32_WRAPPER
  687. int FORWARD_API WINAPI
  688. CopyAcceleratorTableWrapW(
  689. HACCEL hAccelSrc,
  690. LPACCEL lpAccelDst,
  691. int cAccelEntries)
  692. {
  693. VALIDATE_PROTOTYPE(CopyAcceleratorTable);
  694. FORWARD_AW(CopyAcceleratorTable, (hAccelSrc, lpAccelDst, cAccelEntries));
  695. }
  696. #endif // NEED_USER32_WRAPPER
  697. #ifdef NEED_USER32_WRAPPER
  698. HACCEL FORWARD_API WINAPI
  699. CreateAcceleratorTableWrapW(LPACCEL lpAccel, int cEntries)
  700. {
  701. VALIDATE_PROTOTYPE(CreateAcceleratorTable);
  702. FORWARD_AW(CreateAcceleratorTable, (lpAccel, cEntries));
  703. }
  704. #endif // NEED_USER32_WRAPPER
  705. #ifdef NEED_GDI32_WRAPPER
  706. typedef HDC (*FnCreateHDCA)(LPCSTR, LPCSTR, LPCSTR, CONST DEVMODEA *);
  707. HDC WINAPI
  708. CreateHDCWrapW(
  709. LPCWSTR lpszDriver,
  710. LPCWSTR lpszDevice,
  711. LPCWSTR lpszOutput,
  712. CONST DEVMODEW * lpInitData,
  713. FnCreateHDCA pfn)
  714. {
  715. DEVMODEA * pdevmode = NULL;
  716. CStrIn strDriver(lpszDriver);
  717. CStrIn strDevice(lpszDevice);
  718. CStrIn strOutput(lpszOutput);
  719. HDC hdcReturn = 0;
  720. if (lpInitData)
  721. {
  722. pdevmode = (DEVMODEA *) LocalAlloc( LPTR, lpInitData->dmSize + lpInitData->dmDriverExtra );
  723. if (pdevmode)
  724. {
  725. // LPBYTE->LPSTR casts below
  726. SHUnicodeToAnsi(lpInitData->dmDeviceName, (LPSTR)pdevmode->dmDeviceName, ARRAYSIZE(pdevmode->dmDeviceName));
  727. memcpy(&pdevmode->dmSpecVersion,
  728. &lpInitData->dmSpecVersion,
  729. FIELD_OFFSET(DEVMODEW,dmFormName) - FIELD_OFFSET(DEVMODEW,dmSpecVersion));
  730. SHUnicodeToAnsi(lpInitData->dmFormName, (LPSTR)pdevmode->dmFormName, ARRAYSIZE(pdevmode->dmFormName));
  731. memcpy(&pdevmode->dmLogPixels,
  732. &lpInitData->dmLogPixels,
  733. lpInitData->dmDriverExtra + lpInitData->dmSize - FIELD_OFFSET(DEVMODEW, dmLogPixels));
  734. pdevmode->dmSize -= (sizeof(BCHAR) - sizeof(char)) * (CCHDEVICENAME + CCHFORMNAME);
  735. }
  736. }
  737. hdcReturn = (*pfn)(strDriver, strDevice, strOutput, pdevmode);
  738. if (pdevmode)
  739. {
  740. LocalFree(pdevmode);
  741. }
  742. return hdcReturn;
  743. }
  744. #endif // NEED_GDI32_WRAPPER
  745. #ifdef NEED_GDI32_WRAPPER
  746. HDC WINAPI
  747. CreateDCWrapW(
  748. LPCWSTR lpszDriver,
  749. LPCWSTR lpszDevice,
  750. LPCWSTR lpszOutput,
  751. CONST DEVMODEW * lpInitData)
  752. {
  753. VALIDATE_PROTOTYPE(CreateDC);
  754. if (g_bRunningOnNT)
  755. {
  756. return CreateDCW(lpszDriver, lpszDevice, lpszOutput, lpInitData);
  757. }
  758. return CreateHDCWrapW(lpszDriver, lpszDevice, lpszOutput, lpInitData, CreateDCA);
  759. }
  760. #endif // NEED_GDI32_WRAPPER
  761. #ifdef NEED_GDI32_WRAPPER
  762. HDC WINAPI
  763. CreateICWrapW(
  764. LPCWSTR lpszDriver,
  765. LPCWSTR lpszDevice,
  766. LPCWSTR lpszOutput,
  767. CONST DEVMODEW * lpInitData)
  768. {
  769. VALIDATE_PROTOTYPE(CreateIC);
  770. if (g_bRunningOnNT)
  771. {
  772. return CreateICW(lpszDriver, lpszDevice, lpszOutput, lpInitData);
  773. }
  774. return CreateHDCWrapW(lpszDriver, lpszDevice, lpszOutput, lpInitData, CreateICA);
  775. }
  776. #endif // NEED_GDI32_WRAPPER
  777. #ifdef NEED_USER32_WRAPPER
  778. HWND WINAPI
  779. CreateDialogIndirectParamWrapW(
  780. HINSTANCE hInstance,
  781. LPCDLGTEMPLATEW hDialogTemplate,
  782. HWND hWndParent,
  783. DLGPROC lpDialogFunc,
  784. LPARAM dwInitParam)
  785. {
  786. VALIDATE_PROTOTYPE(CreateDialogIndirectParam);
  787. if (g_bRunningOnNT)
  788. {
  789. return CreateDialogIndirectParamW(
  790. hInstance,
  791. hDialogTemplate,
  792. hWndParent,
  793. lpDialogFunc,
  794. dwInitParam);
  795. }
  796. return CreateDialogIndirectParamA(
  797. hInstance,
  798. hDialogTemplate,
  799. hWndParent,
  800. lpDialogFunc,
  801. dwInitParam);
  802. }
  803. HWND WINAPI
  804. CreateDialogParamWrapW(
  805. HINSTANCE hInstance,
  806. LPCWSTR lpTemplateName,
  807. HWND hWndParent,
  808. DLGPROC lpDialogFunc,
  809. LPARAM dwInitParam)
  810. {
  811. VALIDATE_PROTOTYPE(CreateDialogParam);
  812. ASSERT(HIWORD64(lpTemplateName) == 0);
  813. if (g_bRunningOnNT)
  814. {
  815. return CreateDialogParamW(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
  816. }
  817. return CreateDialogParamA(hInstance, (LPSTR) lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
  818. }
  819. #endif // NEED_USER32_WRAPPER
  820. #ifdef NEED_KERNEL32_WRAPPER
  821. BOOL WINAPI
  822. CreateDirectoryWrapW(
  823. LPCWSTR lpPathName,
  824. LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  825. {
  826. VALIDATE_PROTOTYPE(CreateDirectory);
  827. if (g_bRunningOnNT)
  828. {
  829. return CreateDirectoryW(lpPathName, lpSecurityAttributes);
  830. }
  831. CStrIn str(lpPathName);
  832. ASSERT(!lpSecurityAttributes);
  833. return CreateDirectoryA(str, lpSecurityAttributes);
  834. }
  835. #endif // NEED_KERNEL32_WRAPPER
  836. #ifdef NEED_KERNEL32_WRAPPER
  837. HANDLE WINAPI
  838. CreateEventWrapW(
  839. LPSECURITY_ATTRIBUTES lpEventAttributes,
  840. BOOL bManualReset,
  841. BOOL bInitialState,
  842. LPCWSTR lpName)
  843. {
  844. VALIDATE_PROTOTYPE(CreateEvent);
  845. //Totally bogus assert.
  846. //ASSERT(!lpName);
  847. // cast means we can't use FORWARD_AW
  848. if (g_bRunningOnNT)
  849. {
  850. return CreateEventW(lpEventAttributes, bManualReset, bInitialState, lpName);
  851. }
  852. return CreateEventA(lpEventAttributes, bManualReset, bInitialState, (LPCSTR)lpName);
  853. }
  854. #endif // NEED_KERNEL32_WRAPPER
  855. #ifdef NEED_KERNEL32_WRAPPER
  856. HANDLE WINAPI
  857. CreateFileWrapW(
  858. LPCWSTR lpFileName,
  859. DWORD dwDesiredAccess,
  860. DWORD dwShareMode,
  861. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  862. DWORD dwCreationDisposition,
  863. DWORD dwFlagsAndAttributes,
  864. HANDLE hTemplateFile)
  865. {
  866. VALIDATE_PROTOTYPE(CreateFile);
  867. if (g_bRunningOnNT)
  868. {
  869. return CreateFileW(
  870. lpFileName,
  871. dwDesiredAccess,
  872. dwShareMode,
  873. lpSecurityAttributes,
  874. dwCreationDisposition,
  875. dwFlagsAndAttributes,
  876. hTemplateFile);
  877. }
  878. CStrIn str(lpFileName);
  879. return CreateFileA(
  880. str,
  881. dwDesiredAccess,
  882. dwShareMode,
  883. lpSecurityAttributes,
  884. dwCreationDisposition,
  885. dwFlagsAndAttributes,
  886. hTemplateFile);
  887. }
  888. #endif // NEED_KERNEL32_WRAPPER
  889. #ifdef NEED_GDI32_WRAPPER
  890. HFONT WINAPI
  891. CreateFontIndirectWrapW(CONST LOGFONTW * plfw)
  892. {
  893. VALIDATE_PROTOTYPE(CreateFontIndirect);
  894. if (g_bRunningOnNT)
  895. {
  896. return CreateFontIndirectW(plfw);
  897. }
  898. LOGFONTA lfa;
  899. HFONT hFont;
  900. memcpy(&lfa, plfw, FIELD_OFFSET(LOGFONTA, lfFaceName));
  901. SHUnicodeToAnsi(plfw->lfFaceName, lfa.lfFaceName, ARRAYSIZE(lfa.lfFaceName));
  902. hFont = CreateFontIndirectA(&lfa);
  903. return hFont;
  904. }
  905. #endif // NEED_GDI32_WRAPPER
  906. #ifdef NEED_USER32_WRAPPER
  907. HWND WINAPI
  908. CreateWindowExWrapW(
  909. DWORD dwExStyle,
  910. LPCWSTR lpClassName,
  911. LPCWSTR lpWindowName,
  912. DWORD dwStyle,
  913. int X,
  914. int Y,
  915. int nWidth,
  916. int nHeight,
  917. HWND hWndParent,
  918. HMENU hMenu,
  919. HINSTANCE hInstance,
  920. LPVOID lpParam)
  921. {
  922. VALIDATE_PROTOTYPE(CreateWindowEx);
  923. if (g_bRunningOnNT)
  924. {
  925. return CreateWindowExW(
  926. dwExStyle,
  927. lpClassName,
  928. lpWindowName,
  929. dwStyle,
  930. X,
  931. Y,
  932. nWidth,
  933. nHeight,
  934. hWndParent,
  935. hMenu,
  936. hInstance,
  937. lpParam);
  938. }
  939. CStrIn strClass(lpClassName);
  940. CStrIn strWindow(lpWindowName);
  941. return CreateWindowExA(
  942. dwExStyle,
  943. strClass,
  944. strWindow,
  945. dwStyle,
  946. X,
  947. Y,
  948. nWidth,
  949. nHeight,
  950. hWndParent,
  951. hMenu,
  952. hInstance,
  953. lpParam);
  954. }
  955. #endif // NEED_USER32_WRAPPER
  956. #ifdef NEED_USER32_WRAPPER
  957. LRESULT FORWARD_API WINAPI DefWindowProcWrapW(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  958. {
  959. VALIDATE_PROTOTYPE(DefWindowProc);
  960. FORWARD_AW(DefWindowProc, (hWnd, msg, wParam, lParam));
  961. }
  962. #endif // NEED_USER32_WRAPPER
  963. #ifdef NEED_KERNEL32_WRAPPER
  964. BOOL WINAPI DeleteFileWrapW(LPCWSTR pwsz)
  965. {
  966. VALIDATE_PROTOTYPE(DeleteFile);
  967. if (g_bRunningOnNT)
  968. {
  969. return DeleteFileW(pwsz);
  970. }
  971. CStrIn str(pwsz);
  972. return DeleteFileA(str);
  973. }
  974. #endif // NEED_KERNEL32_WRAPPER
  975. #ifdef NEED_USER32_WRAPPER
  976. INT_PTR WINAPI
  977. DialogBoxIndirectParamWrapW(
  978. HINSTANCE hInstance,
  979. LPCDLGTEMPLATEW hDialogTemplate,
  980. HWND hWndParent,
  981. DLGPROC lpDialogFunc,
  982. LPARAM dwInitParam)
  983. {
  984. VALIDATE_PROTOTYPE(DialogBoxIndirectParam);
  985. ASSERT(HIWORD64(hDialogTemplate) == 0);
  986. if (g_bRunningOnNT)
  987. {
  988. return DialogBoxIndirectParamW(
  989. hInstance,
  990. hDialogTemplate,
  991. hWndParent,
  992. lpDialogFunc,
  993. dwInitParam);
  994. }
  995. return DialogBoxIndirectParamA(
  996. hInstance,
  997. hDialogTemplate,
  998. hWndParent,
  999. lpDialogFunc,
  1000. dwInitParam);
  1001. }
  1002. #endif // NEED_USER32_WRAPPER
  1003. #ifdef NEED_USER32_WRAPPER
  1004. INT_PTR WINAPI
  1005. DialogBoxParamWrapW(
  1006. HINSTANCE hInstance,
  1007. LPCWSTR lpszTemplate,
  1008. HWND hWndParent,
  1009. DLGPROC lpDialogFunc,
  1010. LPARAM dwInitParam)
  1011. {
  1012. VALIDATE_PROTOTYPE(DialogBoxParam);
  1013. ASSERT(HIWORD64(lpszTemplate) == 0);
  1014. if (g_bRunningOnNT)
  1015. {
  1016. return DialogBoxParamW(
  1017. hInstance,
  1018. lpszTemplate,
  1019. hWndParent,
  1020. lpDialogFunc,
  1021. dwInitParam);
  1022. }
  1023. return DialogBoxParamA(hInstance, (LPCSTR) lpszTemplate, hWndParent, lpDialogFunc, dwInitParam);
  1024. }
  1025. #endif // NEED_USER32_WRAPPER
  1026. #ifdef NEED_USER32_WRAPPER
  1027. LRESULT FORWARD_API WINAPI
  1028. DispatchMessageWrapW(CONST MSG * lpMsg)
  1029. {
  1030. VALIDATE_PROTOTYPE(DispatchMessage);
  1031. FORWARD_AW(DispatchMessage, (lpMsg));
  1032. }
  1033. #endif // NEED_USER32_WRAPPER
  1034. #ifdef NEED_USER32_WRAPPER
  1035. int WINAPI
  1036. DrawTextWrapW(
  1037. HDC hDC,
  1038. LPCWSTR lpString,
  1039. int nCount,
  1040. LPRECT lpRect,
  1041. UINT uFormat)
  1042. {
  1043. VALIDATE_PROTOTYPE(DrawText);
  1044. if (g_bRunningOnNT)
  1045. {
  1046. return DrawTextW(hDC, lpString, nCount, lpRect, uFormat);
  1047. }
  1048. CStrIn str(lpString, nCount);
  1049. return DrawTextA(hDC, str, str.strlen(), lpRect, uFormat);
  1050. }
  1051. #endif // NEED_USER32_WRAPPER
  1052. #ifdef NEED_GDI32_WRAPPER
  1053. struct EFFSTAT
  1054. {
  1055. LPARAM lParam;
  1056. FONTENUMPROC lpEnumFontProc;
  1057. BOOL fFamilySpecified;
  1058. };
  1059. int CALLBACK
  1060. EnumFontFamiliesCallbackWrap(
  1061. ENUMLOGFONTA * lpelf,
  1062. NEWTEXTMETRIC * lpntm,
  1063. DWORD FontType,
  1064. LPARAM lParam)
  1065. {
  1066. ENUMLOGFONTW elf;
  1067. // Convert strings from ANSI to Unicode
  1068. if (((EFFSTAT *)lParam)->fFamilySpecified && (FontType & TRUETYPE_FONTTYPE) )
  1069. {
  1070. // LPBYTE->LPCSTR cast below
  1071. SHAnsiToUnicode((LPCSTR)lpelf->elfFullName, elf.elfFullName, ARRAYSIZE(elf.elfFullName));
  1072. SHAnsiToUnicode((LPCSTR)lpelf->elfStyle, elf.elfStyle, ARRAYSIZE(elf.elfStyle));
  1073. }
  1074. else
  1075. {
  1076. elf.elfStyle[0] = L'\0';
  1077. elf.elfFullName[0] = L'\0';
  1078. }
  1079. SHAnsiToUnicode(lpelf->elfLogFont.lfFaceName, elf.elfLogFont.lfFaceName, ARRAYSIZE(elf.elfLogFont.lfFaceName));
  1080. // Copy the non-string data
  1081. memcpy(
  1082. &elf.elfLogFont,
  1083. &lpelf->elfLogFont,
  1084. FIELD_OFFSET(LOGFONTA, lfFaceName));
  1085. // Chain to the original callback function
  1086. return(*((EFFSTAT *) lParam)->lpEnumFontProc)(
  1087. (const LOGFONTW *)&elf,
  1088. (const TEXTMETRICW *) lpntm,
  1089. FontType,
  1090. ((EFFSTAT *) lParam)->lParam);
  1091. }
  1092. #endif // NEED_GDI32_WRAPPER
  1093. #ifdef NEED_GDI32_WRAPPER
  1094. int WINAPI
  1095. EnumFontFamiliesWrapW(
  1096. HDC hdc,
  1097. LPCWSTR lpszFamily,
  1098. FONTENUMPROC lpEnumFontProc,
  1099. LPARAM lParam)
  1100. {
  1101. VALIDATE_PROTOTYPE(EnumFontFamilies);
  1102. if (g_bRunningOnNT)
  1103. {
  1104. return EnumFontFamiliesW(
  1105. hdc,
  1106. lpszFamily,
  1107. lpEnumFontProc,
  1108. lParam);
  1109. }
  1110. CStrIn str(lpszFamily);
  1111. EFFSTAT effstat;
  1112. effstat.lParam = lParam;
  1113. effstat.lpEnumFontProc = lpEnumFontProc;
  1114. effstat.fFamilySpecified = lpszFamily != NULL;
  1115. return EnumFontFamiliesA(
  1116. hdc,
  1117. str,
  1118. (FONTENUMPROCA) EnumFontFamiliesCallbackWrap,
  1119. (LPARAM) &effstat);
  1120. }
  1121. #endif // NEED_GDI32_WRAPPER
  1122. #ifdef NEED_GDI32_WRAPPER
  1123. int WINAPI
  1124. EnumFontFamiliesExWrapW(
  1125. HDC hdc,
  1126. LPLOGFONTW lplfw,
  1127. FONTENUMPROC lpEnumFontProc,
  1128. LPARAM lParam,
  1129. DWORD dwFlags )
  1130. {
  1131. VALIDATE_PROTOTYPE(EnumFontFamiliesEx);
  1132. if (g_bRunningOnNT)
  1133. {
  1134. return EnumFontFamiliesExW(
  1135. hdc,
  1136. lplfw,
  1137. lpEnumFontProc,
  1138. lParam,
  1139. dwFlags);
  1140. }
  1141. LOGFONTA lfa;
  1142. CStrIn str(lplfw->lfFaceName);
  1143. EFFSTAT effstat;
  1144. ASSERT( FIELD_OFFSET(LOGFONTW, lfFaceName) == FIELD_OFFSET(LOGFONTA, lfFaceName) );
  1145. memcpy( &lfa, lplfw, sizeof(LOGFONTA) - FIELD_OFFSET(LOGFONTA, lfFaceName) );
  1146. memcpy( lfa.lfFaceName, str, LF_FACESIZE );
  1147. effstat.lParam = lParam;
  1148. effstat.lpEnumFontProc = lpEnumFontProc;
  1149. effstat.fFamilySpecified = lplfw->lfFaceName != NULL;
  1150. return EnumFontFamiliesExA(
  1151. hdc,
  1152. &lfa,
  1153. (FONTENUMPROCA) EnumFontFamiliesCallbackWrap,
  1154. (LPARAM) &effstat,
  1155. dwFlags );
  1156. }
  1157. #endif // NEED_GDI32_WRAPPER
  1158. #ifdef NEED_KERNEL32_WRAPPER
  1159. BOOL WINAPI
  1160. EnumResourceNamesWrapW(
  1161. HINSTANCE hModule,
  1162. LPCWSTR lpType,
  1163. ENUMRESNAMEPROCW lpEnumFunc,
  1164. LPARAM lParam)
  1165. {
  1166. VALIDATE_PROTOTYPE(EnumResourceNames);
  1167. ASSERT(HIWORD64(lpType) == 0);
  1168. if (g_bRunningOnNT)
  1169. {
  1170. return EnumResourceNamesW(hModule, lpType, lpEnumFunc, lParam);
  1171. }
  1172. return EnumResourceNamesA(hModule, (LPCSTR) lpType, (ENUMRESNAMEPROCA)lpEnumFunc, lParam);
  1173. }
  1174. #endif // NEED_KERNEL32_WRAPPER
  1175. #ifdef NEED_KERNEL32_WRAPPER
  1176. HANDLE WINAPI
  1177. FindFirstFileWrapW(
  1178. LPCWSTR lpFileName,
  1179. LPWIN32_FIND_DATAW pwszFd)
  1180. {
  1181. VALIDATE_PROTOTYPE(FindFirstFile);
  1182. if (g_bRunningOnNT)
  1183. {
  1184. return FindFirstFileW(lpFileName, pwszFd);
  1185. }
  1186. CStrIn str(lpFileName);
  1187. CWin32FindDataInOut fd(pwszFd);
  1188. return FindFirstFileA(str, fd);
  1189. }
  1190. #endif // NEED_KERNEL32_WRAPPER
  1191. #ifdef NEED_KERNEL32_WRAPPER
  1192. HRSRC WINAPI
  1193. FindResourceWrapW(HINSTANCE hModule, LPCWSTR lpName, LPCWSTR lpType)
  1194. {
  1195. VALIDATE_PROTOTYPE(FindResource);
  1196. if (g_bRunningOnNT)
  1197. {
  1198. return FindResourceW(hModule, lpName, lpType);
  1199. }
  1200. CStrIn strName(lpName);
  1201. CStrIn strType(lpType);
  1202. return FindResourceA(hModule, strName, strType);
  1203. }
  1204. LPWSTR lstrcpyWrapW(LPWSTR pszDst, LPCWSTR pszSrc)
  1205. {
  1206. while((*pszDst++ = *pszSrc++));
  1207. return pszDst;
  1208. }
  1209. LPWSTR lstrcatWrapW(LPWSTR pszDst, LPCWSTR pszSrc)
  1210. {
  1211. return lstrcpyWrapW(pszDst + lstrlenW(pszDst), pszSrc);
  1212. }
  1213. LPWSTR
  1214. lstrcpynWrapW(
  1215. LPWSTR lpString1,
  1216. LPCWSTR lpString2,
  1217. int iMaxLength
  1218. )
  1219. {
  1220. LPWSTR src,dst;
  1221. __try {
  1222. src = (LPWSTR)lpString2;
  1223. dst = lpString1;
  1224. if ( iMaxLength ) {
  1225. while(iMaxLength && *src){
  1226. *dst++ = *src++;
  1227. iMaxLength--;
  1228. }
  1229. if ( iMaxLength ) {
  1230. *dst = '\0';
  1231. }
  1232. else {
  1233. dst--;
  1234. *dst = '\0';
  1235. }
  1236. }
  1237. }
  1238. __except (EXCEPTION_EXECUTE_HANDLER) {
  1239. return NULL;
  1240. }
  1241. return lpString1;
  1242. }
  1243. INT
  1244. APIENTRY
  1245. lstrcmpiWrapW(
  1246. LPCWSTR lpString1,
  1247. LPCWSTR lpString2
  1248. )
  1249. {
  1250. if (g_bRunningOnNT)
  1251. {
  1252. return lstrcmpiW(lpString1, lpString2);
  1253. }
  1254. CStrIn sz1(lpString1);
  1255. CStrIn sz2(lpString2);
  1256. return lstrcmpiA(sz1, sz2);
  1257. }
  1258. #endif // NEED_KERNEL32_WRAPPER
  1259. #ifdef NEED_USER32_WRAPPER
  1260. HWND WINAPI
  1261. FindWindowWrapW(LPCWSTR lpClassName, LPCWSTR lpWindowName)
  1262. {
  1263. VALIDATE_PROTOTYPE(FindWindow);
  1264. if (g_bRunningOnNT)
  1265. {
  1266. return FindWindowW(lpClassName, lpWindowName);
  1267. }
  1268. // Let FindWindowExWrapW do the thunking
  1269. return FindWindowExWrapW(NULL, NULL, lpClassName, lpWindowName);
  1270. }
  1271. #endif // NEED_USER32_WRAPPER
  1272. #ifdef NEED_USER32_WRAPPER
  1273. HWND WINAPI
  1274. FindWindowExWrapW(HWND hwndParent, HWND hwndChildAfter, LPCWSTR pwzClassName, LPCWSTR pwzWindowName)
  1275. {
  1276. VALIDATE_PROTOTYPE(FindWindowEx);
  1277. if (g_bRunningOnNT)
  1278. return FindWindowExW(hwndParent, hwndChildAfter, pwzClassName, pwzWindowName);
  1279. CStrIn strClass(pwzClassName);
  1280. CStrIn strWindow(pwzWindowName);
  1281. return FindWindowExA(hwndParent, hwndChildAfter, strClass, strWindow);
  1282. }
  1283. #endif // NEED_USER32_WRAPPER
  1284. #ifdef NEED_KERNEL32_WRAPPER
  1285. DWORD WINAPI
  1286. FormatMessageWrapW(
  1287. DWORD dwFlags,
  1288. LPCVOID lpSource,
  1289. DWORD dwMessageId,
  1290. DWORD dwLanguageId,
  1291. LPWSTR lpBuffer,
  1292. DWORD nSize,
  1293. va_list * Arguments)
  1294. {
  1295. VALIDATE_PROTOTYPE(FormatMessage);
  1296. if (!(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER))
  1297. {
  1298. VALIDATE_OUTBUF(lpBuffer, nSize);
  1299. }
  1300. DWORD dwResult;
  1301. #if DBG
  1302. // If a source string is passed, make sure that all string insertions
  1303. // have explicit character set markers. Otherwise, you get random
  1304. // behavior depending on whether we need to thunk to ANSI or not.
  1305. // (We are not clever enough to thunk the inserts; that's the caller's
  1306. // responsibility.)
  1307. //
  1308. if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
  1309. {
  1310. LPCWSTR pwsz;
  1311. for (pwsz = (LPCWSTR)lpSource; *pwsz; pwsz++)
  1312. {
  1313. if (*pwsz == L'%')
  1314. {
  1315. pwsz++;
  1316. // Found an insertion. Get the digit or two.
  1317. if (*pwsz == L'0')
  1318. continue; // "%0" is special
  1319. if (*pwsz < L'0' || *pwsz > L'9')
  1320. continue; // skip % followed by nondigit
  1321. pwsz++; // Skip the digit
  1322. if (*pwsz >= L'0' && *pwsz <= L'9')
  1323. pwsz++; // Skip the optional second digit
  1324. // The next character MUST be an exclamation point!
  1325. ASSERT(*pwsz == L'!' &&
  1326. "FormatMessageWrapW: All string insertions must have explicit character sets.");
  1327. // I'm not going to validate that the insertion contains
  1328. // an explicit character set override because if you went
  1329. // so far as to do a %n!...!, you'll get the last bit right too.
  1330. }
  1331. }
  1332. }
  1333. #endif
  1334. if (g_bRunningOnNT)
  1335. {
  1336. return FormatMessageW(
  1337. dwFlags,
  1338. lpSource,
  1339. dwMessageId,
  1340. dwLanguageId,
  1341. lpBuffer,
  1342. nSize,
  1343. Arguments);
  1344. }
  1345. //
  1346. // FORMAT_MESSAGE_FROM_STRING means that the source is a string.
  1347. // Otherwise, it's an opaque LPVOID (aka, an atom).
  1348. //
  1349. CStrIn strSource((dwFlags & FORMAT_MESSAGE_FROM_STRING) ? CP_ACP : CP_ATOM,
  1350. (LPCWSTR)lpSource, -1);
  1351. if (!(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER))
  1352. {
  1353. CStrOut str(lpBuffer, nSize);
  1354. FormatMessageA(
  1355. dwFlags,
  1356. strSource,
  1357. dwMessageId,
  1358. dwLanguageId,
  1359. str,
  1360. str.BufSize(),
  1361. Arguments); // We don't handle Arguments != NULL
  1362. dwResult = str.ConvertExcludingNul();
  1363. }
  1364. else
  1365. {
  1366. LPSTR pszBuffer = NULL;
  1367. LPWSTR * ppwzOut = (LPWSTR *)lpBuffer;
  1368. *ppwzOut = NULL;
  1369. FormatMessageA(
  1370. dwFlags,
  1371. strSource,
  1372. dwMessageId,
  1373. dwLanguageId,
  1374. (LPSTR)&pszBuffer,
  1375. 0,
  1376. Arguments);
  1377. if (pszBuffer)
  1378. {
  1379. DWORD cchSize = (lstrlenA(pszBuffer) + 1);
  1380. LPWSTR pszThunkedBuffer;
  1381. if (cchSize < nSize)
  1382. cchSize = nSize;
  1383. pszThunkedBuffer = (LPWSTR) LocalAlloc(LPTR, cchSize * sizeof(WCHAR));
  1384. if (pszThunkedBuffer)
  1385. {
  1386. *ppwzOut = pszThunkedBuffer;
  1387. SHAnsiToUnicode(pszBuffer, pszThunkedBuffer, cchSize);
  1388. }
  1389. LocalFree(pszBuffer);
  1390. }
  1391. dwResult = (*ppwzOut ? lstrlenW(*ppwzOut) : 0);
  1392. }
  1393. return dwResult;
  1394. }
  1395. #endif // NEED_KERNEL32_WRAPPER
  1396. #ifdef NEED_USER32_WRAPPER
  1397. BOOL WINAPI
  1398. GetClassInfoWrapW(HINSTANCE hModule, LPCWSTR lpClassName, LPWNDCLASSW lpWndClassW)
  1399. {
  1400. VALIDATE_PROTOTYPE(GetClassInfo);
  1401. if (g_bRunningOnNT)
  1402. {
  1403. return GetClassInfoW(hModule, lpClassName, lpWndClassW);
  1404. }
  1405. BOOL ret;
  1406. CStrIn strClassName(lpClassName);
  1407. ASSERT(sizeof(WNDCLASSA) == sizeof(WNDCLASSW));
  1408. ret = GetClassInfoA(hModule, strClassName, (LPWNDCLASSA) lpWndClassW);
  1409. lpWndClassW->lpszMenuName = NULL;
  1410. lpWndClassW->lpszClassName = NULL;
  1411. return ret;
  1412. }
  1413. #endif // NEED_USER32_WRAPPER
  1414. #ifdef NEED_USER32_WRAPPER
  1415. DWORD FORWARD_API WINAPI
  1416. GetClassLongWrapW(HWND hWnd, int nIndex)
  1417. {
  1418. VALIDATE_PROTOTYPE(GetClassLong);
  1419. FORWARD_AW(GetClassLong, (hWnd, nIndex));
  1420. }
  1421. #endif // NEED_USER32_WRAPPER
  1422. #ifdef NEED_USER32_WRAPPER
  1423. int WINAPI
  1424. GetClassNameWrapW(HWND hWnd, LPWSTR lpClassName, int nMaxCount)
  1425. {
  1426. VALIDATE_PROTOTYPE(GetClassName);
  1427. VALIDATE_OUTBUF(lpClassName, nMaxCount);
  1428. if (g_bRunningOnNT)
  1429. {
  1430. return GetClassNameW(hWnd, lpClassName, nMaxCount);
  1431. }
  1432. CStrOut strClassName(lpClassName, nMaxCount);
  1433. GetClassNameA(hWnd, strClassName, strClassName.BufSize());
  1434. return strClassName.ConvertIncludingNul();
  1435. }
  1436. #endif // NEED_USER32_WRAPPER
  1437. #ifdef NEED_USER32_WRAPPER
  1438. int WINAPI
  1439. GetClipboardFormatNameWrapW(UINT format, LPWSTR lpFormatName, int cchFormatName)
  1440. {
  1441. VALIDATE_PROTOTYPE(GetClipboardFormatName);
  1442. VALIDATE_OUTBUF(lpFormatName, cchFormatName);
  1443. if (g_bRunningOnNT)
  1444. {
  1445. return GetClipboardFormatNameW(format, lpFormatName, cchFormatName);
  1446. }
  1447. CStrOut strFormatName(lpFormatName, cchFormatName);
  1448. GetClipboardFormatNameA(format, strFormatName, strFormatName.BufSize());
  1449. return strFormatName.ConvertIncludingNul();
  1450. }
  1451. #endif // NEED_USER32_WRAPPER
  1452. #ifdef NEED_KERNEL32_WRAPPER
  1453. DWORD WINAPI
  1454. GetCurrentDirectoryWrapW(DWORD nBufferLength, LPWSTR lpBuffer)
  1455. {
  1456. VALIDATE_PROTOTYPE(GetCurrentDirectory);
  1457. VALIDATE_OUTBUF(lpBuffer, nBufferLength);
  1458. if (g_bRunningOnNT)
  1459. {
  1460. return GetCurrentDirectoryW(nBufferLength, lpBuffer);
  1461. }
  1462. CStrOut str(lpBuffer, nBufferLength);
  1463. GetCurrentDirectoryA(str.BufSize(), str);
  1464. return str.ConvertExcludingNul();
  1465. }
  1466. #endif // NEED_KERNEL32_WRAPPER
  1467. #ifdef NEED_USER32_WRAPPER
  1468. UINT WINAPI
  1469. GetDlgItemTextWrapW(
  1470. HWND hWndDlg,
  1471. int idControl,
  1472. LPWSTR lpsz,
  1473. int cchMax)
  1474. {
  1475. VALIDATE_PROTOTYPE(GetDlgItemText);
  1476. VALIDATE_OUTBUF(lpsz, cchMax);
  1477. if (g_bRunningOnNT)
  1478. {
  1479. return GetDlgItemTextW(hWndDlg, idControl, lpsz, cchMax);
  1480. }
  1481. CStrOut str(lpsz, cchMax);
  1482. GetDlgItemTextA(hWndDlg, idControl, str, str.BufSize());
  1483. return str.ConvertExcludingNul();
  1484. }
  1485. #endif // NEED_USER32_WRAPPER
  1486. #ifdef NEED_KERNEL32_WRAPPER
  1487. DWORD WINAPI
  1488. GetFileAttributesWrapW(LPCWSTR lpFileName)
  1489. {
  1490. VALIDATE_PROTOTYPE(GetFileAttributes);
  1491. if (g_bRunningOnNT)
  1492. {
  1493. return GetFileAttributesW(lpFileName);
  1494. }
  1495. CStrIn str(lpFileName);
  1496. return GetFileAttributesA(str);
  1497. }
  1498. #endif // NEED_KERNEL32_WRAPPER
  1499. #ifdef NEED_KERNEL32_WRAPPER
  1500. int WINAPI
  1501. GetLocaleInfoWrapW(LCID Locale, LCTYPE LCType, LPWSTR lpsz, int cchData)
  1502. {
  1503. VALIDATE_PROTOTYPE(GetLocaleInfo);
  1504. VALIDATE_OUTBUF(lpsz, cchData);
  1505. if (g_bRunningOnNT)
  1506. {
  1507. return GetLocaleInfoW(Locale, LCType, lpsz, cchData);
  1508. }
  1509. CStrOut str(lpsz, cchData);
  1510. GetLocaleInfoA(Locale, LCType, str, str.BufSize());
  1511. return str.ConvertIncludingNul();
  1512. }
  1513. #endif // NEED_KERNEL32_WRAPPER
  1514. #ifdef NEED_USER32_WRAPPER
  1515. int WINAPI
  1516. GetMenuStringWrapW(
  1517. HMENU hMenu,
  1518. UINT uIDItem,
  1519. LPWSTR lpString,
  1520. int nMaxCount,
  1521. UINT uFlag)
  1522. {
  1523. VALIDATE_PROTOTYPE(GetMenuString);
  1524. VALIDATE_OUTBUF(lpString, nMaxCount);
  1525. if (g_bRunningOnNT)
  1526. {
  1527. return GetMenuStringW(hMenu, uIDItem, lpString, nMaxCount, uFlag);
  1528. }
  1529. CStrOut str(lpString, nMaxCount);
  1530. GetMenuStringA(hMenu, uIDItem, str, str.BufSize(), uFlag);
  1531. return str.ConvertExcludingNul();
  1532. }
  1533. #endif // NEED_USER32_WRAPPER
  1534. #ifdef NEED_USER32_WRAPPER
  1535. BOOL FORWARD_API WINAPI
  1536. GetMessageWrapW(
  1537. LPMSG lpMsg,
  1538. HWND hWnd,
  1539. UINT wMsgFilterMin,
  1540. UINT wMsgFilterMax)
  1541. {
  1542. VALIDATE_PROTOTYPE(GetMessage);
  1543. FORWARD_AW(GetMessage, (lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax));
  1544. }
  1545. #endif // NEED_USER32_WRAPPER
  1546. #ifdef NEED_KERNEL32_WRAPPER
  1547. DWORD WINAPI
  1548. GetModuleFileNameWrapW(HINSTANCE hModule, LPWSTR pwszFilename, DWORD nSize)
  1549. {
  1550. VALIDATE_PROTOTYPE(GetModuleFileName);
  1551. VALIDATE_OUTBUF(pwszFilename, nSize);
  1552. if (g_bRunningOnNT)
  1553. {
  1554. return GetModuleFileNameW(hModule, pwszFilename, nSize);
  1555. }
  1556. CStrOut str(pwszFilename, nSize);
  1557. GetModuleFileNameA(hModule, str, str.BufSize());
  1558. return str.ConvertIncludingNul();
  1559. }
  1560. #endif // NEED_KERNEL32_WRAPPER
  1561. #ifdef NEED_KERNEL32_WRAPPER
  1562. UINT WINAPI
  1563. GetSystemDirectoryWrapW(LPWSTR lpBuffer, UINT uSize)
  1564. {
  1565. VALIDATE_PROTOTYPE(GetSystemDirectory);
  1566. VALIDATE_OUTBUF(lpBuffer, uSize);
  1567. if (g_bRunningOnNT)
  1568. {
  1569. return GetSystemDirectoryW(lpBuffer, uSize);
  1570. }
  1571. CStrOut str(lpBuffer, uSize);
  1572. GetSystemDirectoryA(str, str.BufSize());
  1573. return str.ConvertExcludingNul();
  1574. }
  1575. #endif // NEED_KERNEL32_WRAPPER
  1576. #ifdef NEED_KERNEL32_WRAPPER
  1577. DWORD WINAPI
  1578. SearchPathWrapW(
  1579. LPCWSTR lpPathName,
  1580. LPCWSTR lpFileName,
  1581. LPCWSTR lpExtension,
  1582. DWORD cchReturnBuffer,
  1583. LPWSTR lpReturnBuffer,
  1584. LPWSTR * plpfilePart)
  1585. {
  1586. VALIDATE_PROTOTYPE(SearchPath);
  1587. VALIDATE_OUTBUF(lpReturnBuffer, cchReturnBuffer);
  1588. if (g_bRunningOnNT)
  1589. {
  1590. return SearchPathW(
  1591. lpPathName,
  1592. lpFileName,
  1593. lpExtension,
  1594. cchReturnBuffer,
  1595. lpReturnBuffer,
  1596. plpfilePart);
  1597. }
  1598. CStrIn strPath(lpPathName);
  1599. CStrIn strFile(lpFileName);
  1600. CStrIn strExtension(lpExtension);
  1601. CStrOut strReturnBuffer(lpReturnBuffer, cchReturnBuffer);
  1602. DWORD dwLen = SearchPathA(
  1603. strPath,
  1604. strFile,
  1605. strExtension,
  1606. strReturnBuffer.BufSize(),
  1607. strReturnBuffer,
  1608. (LPSTR *)plpfilePart);
  1609. //
  1610. // Getting the correct value for plpfilePart requires
  1611. // a strrchr on the converted string. If this value
  1612. // is needed, just add the code to do it here.
  1613. //
  1614. *plpfilePart = NULL;
  1615. if (cchReturnBuffer == 0)
  1616. dwLen = 2*dwLen;
  1617. else
  1618. dwLen = strReturnBuffer.ConvertExcludingNul();
  1619. return dwLen;
  1620. }
  1621. #endif // NEED_KERNEL32_WRAPPER
  1622. #ifdef NEED_KERNEL32_WRAPPER
  1623. HMODULE WINAPI
  1624. GetModuleHandleWrapW(LPCWSTR lpModuleName)
  1625. {
  1626. VALIDATE_PROTOTYPE(GetModuleHandle);
  1627. if (g_bRunningOnNT)
  1628. {
  1629. return GetModuleHandleW(lpModuleName);
  1630. }
  1631. CStrIn str(lpModuleName);
  1632. return GetModuleHandleA(str);
  1633. }
  1634. #endif // NEED_KERNEL32_WRAPPER
  1635. #ifdef NEED_GDI32_WRAPPER
  1636. int WINAPI
  1637. GetObjectWrapW(HGDIOBJ hgdiObj, int cbBuffer, LPVOID lpvObj)
  1638. {
  1639. VALIDATE_PROTOTYPE(GetObject);
  1640. if (g_bRunningOnNT)
  1641. {
  1642. return GetObjectW(hgdiObj, cbBuffer, lpvObj);
  1643. }
  1644. int nRet;
  1645. if (cbBuffer != sizeof(LOGFONTW))
  1646. {
  1647. nRet = GetObjectA(hgdiObj, cbBuffer, lpvObj);
  1648. }
  1649. else
  1650. {
  1651. LOGFONTA lfa;
  1652. nRet = GetObjectA(hgdiObj, sizeof(lfa), &lfa);
  1653. if (nRet > 0)
  1654. {
  1655. memcpy(lpvObj, &lfa, FIELD_OFFSET(LOGFONTW, lfFaceName));
  1656. SHAnsiToUnicode(lfa.lfFaceName, ((LOGFONTW*)lpvObj)->lfFaceName, ARRAYSIZE(((LOGFONTW*)lpvObj)->lfFaceName));
  1657. nRet = sizeof(LOGFONTW);
  1658. }
  1659. }
  1660. return nRet;
  1661. }
  1662. #endif // NEED_GDI32_WRAPPER
  1663. //
  1664. // Demand load shell32 _SHFileOperationW because
  1665. // older versions of the Shell on 9x didn't necessarily
  1666. // have this function
  1667. //
  1668. int WINAPI _SHFileOperationW(LPSHFILEOPSTRUCTW pFileOpW)
  1669. {
  1670. int result = 1;
  1671. HMODULE hmodSH32DLL;
  1672. typedef HRESULT (STDAPICALLTYPE FNSHFileOperationW)(LPSHFILEOPSTRUCT);
  1673. FNSHFileOperationW *pfnSHFileOperationW;
  1674. // get the handle to shell32.dll library
  1675. hmodSH32DLL = LoadLibraryWrapW(TEXT("SHELL32.DLL"));
  1676. if (hmodSH32DLL != NULL) {
  1677. // get the proc address for SHFileOperation
  1678. pfnSHFileOperationW = (FNSHFileOperationW *)GetProcAddress(
  1679. hmodSH32DLL,
  1680. "SHFileOperationW");
  1681. if (pfnSHFileOperationW != NULL) {
  1682. result = (*pfnSHFileOperationW) (pFileOpW);
  1683. }
  1684. FreeLibrary(hmodSH32DLL);
  1685. }
  1686. return result ;
  1687. }
  1688. int WINAPI SHFileOperationWrapW(LPSHFILEOPSTRUCTW pFileOpW)
  1689. {
  1690. VALIDATE_PROTOTYPE_DELAYLOAD(SHFileOperation, _SHFileOperation);
  1691. // We don't thunk multiple files.
  1692. ASSERT(!(pFileOpW->fFlags & FOF_MULTIDESTFILES));
  1693. if (UseUnicodeShell32())
  1694. return _SHFileOperationW(pFileOpW);
  1695. int nResult = 1; // non-Zero is failure.
  1696. if (pFileOpW)
  1697. {
  1698. SHFILEOPSTRUCTA FileOpA;
  1699. CStrIn strTo(pFileOpW->pTo);
  1700. CStrIn strFrom(pFileOpW->pFrom);
  1701. CStrIn strProgressTitle(pFileOpW->lpszProgressTitle);
  1702. FileOpA = *(LPSHFILEOPSTRUCTA) pFileOpW;
  1703. FileOpA.pFrom = strFrom;
  1704. FileOpA.pTo = strTo;
  1705. FileOpA.lpszProgressTitle = strProgressTitle;
  1706. nResult = SHFileOperationA(&FileOpA);
  1707. }
  1708. return nResult;
  1709. }
  1710. //
  1711. // We don't need many of the shell api's
  1712. // so they are no wrapped
  1713. //
  1714. #ifdef NEED_SHELL32_WRAPPER
  1715. LPITEMIDLIST WINAPI SHBrowseForFolderWrapW(LPBROWSEINFOW pbiW)
  1716. {
  1717. VALIDATE_PROTOTYPE_DELAYLOAD(SHBrowseForFolder, _SHBrowseForFolder);
  1718. if (UseUnicodeShell32())
  1719. return _SHBrowseForFolderW(pbiW);
  1720. LPITEMIDLIST pidl = NULL;
  1721. if (EVAL(pbiW))
  1722. {
  1723. CStrIn strTitle(pbiW->lpszTitle);
  1724. CStrOut strDisplayName(pbiW->pszDisplayName, MAX_PATH);
  1725. BROWSEINFOA biA;
  1726. biA = * (LPBROWSEINFOA) pbiW;
  1727. biA.lpszTitle = strTitle;
  1728. biA.pszDisplayName = strDisplayName;
  1729. pidl = _SHBrowseForFolderA(&biA);
  1730. if (pidl)
  1731. strDisplayName.ConvertIncludingNul();
  1732. }
  1733. return pidl;
  1734. }
  1735. #endif // NEED_SHELL32_WRAPPER
  1736. #ifdef NEED_SHELL32_WRAPPER
  1737. BOOL WINAPI ShellExecuteExWrapW(LPSHELLEXECUTEINFOW pExecInfoW)
  1738. {
  1739. VALIDATE_PROTOTYPE_DELAYLOAD(ShellExecuteEx, _ShellExecuteEx);
  1740. if (g_bRunningOnNT)
  1741. return _ShellExecuteExW(pExecInfoW);
  1742. BOOL fResult = FALSE;
  1743. if (EVAL(pExecInfoW))
  1744. {
  1745. SHELLEXECUTEINFOA ExecInfoA;
  1746. CStrIn strVerb(pExecInfoW->lpVerb);
  1747. CStrIn strParameters(pExecInfoW->lpParameters);
  1748. CStrIn strDirectory(pExecInfoW->lpDirectory);
  1749. CStrIn strClass(pExecInfoW->lpClass);
  1750. CHAR szFile[MAX_PATH + INTERNET_MAX_URL_LENGTH + 2];
  1751. ExecInfoA = *(LPSHELLEXECUTEINFOA) pExecInfoW;
  1752. ExecInfoA.lpVerb = strVerb;
  1753. ExecInfoA.lpParameters = strParameters;
  1754. ExecInfoA.lpDirectory = strDirectory;
  1755. ExecInfoA.lpClass = strClass;
  1756. if (pExecInfoW->lpFile)
  1757. {
  1758. ExecInfoA.lpFile = szFile;
  1759. SHUnicodeToAnsi(pExecInfoW->lpFile, szFile, ARRAYSIZE(szFile));
  1760. // SEE_MASK_FILEANDURL passes "file\0url". What a hack!
  1761. if (pExecInfoW->fMask & SEE_MASK_FILEANDURL)
  1762. {
  1763. // We are so lucky that Win9x implements lstrlenW
  1764. int cch = lstrlenW(pExecInfoW->lpFile) + 1;
  1765. cch += lstrlenW(pExecInfoW->lpFile + cch) + 1;
  1766. if (!WideCharToMultiByte(CP_ACP, 0, pExecInfoW->lpFile, cch, szFile, ARRAYSIZE(szFile), NULL, NULL))
  1767. {
  1768. // Return a completely random error code
  1769. pExecInfoW->hInstApp = (HINSTANCE)SE_ERR_OOM;
  1770. SetLastError(ERROR_INVALID_PARAMETER);
  1771. return FALSE;
  1772. }
  1773. }
  1774. }
  1775. fResult = _ShellExecuteExA(&ExecInfoA);
  1776. // Out parameters
  1777. pExecInfoW->hInstApp = ExecInfoA.hInstApp;
  1778. pExecInfoW->hProcess = ExecInfoA.hProcess;
  1779. }
  1780. else
  1781. SetLastError(ERROR_INVALID_PARAMETER);
  1782. return fResult;
  1783. }
  1784. #endif // NEED_SHELL32_WRAPPER
  1785. #ifdef NEED_SHELL32_WRAPPER
  1786. UINT WINAPI ExtractIconExWrapW(LPCWSTR pwzFile, int nIconIndex, HICON FAR *phiconLarge, HICON FAR *phiconSmall, UINT nIcons)
  1787. {
  1788. VALIDATE_PROTOTYPE_DELAYLOAD(ExtractIconEx, _ExtractIconEx);
  1789. if ( UseUnicodeShell32() )
  1790. return _ExtractIconExW(pwzFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
  1791. CStrIn str(pwzFile);
  1792. return _ExtractIconExA(str, nIconIndex, phiconLarge, phiconSmall, nIcons);
  1793. }
  1794. #endif // NEED_SHELL32_WRAPPER
  1795. #ifdef NEED_KERNEL32_WRAPPER
  1796. BOOL WINAPI SetFileAttributesWrapW(LPCWSTR pwzFile, DWORD dwFileAttributes)
  1797. {
  1798. VALIDATE_PROTOTYPE(SetFileAttributes);
  1799. if (g_bRunningOnNT)
  1800. return SetFileAttributesW(pwzFile, dwFileAttributes);
  1801. CStrIn str(pwzFile);
  1802. return SetFileAttributesA(str, dwFileAttributes);
  1803. }
  1804. #endif // NEED_KERNEL32_WRAPPER
  1805. #ifdef NEED_KERNEL32_WRAPPER
  1806. int WINAPI GetNumberFormatWrapW(LCID Locale, DWORD dwFlags, LPCWSTR pwzValue, CONST NUMBERFMTW * pFormatW, LPWSTR pwzNumberStr, int cchNumber)
  1807. {
  1808. VALIDATE_PROTOTYPE(GetNumberFormat);
  1809. if (g_bRunningOnNT)
  1810. return GetNumberFormatW(Locale, dwFlags, pwzValue, pFormatW, pwzNumberStr, cchNumber);
  1811. int nResult;
  1812. NUMBERFMTA FormatA;
  1813. CStrIn strValue(pwzValue);
  1814. CStrIn strDecimalSep(pFormatW ? pFormatW->lpDecimalSep : NULL);
  1815. CStrIn strThousandSep(pFormatW ? pFormatW->lpThousandSep : NULL);
  1816. CStrOut strNumberStr(pwzNumberStr, cchNumber);
  1817. if (pFormatW)
  1818. {
  1819. FormatA = *(NUMBERFMTA *) pFormatW;
  1820. FormatA.lpDecimalSep = strDecimalSep;
  1821. FormatA.lpThousandSep = strThousandSep;
  1822. }
  1823. nResult = GetNumberFormatA(Locale, dwFlags, strValue, (pFormatW ? &FormatA : NULL), strNumberStr, strNumberStr.BufSize());
  1824. if (ERROR_SUCCESS == nResult)
  1825. strNumberStr.ConvertIncludingNul();
  1826. return nResult;
  1827. }
  1828. #endif // NEED_KERNEL32_WRAPPER
  1829. #ifdef NEED_USER32_WRAPPER
  1830. int WINAPI MessageBoxWrapW(HWND hwnd, LPCWSTR pwzText, LPCWSTR pwzCaption, UINT uType)
  1831. {
  1832. VALIDATE_PROTOTYPE(MessageBox);
  1833. if (g_bRunningOnNT)
  1834. return MessageBoxW(hwnd, pwzText, pwzCaption, uType);
  1835. CStrIn strCaption(pwzCaption);
  1836. CStrIn strText(pwzText);
  1837. return MessageBoxA(hwnd, strText, strCaption, uType);
  1838. }
  1839. #endif // NEED_USER32_WRAPPER
  1840. #ifdef NEED_KERNEL32_WRAPPER
  1841. BOOL WINAPI FindNextFileWrapW(HANDLE hSearchHandle, LPWIN32_FIND_DATAW pFindFileDataW)
  1842. {
  1843. VALIDATE_PROTOTYPE(FindNextFile);
  1844. if (g_bRunningOnNT)
  1845. return FindNextFileW(hSearchHandle, pFindFileDataW);
  1846. CWin32FindDataInOut fd(pFindFileDataW);
  1847. return FindNextFileA(hSearchHandle, fd);
  1848. }
  1849. #endif // NEED_KERNEL32_WRAPPER
  1850. #ifdef NEED_KERNEL32_WRAPPER
  1851. //--------------------------------------------------------------
  1852. // GetFullPathNameWrap
  1853. //--------------------------------------------------------------
  1854. DWORD
  1855. WINAPI
  1856. GetFullPathNameWrapW( LPCWSTR lpFileName,
  1857. DWORD nBufferLength,
  1858. LPWSTR lpBuffer,
  1859. LPWSTR *lpFilePart)
  1860. {
  1861. VALIDATE_PROTOTYPE(GetFullPathName);
  1862. VALIDATE_OUTBUF(lpBuffer, nBufferLength);
  1863. if (g_bRunningOnNT)
  1864. {
  1865. return GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
  1866. }
  1867. CStrIn strIn(lpFileName);
  1868. CStrOut strOut(lpBuffer,nBufferLength);
  1869. LPSTR pFile;
  1870. DWORD dwRet;
  1871. dwRet = GetFullPathNameA(strIn, nBufferLength, strOut, &pFile);
  1872. strOut.ConvertIncludingNul();
  1873. // BUGBUG raymondc - This is wrong if we had to do DBCS or related goo
  1874. *lpFilePart = lpBuffer + (pFile - strOut);
  1875. return dwRet;
  1876. }
  1877. #endif // NEED_KERNEL32_WRAPPER
  1878. #ifdef NEED_KERNEL32_WRAPPER
  1879. DWORD WINAPI
  1880. GetShortPathNameWrapW(
  1881. LPCWSTR lpszLongPath,
  1882. LPWSTR lpszShortPath,
  1883. DWORD cchBuffer)
  1884. {
  1885. VALIDATE_PROTOTYPE(GetShortPathName);
  1886. if (g_bRunningOnNT)
  1887. {
  1888. return GetShortPathNameW(lpszLongPath, lpszShortPath, cchBuffer);
  1889. }
  1890. CStrIn strLongPath(lpszLongPath);
  1891. CStrOut strShortPath(lpszShortPath, cchBuffer);
  1892. return GetShortPathNameA(strLongPath, strShortPath, strShortPath.BufSize());
  1893. }
  1894. #endif // NEED_KERNEL32_WRAPPER
  1895. #ifdef NEED_KERNEL32_WRAPPER
  1896. BOOL WINAPI
  1897. GetStringTypeExWrapW(LCID lcid, DWORD dwInfoType, LPCTSTR lpSrcStr, int cchSrc, LPWORD lpCharType)
  1898. {
  1899. VALIDATE_PROTOTYPE(GetStringTypeEx);
  1900. if (g_bRunningOnNT)
  1901. {
  1902. return GetStringTypeExW(lcid, dwInfoType, lpSrcStr, cchSrc, lpCharType);
  1903. }
  1904. CStrIn str(lpSrcStr, cchSrc);
  1905. return GetStringTypeExA(lcid, dwInfoType, str, str.strlen(), lpCharType);
  1906. }
  1907. #endif // NEED_KERNEL32_WRAPPER
  1908. #ifdef NEED_KERNEL32_WRAPPER
  1909. UINT WINAPI
  1910. GetPrivateProfileIntWrapW(
  1911. LPCWSTR lpAppName,
  1912. LPCWSTR lpKeyName,
  1913. INT nDefault,
  1914. LPCWSTR lpFileName)
  1915. {
  1916. VALIDATE_PROTOTYPE(GetPrivateProfileInt);
  1917. if (g_bRunningOnNT)
  1918. {
  1919. return GetPrivateProfileIntW(lpAppName, lpKeyName, nDefault, lpFileName);
  1920. }
  1921. CStrIn strApp(lpAppName);
  1922. CStrIn strKey(lpKeyName);
  1923. CStrIn strFile(lpFileName);
  1924. return GetPrivateProfileIntA(strApp, strKey, nDefault, strFile);
  1925. }
  1926. #endif // NEED_KERNEL32_WRAPPER
  1927. #ifdef NEED_KERNEL32_WRAPPER
  1928. DWORD WINAPI
  1929. GetProfileStringWrapW(
  1930. LPCWSTR lpAppName,
  1931. LPCWSTR lpKeyName,
  1932. LPCWSTR lpDefault,
  1933. LPWSTR lpBuffer,
  1934. DWORD dwBuffersize)
  1935. {
  1936. VALIDATE_PROTOTYPE(GetProfileString);
  1937. VALIDATE_OUTBUF(lpBuffer, dwBuffersize);
  1938. if (g_bRunningOnNT)
  1939. {
  1940. return GetProfileStringW(lpAppName, lpKeyName, lpDefault, lpBuffer, dwBuffersize);
  1941. }
  1942. CStrIn strApp(lpAppName);
  1943. CStrIn strKey(lpKeyName);
  1944. CStrIn strDefault(lpDefault);
  1945. CStrOut strBuffer(lpBuffer, dwBuffersize);
  1946. GetProfileStringA(strApp, strKey, strDefault, strBuffer, dwBuffersize);
  1947. return strBuffer.ConvertIncludingNul();
  1948. }
  1949. #endif // NEED_KERNEL32_WRAPPER
  1950. #ifdef NEED_USER32_WRAPPER
  1951. HANDLE WINAPI
  1952. GetPropWrapW(HWND hWnd, LPCWSTR lpString)
  1953. {
  1954. VALIDATE_PROTOTYPE(GetProp);
  1955. if (g_bRunningOnNT)
  1956. {
  1957. return GetPropW(hWnd, lpString);
  1958. }
  1959. CStrIn str(lpString);
  1960. return GetPropA(hWnd, str);
  1961. }
  1962. #endif // NEED_USER32_WRAPPER
  1963. #ifdef NEED_KERNEL32_WRAPPER
  1964. UINT WINAPI
  1965. GetTempFileNameWrapW(
  1966. LPCWSTR lpPathName,
  1967. LPCWSTR lpPrefixString,
  1968. UINT uUnique,
  1969. LPWSTR lpTempFileName)
  1970. {
  1971. VALIDATE_PROTOTYPE(GetTempFileName);
  1972. VALIDATE_OUTBUF(lpTempFileName, MAX_PATH);
  1973. if (g_bRunningOnNT)
  1974. {
  1975. return GetTempFileNameW(lpPathName, lpPrefixString, uUnique, lpTempFileName);
  1976. }
  1977. CStrIn strPath(lpPathName);
  1978. CStrIn strPrefix(lpPrefixString);
  1979. CStrOut strFileName(lpTempFileName, MAX_PATH);
  1980. return GetTempFileNameA(strPath, strPrefix, uUnique, strFileName);
  1981. }
  1982. #endif // NEED_KERNEL32_WRAPPER
  1983. #ifdef NEED_KERNEL32_WRAPPER
  1984. DWORD WINAPI
  1985. GetTempPathWrapW(DWORD nBufferLength, LPWSTR lpBuffer)
  1986. {
  1987. VALIDATE_PROTOTYPE(GetTempPath);
  1988. VALIDATE_OUTBUF(lpBuffer, nBufferLength);
  1989. if (g_bRunningOnNT)
  1990. {
  1991. return GetTempPathW(nBufferLength, lpBuffer);
  1992. }
  1993. CStrOut str(lpBuffer, nBufferLength);
  1994. GetTempPathA(str.BufSize(), str);
  1995. return str.ConvertExcludingNul();
  1996. }
  1997. #endif // NEED_KERNEL32_WRAPPER
  1998. #ifdef NEED_GDI32_WRAPPER
  1999. BOOL APIENTRY
  2000. GetTextExtentPoint32WrapW(
  2001. HDC hdc,
  2002. LPCWSTR pwsz,
  2003. int cb,
  2004. LPSIZE pSize)
  2005. {
  2006. VALIDATE_PROTOTYPE(GetTextExtentPoint32);
  2007. if (g_bRunningOnNT)
  2008. {
  2009. return GetTextExtentPoint32W(hdc, pwsz, cb, pSize);
  2010. }
  2011. CStrIn str(pwsz,cb);
  2012. return GetTextExtentPoint32A(hdc, str, str.strlen(), pSize);
  2013. }
  2014. #endif // NEED_GDI32_WRAPPER
  2015. #ifdef NEED_GDI32_WRAPPER
  2016. int WINAPI
  2017. GetTextFaceWrapW(
  2018. HDC hdc,
  2019. int cch,
  2020. LPWSTR lpFaceName)
  2021. {
  2022. VALIDATE_PROTOTYPE(GetTextFace);
  2023. VALIDATE_OUTBUF(lpFaceName, cch);
  2024. if (g_bRunningOnNT)
  2025. {
  2026. return GetTextFaceW(hdc, cch, lpFaceName);
  2027. }
  2028. CStrOut str(lpFaceName, cch);
  2029. GetTextFaceA(hdc, str.BufSize(), str);
  2030. return str.ConvertIncludingNul();
  2031. }
  2032. #endif // NEED_GDI32_WRAPPER
  2033. #ifdef NEED_GDI32_WRAPPER
  2034. BOOL WINAPI
  2035. GetTextMetricsWrapW(HDC hdc, LPTEXTMETRICW lptm)
  2036. {
  2037. VALIDATE_PROTOTYPE(GetTextMetrics);
  2038. if (g_bRunningOnNT)
  2039. {
  2040. return GetTextMetricsW(hdc, lptm);
  2041. }
  2042. BOOL ret;
  2043. TEXTMETRICA tm;
  2044. ret = GetTextMetricsA(hdc, &tm);
  2045. if (ret)
  2046. {
  2047. lptm->tmHeight = tm.tmHeight;
  2048. lptm->tmAscent = tm.tmAscent;
  2049. lptm->tmDescent = tm.tmDescent;
  2050. lptm->tmInternalLeading = tm.tmInternalLeading;
  2051. lptm->tmExternalLeading = tm.tmExternalLeading;
  2052. lptm->tmAveCharWidth = tm.tmAveCharWidth;
  2053. lptm->tmMaxCharWidth = tm.tmMaxCharWidth;
  2054. lptm->tmWeight = tm.tmWeight;
  2055. lptm->tmOverhang = tm.tmOverhang;
  2056. lptm->tmDigitizedAspectX = tm.tmDigitizedAspectX;
  2057. lptm->tmDigitizedAspectY = tm.tmDigitizedAspectY;
  2058. lptm->tmItalic = tm.tmItalic;
  2059. lptm->tmUnderlined = tm.tmUnderlined;
  2060. lptm->tmStruckOut = tm.tmStruckOut;
  2061. lptm->tmPitchAndFamily = tm.tmPitchAndFamily;
  2062. lptm->tmCharSet = tm.tmCharSet;
  2063. // LPBYTE -> LPCSTR casts below
  2064. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&tm.tmFirstChar, 1, &lptm->tmFirstChar, 1);
  2065. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&tm.tmLastChar, 1, &lptm->tmLastChar, 1);
  2066. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&tm.tmDefaultChar, 1, &lptm->tmDefaultChar, 1);
  2067. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&tm.tmBreakChar, 1, &lptm->tmBreakChar, 1);
  2068. }
  2069. return ret;
  2070. }
  2071. #endif // NEED_GDI32_WRAPPER
  2072. #ifdef NEED_ADVAPI32_WRAPPER
  2073. BOOL WINAPI GetUserNameWrapW(LPWSTR pszBuffer, LPDWORD pcch)
  2074. {
  2075. VALIDATE_PROTOTYPE(GetUserName);
  2076. BOOL fRet;
  2077. if (UseUnicodeShell32())
  2078. {
  2079. fRet = GetUserNameW(pszBuffer, pcch);
  2080. }
  2081. else
  2082. {
  2083. CStrOut stroBuffer(pszBuffer, *pcch);
  2084. fRet = GetUserNameA(stroBuffer, pcch);
  2085. if (fRet)
  2086. *pcch = stroBuffer.ConvertIncludingNul();
  2087. }
  2088. return fRet;
  2089. }
  2090. #endif // NEED_ADVAPI32_WRAPPER
  2091. #ifdef NEED_USER32_WRAPPER
  2092. LONG FORWARD_API WINAPI
  2093. GetWindowLongWrapW(HWND hWnd, int nIndex)
  2094. {
  2095. VALIDATE_PROTOTYPE(GetWindowLong);
  2096. FORWARD_AW(GetWindowLong, (hWnd, nIndex));
  2097. }
  2098. LONG_PTR FORWARD_API WINAPI
  2099. GetWindowLongPtrWrapW(
  2100. HWND hWnd,
  2101. int nIndex)
  2102. {
  2103. VALIDATE_PROTOTYPE(GetWindowLongPtr);
  2104. FORWARD_AW(GetWindowLongPtr, (hWnd, nIndex));
  2105. }
  2106. #endif // NEED_USER32_WRAPPER
  2107. #ifdef NEED_USER32_WRAPPER
  2108. int WINAPI
  2109. GetWindowTextWrapW(HWND hWnd, LPWSTR lpString, int nMaxCount)
  2110. {
  2111. VALIDATE_PROTOTYPE(GetWindowText);
  2112. VALIDATE_OUTBUF(lpString, nMaxCount);
  2113. if (g_bRunningOnNT)
  2114. {
  2115. return GetWindowTextW(hWnd, lpString, nMaxCount);
  2116. }
  2117. CStrOut str(lpString, nMaxCount);
  2118. GetWindowTextA(hWnd, str, str.BufSize());
  2119. return str.ConvertExcludingNul();
  2120. }
  2121. #endif // NEED_USER32_WRAPPER
  2122. #ifdef NEED_USER32_WRAPPER
  2123. int WINAPI
  2124. GetWindowTextLengthWrapW(HWND hWnd)
  2125. {
  2126. VALIDATE_PROTOTYPE(GetWindowTextLength);
  2127. if (g_bRunningOnNT)
  2128. {
  2129. return GetWindowTextLengthW(hWnd);
  2130. }
  2131. return GetWindowTextLengthA(hWnd);
  2132. }
  2133. #endif // NEED_USER32_WRAPPER
  2134. #ifdef NEED_KERNEL32_WRAPPER
  2135. UINT WINAPI
  2136. GetWindowsDirectoryWrapW(LPWSTR lpWinPath, UINT cch)
  2137. {
  2138. VALIDATE_PROTOTYPE(GetWindowsDirectory);
  2139. VALIDATE_OUTBUF(lpWinPath, cch);
  2140. if (g_bRunningOnNT)
  2141. {
  2142. return GetWindowsDirectoryW(lpWinPath, cch);
  2143. }
  2144. CStrOut str(lpWinPath, cch);
  2145. if (!GetWindowsDirectoryA(str, str.BufSize()))
  2146. {
  2147. return 0;
  2148. }
  2149. return str.ConvertExcludingNul();
  2150. }
  2151. #endif // NEED_KERNEL32_WRAPPER
  2152. #ifdef NEED_USER32_WRAPPER
  2153. BOOL WINAPI
  2154. InsertMenuWrapW(
  2155. HMENU hMenu,
  2156. UINT uPosition,
  2157. UINT uFlags,
  2158. UINT_PTR uIDNewItem,
  2159. LPCWSTR lpNewItem)
  2160. {
  2161. VALIDATE_PROTOTYPE(InsertMenu);
  2162. if (g_bRunningOnNT)
  2163. {
  2164. return InsertMenuW(hMenu, uPosition, uFlags, uIDNewItem, lpNewItem);
  2165. }
  2166. //
  2167. // You can't test for MFT_STRING because MFT_STRING is zero!
  2168. // So instead you have to check for everything *other* than
  2169. // a string.
  2170. //
  2171. // The presence of any non-string menu type turns lpnewItem into
  2172. // an atom.
  2173. //
  2174. CStrIn str((uFlags & MFT_NONSTRING) ? CP_ATOM : CP_ACP, lpNewItem);
  2175. return InsertMenuA(hMenu, uPosition, uFlags, uIDNewItem, str);
  2176. }
  2177. #endif // NEED_USER32_WRAPPER
  2178. #ifdef NEED_USER32_WRAPPER
  2179. BOOL FORWARD_API WINAPI
  2180. IsDialogMessageWrapW(HWND hWndDlg, LPMSG lpMsg)
  2181. {
  2182. VALIDATE_PROTOTYPE(IsDialogMessage);
  2183. FORWARD_AW(IsDialogMessage, (hWndDlg, lpMsg));
  2184. }
  2185. #endif // NEED_USER32_WRAPPER
  2186. #ifdef NEED_USER32_WRAPPER
  2187. HACCEL WINAPI
  2188. LoadAcceleratorsWrapW(HINSTANCE hInstance, LPCWSTR lpTableName)
  2189. {
  2190. VALIDATE_PROTOTYPE(LoadAccelerators);
  2191. ASSERT(HIWORD64(lpTableName) == 0);
  2192. if (g_bRunningOnNT)
  2193. {
  2194. return LoadAcceleratorsW(hInstance, lpTableName);
  2195. }
  2196. return LoadAcceleratorsA(hInstance, (LPCSTR) lpTableName);
  2197. }
  2198. #endif // NEED_USER32_WRAPPER
  2199. #ifdef NEED_USER32_WRAPPER
  2200. HBITMAP WINAPI
  2201. LoadBitmapWrapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
  2202. {
  2203. VALIDATE_PROTOTYPE(LoadBitmap);
  2204. ASSERT(HIWORD64(lpBitmapName) == 0);
  2205. if (g_bRunningOnNT)
  2206. {
  2207. return LoadBitmapW(hInstance, lpBitmapName);
  2208. }
  2209. return LoadBitmapA(hInstance, (LPCSTR) lpBitmapName);
  2210. }
  2211. #endif // NEED_USER32_WRAPPER
  2212. #ifdef NEED_USER32_WRAPPER
  2213. HCURSOR WINAPI
  2214. LoadCursorWrapW(HINSTANCE hInstance, LPCWSTR lpCursorName)
  2215. {
  2216. VALIDATE_PROTOTYPE(LoadCursor);
  2217. ASSERT(HIWORD64(lpCursorName) == 0);
  2218. if (g_bRunningOnNT)
  2219. {
  2220. return LoadCursorW(hInstance, lpCursorName);
  2221. }
  2222. return LoadCursorA(hInstance, (LPCSTR) lpCursorName);
  2223. }
  2224. #endif // NEED_USER32_WRAPPER
  2225. #ifdef NEED_USER32_WRAPPER
  2226. HICON WINAPI
  2227. LoadIconWrapW(HINSTANCE hInstance, LPCWSTR lpIconName)
  2228. {
  2229. VALIDATE_PROTOTYPE(LoadIcon);
  2230. ASSERT(HIWORD64(lpIconName) == 0);
  2231. if (g_bRunningOnNT)
  2232. {
  2233. return LoadIconW(hInstance, lpIconName);
  2234. }
  2235. return LoadIconA(hInstance, (LPCSTR) lpIconName);
  2236. }
  2237. #endif // NEED_USER32_WRAPPER
  2238. #ifdef NEED_USER32_WRAPPER
  2239. HANDLE WINAPI
  2240. LoadImageWrapW(
  2241. HINSTANCE hInstance,
  2242. LPCWSTR lpName,
  2243. UINT uType,
  2244. int cxDesired,
  2245. int cyDesired,
  2246. UINT fuLoad)
  2247. {
  2248. VALIDATE_PROTOTYPE(LoadImage);
  2249. if (g_bRunningOnNT)
  2250. {
  2251. return LoadImageW(
  2252. hInstance,
  2253. lpName,
  2254. uType,
  2255. cxDesired,
  2256. cyDesired,
  2257. fuLoad);
  2258. }
  2259. CStrIn str(lpName);
  2260. return LoadImageA(
  2261. hInstance,
  2262. str,
  2263. uType,
  2264. cxDesired,
  2265. cyDesired,
  2266. fuLoad);
  2267. }
  2268. #endif // NEED_USER32_WRAPPER
  2269. #ifdef NEED_KERNEL32_WRAPPER
  2270. HINSTANCE WINAPI
  2271. LoadLibraryExWrapW(
  2272. LPCWSTR lpLibFileName,
  2273. HANDLE hFile,
  2274. DWORD dwFlags)
  2275. {
  2276. VALIDATE_PROTOTYPE(LoadLibraryEx);
  2277. if (g_bRunningOnNT)
  2278. return LoadLibraryExW(lpLibFileName, hFile, dwFlags);
  2279. CStrIn str(lpLibFileName);
  2280. // Win9X will crash if the pathname is longer than MAX_PATH bytes.
  2281. if (str.strlen() >= MAX_PATH)
  2282. {
  2283. SetLastError( ERROR_BAD_PATHNAME );
  2284. return NULL;
  2285. }
  2286. else
  2287. {
  2288. return LoadLibraryExA(str, hFile, dwFlags);
  2289. }
  2290. }
  2291. #endif // NEED_KERNEL32_WRAPPER
  2292. #ifdef NEED_USER32_WRAPPER
  2293. HMENU WINAPI
  2294. LoadMenuWrapW(HINSTANCE hInstance, LPCWSTR lpMenuName)
  2295. {
  2296. VALIDATE_PROTOTYPE(LoadMenu);
  2297. ASSERT(HIWORD64(lpMenuName) == 0);
  2298. if (g_bRunningOnNT)
  2299. {
  2300. return LoadMenuW(hInstance, lpMenuName);
  2301. }
  2302. return LoadMenuA(hInstance, (LPCSTR) lpMenuName);
  2303. }
  2304. #endif // NEED_USER32_WRAPPER
  2305. #ifdef NEED_USER32_WRAPPER
  2306. int WINAPI
  2307. LoadStringWrapW(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax)
  2308. {
  2309. VALIDATE_PROTOTYPE(LoadString);
  2310. if (g_bRunningOnNT)
  2311. {
  2312. return LoadStringW(hInstance, uID, lpBuffer, nBufferMax);
  2313. }
  2314. //
  2315. // Do it manually. The old code used to call LoadStringA and then
  2316. // convert it up to unicode, which is bad since resources are
  2317. // physically already Unicode! Just take it out directly.
  2318. //
  2319. // The old code was also buggy in the case where the loaded string
  2320. // contains embedded NULLs.
  2321. //
  2322. if (nBufferMax <= 0) return 0; // sanity check
  2323. PWCHAR pwch;
  2324. /*
  2325. * String tables are broken up into "bundles" of 16 strings each.
  2326. */
  2327. HRSRC hrsrc;
  2328. int cwch = 0;
  2329. hrsrc = FindResourceA(hInstance, (LPSTR)(LONG_PTR)(1 + uID / 16), (LPSTR)RT_STRING);
  2330. if (hrsrc)
  2331. {
  2332. pwch = (PWCHAR)LoadResource(hInstance, hrsrc);
  2333. if (pwch)
  2334. {
  2335. /*
  2336. * Now skip over the strings in the resource until we
  2337. * hit the one we want. Each entry is a counted string,
  2338. * just like Pascal.
  2339. */
  2340. for (uID %= 16; uID; uID--)
  2341. {
  2342. pwch += *pwch + 1;
  2343. }
  2344. cwch = min(*pwch, nBufferMax - 1);
  2345. memcpy(lpBuffer, pwch+1, cwch * sizeof(WCHAR)); /* Copy the goo */
  2346. }
  2347. }
  2348. lpBuffer[cwch] = L'\0'; /* Terminate the string */
  2349. return cwch;
  2350. }
  2351. #endif // NEED_USER32_WRAPPER
  2352. //----------------------------------------------------------------------
  2353. //
  2354. // function: TransformCharNoOp1( WCHAR **ppch )
  2355. //
  2356. // purpose: Stand-in for TransformCharWidth. Used by the function
  2357. // CompareStringString.
  2358. //
  2359. // returns: Character at *ppch. The value *ppch is incremented.
  2360. //
  2361. //----------------------------------------------------------------------
  2362. static WCHAR
  2363. TransformCharNoOp1( LPCWSTR *ppch, int )
  2364. {
  2365. WCHAR ch = **ppch;
  2366. (*ppch)++;
  2367. return ch;
  2368. }
  2369. //----------------------------------------------------------------------
  2370. //
  2371. // function: TransformCharWidth( WCHAR **ppch, cchRemaining )
  2372. //
  2373. // purpose: Converts halfwidth characters to fullwidth characters.
  2374. // Also combines voiced (dakuon) and semi-voiced (handakuon)
  2375. // characters. *pch is advanced by one, unless there is a
  2376. // (semi)voiced character, in which case it is advanced by
  2377. // two characters.
  2378. //
  2379. // Note that unlike the full widechar version, we do not
  2380. // combine other characters, notably the combining Hiragana
  2381. // characters (U+3099 and U+309A.) This is to keep the
  2382. // tables from getting unnecessarily large.
  2383. //
  2384. // cchRemaining is passed so as to not include the voiced
  2385. // marks if it's passed the end of the specified buffer.
  2386. //
  2387. // returns: Full width character. *pch is incremented.
  2388. //
  2389. //----------------------------------------------------------------------
  2390. static WCHAR
  2391. TransformCharWidth( LPCWSTR *ppch, int cchRemaining )
  2392. {
  2393. WCHAR ch = **ppch;
  2394. (*ppch)++;
  2395. if (ch == 0x0020)
  2396. {
  2397. ch = 0x3000;
  2398. }
  2399. else if (ch == 0x005c)
  2400. {
  2401. // REVERSE SOLIDUS (aka BACKSLASH) maps to itself
  2402. }
  2403. else if (InRange(ch, 0x0021, 0x07e))
  2404. {
  2405. ch += 65248;
  2406. }
  2407. else if (InRange(ch, 0x00a2, 0x00af))
  2408. {
  2409. static const WCHAR achFull[] =
  2410. {
  2411. 0xffe0, 0xffe1, 0x00a4, 0xffe5, 0xffe4, 0x00a7, 0x00a8, // 0xa2-0xa8
  2412. 0x00a9, 0x00aa, 0x00ab, 0xffe2, 0x00ad, 0x00ae, 0xffe3 // 0xa9-0xaf
  2413. };
  2414. ch = achFull[ch - 0x00a2];
  2415. }
  2416. else if (ch == 0x20a9) // WON SIGN
  2417. {
  2418. ch = 0xffe6;
  2419. }
  2420. else if (InRange(ch, 0xff61, 0xffdc))
  2421. {
  2422. WCHAR chNext = (cchRemaining > 1) ? **ppch : 0;
  2423. if (chNext == 0xff9e && InRange(ch, 0xff73, 0xff8e))
  2424. {
  2425. if (cchRemaining != 1)
  2426. {
  2427. static const WCHAR achFull[] =
  2428. {
  2429. /* 0xff73-0xff79 */0xb0f4, 0x30a8, 0x30aa, 0xb0ac, 0xb0ae, 0xb0b0, 0xb0b2,
  2430. /* 0xff7a-0xff80 */ 0xb0b4, 0xb0b6, 0xb0b8, 0xb0ba, 0xb0bc, 0xb0be, 0xb0c0,
  2431. /* 0xff81-0xff87 */ 0xb0c2, 0xb0c5, 0xb0c7, 0xb0c9, 0x30ca, 0x30cb, 0x30cc,
  2432. /* 0xff88-0xff8e */ 0x30cd, 0x30ce, 0xb0d0, 0xb0d3, 0xb0d6, 0xb0d9, 0xb0dc
  2433. };
  2434. // HALFWIDTH KATAKANA VOICED SOUND MARK
  2435. WCHAR chTemp = achFull[ch - 0xff73];
  2436. // Some in the range absorb the sound mark.
  2437. // These are indicated by the set high-bit.
  2438. ch = chTemp & 0x7fff;
  2439. if (chTemp & 0x8000)
  2440. {
  2441. (*ppch)++;
  2442. }
  2443. }
  2444. }
  2445. else if (chNext == 0xff9f && InRange(ch, 0xff8a, 0xff8e))
  2446. {
  2447. // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
  2448. ch = 0x30d1 + (ch - 0xff8a) * 3;
  2449. (*ppch)++;
  2450. }
  2451. else
  2452. {
  2453. static const WCHAR achMapFullFFxx[] =
  2454. {
  2455. 0x3002, 0x300c, 0x300d, 0x3001, 0x30fb, 0x30f2, 0x30a1, // 0xff61-0xff67
  2456. 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, // 0xff68-0xff6e
  2457. 0x30c3, 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, // 0xff6f-0xff75
  2458. 0x30ab, 0x30ad, 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, // 0xff76-0xff7c
  2459. 0x30b9, 0x30bb, 0x30bd, 0x30bf, 0x30c1, 0x30c4, 0x30c6, // 0xff7d-0xff83
  2460. 0x30c8, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, // 0xff84-0xff8a
  2461. 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, // 0xff8b-0xff91
  2462. 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, 0x30ea, // 0xff92-0xff98
  2463. 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c, // 0xff99-0xff9f
  2464. 0x3164, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, // 0xffa0-0xffa6
  2465. 0x3137, 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, // 0xffa7-0xffad
  2466. 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, // 0xffae-0xffb4
  2467. 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, // 0xffb5-0xffbb
  2468. 0x314c, 0x314d, 0x314e, 0xffbf, 0xffc0, 0xffc1, 0x314f, // 0xffbc-0xffc2
  2469. 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0xffc8, 0xffc9, // 0xffc3-0xffc9
  2470. 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0xffd0, // 0xffca-0xffd0
  2471. 0xffd1, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, // 0xffd1-0xffd7
  2472. 0xffd8, 0xffd9, 0x3161, 0x3162, 0x3163 // 0xffd8-0xffac
  2473. };
  2474. ch = achMapFullFFxx[ch - 0xff61];
  2475. }
  2476. }
  2477. return ch;
  2478. }
  2479. //----------------------------------------------------------------------
  2480. //
  2481. // function: TransformaCharNoOp2( WCHAR ch )
  2482. //
  2483. // purpose: Stand-in for CharLowerBuffWrap. Used by the function
  2484. // CompareStringString.
  2485. //
  2486. // returns: Original character
  2487. //
  2488. //----------------------------------------------------------------------
  2489. static WCHAR
  2490. TransformCharNoOp2( WCHAR ch )
  2491. {
  2492. return ch;
  2493. }
  2494. //----------------------------------------------------------------------
  2495. //
  2496. // function: TransformaCharKana( WCHAR ch )
  2497. //
  2498. // purpose: Converts Hiragana characters to Katakana characters
  2499. //
  2500. // returns: Original character if not Hiragana,
  2501. // Katanaka character if Hiragana
  2502. //
  2503. //----------------------------------------------------------------------
  2504. static WCHAR
  2505. TransformCharKana( WCHAR ch )
  2506. {
  2507. if (((ch & 0xff00) == 0x3000) &&
  2508. (InRange(ch, 0x3041, 0x3094) || InRange(ch, 0x309d, 0x309e)))
  2509. {
  2510. ch += 0x060;
  2511. }
  2512. return ch;
  2513. }
  2514. //----------------------------------------------------------------------
  2515. //
  2516. // function: TransformCharNoOp3( LPWSTR pch, DWORD cch )
  2517. //
  2518. // purpose: Stand-in for CharLowerBuffWrap. Used by the function
  2519. // CompareStringString.
  2520. //
  2521. // returns: Character count (cch).
  2522. //
  2523. //----------------------------------------------------------------------
  2524. static DWORD
  2525. TransformCharNoOp3( LPWSTR, DWORD cch )
  2526. {
  2527. return cch;
  2528. }
  2529. //----------------------------------------------------------------------
  2530. //
  2531. // function: TransformaCharFinal( WCHAR ch )
  2532. //
  2533. // purpose: Converts "final" forms to regular forms
  2534. //
  2535. // returns: Original character if not Hiragana,
  2536. // Katanaka character if Hiragana
  2537. //
  2538. //----------------------------------------------------------------------
  2539. // BUGBUG (cthrash) We do not fold Presentation Forms (Alphabetic or Arabic)
  2540. static WCHAR
  2541. TransformCharFinal( WCHAR ch )
  2542. {
  2543. WCHAR chRet = ch;
  2544. if (ch >= 0x3c2) // short-circuit ASCII +
  2545. {
  2546. switch (ch)
  2547. {
  2548. case 0x03c2: // GREEK SMALL LETTER FINAL SIGMA
  2549. case 0x05da: // HEBREW LETTER FINAL KAF
  2550. case 0x05dd: // HEBREW LETTER FINAL MEM
  2551. case 0x05df: // HEBREW LETTER FINAL NUN
  2552. case 0x05e3: // HEBREW LETTER FINAL PE
  2553. case 0x05e5: // HEBREW LETTER FINAL TSADI
  2554. case 0xfb26: // HEBREW LETTER WIDE FINAL MEM
  2555. case 0xfb3a: // HEBREW LETTER FINAL KAF WITH DAGESH
  2556. case 0xfb43: // HEBREW LETTER FINAL PE WITH DAGESH
  2557. chRet++;
  2558. break;
  2559. }
  2560. }
  2561. return ch;
  2562. }
  2563. //----------------------------------------------------------------------
  2564. //
  2565. // function: CompareStringString( ... )
  2566. //
  2567. // purpose: Helper for CompareStringWrap.
  2568. //
  2569. // We handle the string comparsion for CompareStringWrap.
  2570. // We can convert each character to (1) fullwidth,
  2571. // (2) Katakana, and (3) lowercase, as necessary.
  2572. //
  2573. // returns: 1 - string A is less in lexical value as string B
  2574. // 2 - string B is equal in lexical value as string B
  2575. // 3 - string B is greater in lexical value as string B
  2576. //
  2577. //----------------------------------------------------------------------
  2578. #ifdef NEED_USER32_WRAPPER
  2579. #if UNUSED_DONOTBUILD
  2580. static int
  2581. CompareStringString(
  2582. DWORD dwFlags,
  2583. LPCWSTR lpA,
  2584. int cchA,
  2585. LPCWSTR lpB,
  2586. int cchB )
  2587. {
  2588. int nRet = 0;
  2589. WCHAR wchIgnoreNulA = cchA == -1 ? 0 : -1;
  2590. WCHAR wchIgnoreNulB = cchB == -1 ? 0 : -1;
  2591. WCHAR (*pfnTransformWidth)(LPCWSTR *, int);
  2592. WCHAR (*pfnTransformKana)(WCHAR);
  2593. DWORD (*pfnTransformLower)(LPWSTR, DWORD);
  2594. WCHAR (*pfnTransformFinal)(WCHAR);
  2595. pfnTransformWidth = (dwFlags & NORM_IGNOREWIDTH)
  2596. ? TransformCharWidth : TransformCharNoOp1;
  2597. pfnTransformKana = (dwFlags & NORM_IGNOREKANATYPE)
  2598. ? TransformCharKana : TransformCharNoOp2;
  2599. pfnTransformLower = (dwFlags & NORM_IGNORECASE)
  2600. ? CharLowerBuffWrap : TransformCharNoOp3;
  2601. pfnTransformFinal = (dwFlags & NORM_IGNORECASE)
  2602. ? TransformCharFinal : TransformCharNoOp2;
  2603. while ( !nRet
  2604. && cchA
  2605. && cchB
  2606. && (*lpA | wchIgnoreNulA)
  2607. && (*lpB | wchIgnoreNulB) )
  2608. {
  2609. WCHAR chA, chB;
  2610. LPCWSTR lpAOld = lpA;
  2611. LPCWSTR lpBOld = lpB;
  2612. chA = (*pfnTransformWidth)(&lpA, cchA);
  2613. chA = (*pfnTransformKana)(chA);
  2614. (*pfnTransformLower)(&chA, 1);
  2615. chA = (*pfnTransformFinal)(chA);
  2616. chB = (*pfnTransformWidth)(&lpB, cchB);
  2617. chB = (*pfnTransformKana)(chB);
  2618. (*pfnTransformLower)(&chB, 1);
  2619. chB = (*pfnTransformFinal)(chB);
  2620. nRet = (int)chA - (int)chB;
  2621. cchA -= (int) (lpA - lpAOld);
  2622. cchB -= (int) (lpB - lpBOld);
  2623. }
  2624. if (!nRet)
  2625. {
  2626. nRet = cchA - cchB;
  2627. }
  2628. if (nRet)
  2629. {
  2630. nRet = nRet > 0 ? 1 : -1;
  2631. }
  2632. return nRet + 2;
  2633. }
  2634. #endif //UNUSED_DONOTBUILD
  2635. #endif // NEED_USER32_WRAPPER
  2636. //----------------------------------------------------------------------
  2637. //
  2638. // function: CompareStringWord( ... )
  2639. //
  2640. // purpose: Helper for CompareStringWrap.
  2641. //
  2642. // We handle the word comparsion for CompareStringWrap.
  2643. //
  2644. // returns: 1 - string A is less in lexical value as string B
  2645. // 2 - string B is equal in lexical value as string B
  2646. // 3 - string B is greater in lexical value as string B
  2647. //
  2648. //----------------------------------------------------------------------
  2649. static int
  2650. CompareStringWord(
  2651. LCID lcid,
  2652. DWORD dwFlags,
  2653. LPCWSTR lpA,
  2654. int cchA,
  2655. LPCWSTR lpB,
  2656. int cchB )
  2657. {
  2658. // BUGBUG (cthrash) We won't properly support word compare for the
  2659. // time being. Do the same old CP_ACP trick, which should cover
  2660. // enough cases.
  2661. // fail if either string is NULL, as it causes assert on debug windows
  2662. if (!lpA || !lpB)
  2663. return 0;
  2664. CStrIn strA(lpA, cchA);
  2665. CStrIn strB(lpB, cchB);
  2666. cchA = strA.strlen();
  2667. cchB = strB.strlen();
  2668. return CompareStringA(lcid, dwFlags, strA, cchA, strB, cchB);
  2669. }
  2670. //----------------------------------------------------------------------
  2671. //
  2672. // function: CompareStringWrapW( ... )
  2673. //
  2674. // purpose: Unicode wrapper of CompareString for Win95.
  2675. //
  2676. // Note not all bits in dwFlags are honored; specifically,
  2677. // since we don't do a true widechar word compare, we
  2678. // won't properly handle NORM_IGNORENONSPACE or
  2679. // NORM_IGNORESYMBOLS for arbitrary widechar strings.
  2680. //
  2681. // returns: 1 - string A is less in lexical value as string B
  2682. // 2 - string B is equal in lexical value as string B
  2683. // 3 - string B is greater in lexical value as string B
  2684. //
  2685. //----------------------------------------------------------------------
  2686. #if UNUSED_DONOTBUILD
  2687. #ifdef NEED_USER32_WRAPPER
  2688. FUS9xWRAPAPI(int)
  2689. CompareStringAltW(
  2690. LCID lcid,
  2691. DWORD dwFlags,
  2692. LPCWSTR lpA,
  2693. int cchA,
  2694. LPCWSTR lpB,
  2695. int cchB )
  2696. {
  2697. if (g_bRunningOnNT)
  2698. {
  2699. return CompareStringW(lcid, dwFlags, lpA, cchA, lpB, cchB);
  2700. }
  2701. int nRet;
  2702. if (dwFlags & SORT_STRINGSORT)
  2703. {
  2704. nRet = CompareStringString(dwFlags, lpA, cchA, lpB, cchB);
  2705. }
  2706. else
  2707. {
  2708. nRet = CompareStringWord(lcid, dwFlags, lpA, cchA, lpB, cchB);
  2709. }
  2710. return nRet;
  2711. }
  2712. #endif // NEED_KERNEL32_WRAPPER
  2713. #ifdef NEED_KERNEL32_WRAPPER
  2714. int WINAPI
  2715. CompareStringWrapW(
  2716. LCID Locale,
  2717. DWORD dwCmpFlags,
  2718. LPCWSTR lpString1,
  2719. int cchCount1,
  2720. LPCWSTR lpString2,
  2721. int cchCount2)
  2722. {
  2723. VALIDATE_PROTOTYPE(CompareString);
  2724. if (g_bRunningOnNT)
  2725. {
  2726. return CompareStringW(Locale,
  2727. dwCmpFlags,
  2728. lpString1,
  2729. cchCount1,
  2730. lpString2,
  2731. cchCount2);
  2732. }
  2733. // fail if either string is NULL, as it causes assert on debug windows
  2734. if (!lpString1 || !lpString2)
  2735. return 0;
  2736. CStrIn strString1(lpString1, cchCount1);
  2737. CStrIn strString2(lpString2, cchCount2);
  2738. cchCount1 = strString1.strlen();
  2739. cchCount2 = strString2.strlen();
  2740. return CompareStringA(Locale, dwCmpFlags & ~NORM_STOP_ON_NULL,
  2741. strString1, cchCount1, strString2, cchCount2);
  2742. }
  2743. #endif // NEED_KERNEL32_WRAPPER
  2744. #endif //#if UNUSED_DONOTBUILD
  2745. #ifdef NEED_USER32_WRAPPER
  2746. #ifndef UNIX
  2747. BOOL WINAPI
  2748. MessageBoxIndirectWrapW(CONST MSGBOXPARAMS *pmbp)
  2749. #else
  2750. int WINAPI
  2751. MessageBoxIndirectWrapW(LPMSGBOXPARAMS pmbp)
  2752. #endif /* UNIX */
  2753. {
  2754. VALIDATE_PROTOTYPE(MessageBoxIndirect);
  2755. ASSERT(HIWORD64(pmbp->lpszIcon) == 0);
  2756. if (g_bRunningOnNT)
  2757. {
  2758. return MessageBoxIndirectW(pmbp);
  2759. }
  2760. CStrIn strText(pmbp->lpszText);
  2761. CStrIn strCaption(pmbp->lpszCaption);
  2762. MSGBOXPARAMSA mbp;
  2763. memcpy(&mbp, pmbp, sizeof(mbp));
  2764. mbp.lpszText = strText;
  2765. mbp.lpszCaption = strCaption;
  2766. return MessageBoxIndirectA(&mbp);
  2767. }
  2768. #endif // NEED_USER32_WRAPPER
  2769. #ifdef NEED_GDI32_WRAPPER
  2770. DWORD GetCharacterPlacementWrapW(
  2771. HDC hdc, // handle to device context
  2772. LPCTSTR lpString, // pointer to string
  2773. int nCount, // number of characters in string
  2774. int nMaxExtent, // maximum extent for displayed string
  2775. LPGCP_RESULTS lpResults, // pointer to buffer for placement result
  2776. DWORD dwFlags // placement flags
  2777. )
  2778. {
  2779. VALIDATE_PROTOTYPE(GetCharacterPlacement);
  2780. // Leave for someone else.
  2781. ASSERT (lpResults->lpOutString == NULL);
  2782. ASSERT (lpResults->lpClass == NULL);
  2783. if (g_bRunningOnNT)
  2784. {
  2785. return GetCharacterPlacementW (hdc,
  2786. lpString,
  2787. nCount,
  2788. nMaxExtent,
  2789. lpResults,
  2790. dwFlags);
  2791. }
  2792. CStrIn strText(lpString);
  2793. DWORD dwRet;
  2794. dwRet = GetCharacterPlacementA (hdc, strText, nCount, nMaxExtent,
  2795. (LPGCP_RESULTSA)lpResults,
  2796. dwFlags);
  2797. return dwRet;
  2798. }
  2799. #endif // NEED_GDI32_WRAPPER
  2800. #ifdef NEED_GDI32_WRAPPER
  2801. //
  2802. // Note that we're calling get GetCharWidthA instead of GetCharWidth32A
  2803. // because the 32 version doesn't exist under Win95.
  2804. BOOL WINAPI GetCharWidth32WrapW(
  2805. HDC hdc,
  2806. UINT iFirstChar,
  2807. UINT iLastChar,
  2808. LPINT lpBuffer)
  2809. {
  2810. VALIDATE_PROTOTYPE(GetCharWidth32);
  2811. if (g_bRunningOnNT)
  2812. {
  2813. return GetCharWidth32W (hdc, iFirstChar, iLastChar, lpBuffer);
  2814. }
  2815. // Note that we expect to do only one character at a time for anything but
  2816. // ISO Latin 1.
  2817. if (iFirstChar > 255)
  2818. {
  2819. UINT mbChar=0;
  2820. WCHAR ch;
  2821. // Convert string
  2822. ch = (WCHAR)iFirstChar;
  2823. WideCharToMultiByte(CP_ACP, 0, &ch, 1,
  2824. (char *)&mbChar, 2, NULL, NULL);
  2825. }
  2826. return(GetCharWidthA (hdc, iFirstChar, iLastChar, lpBuffer));
  2827. }
  2828. #endif // NEED_GDI32_WRAPPER
  2829. //
  2830. // Note: Win95 does support ExtTextOutW. This thunk is not for
  2831. // ANSI/UNICODE wrapping. It's to work around an ISV app bug.
  2832. //
  2833. // Y'see, there's an app that patches Win95 GDI and their ExtTextOutW handler
  2834. // is broken. It always dereferences the lpStr parameter, even if
  2835. // cch is zero. Consequently, any time we are about to pass NULL as
  2836. // the lpStr, we have to change our mind and pass a null UNICODE string
  2837. // instead.
  2838. //
  2839. // The name of this app: Lotus SmartSuite ScreenCam 97.
  2840. //
  2841. FUS9xWRAPAPI(BOOL)
  2842. ExtTextOutWrapW(HDC hdc, int x, int y, UINT fuOptions, CONST RECT *lprc, LPCWSTR lpStr, UINT cch, CONST INT *lpDx)
  2843. {
  2844. VALIDATE_PROTOTYPE(ExtTextOut);
  2845. if (lpStr == NULL) // Stupid workaround
  2846. lpStr = L""; // for ScreenCam 97
  2847. return ExtTextOutW(hdc, x, y, fuOptions, lprc, lpStr, cch, lpDx);
  2848. }
  2849. #ifdef NEED_USER32_WRAPPER
  2850. BOOL WINAPI
  2851. ModifyMenuWrapW(
  2852. HMENU hMenu,
  2853. UINT uPosition,
  2854. UINT uFlags,
  2855. UINT_PTR uIDNewItem,
  2856. LPCWSTR lpNewItem)
  2857. {
  2858. VALIDATE_PROTOTYPE(ModifyMenu);
  2859. ASSERT(!(uFlags & MF_BITMAP) && !(uFlags & MF_OWNERDRAW));
  2860. if (g_bRunningOnNT)
  2861. {
  2862. return ModifyMenuW(hMenu, uPosition, uFlags, uIDNewItem, lpNewItem);
  2863. }
  2864. CStrIn str(lpNewItem);
  2865. return ModifyMenuA(hMenu, uPosition, uFlags, uIDNewItem, str);
  2866. }
  2867. #endif // NEED_USER32_WRAPPER
  2868. #ifdef NEED_KERNEL32_WRAPPER
  2869. BOOL WINAPI
  2870. CopyFileWrapW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
  2871. {
  2872. VALIDATE_PROTOTYPE(CopyFile);
  2873. if (g_bRunningOnNT)
  2874. {
  2875. return CopyFileW(lpExistingFileName, lpNewFileName, bFailIfExists);
  2876. }
  2877. CStrIn strOld(lpExistingFileName);
  2878. CStrIn strNew(lpNewFileName);
  2879. return CopyFileA(strOld, strNew, bFailIfExists);
  2880. }
  2881. #endif // NEED_KERNEL32_WRAPPER
  2882. #ifdef NEED_KERNEL32_WRAPPER
  2883. BOOL WINAPI
  2884. MoveFileWrapW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
  2885. {
  2886. VALIDATE_PROTOTYPE(MoveFile);
  2887. if (g_bRunningOnNT)
  2888. {
  2889. return MoveFileW(lpExistingFileName, lpNewFileName);
  2890. }
  2891. CStrIn strOld(lpExistingFileName);
  2892. CStrIn strNew(lpNewFileName);
  2893. return MoveFileA(strOld, strNew);
  2894. }
  2895. #endif // NEED_KERNEL32_WRAPPER
  2896. #ifdef NEED_USER32_WRAPPER
  2897. #endif // NEED_USER32_WRAPPER
  2898. #ifdef NEED_KERNEL32_WRAPPER
  2899. HANDLE WINAPI
  2900. OpenEventWrapW(
  2901. DWORD fdwAccess,
  2902. BOOL fInherit,
  2903. LPCWSTR lpszEventName)
  2904. {
  2905. VALIDATE_PROTOTYPE(OpenEvent);
  2906. if (g_bRunningOnNT)
  2907. {
  2908. return OpenEventW(fdwAccess, fInherit, lpszEventName);
  2909. }
  2910. CStrIn strEventName(lpszEventName);
  2911. return OpenEventA(fdwAccess, fInherit, strEventName);
  2912. }
  2913. #endif // NEED_KERNEL32_WRAPPER
  2914. #ifdef NEED_KERNEL32_WRAPPER
  2915. VOID WINAPI
  2916. OutputDebugStringWrapW(LPCWSTR lpOutputString)
  2917. {
  2918. VALIDATE_PROTOTYPE(OutputDebugString);
  2919. if (g_bRunningOnNT)
  2920. {
  2921. OutputDebugStringW(lpOutputString);
  2922. return;
  2923. }
  2924. CStrIn str(lpOutputString);
  2925. OutputDebugStringA(str);
  2926. }
  2927. #endif // NEED_KERNEL32_WRAPPER
  2928. #ifdef NEED_USER32_WRAPPER
  2929. BOOL FORWARD_API WINAPI
  2930. PeekMessageWrapW(
  2931. LPMSG lpMsg,
  2932. HWND hWnd,
  2933. UINT wMsgFilterMin,
  2934. UINT wMsgFilterMax,
  2935. UINT wRemoveMsg)
  2936. {
  2937. VALIDATE_PROTOTYPE(PeekMessage);
  2938. FORWARD_AW(PeekMessage, (lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg));
  2939. }
  2940. #endif // NEED_USER32_WRAPPER
  2941. #ifdef NEED_WINMM_WRAPPER
  2942. FUS9xWRAPAPI(BOOL)
  2943. PlaySoundWrapW(
  2944. LPCWSTR pszSound,
  2945. HMODULE hmod,
  2946. DWORD fdwSound)
  2947. {
  2948. VALIDATE_PROTOTYPE_DELAYLOAD(PlaySound, _PlaySound);
  2949. if (g_bRunningOnNT)
  2950. {
  2951. return _PlaySoundW(pszSound, hmod, fdwSound);
  2952. }
  2953. CStrIn strSound(pszSound);
  2954. return _PlaySoundA(strSound, hmod, fdwSound);
  2955. }
  2956. #endif // NEED_WINMM_WRAPPER
  2957. #ifdef NEED_USER32_WRAPPER
  2958. BOOL FORWARD_API WINAPI
  2959. PostMessageWrapW(
  2960. HWND hWnd,
  2961. UINT Msg,
  2962. WPARAM wParam,
  2963. LPARAM lParam)
  2964. {
  2965. VALIDATE_PROTOTYPE(PostMessage);
  2966. FORWARD_AW(PostMessage, (hWnd, Msg, wParam, lParam));
  2967. }
  2968. #endif // NEED_USER32_WRAPPER
  2969. #ifdef NEED_USER32_WRAPPER
  2970. BOOL FORWARD_API WINAPI
  2971. PostThreadMessageWrapW(
  2972. DWORD idThread,
  2973. UINT Msg,
  2974. WPARAM wParam,
  2975. LPARAM lParam)
  2976. {
  2977. VALIDATE_PROTOTYPE(PostThreadMessage);
  2978. FORWARD_AW(PostThreadMessage, (idThread, Msg, wParam, lParam));
  2979. }
  2980. #endif // NEED_USER32_WRAPPER
  2981. #ifdef NEED_ADVAPI32_WRAPPER
  2982. LONG APIENTRY
  2983. RegCreateKeyWrapW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
  2984. {
  2985. VALIDATE_PROTOTYPE(RegCreateKey);
  2986. if (g_bRunningOnNT)
  2987. {
  2988. return RegCreateKeyW(hKey, lpSubKey, phkResult);
  2989. }
  2990. CStrIn str(lpSubKey);
  2991. return RegCreateKeyA(hKey, str, phkResult);
  2992. }
  2993. #endif // NEED_ADVAPI32_WRAPPER
  2994. #ifdef NEED_ADVAPI32_WRAPPER
  2995. LONG APIENTRY
  2996. RegCreateKeyExWrapW(HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)
  2997. {
  2998. VALIDATE_PROTOTYPE(RegCreateKeyEx);
  2999. if (g_bRunningOnNT)
  3000. {
  3001. return RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
  3002. }
  3003. CStrIn strSubKey(lpSubKey);
  3004. CStrIn strClass(lpClass);
  3005. return RegCreateKeyExA(hKey, strSubKey, Reserved, strClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
  3006. }
  3007. #endif // NEED_ADVAPI32_WRAPPER
  3008. #ifdef NEED_ADVAPI32_WRAPPER
  3009. //
  3010. // Subtle difference: RegDeleteKey on Win9x will recursively delete subkeys.
  3011. // On NT, it fails if the key being deleted has subkeys. If you need to
  3012. // force NT-style behavior, use SHDeleteEmptyKey. To force 95-style
  3013. // behavior, use SHDeleteKey.
  3014. //
  3015. LONG APIENTRY
  3016. RegDeleteKeyWrapW(HKEY hKey, LPCWSTR pwszSubKey)
  3017. {
  3018. VALIDATE_PROTOTYPE(RegDeleteKey);
  3019. if (g_bRunningOnNT)
  3020. {
  3021. return RegDeleteKeyW(hKey, pwszSubKey);
  3022. }
  3023. CStrIn str(pwszSubKey);
  3024. return RegDeleteKeyA(hKey, str);
  3025. }
  3026. #endif // NEED_ADVAPI32_WRAPPER
  3027. #ifdef NEED_ADVAPI32_WRAPPER
  3028. LONG APIENTRY
  3029. RegDeleteValueWrapW(HKEY hKey, LPCWSTR pwszSubKey)
  3030. {
  3031. VALIDATE_PROTOTYPE(RegDeleteValue);
  3032. if (g_bRunningOnNT)
  3033. {
  3034. return RegDeleteValueW(hKey, pwszSubKey);
  3035. }
  3036. CStrIn str(pwszSubKey);
  3037. return RegDeleteValueA(hKey, str);
  3038. }
  3039. #endif // NEED_ADVAPI32_WRAPPER
  3040. #ifdef NEED_ADVAPI32_WRAPPER
  3041. LONG APIENTRY
  3042. RegEnumKeyWrapW(
  3043. HKEY hKey,
  3044. DWORD dwIndex,
  3045. LPWSTR lpName,
  3046. DWORD cbName)
  3047. {
  3048. VALIDATE_PROTOTYPE(RegEnumKey);
  3049. VALIDATE_OUTBUF(lpName, cbName);
  3050. if (g_bRunningOnNT)
  3051. {
  3052. return RegEnumKeyW(hKey, dwIndex, lpName, cbName);
  3053. }
  3054. CStrOut str(lpName, cbName);
  3055. return RegEnumKeyA(hKey, dwIndex, str, str.BufSize());
  3056. }
  3057. #endif // NEED_ADVAPI32_WRAPPER
  3058. #ifdef NEED_ADVAPI32_WRAPPER
  3059. LONG APIENTRY
  3060. RegEnumKeyExWrapW(
  3061. HKEY hKey,
  3062. DWORD dwIndex,
  3063. LPWSTR lpName,
  3064. LPDWORD lpcbName,
  3065. LPDWORD lpReserved,
  3066. LPWSTR lpClass,
  3067. LPDWORD lpcbClass,
  3068. PFILETIME lpftLastWriteTime)
  3069. {
  3070. VALIDATE_PROTOTYPE(RegEnumKeyEx);
  3071. if (lpcbName)
  3072. {
  3073. VALIDATE_OUTBUF(lpName, *lpcbName);
  3074. }
  3075. if (lpcbClass)
  3076. {
  3077. VALIDATE_OUTBUF(lpClass, *lpcbClass);
  3078. }
  3079. if (g_bRunningOnNT)
  3080. {
  3081. return RegEnumKeyExW(
  3082. hKey,
  3083. dwIndex,
  3084. lpName,
  3085. lpcbName,
  3086. lpReserved,
  3087. lpClass,
  3088. lpcbClass,
  3089. lpftLastWriteTime);
  3090. }
  3091. long ret;
  3092. DWORD dwClass = 0;
  3093. if (!lpcbClass)
  3094. {
  3095. lpcbClass = &dwClass;
  3096. }
  3097. CStrOut strName(lpName, *lpcbName);
  3098. CStrOut strClass(lpClass, *lpcbClass);
  3099. ret = RegEnumKeyExA(
  3100. hKey,
  3101. dwIndex,
  3102. strName,
  3103. lpcbName,
  3104. lpReserved,
  3105. strClass,
  3106. lpcbClass,
  3107. lpftLastWriteTime);
  3108. *lpcbName = strName.ConvertExcludingNul();
  3109. *lpcbClass = strClass.ConvertExcludingNul();
  3110. return ret;
  3111. }
  3112. #endif // NEED_ADVAPI32_WRAPPER
  3113. #ifdef NEED_ADVAPI32_WRAPPER
  3114. LONG WINAPI RegEnumValueWrapW(HKEY hkey, DWORD dwIndex, LPWSTR lpValueName,
  3115. LPDWORD lpcbValueName, LPDWORD lpReserved,
  3116. LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
  3117. {
  3118. VALIDATE_PROTOTYPE(RegEnumValue);
  3119. LONG lRet;
  3120. if (UseUnicodeShell32())
  3121. {
  3122. lRet = RegEnumValueW(hkey, dwIndex, lpValueName, lpcbValueName,
  3123. lpReserved, lpType, lpData, lpcbData);
  3124. }
  3125. else
  3126. {
  3127. CStrOut stroValueName(lpValueName, *lpcbValueName);
  3128. DWORD dwTypeTemp;
  3129. if (lpData)
  3130. {
  3131. ASSERT(lpcbData);
  3132. CStrOut stroData((LPWSTR)lpData, (*lpcbData) / sizeof(WCHAR));
  3133. lRet = RegEnumValueA(hkey, dwIndex, stroValueName, lpcbValueName,
  3134. lpReserved, &dwTypeTemp,
  3135. (LPBYTE)(LPSTR)stroData, lpcbData);
  3136. if (ERROR_SUCCESS == lRet)
  3137. {
  3138. if (REG_SZ == dwTypeTemp)
  3139. {
  3140. *lpcbData = sizeof(WCHAR) * stroData.ConvertIncludingNul();
  3141. }
  3142. else if (REG_BINARY == dwTypeTemp)
  3143. {
  3144. stroData.CopyNoConvert(*lpcbData);
  3145. }
  3146. }
  3147. }
  3148. else
  3149. {
  3150. lRet = RegEnumValueA(hkey, dwIndex, stroValueName, lpcbValueName,
  3151. lpReserved, &dwTypeTemp, lpData, lpcbData);
  3152. }
  3153. if (ERROR_SUCCESS == lRet)
  3154. *lpcbValueName = stroValueName.ConvertExcludingNul();
  3155. if (lpType)
  3156. *lpType = dwTypeTemp;
  3157. }
  3158. return lRet;
  3159. }
  3160. #endif // NEED_ADVAPI32_WRAPPER
  3161. #ifdef NEED_ADVAPI32_WRAPPER
  3162. LONG APIENTRY
  3163. RegOpenKeyWrapW(HKEY hKey, LPCWSTR pwszSubKey, PHKEY phkResult)
  3164. {
  3165. VALIDATE_PROTOTYPE(RegOpenKey);
  3166. if (g_bRunningOnNT)
  3167. {
  3168. return RegOpenKeyW(hKey, pwszSubKey, phkResult);
  3169. }
  3170. CStrIn str(pwszSubKey);
  3171. return RegOpenKeyA(hKey, str, phkResult);
  3172. }
  3173. #endif // NEED_ADVAPI32_WRAPPER
  3174. #ifdef NEED_ADVAPI32_WRAPPER
  3175. LONG APIENTRY
  3176. RegOpenKeyExWrapW(
  3177. HKEY hKey,
  3178. LPCWSTR lpSubKey,
  3179. DWORD ulOptions,
  3180. REGSAM samDesired,
  3181. PHKEY phkResult)
  3182. {
  3183. VALIDATE_PROTOTYPE(RegOpenKeyEx);
  3184. if (g_bRunningOnNT)
  3185. {
  3186. return RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
  3187. }
  3188. CStrIn str(lpSubKey);
  3189. return RegOpenKeyExA(hKey, str, ulOptions, samDesired, phkResult);
  3190. }
  3191. #endif // NEED_ADVAPI32_WRAPPER
  3192. #ifdef NEED_ADVAPI32_WRAPPER
  3193. LONG APIENTRY
  3194. RegQueryInfoKeyWrapW(
  3195. HKEY hKey,
  3196. LPWSTR lpClass,
  3197. LPDWORD lpcbClass,
  3198. LPDWORD lpReserved,
  3199. LPDWORD lpcSubKeys,
  3200. LPDWORD lpcbMaxSubKeyLen,
  3201. LPDWORD lpcbMaxClassLen,
  3202. LPDWORD lpcValues,
  3203. LPDWORD lpcbMaxValueNameLen,
  3204. LPDWORD lpcbMaxValueLen,
  3205. LPDWORD lpcbSecurityDescriptor,
  3206. PFILETIME lpftLastWriteTime)
  3207. {
  3208. VALIDATE_PROTOTYPE(RegQueryInfoKey);
  3209. if (g_bRunningOnNT)
  3210. {
  3211. return RegQueryInfoKeyW(
  3212. hKey,
  3213. lpClass,
  3214. lpcbClass,
  3215. lpReserved,
  3216. lpcSubKeys,
  3217. lpcbMaxSubKeyLen,
  3218. lpcbMaxClassLen,
  3219. lpcValues,
  3220. lpcbMaxValueNameLen,
  3221. lpcbMaxValueLen,
  3222. lpcbSecurityDescriptor,
  3223. lpftLastWriteTime);
  3224. }
  3225. CStrIn str(lpClass);
  3226. return RegQueryInfoKeyA(
  3227. hKey,
  3228. str,
  3229. lpcbClass,
  3230. lpReserved,
  3231. lpcSubKeys,
  3232. lpcbMaxSubKeyLen,
  3233. lpcbMaxClassLen,
  3234. lpcValues,
  3235. lpcbMaxValueNameLen,
  3236. lpcbMaxValueLen,
  3237. lpcbSecurityDescriptor,
  3238. lpftLastWriteTime);
  3239. }
  3240. #endif // NEED_ADVAPI32_WRAPPER
  3241. #ifdef NEED_ADVAPI32_WRAPPER
  3242. LONG APIENTRY
  3243. RegQueryValueWrapW(
  3244. HKEY hKey,
  3245. LPCWSTR pwszSubKey,
  3246. LPWSTR pwszValue,
  3247. PLONG lpcbValue)
  3248. {
  3249. VALIDATE_PROTOTYPE(RegQueryValue);
  3250. if (lpcbValue)
  3251. {
  3252. VALIDATE_OUTBUF(pwszValue, *lpcbValue);
  3253. }
  3254. if (g_bRunningOnNT)
  3255. {
  3256. return RegQueryValueW(hKey, pwszSubKey, pwszValue, lpcbValue);
  3257. }
  3258. long ret;
  3259. long cb;
  3260. CStrIn strKey(pwszSubKey);
  3261. CStrOut strValue(pwszValue, (lpcbValue ? ((*lpcbValue) / sizeof(WCHAR)) : 0));
  3262. cb = strValue.BufSize();
  3263. ret = RegQueryValueA(hKey, strKey, strValue, (lpcbValue ? &cb : NULL));
  3264. if (ret != ERROR_SUCCESS)
  3265. goto Cleanup;
  3266. if (strValue)
  3267. {
  3268. cb = strValue.ConvertIncludingNul();
  3269. }
  3270. if (lpcbValue)
  3271. *lpcbValue = cb * sizeof(WCHAR);
  3272. Cleanup:
  3273. return ret;
  3274. }
  3275. #endif // NEED_ADVAPI32_WRAPPER
  3276. #ifdef NEED_ADVAPI32_WRAPPER
  3277. LONG APIENTRY
  3278. RegQueryValueExWrapW(
  3279. HKEY hKey,
  3280. LPCWSTR lpValueName,
  3281. LPDWORD lpReserved,
  3282. LPDWORD lpType,
  3283. LPBYTE lpData,
  3284. LPDWORD lpcbData)
  3285. {
  3286. VALIDATE_PROTOTYPE(RegQueryValueEx);
  3287. if (lpcbData)
  3288. {
  3289. VALIDATE_OUTBUF(lpData, *lpcbData);
  3290. }
  3291. LONG ret;
  3292. DWORD dwTempType;
  3293. if (g_bRunningOnNT)
  3294. {
  3295. #if DBG
  3296. if (lpType == NULL)
  3297. lpType = &dwTempType;
  3298. #endif
  3299. ret = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
  3300. if (ret == ERROR_SUCCESS)
  3301. {
  3302. // The Win9x wrapper does not support REG_MULTI_SZ, so it had
  3303. // better not be one
  3304. ASSERT(*lpType != REG_MULTI_SZ);
  3305. }
  3306. return ret;
  3307. }
  3308. CStrIn strValueName(lpValueName);
  3309. DWORD cb;
  3310. //
  3311. // Determine the type of buffer needed
  3312. //
  3313. ret = RegQueryValueExA(hKey, strValueName, lpReserved, &dwTempType, NULL, (lpcbData ? &cb : NULL));
  3314. if (ret != ERROR_SUCCESS)
  3315. goto Cleanup;
  3316. ASSERT(dwTempType != REG_MULTI_SZ);
  3317. switch (dwTempType)
  3318. {
  3319. case REG_EXPAND_SZ:
  3320. case REG_SZ:
  3321. {
  3322. CStrOut strData((LPWSTR) lpData, (lpcbData ? ((*lpcbData) / sizeof(WCHAR)) : 0));
  3323. cb = strData.BufSize();
  3324. ret = RegQueryValueExA(hKey, strValueName, lpReserved, lpType, (LPBYTE)(LPSTR)strData, (lpcbData ? &cb : NULL));
  3325. if (ret != ERROR_SUCCESS)
  3326. break;
  3327. if (strData)
  3328. {
  3329. cb = strData.ConvertIncludingNul();
  3330. }
  3331. if (lpcbData)
  3332. *lpcbData = cb * sizeof(WCHAR);
  3333. break;
  3334. }
  3335. default:
  3336. {
  3337. ret = RegQueryValueExA(
  3338. hKey,
  3339. strValueName,
  3340. lpReserved,
  3341. lpType,
  3342. lpData,
  3343. lpcbData);
  3344. break;
  3345. }
  3346. }
  3347. Cleanup:
  3348. return ret;
  3349. }
  3350. #endif // NEED_ADVAPI32_WRAPPER
  3351. #ifdef NEED_ADVAPI32_WRAPPER
  3352. LONG APIENTRY
  3353. RegSetValueWrapW(
  3354. HKEY hKey,
  3355. LPCWSTR lpSubKey,
  3356. DWORD dwType,
  3357. LPCWSTR lpData,
  3358. DWORD cbData)
  3359. {
  3360. VALIDATE_PROTOTYPE(RegSetValue);
  3361. if (g_bRunningOnNT)
  3362. {
  3363. return RegSetValueW(hKey, lpSubKey, dwType, lpData, cbData);
  3364. }
  3365. CStrIn strKey(lpSubKey);
  3366. CStrIn strValue(lpData);
  3367. return RegSetValueA(hKey, strKey, dwType, strValue, cbData);
  3368. }
  3369. #endif // NEED_ADVAPI32_WRAPPER
  3370. #ifdef NEED_ADVAPI32_WRAPPER
  3371. LONG APIENTRY
  3372. RegSetValueExWrapW(
  3373. HKEY hKey,
  3374. LPCWSTR lpValueName,
  3375. DWORD Reserved,
  3376. DWORD dwType,
  3377. CONST BYTE* lpData,
  3378. DWORD cbData)
  3379. {
  3380. VALIDATE_PROTOTYPE(RegSetValueEx);
  3381. ASSERT(dwType != REG_MULTI_SZ);
  3382. if (g_bRunningOnNT)
  3383. {
  3384. return RegSetValueExW(
  3385. hKey,
  3386. lpValueName,
  3387. Reserved,
  3388. dwType,
  3389. lpData,
  3390. cbData);
  3391. }
  3392. CStrIn strKey(lpValueName);
  3393. CStrIn strSZ((dwType == REG_SZ || dwType == REG_EXPAND_SZ) ? (LPCWSTR) lpData : NULL);
  3394. if (strSZ)
  3395. {
  3396. lpData = (LPBYTE) (LPSTR) strSZ;
  3397. cbData = strSZ.strlen() + 1;
  3398. }
  3399. return RegSetValueExA(
  3400. hKey,
  3401. strKey,
  3402. Reserved,
  3403. dwType,
  3404. lpData,
  3405. cbData);
  3406. }
  3407. #endif // NEED_ADVAPI32_WRAPPER
  3408. #ifdef NEED_USER32_WRAPPER
  3409. ATOM WINAPI
  3410. RegisterClassWrapW(CONST WNDCLASSW * lpWndClass)
  3411. {
  3412. VALIDATE_PROTOTYPE(RegisterClass);
  3413. if (g_bRunningOnNT)
  3414. {
  3415. return RegisterClassW(lpWndClass);
  3416. }
  3417. WNDCLASSA wc;
  3418. CStrIn strMenuName(lpWndClass->lpszMenuName);
  3419. CStrIn strClassName(lpWndClass->lpszClassName);
  3420. ASSERT(sizeof(wc) == sizeof(*lpWndClass));
  3421. memcpy(&wc, lpWndClass, sizeof(wc));
  3422. wc.lpszMenuName = strMenuName;
  3423. wc.lpszClassName = strClassName;
  3424. return RegisterClassA(&wc);
  3425. }
  3426. #endif // NEED_USER32_WRAPPER
  3427. #ifdef NEED_USER32_WRAPPER
  3428. UINT WINAPI
  3429. RegisterClipboardFormatWrapW(LPCWSTR lpString)
  3430. {
  3431. VALIDATE_PROTOTYPE(RegisterClipboardFormat);
  3432. if (g_bRunningOnNT)
  3433. {
  3434. return RegisterClipboardFormatW(lpString);
  3435. }
  3436. CStrIn str(lpString);
  3437. return RegisterClipboardFormatA(str);
  3438. }
  3439. #endif // NEED_USER32_WRAPPER
  3440. #ifdef NEED_USER32_WRAPPER
  3441. UINT WINAPI
  3442. RegisterWindowMessageWrapW(LPCWSTR lpString)
  3443. {
  3444. VALIDATE_PROTOTYPE(RegisterWindowMessage);
  3445. if (g_bRunningOnNT)
  3446. {
  3447. return RegisterWindowMessageW(lpString);
  3448. }
  3449. CStrIn str(lpString);
  3450. return RegisterWindowMessageA(str);
  3451. }
  3452. #endif // NEED_USER32_WRAPPER
  3453. #ifdef NEED_KERNEL32_WRAPPER
  3454. BOOL WINAPI
  3455. RemoveDirectoryWrapW(LPCWSTR lpszDir)
  3456. {
  3457. VALIDATE_PROTOTYPE(RemoveDirectory);
  3458. if (g_bRunningOnNT)
  3459. {
  3460. return RemoveDirectoryW(lpszDir);
  3461. }
  3462. CStrIn strDir(lpszDir);
  3463. return RemoveDirectoryA(strDir);
  3464. }
  3465. #endif // NEED_KERNEL32_WRAPPER
  3466. #ifdef NEED_USER32_WRAPPER
  3467. HANDLE WINAPI
  3468. RemovePropWrapW(
  3469. HWND hWnd,
  3470. LPCWSTR lpString)
  3471. {
  3472. VALIDATE_PROTOTYPE(RemoveProp);
  3473. if (g_bRunningOnNT)
  3474. {
  3475. return RemovePropW(hWnd, lpString);
  3476. }
  3477. CStrIn str(lpString);
  3478. return RemovePropA(hWnd, str);
  3479. }
  3480. #endif // NEED_USER32_WRAPPER
  3481. #ifdef NEED_USER32_WRAPPER
  3482. LRESULT WINAPI SendMessageWrapW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  3483. // NOTE (SumitC) Instead of calling SendDlgItemMessageA below, I'm forwarding to
  3484. // SendMessageWrap so as not to have to re-do the special-case processing.
  3485. LRESULT WINAPI
  3486. SendDlgItemMessageWrapW(
  3487. HWND hDlg,
  3488. int nIDDlgItem,
  3489. UINT Msg,
  3490. WPARAM wParam,
  3491. LPARAM lParam)
  3492. {
  3493. VALIDATE_PROTOTYPE(SendDlgItemMessage);
  3494. if (g_bRunningOnNT)
  3495. {
  3496. return SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam, lParam);
  3497. }
  3498. HWND hWnd;
  3499. hWnd = GetDlgItem(hDlg, nIDDlgItem);
  3500. return SendMessageWrapW(hWnd, Msg, wParam, lParam);
  3501. }
  3502. #endif // NEED_USER32_WRAPPER
  3503. #ifdef NEED_USER32_WRAPPER
  3504. #if DBG
  3505. int g_cSMTot, g_cSMHit;
  3506. int g_cSMMod = 100;
  3507. #endif
  3508. LRESULT WINAPI
  3509. SendMessageAThunk(
  3510. HWND hWnd,
  3511. UINT Msg,
  3512. WPARAM wParam,
  3513. LPARAM lParam)
  3514. {
  3515. #if 0 && DBG
  3516. if ((g_cSMTot % g_cSMMod) == 0)
  3517. TraceMsg(DM_PERF, "sm: tot=%d hit=%d", g_cSMTot, g_cSMHit);
  3518. #endif
  3519. #if 0 //nadima took this out
  3520. DBEXEC(TRUE, g_cSMTot++);
  3521. // todo: perf? seems to be pretty common case, at least for now...
  3522. DBEXEC(Msg > WM_USER, g_cSMHit++);
  3523. #endif
  3524. #if 0
  3525. if (Msg > WM_USER)
  3526. goto Ldef;
  3527. #endif
  3528. switch (Msg)
  3529. {
  3530. case WM_GETTEXT:
  3531. {
  3532. CStrOut str((LPWSTR)lParam, (int) wParam);
  3533. return SendMessageA(hWnd, Msg, (WPARAM) str.BufSize(), (LPARAM) (LPSTR) str);
  3534. }
  3535. case EM_GETLINE:
  3536. {
  3537. LRESULT nLen;
  3538. CStrOut str((LPWSTR) lParam, (* (SHORT *) lParam) + 1);
  3539. * (SHORT *) (LPSTR) str = * (SHORT *) lParam;
  3540. nLen = SendMessageA(hWnd, Msg, (WPARAM) wParam, (LPARAM) (LPSTR) str);
  3541. if (nLen > 0)
  3542. ((LPSTR) str)[nLen] = '\0';
  3543. return nLen;
  3544. }
  3545. case WM_SETTEXT:
  3546. case CB_ADDSTRING:
  3547. case EM_REPLACESEL:
  3548. ASSERT(wParam == 0 && "wParam should be 0 for these messages");
  3549. // fall through
  3550. case CB_SELECTSTRING:
  3551. case CB_FINDSTRINGEXACT:
  3552. case CB_FINDSTRING:
  3553. case CB_INSERTSTRING:
  3554. {
  3555. CStrIn str((LPWSTR) lParam);
  3556. return SendMessageA(hWnd, Msg, wParam, (LPARAM) (LPSTR) str);
  3557. }
  3558. case LB_ADDSTRING:
  3559. case LB_INSERTSTRING:
  3560. case LB_FINDSTRINGEXACT:
  3561. {
  3562. LONG wndStyle = GetWindowLongA( hWnd, GWL_STYLE);
  3563. // (nadima)
  3564. // If the control is an ownerdraw and does not have
  3565. // LBS_HASSTRINGS then treat lParam as an opaque ptr
  3566. // NOT a string. This fixes a bug in this original code
  3567. // which would mess up our browse for servers UI
  3568. //
  3569. if(hWnd && !(wndStyle & LBS_HASSTRINGS) &&
  3570. (wndStyle & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)))
  3571. {
  3572. return SendMessageA(hWnd, Msg, wParam, lParam);
  3573. }
  3574. else
  3575. {
  3576. //Otherwise it really is a string so convert it
  3577. CStrIn str((LPWSTR) lParam);
  3578. return SendMessageA(hWnd, Msg, wParam, (LPARAM) (LPSTR) str);
  3579. }
  3580. }
  3581. case LB_GETTEXT:
  3582. case CB_GETLBTEXT:
  3583. {
  3584. CStrOut str((LPWSTR)lParam, 255);
  3585. return SendMessageA(hWnd, Msg, wParam, (LPARAM) (LPSTR) str);
  3586. }
  3587. case EM_SETPASSWORDCHAR:
  3588. {
  3589. WPARAM wp = 0;
  3590. ASSERT(HIWORD64(wParam) == 0);
  3591. SHUnicodeToAnsi((LPWSTR) &wParam, (LPSTR) &wp, sizeof(wp));
  3592. ASSERT(HIWORD64(wp) == 0);
  3593. return SendMessageA(hWnd, Msg, wp, lParam);
  3594. }
  3595. case TCM_INSERTITEM:
  3596. {
  3597. LPTCITEM lptc = (LPTCITEM) lParam;
  3598. LPWSTR wszOldStr = NULL;
  3599. LRESULT lr;
  3600. if(lptc && (lptc->mask & TCIF_TEXT) && lptc->pszText)
  3601. {
  3602. //
  3603. // Cheat by using the same LPTCITEM but converting
  3604. // the text field
  3605. //
  3606. wszOldStr = lptc->pszText;
  3607. CStrIn str(lptc->pszText);
  3608. // hack to force str to convert to ANSI and then assign
  3609. // back to the same structure.
  3610. lptc->pszText = (LPTSTR)((char*) str);
  3611. //translate the message TCM_INSERTITEMA is a different
  3612. //value than TCM_INSERTITEMW
  3613. lr = SendMessageA( hWnd, TCM_INSERTITEMA, wParam, (LPARAM) lptc);
  3614. //
  3615. // replace the old string
  3616. //
  3617. lptc->pszText = wszOldStr;
  3618. return lr;
  3619. }
  3620. else
  3621. {
  3622. //translate the message TCM_INSERTITEMA is a different
  3623. //value than TCM_INSERTITEMW
  3624. return SendMessageA( hWnd, TCM_INSERTITEMA, wParam, lParam);
  3625. }
  3626. }
  3627. break;
  3628. case CBEM_INSERTITEM:
  3629. {
  3630. LPWSTR wszOldStr = NULL;
  3631. LRESULT lr;
  3632. PCOMBOBOXEXITEM pcex = (PCOMBOBOXEXITEM)lParam;
  3633. if(pcex && (pcex->mask & CBEIF_TEXT) && pcex->pszText)
  3634. {
  3635. //
  3636. // Cheat by using the same PCOMBOBOXEXITEM but converting
  3637. // the text field
  3638. //
  3639. wszOldStr = pcex->pszText;
  3640. CStrIn str(pcex->pszText);
  3641. // hack to force str to convert to ANSI and then assign
  3642. // back to the same structure.
  3643. pcex->pszText = (LPTSTR)((char*) str);
  3644. //translate the message CBEM_INSERTITEMW is a different
  3645. //value than CBEM_INSERTITEMA
  3646. lr = SendMessageA( hWnd, CBEM_INSERTITEMA, wParam, (LPARAM) pcex);
  3647. //
  3648. // replace the old string
  3649. //
  3650. pcex->pszText = wszOldStr;
  3651. return lr;
  3652. }
  3653. else
  3654. {
  3655. //Just translate the message
  3656. return SendMessageA( hWnd, CBEM_INSERTITEMA, wParam, lParam);
  3657. }
  3658. }
  3659. break;
  3660. case TVM_INSERTITEM:
  3661. {
  3662. LPWSTR wszOldStr = NULL;
  3663. LRESULT lr;
  3664. LPTVINSERTSTRUCT lptv = (LPTVINSERTSTRUCT) lParam;
  3665. if(lptv && (lptv->item.mask & TVIF_TEXT) && lptv->item.pszText)
  3666. {
  3667. //
  3668. // Cheat by using the same LPTVINSERTSTRUCT but converting
  3669. // the text field
  3670. //
  3671. wszOldStr = lptv->item.pszText;
  3672. CStrIn str(lptv->item.pszText);
  3673. // hack to force str to convert to ANSI and then assign
  3674. // back to the same structure.
  3675. lptv->item.pszText = (LPTSTR)((char*) str);
  3676. //translate the message TVM_INSERTITEMW is a different
  3677. //value than TVM_INSERTITEMA
  3678. lr = SendMessageA( hWnd, TVM_INSERTITEMA, wParam, (LPARAM) lptv);
  3679. //
  3680. // replace the old string
  3681. //
  3682. lptv->item.pszText = wszOldStr;
  3683. return lr;
  3684. }
  3685. else
  3686. {
  3687. //Just translate the message
  3688. return SendMessageA( hWnd, TVM_INSERTITEMA, wParam, lParam);
  3689. }
  3690. return 0;
  3691. }
  3692. break;
  3693. case TVM_GETITEM:
  3694. {
  3695. //UNHANDLED case: retreiving text from the tree
  3696. //this is a nightmare because the memory could normally
  3697. //be allocated by the tree control and so there would be
  3698. //no good place to free it in UNIWRAP. Luckily nothing in tsclient
  3699. //does this right now, but if that changes pop an assert and
  3700. //add support.
  3701. LPTVITEM ptvi = (LPTVITEM)lParam;
  3702. if(ptvi)
  3703. {
  3704. //Unsupported
  3705. ASSERT(!((ptvi->mask & TVIF_TEXT)));
  3706. }
  3707. return SendMessageA( hWnd, Msg, wParam, lParam);
  3708. }
  3709. break;
  3710. case CBEM_SETITEM:
  3711. case CBEM_GETITEM:
  3712. case TCM_GETITEM:
  3713. case TCM_SETITEM:
  3714. case TTM_DELTOOL:
  3715. case TTM_ADDTOOL:
  3716. case TVM_SETITEM:
  3717. {
  3718. //UNHANDLED case, need to add support if we start using these
  3719. ASSERT(0);
  3720. // Bad things can happen here if UNICODE strings
  3721. // are not converted
  3722. return SendMessageA(hWnd, Msg, wParam, lParam);
  3723. }
  3724. break;
  3725. case TB_ADDBUTTONS:
  3726. {
  3727. //Translate to the A version
  3728. return SendMessageA(hWnd, TB_ADDBUTTONSA, wParam, lParam);
  3729. }
  3730. break;
  3731. default:
  3732. //Ldef:
  3733. return SendMessageA(hWnd, Msg, wParam, lParam);
  3734. }
  3735. }
  3736. LRESULT FORWARD_API WINAPI
  3737. SendMessageWrapW(
  3738. HWND hWnd,
  3739. UINT Msg,
  3740. WPARAM wParam,
  3741. LPARAM lParam)
  3742. {
  3743. VALIDATE_PROTOTYPE(SendMessage);
  3744. // perf: we should do _asm here (see CallWindowProcWrapW), but
  3745. // to do that we need to 'outline' the below switch (o.w. we
  3746. // can't be 'naked'). that in turn slows down the non-NT case...
  3747. // n.b. THUNK not FORWARD
  3748. THUNK_AW(SendMessage, (hWnd, Msg, wParam, lParam));
  3749. }
  3750. #endif // NEED_USER32_WRAPPER
  3751. #ifdef NEED_KERNEL32_WRAPPER
  3752. BOOL WINAPI
  3753. SetCurrentDirectoryWrapW(LPCWSTR lpszCurDir)
  3754. {
  3755. VALIDATE_PROTOTYPE(SetCurrentDirectory);
  3756. if (g_bRunningOnNT)
  3757. {
  3758. return SetCurrentDirectoryW(lpszCurDir);
  3759. }
  3760. CStrIn str(lpszCurDir);
  3761. return SetCurrentDirectoryA(str);
  3762. }
  3763. #endif // NEED_KERNEL32_WRAPPER
  3764. #ifdef NEED_USER32_WRAPPER
  3765. BOOL WINAPI
  3766. SetDlgItemTextWrapW(HWND hDlg, int nIDDlgItem, LPCWSTR lpString)
  3767. {
  3768. VALIDATE_PROTOTYPE(SetDlgItemText);
  3769. if (g_bRunningOnNT)
  3770. {
  3771. return SetDlgItemTextW(hDlg, nIDDlgItem, lpString);
  3772. }
  3773. CStrIn str(lpString);
  3774. return SetDlgItemTextA(hDlg, nIDDlgItem, str);
  3775. }
  3776. #endif // NEED_USER32_WRAPPER
  3777. #ifdef NEED_USER32_WRAPPER
  3778. BOOL WINAPI
  3779. SetMenuItemInfoWrapW(
  3780. HMENU hMenu,
  3781. UINT uItem,
  3782. BOOL fByPosition,
  3783. LPCMENUITEMINFOW lpmiiW)
  3784. {
  3785. VALIDATE_PROTOTYPE(SetMenuItemInfo);
  3786. ASSERT(lpmiiW->cbSize == MENUITEMINFOSIZE_WIN95); // Ensure Win95 compatibility
  3787. if (g_bRunningOnNT)
  3788. {
  3789. return SetMenuItemInfoW( hMenu, uItem, fByPosition, lpmiiW);
  3790. }
  3791. BOOL fRet;
  3792. ASSERT( sizeof(MENUITEMINFOW) == sizeof(MENUITEMINFOA) &&
  3793. FIELD_OFFSET(MENUITEMINFOW, dwTypeData) ==
  3794. FIELD_OFFSET(MENUITEMINFOA, dwTypeData) );
  3795. if ( (MIIM_TYPE & lpmiiW->fMask) &&
  3796. 0 == (lpmiiW->fType & (MFT_BITMAP | MFT_SEPARATOR)))
  3797. {
  3798. MENUITEMINFOA miiA;
  3799. // the cch is ignored on SetMenuItemInfo
  3800. CStrIn str((LPWSTR)lpmiiW->dwTypeData, -1);
  3801. memcpy( &miiA, lpmiiW, sizeof(MENUITEMINFOA) );
  3802. miiA.dwTypeData = (LPSTR)str;
  3803. miiA.cch = str.strlen();
  3804. fRet = SetMenuItemInfoA( hMenu, uItem, fByPosition, &miiA );
  3805. }
  3806. else
  3807. {
  3808. fRet = SetMenuItemInfoA( hMenu, uItem, fByPosition,
  3809. (LPCMENUITEMINFOA)lpmiiW );
  3810. }
  3811. return fRet;
  3812. }
  3813. #endif // NEED_USER32_WRAPPER
  3814. #ifdef NEED_USER32_WRAPPER
  3815. BOOL WINAPI
  3816. SetPropWrapW(
  3817. HWND hWnd,
  3818. LPCWSTR lpString,
  3819. HANDLE hData)
  3820. {
  3821. VALIDATE_PROTOTYPE(SetProp);
  3822. if (g_bRunningOnNT)
  3823. {
  3824. return SetPropW(hWnd, lpString, hData);
  3825. }
  3826. CStrIn str(lpString);
  3827. return SetPropA(hWnd, str, hData);
  3828. }
  3829. #endif // NEED_USER32_WRAPPER
  3830. #ifdef NEED_USER32_WRAPPER
  3831. LONG FORWARD_API WINAPI
  3832. SetWindowLongWrapW(HWND hWnd, int nIndex, LONG dwNewLong)
  3833. {
  3834. VALIDATE_PROTOTYPE(SetWindowLong);
  3835. FORWARD_AW(SetWindowLong, (hWnd, nIndex, dwNewLong));
  3836. }
  3837. LONG_PTR FORWARD_API WINAPI
  3838. SetWindowLongPtrWrapW(
  3839. HWND hWnd,
  3840. int nIndex,
  3841. LONG_PTR dwNewLong)
  3842. {
  3843. VALIDATE_PROTOTYPE(SetWindowLongPtr);
  3844. FORWARD_AW(SetWindowLongPtr, (hWnd, nIndex, dwNewLong));
  3845. }
  3846. #endif // NEED_USER32_WRAPPER
  3847. #ifdef NEED_USER32_WRAPPER
  3848. HHOOK
  3849. FORWARD_API WINAPI
  3850. SetWindowsHookExWrapW(
  3851. int idHook,
  3852. HOOKPROC lpfn,
  3853. HINSTANCE hmod,
  3854. DWORD dwThreadId)
  3855. {
  3856. VALIDATE_PROTOTYPE(SetWindowsHookEx);
  3857. FORWARD_AW(SetWindowsHookEx, (idHook, lpfn, hmod, dwThreadId));
  3858. }
  3859. #endif // NEED_USER32_WRAPPER
  3860. #ifdef NEED_USER32_WRAPPER
  3861. BOOL WINAPI
  3862. SetWindowTextWrapW(HWND hWnd, LPCWSTR lpString)
  3863. {
  3864. VALIDATE_PROTOTYPE(SetWindowText);
  3865. if (g_bRunningOnNT)
  3866. {
  3867. return SetWindowTextW(hWnd, lpString);
  3868. }
  3869. CStrIn str(lpString);
  3870. return SetWindowTextA(hWnd, str);
  3871. }
  3872. #endif // NEED_USER32_WRAPPER
  3873. #ifdef NEED_USER32_WRAPPER
  3874. BOOL WINAPI
  3875. SystemParametersInfoWrapW(
  3876. UINT uiAction,
  3877. UINT uiParam,
  3878. PVOID pvParam,
  3879. UINT fWinIni)
  3880. {
  3881. VALIDATE_PROTOTYPE(SystemParametersInfo);
  3882. if (g_bRunningOnNT)
  3883. {
  3884. return SystemParametersInfoW(
  3885. uiAction,
  3886. uiParam,
  3887. pvParam,
  3888. fWinIni);
  3889. }
  3890. BOOL ret;
  3891. char ach[LF_FACESIZE];
  3892. if (uiAction == SPI_SETDESKWALLPAPER)
  3893. {
  3894. CStrIn str((LPCWSTR) pvParam);
  3895. ret = SystemParametersInfoA(
  3896. uiAction,
  3897. uiParam,
  3898. str,
  3899. fWinIni);
  3900. }
  3901. else
  3902. ret = SystemParametersInfoA(
  3903. uiAction,
  3904. uiParam,
  3905. pvParam,
  3906. fWinIni);
  3907. if ((uiAction == SPI_GETICONTITLELOGFONT) && ret)
  3908. {
  3909. strcpy(ach, ((LPLOGFONTA)pvParam)->lfFaceName);
  3910. SHAnsiToUnicode(ach, ((LPLOGFONTW)pvParam)->lfFaceName, ARRAYSIZE(((LPLOGFONTW)pvParam)->lfFaceName));
  3911. }
  3912. return ret;
  3913. }
  3914. #endif // NEED_USER32_WRAPPER
  3915. #ifdef NEED_USER32_WRAPPER
  3916. int FORWARD_API WINAPI
  3917. TranslateAcceleratorWrapW(HWND hWnd, HACCEL hAccTable, LPMSG lpMsg)
  3918. {
  3919. VALIDATE_PROTOTYPE(TranslateAccelerator);
  3920. FORWARD_AW(TranslateAccelerator, (hWnd, hAccTable, lpMsg));
  3921. }
  3922. #endif // NEED_USER32_WRAPPER
  3923. #ifdef NEED_USER32_WRAPPER
  3924. BOOL WINAPI
  3925. UnregisterClassWrapW(LPCWSTR lpClassName, HINSTANCE hInstance)
  3926. {
  3927. VALIDATE_PROTOTYPE(UnregisterClass);
  3928. if (g_bRunningOnNT)
  3929. {
  3930. return UnregisterClassW(lpClassName, hInstance);
  3931. }
  3932. CStrIn str(lpClassName);
  3933. return UnregisterClassA(str, hInstance);
  3934. }
  3935. #endif // NEED_USER32_WRAPPER
  3936. #ifdef NEED_USER32_WRAPPER
  3937. SHORT
  3938. WINAPI
  3939. VkKeyScanWrapW(WCHAR ch)
  3940. {
  3941. VALIDATE_PROTOTYPE(VkKeyScan);
  3942. if (g_bRunningOnNT)
  3943. {
  3944. return VkKeyScanW(ch);
  3945. }
  3946. CStrIn str(&ch, 1);
  3947. return VkKeyScanA(*(char *)str);
  3948. }
  3949. #endif // NEED_USER32_WRAPPER
  3950. #ifdef NEED_USER32_WRAPPER
  3951. BOOL WINAPI
  3952. WinHelpWrapW(HWND hwnd, LPCWSTR szFile, UINT uCmd, ULONG_PTR dwData)
  3953. {
  3954. VALIDATE_PROTOTYPE(WinHelp);
  3955. if (g_bRunningOnNT)
  3956. {
  3957. return WinHelpW(hwnd, szFile, uCmd, dwData);
  3958. }
  3959. CStrIn str(szFile);
  3960. return WinHelpA(hwnd, str, uCmd, dwData);
  3961. }
  3962. #endif // NEED_USER32_WRAPPER
  3963. #ifdef NEED_USER32_WRAPPER
  3964. //+---------------------------------------------------------------------------
  3965. //
  3966. // Function: wsprintfW
  3967. //
  3968. // Synopsis: Nightmare string function
  3969. //
  3970. // Arguments: [pwszOut] --
  3971. // [pwszFormat] --
  3972. // [...] --
  3973. //
  3974. // Returns:
  3975. //
  3976. // History: 1-06-94 ErikGav Created
  3977. //
  3978. // Notes: If you're reading this, you're probably having a problem with
  3979. // this function. Make sure that your "%s" in the format string
  3980. // says "%ws" if you are passing wide strings.
  3981. //
  3982. // %s on NT means "wide string"
  3983. // %s on Chicago means "ANSI string"
  3984. //
  3985. // BUGBUG: This function should not be used. Use Format instead.
  3986. //
  3987. //----------------------------------------------------------------------------
  3988. int WINAPI
  3989. wvsprintfWrapW(LPWSTR pwszOut, LPCWSTR pwszFormat, va_list arglist)
  3990. {
  3991. VALIDATE_PROTOTYPE(wvsprintf);
  3992. if (g_bRunningOnNT)
  3993. {
  3994. return wvsprintfW(pwszOut, pwszFormat, arglist);
  3995. }
  3996. // Consider: Out-string bufsize too large or small?
  3997. CStrOut strOut(pwszOut, 1024);
  3998. CStrIn strFormat(pwszFormat);
  3999. #if DBG == 1 /* { */
  4000. {
  4001. LPCWSTR pwch;
  4002. for (pwch = pwszFormat; *pwch; pwch++)
  4003. {
  4004. ASSERT(pwch[0] != L'%' || pwch[1] != L's');
  4005. }
  4006. }
  4007. #endif /* } */
  4008. wvsprintfA(strOut, strFormat, arglist);
  4009. return strOut.ConvertExcludingNul();
  4010. }
  4011. #endif // NEED_USER32_WRAPPER
  4012. #ifdef NEED_MPR_WRAPPER
  4013. //+---------------------------------------------------------------------------
  4014. //
  4015. // Function: WNetRestoreConnectionWrapW
  4016. //
  4017. //----------------------------------------------------------------------------
  4018. DWORD WINAPI WNetRestoreConnectionWrapW(IN HWND hwndParent, IN LPCWSTR pwzDevice)
  4019. {
  4020. VALIDATE_PROTOTYPE(WNetRestoreConnection);
  4021. if (g_bRunningOnNT)
  4022. {
  4023. return WNetRestoreConnectionW(hwndParent, pwzDevice);
  4024. }
  4025. CStrIn strIn(pwzDevice);
  4026. return WNetRestoreConnectionA(hwndParent, strIn);
  4027. }
  4028. #endif // NEED_MPR_WRAPPER
  4029. #ifdef NEED_MPR_WRAPPER
  4030. //+---------------------------------------------------------------------------
  4031. //
  4032. // Function: WNetGetLastErrorWrapW
  4033. //
  4034. //
  4035. //----------------------------------------------------------------------------
  4036. DWORD WINAPI WNetGetLastErrorWrapW(OUT LPDWORD pdwError, OUT LPWSTR pwzErrorBuf, IN DWORD cchErrorBufSize, OUT LPWSTR pwzNameBuf, IN DWORD cchNameBufSize)
  4037. {
  4038. VALIDATE_PROTOTYPE(WNetGetLastError);
  4039. if (g_bRunningOnNT)
  4040. {
  4041. return WNetGetLastErrorW(pdwError, pwzErrorBuf, cchErrorBufSize, pwzNameBuf, cchNameBufSize);
  4042. }
  4043. // Consider: Out-string bufsize too large or small?
  4044. CStrOut strErrorOut(pwzErrorBuf, cchErrorBufSize);
  4045. CStrOut strNameOut(pwzNameBuf, cchNameBufSize);
  4046. DWORD dwResult = WNetGetLastErrorA(pdwError, strErrorOut, strErrorOut.BufSize(), strNameOut, strNameOut.BufSize());
  4047. strErrorOut.ConvertExcludingNul();
  4048. strNameOut.ConvertExcludingNul();
  4049. return dwResult;
  4050. }
  4051. #endif // NEED_MPR_WRAPPER
  4052. #ifdef NEED_USER32_WRAPPER
  4053. int WINAPI DrawTextExWrapW(
  4054. HDC hdc, // handle of device context
  4055. LPWSTR pwzText, // address of string to draw
  4056. int cchText, // length of string to draw
  4057. LPRECT lprc, // address of rectangle coordinates
  4058. UINT dwDTFormat, // formatting options
  4059. LPDRAWTEXTPARAMS lpDTParams // address of structure for more options
  4060. )
  4061. {
  4062. VALIDATE_PROTOTYPE(DrawTextEx);
  4063. if (g_bRunningOnNT)
  4064. return DrawTextExW(hdc, pwzText, cchText, lprc, dwDTFormat, lpDTParams);
  4065. CStrIn strText(pwzText, cchText);
  4066. return DrawTextExA(hdc, strText, strText.strlen(), lprc, dwDTFormat, lpDTParams);
  4067. }
  4068. #endif // NEED_USER32_WRAPPER
  4069. #ifdef NEED_USER32_WRAPPER
  4070. void SetThunkMenuItemInfoWToA(LPCMENUITEMINFOW pmiiW, LPMENUITEMINFOA pmiiA, LPSTR pszBuffer, DWORD cchSize)
  4071. {
  4072. *pmiiA = *(LPMENUITEMINFOA) pmiiW;
  4073. // MFT_STRING is Zero. So MFT_STRING & anything evaluates to False.
  4074. if ((pmiiW->dwTypeData) && (MFT_STRING & pmiiW->fType) == 0)
  4075. {
  4076. pmiiA->dwTypeData = pszBuffer;
  4077. pmiiA->cch = cchSize;
  4078. SHUnicodeToAnsi(pmiiW->dwTypeData, pmiiA->dwTypeData, cchSize);
  4079. }
  4080. }
  4081. void GetThunkMenuItemInfoWToA(LPCMENUITEMINFOW pmiiW, LPMENUITEMINFOA pmiiA, LPSTR pszBuffer, DWORD cchSize)
  4082. {
  4083. *pmiiA = *(LPMENUITEMINFOA) pmiiW;
  4084. if ((pmiiW->dwTypeData) && (MFT_STRING & pmiiW->fType))
  4085. {
  4086. pszBuffer[0] = 0;
  4087. pmiiA->dwTypeData = pszBuffer;
  4088. pmiiA->cch = cchSize;
  4089. }
  4090. }
  4091. void GetThunkMenuItemInfoAToW(LPCMENUITEMINFOA pmiiA, LPMENUITEMINFOW pmiiW)
  4092. {
  4093. LPWSTR pwzText = pmiiW->dwTypeData;
  4094. *pmiiW = *(LPMENUITEMINFOW) pmiiA;
  4095. pmiiW->dwTypeData = pwzText;
  4096. if ((pmiiA->dwTypeData) && (pwzText) && !((MFT_SEPARATOR | MFT_BITMAP) & pmiiW->fType))
  4097. SHAnsiToUnicode(pmiiA->dwTypeData, pmiiW->dwTypeData, (pmiiW->cch + 1));
  4098. }
  4099. #endif // NEED_USER32_WRAPPER
  4100. #ifdef NEED_USER32_WRAPPER
  4101. #if UNUSED_DONOTBUILD
  4102. BOOL WINAPI GetMenuItemInfoWrapW(
  4103. HMENU hMenu,
  4104. UINT uItem,
  4105. BOOL fByPosition,
  4106. LPMENUITEMINFOW pmiiW)
  4107. {
  4108. BOOL fResult;
  4109. VALIDATE_PROTOTYPE(GetMenuItemInfo);
  4110. ASSERT(pmiiW->cbSize == MENUITEMINFOSIZE_WIN95); // Ensure Win95 compatibility
  4111. #ifndef UNIX
  4112. // Widechar API's are messed up in MAINWIN. For now assume not ruuning on
  4113. // NT for this.
  4114. if (g_bRunningOnNT)
  4115. fResult = GetMenuItemInfoW(hMenu, uItem, fByPosition, pmiiW);
  4116. else
  4117. #endif
  4118. {
  4119. if (pmiiW->fMask & MIIM_TYPE)
  4120. {
  4121. MENUITEMINFOA miiA = *(LPMENUITEMINFOA)pmiiW;
  4122. LPSTR pszText = NULL;
  4123. if (pmiiW->cch > 0)
  4124. pszText = NEW(char[pmiiW->cch]);
  4125. miiA.dwTypeData = pszText;
  4126. fResult = GetMenuItemInfoA(hMenu, uItem, fByPosition, &miiA);
  4127. GetThunkMenuItemInfoAToW(&miiA, pmiiW);
  4128. if (pszText)
  4129. delete pszText;
  4130. }
  4131. else
  4132. fResult = GetMenuItemInfoA(hMenu, uItem, fByPosition, (LPMENUITEMINFOA) pmiiW); // It doesn't contain a string so W and A are the same.
  4133. }
  4134. return fResult;
  4135. }
  4136. #endif // UNUSED_DONOTBUILD
  4137. #endif // NEED_USER32_WRAPPER
  4138. #ifdef NEED_USER32_WRAPPER
  4139. BOOL WINAPI InsertMenuItemWrapW(
  4140. HMENU hMenu,
  4141. UINT uItem,
  4142. BOOL fByPosition,
  4143. LPCMENUITEMINFOW pmiiW)
  4144. {
  4145. VALIDATE_PROTOTYPE(InsertMenuItem);
  4146. ASSERT(pmiiW->cbSize == MENUITEMINFOSIZE_WIN95); // Ensure Win95 compatibility
  4147. BOOL fResult;
  4148. if (g_bRunningOnNT)
  4149. return InsertMenuItemW(hMenu, uItem, fByPosition, pmiiW);
  4150. MENUITEMINFOA miiA;
  4151. CHAR szText[MAX_PATH*3]; //nadima changed from INTERNET_MAX_URL_LENGTH
  4152. SetThunkMenuItemInfoWToA(pmiiW, &miiA, szText, ARRAYSIZE(szText));
  4153. fResult = InsertMenuItemA(hMenu, uItem, fByPosition, &miiA);
  4154. return fResult;
  4155. }
  4156. #endif // NEED_USER32_WRAPPER
  4157. #ifdef NEED_GDI32_WRAPPER
  4158. HFONT WINAPI
  4159. CreateFontWrapW(int nHeight, // logical height of font
  4160. int nWidth, // logical average character width
  4161. int nEscapement, // angle of escapement
  4162. int nOrientation, // base-line orientation angle
  4163. int fnWeight, // font weight
  4164. DWORD fdwItalic, // italic attribute flag
  4165. DWORD fdwUnderline, // underline attribute flag
  4166. DWORD fdwStrikeOut, // strikeout attribute flag
  4167. DWORD fdwCharSet, // character set identifier
  4168. DWORD fdwOutputPrecision, // output precision
  4169. DWORD fdwClipPrecision, // clipping precision
  4170. DWORD fdwQuality, // output quality
  4171. DWORD fdwPitchAndFamily, // pitch and family
  4172. LPCWSTR pwzFace) // address of typeface name string )
  4173. {
  4174. VALIDATE_PROTOTYPE(CreateFont);
  4175. if (g_bRunningOnNT)
  4176. {
  4177. return CreateFontW(nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic,
  4178. fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision,
  4179. fdwClipPrecision, fdwQuality, fdwPitchAndFamily, pwzFace);
  4180. }
  4181. CStrIn str(pwzFace);
  4182. return CreateFontA(nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic,
  4183. fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision,
  4184. fdwClipPrecision, fdwQuality, fdwPitchAndFamily, str);
  4185. }
  4186. #endif // NEED_GDI32_WRAPPER
  4187. #ifdef NEED_KERNEL32_WRAPPER
  4188. HANDLE WINAPI CreateMutexWrapW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR pwzName)
  4189. {
  4190. VALIDATE_PROTOTYPE(CreateMutex);
  4191. if (g_bRunningOnNT)
  4192. return CreateMutexW(lpMutexAttributes, bInitialOwner, pwzName);
  4193. CStrIn strText(pwzName);
  4194. return CreateMutexA(lpMutexAttributes, bInitialOwner, strText);
  4195. }
  4196. #endif // NEED_KERNEL32_WRAPPER
  4197. #ifdef NEED_GDI32_WRAPPER
  4198. HDC WINAPI CreateMetaFileWrapW(LPCWSTR pwzFile)
  4199. {
  4200. VALIDATE_PROTOTYPE(CreateMetaFile);
  4201. if (g_bRunningOnNT)
  4202. return CreateMetaFileW(pwzFile);
  4203. CStrIn strText(pwzFile);
  4204. return CreateMetaFileA(strText);
  4205. }
  4206. #endif // NEED_GDI32_WRAPPER
  4207. #ifdef NEED_KERNEL32_WRAPPER
  4208. DWORD WINAPI ExpandEnvironmentStringsWrapW(LPCWSTR pwzSrc, LPWSTR pwzDst, DWORD cchSize)
  4209. {
  4210. VALIDATE_PROTOTYPE(ExpandEnvironmentStrings);
  4211. if (pwzDst)
  4212. {
  4213. VALIDATE_OUTBUF(pwzDst, cchSize);
  4214. }
  4215. if (g_bRunningOnNT)
  4216. return ExpandEnvironmentStringsW(pwzSrc, pwzDst, cchSize);
  4217. CStrIn strTextIn(pwzSrc);
  4218. CStrOut strTextOut(pwzDst, cchSize);
  4219. DWORD dwResult = ExpandEnvironmentStringsA(strTextIn, strTextOut, strTextOut.BufSize());
  4220. strTextOut.ConvertIncludingNul();
  4221. return dwResult;
  4222. }
  4223. #endif // NEED_KERNEL32_WRAPPER
  4224. #ifdef NEED_KERNEL32_WRAPPER
  4225. HANDLE WINAPI CreateSemaphoreWrapW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR pwzName)
  4226. {
  4227. VALIDATE_PROTOTYPE(CreateSemaphore);
  4228. if (g_bRunningOnNT)
  4229. return CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, pwzName);
  4230. CStrIn strText(pwzName);
  4231. return CreateSemaphoreA(lpSemaphoreAttributes, lInitialCount, lMaximumCount, strText);
  4232. }
  4233. #endif // NEED_KERNEL32_WRAPPER
  4234. // BUGBUG: Todo - GetStartupInfoWrapW
  4235. #ifdef NEED_KERNEL32_WRAPPER
  4236. #define ISGOOD 0
  4237. #define ISBAD 1
  4238. BOOL WINAPI IsBadStringPtrWrapW(LPCWSTR pwzString, UINT_PTR ucchMax)
  4239. {
  4240. VALIDATE_PROTOTYPE(IsBadStringPtr);
  4241. if (g_bRunningOnNT)
  4242. return IsBadStringPtrW(pwzString, ucchMax);
  4243. if (!ucchMax)
  4244. return ISGOOD;
  4245. if (!pwzString)
  4246. return ISBAD;
  4247. LPCWSTR pwzStartAddress = pwzString;
  4248. // ucchMax maybe -1 but that's ok because the loop down below will just
  4249. // look for the terminator.
  4250. LPCWSTR pwzEndAddress = &pwzStartAddress[ucchMax - 1];
  4251. TCHAR chTest;
  4252. _try
  4253. {
  4254. chTest = *(volatile WCHAR *)pwzStartAddress;
  4255. while (chTest && (pwzStartAddress != pwzEndAddress))
  4256. {
  4257. pwzStartAddress++;
  4258. chTest = *(volatile WCHAR *)pwzStartAddress;
  4259. }
  4260. }
  4261. _except (EXCEPTION_EXECUTE_HANDLER)
  4262. {
  4263. return ISBAD;
  4264. }
  4265. return ISGOOD;
  4266. }
  4267. #endif // NEED_KERNEL32_WRAPPER
  4268. #ifdef NEED_KERNEL32_WRAPPER
  4269. HINSTANCE WINAPI LoadLibraryWrapW(LPCWSTR pwzLibFileName)
  4270. {
  4271. VALIDATE_PROTOTYPE(LoadLibrary);
  4272. if (g_bRunningOnNT)
  4273. return LoadLibraryW(pwzLibFileName);
  4274. CStrIn strFileName(pwzLibFileName);
  4275. return LoadLibraryA(strFileName);
  4276. }
  4277. #endif // NEED_KERNEL32_WRAPPER
  4278. #ifdef NEED_KERNEL32_WRAPPER
  4279. int WINAPI GetTimeFormatWrapW(LCID Locale, DWORD dwFlags, CONST SYSTEMTIME * lpTime, LPCWSTR pwzFormat, LPWSTR pwzTimeStr, int cchTime)
  4280. {
  4281. VALIDATE_PROTOTYPE(GetTimeFormat);
  4282. if (g_bRunningOnNT)
  4283. return GetTimeFormatW(Locale, dwFlags, lpTime, pwzFormat, pwzTimeStr, cchTime);
  4284. CStrIn strTextIn(pwzFormat);
  4285. CStrOut strTextOut(pwzTimeStr, cchTime);
  4286. int nResult = GetTimeFormatA(Locale, dwFlags, lpTime, strTextIn, strTextOut, strTextOut.BufSize());
  4287. strTextOut.ConvertIncludingNul();
  4288. return nResult;
  4289. }
  4290. #endif // NEED_KERNEL32_WRAPPER
  4291. #ifdef NEED_KERNEL32_WRAPPER
  4292. int WINAPI GetDateFormatWrapW(LCID Locale, DWORD dwFlags, CONST SYSTEMTIME * lpDate, LPCWSTR pwzFormat, LPWSTR pwzDateStr, int cchDate)
  4293. {
  4294. VALIDATE_PROTOTYPE(GetDateFormat);
  4295. if (g_bRunningOnNT)
  4296. return GetDateFormatW(Locale, dwFlags, lpDate, pwzFormat, pwzDateStr, cchDate);
  4297. CStrIn strTextIn(pwzFormat);
  4298. CStrOut strTextOut(pwzDateStr, cchDate);
  4299. int nResult = GetDateFormatA(Locale, dwFlags, lpDate, strTextIn, strTextOut, strTextOut.BufSize());
  4300. strTextOut.ConvertIncludingNul();
  4301. return nResult;
  4302. }
  4303. #endif // NEED_KERNEL32_WRAPPER
  4304. #ifdef NEED_KERNEL32_WRAPPER
  4305. BOOL WINAPI WritePrivateProfileStringWrapW(LPCWSTR pwzAppName, LPCWSTR pwzKeyName, LPCWSTR pwzString, LPCWSTR pwzFileName)
  4306. {
  4307. VALIDATE_PROTOTYPE(WritePrivateProfileString);
  4308. if (g_bRunningOnNT)
  4309. return WritePrivateProfileStringW(pwzAppName, pwzKeyName, pwzString, pwzFileName);
  4310. CStrIn strTextAppName(pwzAppName);
  4311. CStrIn strTextKeyName(pwzKeyName);
  4312. CStrIn strTextString(pwzString);
  4313. CStrIn strTextFileName(pwzFileName);
  4314. return WritePrivateProfileStringA(strTextAppName, strTextKeyName, strTextString, strTextFileName);
  4315. }
  4316. #endif // NEED_KERNEL32_WRAPPER
  4317. #ifdef NEED_KERNEL32_WRAPPER
  4318. DWORD WINAPI GetPrivateProfileStringWrapW(LPCWSTR pwzAppName, LPCWSTR pwzKeyName, LPCWSTR pwzDefault, LPWSTR pwzReturnedString, DWORD cchSize, LPCWSTR pwzFileName)
  4319. {
  4320. VALIDATE_PROTOTYPE(GetPrivateProfileString);
  4321. if (g_bRunningOnNT)
  4322. return GetPrivateProfileStringW(pwzAppName, pwzKeyName, pwzDefault, pwzReturnedString, cchSize, pwzFileName);
  4323. CStrIn strTextAppName(pwzAppName);
  4324. CStrIn strTextKeyName(pwzKeyName);
  4325. CStrIn strTextDefault(pwzDefault);
  4326. CStrIn strTextFileName(pwzFileName);
  4327. CStrOut strTextOut(pwzReturnedString, cchSize);
  4328. DWORD dwResult = GetPrivateProfileStringA(strTextAppName, strTextKeyName, strTextDefault, strTextOut, cchSize, strTextFileName);
  4329. strTextOut.ConvertIncludingNul();
  4330. return dwResult;
  4331. }
  4332. #endif // NEED_KERNEL32_WRAPPER
  4333. #ifdef NEED_SHELL32_WRAPPER
  4334. STDAPI_(DWORD_PTR) SHGetFileInfoWrapW(LPCWSTR pwzPath, DWORD dwFileAttributes, SHFILEINFOW FAR *psfi, UINT cbFileInfo, UINT uFlags)
  4335. {
  4336. VALIDATE_PROTOTYPE_DELAYLOAD(SHGetFileInfo, _SHGetFileInfo);
  4337. if (g_bRunningOnNT)
  4338. return _SHGetFileInfoW(pwzPath, dwFileAttributes, psfi, cbFileInfo, uFlags);
  4339. SHFILEINFOA shFileInfo;
  4340. DWORD_PTR dwResult;
  4341. shFileInfo.szDisplayName[0] = 0; // Terminate so we can always thunk afterward.
  4342. shFileInfo.szTypeName[0] = 0; // Terminate so we can always thunk afterward.
  4343. // Do we need to thunk the Path?
  4344. if (SHGFI_PIDL & uFlags)
  4345. {
  4346. // No, because it's really a pidl pointer.
  4347. dwResult = _SHGetFileInfoA((LPCSTR)pwzPath, dwFileAttributes, &shFileInfo, sizeof(shFileInfo), uFlags);
  4348. }
  4349. else
  4350. {
  4351. // Yes
  4352. CStrIn strPath(pwzPath);
  4353. dwResult = _SHGetFileInfoA(strPath, dwFileAttributes, &shFileInfo, sizeof(shFileInfo), uFlags);
  4354. }
  4355. psfi->hIcon = shFileInfo.hIcon;
  4356. psfi->iIcon = shFileInfo.iIcon;
  4357. psfi->dwAttributes = shFileInfo.dwAttributes;
  4358. SHAnsiToUnicode(shFileInfo.szDisplayName, psfi->szDisplayName, ARRAYSIZE(shFileInfo.szDisplayName));
  4359. SHAnsiToUnicode(shFileInfo.szTypeName, psfi->szTypeName, ARRAYSIZE(shFileInfo.szTypeName));
  4360. return dwResult;
  4361. }
  4362. #endif // NEED_SHELL32_WRAPPER
  4363. #ifdef NEED_USER32_WRAPPER
  4364. STDAPI_(ATOM) RegisterClassExWrapW(CONST WNDCLASSEXW FAR * pwcx)
  4365. {
  4366. VALIDATE_PROTOTYPE(RegisterClassEx);
  4367. if (g_bRunningOnNT)
  4368. return RegisterClassExW(pwcx);
  4369. CStrIn strMenuName(pwcx->lpszMenuName);
  4370. CStrIn strClassName(pwcx->lpszClassName);
  4371. WNDCLASSEXA wcx = *(CONST WNDCLASSEXA FAR *) pwcx;
  4372. wcx.cbSize = sizeof(wcx);
  4373. wcx.lpszMenuName = strMenuName;
  4374. wcx.lpszClassName = strClassName;
  4375. return RegisterClassExA(&wcx);
  4376. }
  4377. #endif // NEED_USER32_WRAPPER
  4378. #ifdef NEED_USER32_WRAPPER
  4379. STDAPI_(BOOL) GetClassInfoExWrapW(HINSTANCE hinst, LPCWSTR pwzClass, LPWNDCLASSEXW lpwcx)
  4380. {
  4381. VALIDATE_PROTOTYPE(GetClassInfoEx);
  4382. if (g_bRunningOnNT)
  4383. return GetClassInfoExW(hinst, pwzClass, lpwcx);
  4384. BOOL fResult;
  4385. CStrIn strClassName(pwzClass);
  4386. WNDCLASSEXA wcx;
  4387. wcx.cbSize = sizeof(wcx);
  4388. fResult = GetClassInfoExA(hinst, strClassName, &wcx);
  4389. *(WNDCLASSEXA FAR *) lpwcx = wcx;
  4390. lpwcx->lpszMenuName = NULL; // GetClassInfoExA makes this point off to private data that they own.
  4391. lpwcx->lpszClassName = pwzClass;
  4392. return fResult;
  4393. }
  4394. #endif // NEED_USER32_WRAPPER
  4395. #ifdef NEED_GDI32_WRAPPER
  4396. //+---------------------------------------------------------------------------
  4397. // StartDoc
  4398. //----------------------------------------------------------------------------
  4399. int
  4400. StartDocWrapW( HDC hDC, const DOCINFO * lpdi )
  4401. {
  4402. VALIDATE_PROTOTYPE(StartDoc);
  4403. if (g_bRunningOnNT)
  4404. {
  4405. return StartDocW( hDC, lpdi );
  4406. }
  4407. CStrIn strDocName( lpdi->lpszDocName );
  4408. CStrIn strOutput( lpdi->lpszOutput );
  4409. CStrIn strDatatype( lpdi->lpszDatatype );
  4410. DOCINFOA dia;
  4411. dia.cbSize = sizeof(DOCINFO);
  4412. dia.lpszDocName = strDocName;
  4413. dia.lpszOutput = strOutput;
  4414. dia.lpszDatatype = strDatatype;
  4415. dia.fwType = lpdi->fwType;
  4416. return StartDocA( hDC, &dia );
  4417. }
  4418. #endif // NEED_GDI32_WRAPPER
  4419. #ifdef NEED_SHELL32_WRAPPER
  4420. STDAPI_(UINT) DragQueryFileWrapW(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch)
  4421. {
  4422. VALIDATE_PROTOTYPE_DELAYLOAD(DragQueryFile, _DragQueryFile);
  4423. VALIDATE_OUTBUF(lpszFile, cch);
  4424. //
  4425. // We are lazy and do not support lpszFile == NULL to query the length
  4426. // of an individual string.
  4427. //
  4428. ASSERT(iFile == 0xFFFFFFFF || lpszFile);
  4429. if (g_bRunningOnNT)
  4430. return _DragQueryFileW(hDrop, iFile, lpszFile, cch);
  4431. //
  4432. // If iFile is 0xFFFFFFFF, then lpszFile and cch are ignored.
  4433. //
  4434. if (iFile == 0xFFFFFFFF)
  4435. return _DragQueryFileA(hDrop, iFile, NULL, 0);
  4436. CStrOut str(lpszFile, cch);
  4437. _DragQueryFileA(hDrop, iFile, str, str.BufSize());
  4438. return str.ConvertExcludingNul();
  4439. }
  4440. #endif // NEED_SHELL32_WRAPPER
  4441. #ifdef NEED_VERSION_WRAPPER
  4442. //
  4443. // the version APIs are not conducive to using
  4444. // wrap versions of the APIs, but we are going to
  4445. // do something reasonable....
  4446. //
  4447. #define VERSIONINFO_BUFF (MAX_PATH * SIZEOF(WCHAR))
  4448. STDAPI_(DWORD)
  4449. GetFileVersionInfoSizeWrapW(LPWSTR pwzFilename, LPDWORD lpdwHandle)
  4450. {
  4451. if (g_bRunningOnNT)
  4452. {
  4453. return GetFileVersionInfoSizeW(pwzFilename, lpdwHandle);
  4454. }
  4455. else
  4456. {
  4457. char szFilename[MAX_PATH];
  4458. DWORD dwRet;
  4459. ASSERT(pwzFilename);
  4460. SHUnicodeToAnsi(pwzFilename, szFilename, ARRAYSIZE(szFilename));
  4461. dwRet = GetFileVersionInfoSizeA(szFilename, lpdwHandle);
  4462. if (dwRet > 0)
  4463. {
  4464. // Add a scratch buffer to front for converting to UNICODE
  4465. dwRet += VERSIONINFO_BUFF;
  4466. }
  4467. return dwRet;
  4468. }
  4469. }
  4470. #endif // NEED_VERSION_WRAPPER
  4471. #ifdef NEED_VERSION_WRAPPER
  4472. STDAPI_(BOOL)
  4473. GetFileVersionInfoWrapW(LPWSTR pwzFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData)
  4474. {
  4475. if (g_bRunningOnNT)
  4476. {
  4477. return GetFileVersionInfoW(pwzFilename, dwHandle, dwLen, lpData);
  4478. }
  4479. else
  4480. {
  4481. char szFilename[MAX_PATH];
  4482. BYTE* pb;
  4483. if (dwLen <= VERSIONINFO_BUFF)
  4484. {
  4485. return FALSE;
  4486. }
  4487. ASSERT(pwzFilename);
  4488. SHUnicodeToAnsi(pwzFilename, szFilename, ARRAYSIZE(szFilename));
  4489. //Skip over our scratch buffer at the beginning
  4490. pb = (BYTE*)lpData + VERSIONINFO_BUFF;
  4491. return GetFileVersionInfoA(szFilename, dwHandle, dwLen - VERSIONINFO_BUFF, (void*)pb);
  4492. }
  4493. }
  4494. #endif // NEED_VERSION_WRAPPER
  4495. #ifdef NEED_VERSION_WRAPPER
  4496. STDAPI_(BOOL)
  4497. VerQueryValueWrapW(const LPVOID pBlock, LPWSTR pwzSubBlock, LPVOID *ppBuffer, PUINT puLen)
  4498. {
  4499. if (g_bRunningOnNT)
  4500. {
  4501. return VerQueryValueW(pBlock, pwzSubBlock, ppBuffer, puLen);
  4502. }
  4503. else
  4504. {
  4505. const WCHAR pwzStringFileInfo[] = L"\\StringFileInfo";
  4506. //
  4507. // WARNING: This function wipes out any string previously returned
  4508. // for this pBlock because a common buffer at the beginning of the
  4509. // block is used for ansi/unicode translation!
  4510. //
  4511. char szSubBlock[MAX_PATH];
  4512. BOOL fRet;
  4513. BYTE* pb;
  4514. ASSERT(pwzSubBlock);
  4515. SHUnicodeToAnsi(pwzSubBlock, szSubBlock, ARRAYSIZE(szSubBlock));
  4516. // The first chunk is our scratch buffer for converting to UNICODE
  4517. pb = (BYTE*)pBlock + VERSIONINFO_BUFF;
  4518. fRet = VerQueryValueA((void*)pb, szSubBlock, ppBuffer, puLen);
  4519. // Convert to unicode if ansi string returned
  4520. if (fRet && StrCmpNIW(pwzSubBlock, pwzStringFileInfo, ARRAYSIZE(pwzStringFileInfo) - 1) == 0)
  4521. {
  4522. // Convert returned string to UNICODE. We use the scratch buffer
  4523. // at the beginning of pBlock
  4524. LPWSTR pwzBuff = (LPWSTR)pBlock;
  4525. if (*puLen == 0)
  4526. {
  4527. pwzBuff[0] = L'\0';
  4528. }
  4529. else
  4530. {
  4531. SHAnsiToUnicode((LPCSTR)*ppBuffer, pwzBuff, VERSIONINFO_BUFF/sizeof(WCHAR));
  4532. }
  4533. *ppBuffer = pwzBuff;
  4534. }
  4535. return fRet;
  4536. }
  4537. }
  4538. #endif // NEED_VERSION_WRAPPER
  4539. #ifdef NEED_SHELL32_WRAPPER
  4540. HRESULT WINAPI SHDefExtractIconWrapW(LPCWSTR pszFile, int nIconIndex,
  4541. UINT uFlags, HICON *phiconLarge,
  4542. HICON *phiconSmall, UINT nIconSize)
  4543. {
  4544. VALIDATE_PROTOTYPE_DELAYLOAD(SHDefExtractIcon, _SHDefExtractIcon);
  4545. HRESULT hr;
  4546. if (UseUnicodeShell32())
  4547. {
  4548. hr = _SHDefExtractIconW(pszFile, nIconIndex, uFlags, phiconLarge,
  4549. phiconSmall, nIconSize);
  4550. }
  4551. else
  4552. {
  4553. CStrIn striFile(pszFile);
  4554. hr = _SHDefExtractIconA(striFile, nIconIndex, uFlags, phiconLarge,
  4555. phiconSmall, nIconSize);
  4556. }
  4557. return hr;
  4558. }
  4559. #endif // NEED_SHELL32_WRAPPER
  4560. #ifdef NEED_SHELL32_WRAPPER
  4561. BOOL WINAPI SHGetNewLinkInfoWrapW(LPCWSTR pszpdlLinkTo, LPCWSTR pszDir, LPWSTR pszName, BOOL *pfMustCopy, UINT uFlags)
  4562. {
  4563. VALIDATE_PROTOTYPE_DELAYLOAD(SHGetNewLinkInfo, _SHGetNewLinkInfo);
  4564. BOOL fRet;
  4565. if (UseUnicodeShell32())
  4566. {
  4567. fRet = _SHGetNewLinkInfoW(pszpdlLinkTo, pszDir, pszName, pfMustCopy,
  4568. uFlags);
  4569. }
  4570. else
  4571. {
  4572. CStrIn striDir(pszDir);
  4573. CStrOut stroName(pszName, MAX_PATH);
  4574. if (SHGNLI_PIDL & uFlags)
  4575. {
  4576. fRet = _SHGetNewLinkInfoA((LPCSTR)pszpdlLinkTo, striDir,
  4577. stroName, pfMustCopy, uFlags);
  4578. }
  4579. else
  4580. {
  4581. CStrIn striLinkTo(pszpdlLinkTo);
  4582. fRet = _SHGetNewLinkInfoA(striLinkTo, striDir, stroName,
  4583. pfMustCopy, uFlags);
  4584. }
  4585. if (fRet)
  4586. stroName.ConvertIncludingNul();
  4587. }
  4588. return fRet;
  4589. }
  4590. #endif // NEED_SHELL32_WRAPPER
  4591. #ifdef NEED_KERNEL32_WRAPPER
  4592. BOOL WINAPI WritePrivateProfileStructWrapW(LPCWSTR lpszSection, LPCWSTR lpszKey,
  4593. LPVOID lpStruct, UINT uSizeStruct,
  4594. LPCWSTR szFile)
  4595. {
  4596. VALIDATE_PROTOTYPE(WritePrivateProfileStruct);
  4597. BOOL fRet;
  4598. if (UseUnicodeShell32())
  4599. {
  4600. fRet = WritePrivateProfileStructW(lpszSection, lpszKey, lpStruct,
  4601. uSizeStruct, szFile);
  4602. }
  4603. else
  4604. {
  4605. CStrIn striSection(lpszSection);
  4606. CStrIn striKey(lpszKey);
  4607. CStrIn striFile(szFile);
  4608. fRet = WritePrivateProfileStructA(striSection, striKey, lpStruct,
  4609. uSizeStruct, striFile);
  4610. }
  4611. return fRet;
  4612. }
  4613. #endif // NEED_KERNEL32_WRAPPER
  4614. #ifdef NEED_KERNEL32_WRAPPER
  4615. BOOL WINAPI GetPrivateProfileStructWrapW(LPCWSTR lpszSection, LPCWSTR lpszKey,
  4616. LPVOID lpStruct, UINT uSizeStruct,
  4617. LPCWSTR szFile)
  4618. {
  4619. VALIDATE_PROTOTYPE(GetPrivateProfileStruct);
  4620. BOOL fRet;
  4621. if (UseUnicodeShell32())
  4622. {
  4623. fRet = GetPrivateProfileStructW(lpszSection, lpszKey, lpStruct,
  4624. uSizeStruct, szFile);
  4625. }
  4626. else
  4627. {
  4628. CStrIn striSection(lpszSection);
  4629. CStrIn striKey(lpszKey);
  4630. CStrIn striFile(szFile);
  4631. fRet = GetPrivateProfileStructA(striSection, striKey, lpStruct,
  4632. uSizeStruct, striFile);
  4633. }
  4634. return fRet;
  4635. }
  4636. #endif // NEED_KERNEL32_WRAPPER
  4637. BOOL WINAPI CreateProcessWrapW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
  4638. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  4639. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  4640. BOOL bInheritHandles,
  4641. DWORD dwCreationFlags,
  4642. LPVOID lpEnvironment,
  4643. LPCWSTR lpCurrentDirectory,
  4644. LPSTARTUPINFOW lpStartupInfo,
  4645. LPPROCESS_INFORMATION lpProcessInformation)
  4646. {
  4647. BOOL fRet;
  4648. if (UseUnicodeShell32())
  4649. {
  4650. fRet = CreateProcessW(lpApplicationName, lpCommandLine,
  4651. lpProcessAttributes, lpThreadAttributes,
  4652. bInheritHandles, dwCreationFlags, lpEnvironment,
  4653. lpCurrentDirectory, lpStartupInfo,
  4654. lpProcessInformation);
  4655. }
  4656. else
  4657. {
  4658. CStrIn striApplicationName(lpApplicationName);
  4659. CStrIn striCommandLine(lpCommandLine);
  4660. CStrIn striCurrentDirectory(lpCurrentDirectory);
  4661. if (NULL == lpStartupInfo)
  4662. {
  4663. fRet = CreateProcessA(striApplicationName, striCommandLine,
  4664. lpProcessAttributes, lpThreadAttributes,
  4665. bInheritHandles, dwCreationFlags,
  4666. lpEnvironment, striCurrentDirectory,
  4667. NULL, lpProcessInformation);
  4668. }
  4669. else
  4670. {
  4671. STARTUPINFOA si = *(STARTUPINFOA*)lpStartupInfo;
  4672. CStrIn striReserved(lpStartupInfo->lpReserved);
  4673. CStrIn striDesktop(lpStartupInfo->lpDesktop);
  4674. CStrIn striTitle(lpStartupInfo->lpTitle);
  4675. si.lpReserved = striReserved;
  4676. si.lpDesktop = striDesktop;
  4677. si.lpTitle = striTitle;
  4678. fRet = CreateProcessA(striApplicationName, striCommandLine,
  4679. lpProcessAttributes, lpThreadAttributes,
  4680. bInheritHandles, dwCreationFlags,
  4681. lpEnvironment, striCurrentDirectory,
  4682. &si, lpProcessInformation);
  4683. }
  4684. }
  4685. return fRet;
  4686. }
  4687. #ifdef NEED_SHELL32_WRAPPER
  4688. HICON WINAPI ExtractIconWrapW(HINSTANCE hInst, LPCWSTR lpszExeFileName, UINT nIconIndex)
  4689. {
  4690. HICON hicon;
  4691. if (UseUnicodeShell32())
  4692. {
  4693. hicon = _ExtractIconW(hInst, lpszExeFileName, nIconIndex);
  4694. }
  4695. else
  4696. {
  4697. CStrIn striExeFileName(lpszExeFileName);
  4698. hicon = _ExtractIconA(hInst, striExeFileName, nIconIndex);
  4699. }
  4700. return hicon;
  4701. }
  4702. #endif // NEED_SHELL32_WRAPPER
  4703. #ifdef NEED_USER32_WRAPPER
  4704. UINT WINAPI DdeInitializeWrapW(LPDWORD pidInst, PFNCALLBACK pfnCallback,
  4705. DWORD afCmd, DWORD ulRes)
  4706. {
  4707. UINT uRet;
  4708. if (UseUnicodeShell32())
  4709. {
  4710. uRet = DdeInitializeW(pidInst, pfnCallback, afCmd, ulRes);
  4711. }
  4712. else
  4713. {
  4714. //
  4715. // This assumes the callback function will used the wrapped dde
  4716. // string functions (DdeCreateStringHandle and DdeQueryString)
  4717. // to access strings.
  4718. //
  4719. uRet = DdeInitializeA(pidInst, pfnCallback, afCmd, ulRes);
  4720. }
  4721. return uRet;
  4722. }
  4723. #endif // NEED_USER32_WRAPPER
  4724. #ifdef NEED_USER32_WRAPPER
  4725. HSZ WINAPI DdeCreateStringHandleWrapW(DWORD idInst, LPCWSTR psz, int iCodePage)
  4726. {
  4727. HSZ hszRet;
  4728. if (UseUnicodeShell32())
  4729. {
  4730. hszRet = DdeCreateStringHandleW(idInst, psz, iCodePage);
  4731. }
  4732. else
  4733. {
  4734. CStrIn stripsz(psz);
  4735. hszRet = DdeCreateStringHandleA(idInst, stripsz, CP_WINANSI);
  4736. }
  4737. return hszRet;
  4738. }
  4739. #endif // NEED_USER32_WRAPPER
  4740. #ifdef NEED_USER32_WRAPPER
  4741. DWORD WINAPI DdeQueryStringWrapW(DWORD idInst, HSZ hsz, LPWSTR psz,
  4742. DWORD cchMax, int iCodePage)
  4743. {
  4744. DWORD dwRet;
  4745. if (UseUnicodeShell32())
  4746. {
  4747. dwRet = DdeQueryStringW(idInst, hsz, psz, cchMax, iCodePage);
  4748. }
  4749. else
  4750. {
  4751. CStrOut stropsz(psz, cchMax);
  4752. dwRet = DdeQueryStringA(idInst, hsz, stropsz, stropsz.BufSize(),
  4753. CP_WINANSI);
  4754. if (dwRet && psz)
  4755. dwRet = stropsz.ConvertExcludingNul();
  4756. }
  4757. return dwRet;
  4758. }
  4759. #endif // NEED_USER32_WRAPPER
  4760. #ifdef NEED_COMDLG32_WRAPPER
  4761. LPWSTR xxxPathFindExtensionW(
  4762. LPWSTR pszPath)
  4763. {
  4764. LPWSTR pszDot;
  4765. for (pszDot = NULL; *pszPath; pszPath = CharNextWrapW(pszPath)) {
  4766. switch (*pszPath) {
  4767. case L'.':
  4768. pszDot = pszPath; // remember the last dot
  4769. break;
  4770. case L'\\':
  4771. case L' ': // extensions can't have spaces
  4772. pszDot = NULL; // forget last dot, it was in a directory
  4773. break;
  4774. }
  4775. }
  4776. /*
  4777. * if we found the extension, return ptr to the dot, else
  4778. * ptr to end of the string (NULL extension) (cast->non const)
  4779. */
  4780. return pszDot ? (LPWSTR)pszDot : (LPWSTR)pszPath;
  4781. }
  4782. //
  4783. // in:
  4784. // path name, either fully qualified or not
  4785. //
  4786. // returns:
  4787. // pointer into the path where the path is. if none is found
  4788. // returns a poiter to the start of the path
  4789. //
  4790. // c:\foo\bar -> bar
  4791. // c:\foo -> foo
  4792. // c:\foo\ -> c:\foo\ (REVIEW: is this case busted?)
  4793. // c:\ -> c:\ (REVIEW: this case is strange)
  4794. // c: -> c:
  4795. // foo -> foo
  4796. LPTSTR xxxPathFindFileNameW(LPWSTR pPath)
  4797. {
  4798. LPWSTR pT;
  4799. for (pT = pPath; *pPath; pPath = CharNextWrapW(pPath)) {
  4800. if ((pPath[0] == TEXT('\\') || pPath[0] == TEXT(':') || pPath[0] == TEXT('/'))
  4801. && pPath[1] && pPath[1] != TEXT('\\') && pPath[1] != TEXT('/'))
  4802. pT = pPath + 1;
  4803. }
  4804. return (LPTSTR)pT; // const -> non const
  4805. }
  4806. BOOL WINAPI GetSaveFileNameWrapW(LPOPENFILENAMEW lpofn)
  4807. {
  4808. BOOL fRet;
  4809. if (UseUnicodeShell32())
  4810. {
  4811. fRet = GetSaveFileNameW(lpofn);
  4812. }
  4813. else
  4814. {
  4815. ASSERT(lpofn);
  4816. ASSERT(sizeof(OPENFILENAMEA) == sizeof(OPENFILENAMEW));
  4817. OPENFILENAMEA ofnA = *(LPOPENFILENAMEA)lpofn;
  4818. // In parameters
  4819. CStrInMulti strimFilter(lpofn->lpstrFilter);
  4820. CStrIn striInitialDir(lpofn->lpstrInitialDir);
  4821. CStrIn striTitle(lpofn->lpstrTitle);
  4822. CStrIn striDefExt(lpofn->lpstrDefExt);
  4823. CStrIn striTemplateName(lpofn->lpTemplateName);
  4824. ASSERT(NULL == lpofn->lpstrCustomFilter); // add support if you need it.
  4825. // Out parameters
  4826. CStrOut stroFile(lpofn->lpstrFile, lpofn->nMaxFile);
  4827. CStrOut stroFileTitle(lpofn->lpstrFileTitle, lpofn->nMaxFileTitle);
  4828. //In Out parameters
  4829. SHUnicodeToAnsi(lpofn->lpstrFile, stroFile, stroFile.BufSize());
  4830. // Set up the parameters
  4831. ofnA.lpstrFilter = strimFilter;
  4832. ofnA.lpstrInitialDir = striInitialDir;
  4833. ofnA.lpstrTitle = striTitle;
  4834. ofnA.lpstrDefExt = striDefExt;
  4835. ofnA.lpTemplateName = striTemplateName;
  4836. ofnA.lpstrFile = stroFile;
  4837. ofnA.lpstrFileTitle = stroFileTitle;
  4838. fRet = GetSaveFileNameA(&ofnA);
  4839. if (fRet)
  4840. {
  4841. // Copy the out parameters
  4842. lpofn->nFilterIndex = ofnA.nFilterIndex;
  4843. lpofn->Flags = ofnA.Flags;
  4844. // Get the offset to the filename
  4845. stroFile.ConvertIncludingNul();
  4846. LPWSTR psz = xxxPathFindFileNameW(lpofn->lpstrFile);
  4847. if (psz)
  4848. {
  4849. lpofn->nFileOffset = (int) (psz-lpofn->lpstrFile);
  4850. // Get the offset of the extension
  4851. psz = xxxPathFindExtensionW(psz);
  4852. lpofn->nFileExtension = psz ? (int)(psz-lpofn->lpstrFile) : 0;
  4853. }
  4854. else
  4855. {
  4856. lpofn->nFileOffset = 0;
  4857. lpofn->nFileExtension = 0;
  4858. }
  4859. }
  4860. }
  4861. return fRet;
  4862. }
  4863. #endif // NEED_COMDLG32_WRAPPER
  4864. #ifdef NEED_COMDLG32_WRAPPER
  4865. BOOL WINAPI GetOpenFileNameWrapW(LPOPENFILENAMEW lpofn)
  4866. {
  4867. BOOL fRet;
  4868. //VALIDATE_PROTOTYPE_DELAYLOAD(GetOpenFileName, _GetOpenFileName);
  4869. if (UseUnicodeShell32())
  4870. {
  4871. fRet = GetOpenFileNameW(lpofn);
  4872. }
  4873. else
  4874. {
  4875. ASSERT(lpofn);
  4876. ASSERT(sizeof(OPENFILENAMEA) == sizeof(OPENFILENAMEW));
  4877. OPENFILENAMEA ofnA = *(LPOPENFILENAMEA)lpofn;
  4878. // In parameters
  4879. CStrInMulti strimFilter(lpofn->lpstrFilter);
  4880. CStrIn striInitialDir(lpofn->lpstrInitialDir);
  4881. CStrIn striTitle(lpofn->lpstrTitle);
  4882. CStrIn striDefExt(lpofn->lpstrDefExt);
  4883. CStrIn striTemplateName(lpofn->lpTemplateName);
  4884. ASSERT(NULL == lpofn->lpstrCustomFilter); // add support if you need it.
  4885. // Out parameters
  4886. CStrOut stroFile(lpofn->lpstrFile, lpofn->nMaxFile);
  4887. CStrOut stroFileTitle(lpofn->lpstrFileTitle, lpofn->nMaxFileTitle);
  4888. //In Out parameters
  4889. SHUnicodeToAnsi(lpofn->lpstrFile, stroFile, stroFile.BufSize());
  4890. // Set up the parameters
  4891. ofnA.lpstrFilter = strimFilter;
  4892. ofnA.lpstrInitialDir = striInitialDir;
  4893. ofnA.lpstrTitle = striTitle;
  4894. ofnA.lpstrDefExt = striDefExt;
  4895. ofnA.lpTemplateName = striTemplateName;
  4896. ofnA.lpstrFile = stroFile;
  4897. ofnA.lpstrFileTitle = stroFileTitle;
  4898. fRet = GetOpenFileNameA(&ofnA);
  4899. if (fRet)
  4900. {
  4901. // Copy the out parameters
  4902. lpofn->nFilterIndex = ofnA.nFilterIndex;
  4903. lpofn->Flags = ofnA.Flags;
  4904. // Get the offset to the filename
  4905. stroFile.ConvertIncludingNul();
  4906. LPWSTR psz = xxxPathFindFileNameW(lpofn->lpstrFile);
  4907. if (psz)
  4908. {
  4909. lpofn->nFileOffset = (int) (psz-lpofn->lpstrFile);
  4910. // Get the offset of the extension
  4911. psz = xxxPathFindExtensionW(psz);
  4912. lpofn->nFileExtension = psz ? (int)(psz-lpofn->lpstrFile) : 0;
  4913. }
  4914. else
  4915. {
  4916. lpofn->nFileOffset = 0;
  4917. lpofn->nFileExtension = 0;
  4918. }
  4919. }
  4920. }
  4921. return fRet;
  4922. }
  4923. #endif // NEED_COMDLG32_WRAPPER
  4924. #ifdef NEED_SHELL32_WRAPPER
  4925. #define SHCNF_HAS_WSTR_PARAMS(f) ((f & SHCNF_TYPE) == SHCNF_PATHW || \
  4926. (f & SHCNF_TYPE) == SHCNF_PRINTERW || \
  4927. (f & SHCNF_TYPE) == SHCNF_PRINTJOBW )
  4928. void SHChangeNotifyWrap(LONG wEventId, UINT uFlags, LPCVOID dwItem1,
  4929. LPCVOID dwItem2)
  4930. {
  4931. // Can't do this because this is not a "W" function
  4932. // VALIDATE_PROTOTYPE(SHChangeNotify);
  4933. if (UseUnicodeShell32() || !SHCNF_HAS_WSTR_PARAMS(uFlags))
  4934. {
  4935. _SHChangeNotify(wEventId, uFlags, dwItem1, dwItem2);
  4936. }
  4937. else
  4938. {
  4939. CStrIn striItem1((LPWSTR)dwItem1);
  4940. CStrIn striItem2((LPWSTR)dwItem2);
  4941. if ((uFlags & SHCNF_TYPE) == SHCNF_PATHW)
  4942. {
  4943. uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PATHA;
  4944. }
  4945. else if ((uFlags & SHCNF_TYPE) == SHCNF_PRINTERW)
  4946. {
  4947. uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PRINTERA;
  4948. }
  4949. else
  4950. {
  4951. uFlags = (uFlags & ~SHCNF_TYPE) | SHCNF_PRINTJOBA;
  4952. }
  4953. _SHChangeNotify(wEventId, uFlags, (void*)(LPSTR)striItem1,
  4954. (void*)(LPSTR)striItem2);
  4955. }
  4956. return;
  4957. }
  4958. #endif // NEED_SHELL32_WRAPPER
  4959. #ifdef NEED_COMDLG32_WRAPPER
  4960. //+---------------------------------------------------------------------------
  4961. // PrintDlgWrap, PageSetupDlgWrap - wrappers
  4962. // DevNamesAFromDevNamesW, DevNamesWFromDevNamesA - helper functions
  4963. //
  4964. // Copied from mshtml\src\core\wrappers\unicwrap.cpp with some
  4965. // cosmetic changes (peterlee)
  4966. //
  4967. //+---------------------------------------------------------------------------
  4968. HGLOBAL
  4969. DevNamesAFromDevNamesW( HGLOBAL hdnw )
  4970. {
  4971. HGLOBAL hdna = NULL;
  4972. if (hdnw)
  4973. {
  4974. LPDEVNAMES lpdnw = (LPDEVNAMES) GlobalLock( hdnw );
  4975. if (lpdnw)
  4976. {
  4977. CStrIn strDriver( (LPCWSTR) lpdnw + lpdnw->wDriverOffset );
  4978. CStrIn strDevice( (LPCWSTR) lpdnw + lpdnw->wDeviceOffset );
  4979. CStrIn strOutput( (LPCWSTR) lpdnw + lpdnw->wOutputOffset );
  4980. int cchDriver = strDriver.strlen() + 1;
  4981. int cchDevice = strDevice.strlen() + 1;
  4982. int cchOutput = strOutput.strlen() + 1;
  4983. hdna = GlobalAlloc( GHND, sizeof(DEVNAMES) +
  4984. cchDriver + cchDevice + cchOutput );
  4985. if (hdna)
  4986. {
  4987. LPDEVNAMES lpdna = (LPDEVNAMES) GlobalLock( hdna );
  4988. if (!lpdna)
  4989. {
  4990. GlobalFree( hdna );
  4991. hdna = NULL;
  4992. }
  4993. else
  4994. {
  4995. lpdna->wDriverOffset = sizeof(DEVNAMES);
  4996. lpdna->wDeviceOffset = lpdna->wDriverOffset + cchDriver;
  4997. lpdna->wOutputOffset = lpdna->wDeviceOffset + cchDevice;
  4998. lpdna->wDefault = lpdnw->wDefault;
  4999. lstrcpyA( (LPSTR) lpdna + lpdna->wDriverOffset, strDriver );
  5000. lstrcpyA( (LPSTR) lpdna + lpdna->wDeviceOffset, strDevice );
  5001. lstrcpyA( (LPSTR) lpdna + lpdna->wOutputOffset, strOutput );
  5002. GlobalUnlock( hdna );
  5003. }
  5004. }
  5005. GlobalUnlock( hdnw );
  5006. GlobalFree( hdnw );
  5007. }
  5008. }
  5009. return hdna;
  5010. }
  5011. HGLOBAL
  5012. DevNamesWFromDevNamesA( HGLOBAL hdna )
  5013. {
  5014. HGLOBAL hdnw = NULL;
  5015. if (hdna)
  5016. {
  5017. LPDEVNAMES lpdna = (LPDEVNAMES) GlobalLock( hdna );
  5018. if (lpdna)
  5019. {
  5020. LPCSTR lpszDriver = (LPCSTR) lpdna + lpdna->wDriverOffset;
  5021. LPCSTR lpszDevice = (LPCSTR) lpdna + lpdna->wDeviceOffset;
  5022. LPCSTR lpszOutput = (LPCSTR) lpdna + lpdna->wOutputOffset;
  5023. int cchDriver = lstrlenA( lpszDriver ) + 1;
  5024. int cchDevice = lstrlenA( lpszDevice ) + 1;
  5025. int cchOutput = lstrlenA( lpszOutput ) + 1;
  5026. // assume the wide charcount won't exceed the multibyte charcount
  5027. hdnw = GlobalAlloc( GHND, sizeof(DEVNAMES) +
  5028. sizeof(WCHAR) * (cchDriver + cchDevice + cchOutput) );
  5029. if (hdnw)
  5030. {
  5031. LPDEVNAMES lpdnw = (LPDEVNAMES) GlobalLock( hdnw );
  5032. if (!lpdnw)
  5033. {
  5034. GlobalFree( hdnw );
  5035. hdnw = NULL;
  5036. }
  5037. else
  5038. {
  5039. lpdnw->wDriverOffset = sizeof(DEVNAMES) / sizeof(WCHAR);
  5040. lpdnw->wDeviceOffset = lpdnw->wDriverOffset + cchDriver;
  5041. lpdnw->wOutputOffset = lpdnw->wDeviceOffset + cchDevice;
  5042. lpdnw->wDefault = lpdna->wDefault;
  5043. SHAnsiToUnicode( (LPSTR) lpszDriver, (LPWSTR) lpdnw + lpdnw->wDriverOffset,
  5044. cchDriver );
  5045. SHAnsiToUnicode( lpszDevice, (LPWSTR) lpdnw + lpdnw->wDeviceOffset,
  5046. cchDevice);
  5047. SHAnsiToUnicode( lpszOutput, (LPWSTR) lpdnw + lpdnw->wOutputOffset,
  5048. cchOutput);
  5049. GlobalUnlock( hdnw );
  5050. }
  5051. }
  5052. GlobalUnlock( hdna );
  5053. GlobalFree( hdna );
  5054. }
  5055. }
  5056. return hdnw;
  5057. }
  5058. #endif // NEED_COMDLG32_WRAPPER
  5059. #ifdef NEED_COMDLG32_WRAPPER
  5060. //--------------------------------------------------------------
  5061. // PrintDlgW wrapper
  5062. //--------------------------------------------------------------
  5063. #if UNUSED_DONOTBUILD
  5064. BOOL WINAPI
  5065. PrintDlgWrapW(LPPRINTDLGW lppd)
  5066. {
  5067. BOOL fRet;
  5068. VALIDATE_PROTOTYPE_DELAYLOAD(PrintDlg, _PrintDlg);
  5069. if (UseUnicodeShell32())
  5070. {
  5071. fRet = _PrintDlgW(lppd);
  5072. }
  5073. else
  5074. {
  5075. PRINTDLGA pda;
  5076. LPCWSTR lpPrintTemplateName = lppd->lpPrintTemplateName;
  5077. LPCWSTR lpSetupTemplateName = lppd->lpSetupTemplateName;
  5078. CStrIn strPrintTemplateName( lpPrintTemplateName );
  5079. CStrIn strSetupTemplateName( lpSetupTemplateName );
  5080. ASSERT( sizeof(pda) == sizeof( *lppd ));
  5081. memcpy( &pda, lppd, sizeof(pda) );
  5082. // IMPORTANT: We are not converting the DEVMODE structure back and forth
  5083. // from ASCII to Unicode on Win95 anymore because we are not touching the
  5084. // two strings or any other member. Converting the DEVMODE structure can
  5085. // be tricky because of potential and common discrepancies between the
  5086. // value of the dmSize member and sizeof(DEVMODE). (25155)
  5087. // So instead of: pda.hDevMode = DevModeAFromDevModeW( lppd->hDevMode );
  5088. // we just forward the DEVMODE handle:
  5089. pda.hDevMode = lppd->hDevMode;
  5090. pda.hDevNames = DevNamesAFromDevNamesW( lppd->hDevNames );
  5091. pda.lpPrintTemplateName = strPrintTemplateName;
  5092. pda.lpSetupTemplateName = strSetupTemplateName;
  5093. fRet = _PrintDlgA( &pda );
  5094. // copy back wholesale, then restore strings.
  5095. memcpy( lppd, &pda, sizeof(pda) );
  5096. lppd->lpSetupTemplateName = lpSetupTemplateName;
  5097. lppd->lpPrintTemplateName = lpPrintTemplateName;
  5098. lppd->hDevNames = DevNamesWFromDevNamesA( pda.hDevNames );
  5099. // And instead of: lppd->hDevMode = DevModeWFromDevModeA( pda.hDevMode );
  5100. // we just forward the DEVMODE handle:
  5101. lppd->hDevMode = pda.hDevMode;
  5102. }
  5103. return fRet;
  5104. }
  5105. #endif // UNUSED_DONOTBUILD
  5106. #endif // NEED_COMDLG32_WRAPPER
  5107. #ifdef NEED_COMDLG32_WRAPPER
  5108. //--------------------------------------------------------------
  5109. // PageSetupDlgW wrapper
  5110. //--------------------------------------------------------------
  5111. #if UNUSED_DONOTBUILD
  5112. BOOL WINAPI
  5113. PageSetupDlgWrapW(LPPAGESETUPDLGW lppsd)
  5114. {
  5115. BOOL fRet;
  5116. VALIDATE_PROTOTYPE_DELAYLOAD(PageSetupDlg, _PageSetupDlg);
  5117. if (UseUnicodeShell32())
  5118. {
  5119. fRet = _PageSetupDlgW(lppsd);
  5120. }
  5121. else
  5122. {
  5123. PAGESETUPDLGA psda;
  5124. LPCWSTR lpPageSetupTemplateName = lppsd->lpPageSetupTemplateName;
  5125. CStrIn strPageSetupTemplateName( lpPageSetupTemplateName );
  5126. ASSERT( sizeof(psda) == sizeof( *lppsd ) );
  5127. memcpy( &psda, lppsd, sizeof(psda));
  5128. // IMPORTANT: We are not converting the DEVMODE structure back and forth
  5129. // from ASCII to Unicode on Win95 anymore because we are not touching the
  5130. // two strings or any other member. Converting the DEVMODE structure can
  5131. // be tricky because of potential and common discrepancies between the
  5132. // value of the dmSize member and sizeof(DEVMODE). (25155)
  5133. // So instead of: psda.hDevMode = DevModeAFromDevModeW( lppsd->hDevMode );
  5134. // we just forward the DEVMODE handle:
  5135. psda.hDevMode = lppsd->hDevMode;
  5136. psda.hDevNames = DevNamesAFromDevNamesW( lppsd->hDevNames );
  5137. psda.lpPageSetupTemplateName = strPageSetupTemplateName;
  5138. fRet = _PageSetupDlgA( (LPPAGESETUPDLGA) &psda );
  5139. // copy back wholesale, then restore string.
  5140. memcpy( lppsd, &psda, sizeof(psda) );
  5141. lppsd->lpPageSetupTemplateName = lpPageSetupTemplateName;
  5142. lppsd->hDevNames = DevNamesWFromDevNamesA( psda.hDevNames );
  5143. // And instead of: lppsd->hDevMode = DevModeWFromDevModeA( psda.hDevMode );
  5144. // we just forward the DEVMODE handle:
  5145. lppsd->hDevMode = psda.hDevMode;
  5146. }
  5147. return fRet;
  5148. }
  5149. #endif // UNUSED_DONOTBUILD
  5150. #endif // NEED_COMDLG32_WRAPPER
  5151. // Newly added wrappers specifically for ts client (nadima)
  5152. HANDLE
  5153. WINAPI
  5154. CreateFileMappingWrapW(
  5155. IN HANDLE hFile,
  5156. IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  5157. IN DWORD flProtect,
  5158. IN DWORD dwMaximumSizeHigh,
  5159. IN DWORD dwMaximumSizeLow,
  5160. IN LPCWSTR lpName
  5161. )
  5162. {
  5163. VALIDATE_PROTOTYPE(CreateMutex);
  5164. if (g_bRunningOnNT)
  5165. {
  5166. return CreateFileMappingW(hFile, lpFileMappingAttributes,
  5167. flProtect, dwMaximumSizeHigh,
  5168. dwMaximumSizeLow, lpName);
  5169. }
  5170. else
  5171. {
  5172. CStrIn strText(lpName);
  5173. return CreateFileMappingA(hFile, lpFileMappingAttributes,
  5174. flProtect, dwMaximumSizeHigh,
  5175. dwMaximumSizeLow, strText);
  5176. }
  5177. }
  5178. HICON
  5179. ExtractIconWrapW(
  5180. HINSTANCE hInst,
  5181. LPCWSTR lpszExeFileName,
  5182. UINT nIconIndex)
  5183. {
  5184. VALIDATE_PROTOTYPE(ExtractIcon);
  5185. if(g_bRunningOnNT)
  5186. {
  5187. return ExtractIconW( hInst,
  5188. lpszExeFileName,
  5189. nIconIndex);
  5190. }
  5191. else
  5192. {
  5193. CStrIn strText(lpszExeFileName);
  5194. return ExtractIconA( hInst,
  5195. strText,
  5196. nIconIndex);
  5197. }
  5198. }
  5199. BOOL WINAPI SHGetPathFromIDListWrapW(LPCITEMIDLIST pidl, LPWSTR pwzPath)
  5200. {
  5201. //VALIDATE_PROTOTYPE_DELAYLOAD(SHGetPathFromIDList, _SHGetPathFromIDList);
  5202. if (g_bRunningOnNT)
  5203. {
  5204. //
  5205. // SHGetPathFromIDListW is not necessarily available
  5206. // as a stub on 9x, so dynamically bind to it for NT
  5207. //
  5208. HRESULT hr = E_NOTIMPL;
  5209. typedef HRESULT (STDAPICALLTYPE FNSHGetPathFromIDListW)
  5210. (LPCITEMIDLIST pidl, LPWSTR pwzPath);
  5211. FNSHGetPathFromIDListW *pfnSHGetPathFromIDListW = NULL;
  5212. // get the handle to shell32.dll library
  5213. HMODULE hmodSH32DLL = LoadLibraryWrapW(TEXT("SHELL32.DLL"));
  5214. if (hmodSH32DLL != NULL)
  5215. {
  5216. // get the proc address for SHGetFolderPath
  5217. pfnSHGetPathFromIDListW = (FNSHGetPathFromIDListW*)
  5218. GetProcAddress(hmodSH32DLL, "SHGetPathFromIDListW");
  5219. if (pfnSHGetPathFromIDListW)
  5220. {
  5221. hr = (*pfnSHGetPathFromIDListW)( pidl, pwzPath );
  5222. }
  5223. FreeLibrary(hmodSH32DLL);
  5224. }
  5225. return hr;
  5226. }
  5227. else
  5228. {
  5229. CStrOut strPathOut(pwzPath, MAX_PATH);
  5230. BOOL fResult = SHGetPathFromIDListA(pidl, strPathOut);
  5231. if (fResult)
  5232. strPathOut.ConvertIncludingNul();
  5233. return fResult;
  5234. }
  5235. }
  5236. SHORT
  5237. WINAPI
  5238. GetFileTitleWrapW(
  5239. LPCWSTR lpszFileW,
  5240. LPWSTR lpszTitleW,
  5241. WORD cbBuf)
  5242. {
  5243. VALIDATE_PROTOTYPE(GetFileTitle);
  5244. if(g_bRunningOnNT)
  5245. {
  5246. return GetFileTitleW( lpszFileW, lpszTitleW, cbBuf);
  5247. }
  5248. else
  5249. {
  5250. CStrIn strFileName( lpszFileW);
  5251. CStrOut strOutTitle(lpszTitleW, cbBuf);
  5252. return GetFileTitleA( strFileName, strOutTitle, cbBuf);
  5253. }
  5254. }
  5255. BOOL
  5256. WINAPI
  5257. GetKeyboardLayoutNameWrapW(
  5258. OUT LPWSTR pwszKLID)
  5259. {
  5260. if(g_bRunningOnNT)
  5261. {
  5262. return GetKeyboardLayoutNameW( pwszKLID);
  5263. }
  5264. else
  5265. {
  5266. CStrOut strOutKeybId( pwszKLID, KL_NAMELENGTH);
  5267. return GetKeyboardLayoutNameA( strOutKeybId);
  5268. }
  5269. }
  5270. BOOL
  5271. APIENTRY
  5272. GetTextExtentPointWrapW(HDC hdc,LPCWSTR pwsz,DWORD cwc,LPSIZE psizl)
  5273. {
  5274. if(g_bRunningOnNT)
  5275. {
  5276. return GetTextExtentPointW( hdc, pwsz, cwc, psizl);
  5277. }
  5278. else
  5279. {
  5280. CStrIn strIn(pwsz);
  5281. return GetTextExtentPointA( hdc, strIn, cwc, psizl);
  5282. }
  5283. }
  5284. BOOL
  5285. WINAPI
  5286. GetDiskFreeSpaceWrapW(
  5287. IN LPCWSTR lpRootPathName,
  5288. OUT LPDWORD lpSectorsPerCluster,
  5289. OUT LPDWORD lpBytesPerSector,
  5290. OUT LPDWORD lpNumberOfFreeClusters,
  5291. OUT LPDWORD lpTotalNumberOfClusters
  5292. )
  5293. {
  5294. if(g_bRunningOnNT)
  5295. {
  5296. return GetDiskFreeSpaceW( lpRootPathName, lpSectorsPerCluster,
  5297. lpBytesPerSector, lpNumberOfFreeClusters,
  5298. lpTotalNumberOfClusters);
  5299. }
  5300. else
  5301. {
  5302. CStrIn strIn(lpRootPathName);
  5303. return GetDiskFreeSpaceA( strIn, lpSectorsPerCluster,
  5304. lpBytesPerSector, lpNumberOfFreeClusters,
  5305. lpTotalNumberOfClusters);
  5306. }
  5307. }
  5308. UINT
  5309. WINAPI
  5310. GetDriveTypeWrapW(
  5311. IN LPCWSTR lpRootPathName
  5312. )
  5313. {
  5314. if(g_bRunningOnNT)
  5315. {
  5316. return GetDriveTypeW( lpRootPathName);
  5317. }
  5318. else
  5319. {
  5320. CStrIn strIn(lpRootPathName);
  5321. return GetDriveTypeA(strIn);
  5322. }
  5323. }
  5324. HANDLE
  5325. WINAPI
  5326. FindFirstChangeNotificationWrapW(
  5327. IN LPCWSTR lpPathName,
  5328. IN BOOL bWatchSubtree,
  5329. IN DWORD dwNotifyFilter
  5330. )
  5331. {
  5332. if(g_bRunningOnNT)
  5333. {
  5334. return FindFirstChangeNotificationW( lpPathName,
  5335. bWatchSubtree,
  5336. dwNotifyFilter);
  5337. }
  5338. else
  5339. {
  5340. CStrIn strIn(lpPathName);
  5341. return FindFirstChangeNotificationA( strIn,
  5342. bWatchSubtree,
  5343. dwNotifyFilter);
  5344. }
  5345. }
  5346. BOOL
  5347. WINAPI
  5348. GetVolumeInformationWrapW(
  5349. IN LPCWSTR lpRootPathName,
  5350. OUT LPWSTR lpVolumeNameBuffer,
  5351. IN DWORD nVolumeNameSize,
  5352. OUT LPDWORD lpVolumeSerialNumber,
  5353. OUT LPDWORD lpMaximumComponentLength,
  5354. OUT LPDWORD lpFileSystemFlags,
  5355. OUT LPWSTR lpFileSystemNameBuffer,
  5356. IN DWORD nFileSystemNameSize
  5357. )
  5358. {
  5359. if(g_bRunningOnNT)
  5360. {
  5361. return GetVolumeInformationW( lpRootPathName,
  5362. lpVolumeNameBuffer,
  5363. nVolumeNameSize,
  5364. lpVolumeSerialNumber,
  5365. lpMaximumComponentLength,
  5366. lpFileSystemFlags,
  5367. lpFileSystemNameBuffer,
  5368. nFileSystemNameSize);
  5369. }
  5370. else
  5371. {
  5372. CStrIn strRootPathName(lpRootPathName);
  5373. CStrOut strOutVolumeNameBuffer(lpVolumeNameBuffer, nVolumeNameSize);
  5374. CStrOut strOutFileSystemName(lpFileSystemNameBuffer, nFileSystemNameSize);
  5375. return GetVolumeInformationA( strRootPathName,
  5376. strOutVolumeNameBuffer,
  5377. nVolumeNameSize,
  5378. lpVolumeSerialNumber,
  5379. lpMaximumComponentLength,
  5380. lpFileSystemFlags,
  5381. strOutFileSystemName,
  5382. nFileSystemNameSize);
  5383. }
  5384. }
  5385. UINT FORWARD_API WINAPI
  5386. MapVirtualKeyWrapW(
  5387. IN UINT uCode,
  5388. IN UINT uMapType)
  5389. {
  5390. VALIDATE_PROTOTYPE(MapVirtualKey);
  5391. FORWARD_AW(MapVirtualKey, (uCode, uMapType));
  5392. }
  5393. ULONG_PTR FORWARD_API WINAPI
  5394. SetClassLongPtrWrapW(
  5395. IN HWND hWnd,
  5396. IN int nIndex,
  5397. IN LONG_PTR dwNewLong)
  5398. {
  5399. VALIDATE_PROTOTYPE(SetClassLongPtr);
  5400. FORWARD_AW(SetClassLongPtr, (hWnd, nIndex, dwNewLong));
  5401. }
  5402. BOOL
  5403. WINAPI
  5404. GetComputerNameWrapW (
  5405. OUT LPWSTR lpBuffer,
  5406. IN OUT LPDWORD nSize
  5407. )
  5408. {
  5409. VALIDATE_PROTOTYPE(GetComputerName);
  5410. if(g_bRunningOnNT)
  5411. {
  5412. return GetComputerNameW( lpBuffer, nSize);
  5413. }
  5414. else
  5415. {
  5416. CStrOut strOutCompName(lpBuffer, *nSize);
  5417. return GetComputerNameA(strOutCompName, nSize);
  5418. }
  5419. }
  5420. BOOL
  5421. WINAPI
  5422. GetFileSecurityWrapW (
  5423. IN LPCWSTR lpFileName,
  5424. IN SECURITY_INFORMATION RequestedInformation,
  5425. OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
  5426. IN DWORD nLength,
  5427. OUT LPDWORD lpnLengthNeeded
  5428. )
  5429. {
  5430. VALIDATE_PROTOTYPE(GetFileSecurity);
  5431. if(g_bRunningOnNT)
  5432. {
  5433. return GetFileSecurityW( lpFileName, RequestedInformation,
  5434. pSecurityDescriptor, nLength, lpnLengthNeeded);
  5435. }
  5436. else
  5437. {
  5438. CStrIn strInFileName( lpFileName);
  5439. return GetFileSecurityA( strInFileName, RequestedInformation,
  5440. pSecurityDescriptor, nLength, lpnLengthNeeded);
  5441. }
  5442. }
  5443. BOOL
  5444. WINAPI
  5445. SetFileSecurityWrapW (
  5446. IN LPCWSTR lpFileName,
  5447. IN SECURITY_INFORMATION SecurityInformation,
  5448. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  5449. )
  5450. {
  5451. VALIDATE_PROTOTYPE(SetFileSecurity);
  5452. if(g_bRunningOnNT)
  5453. {
  5454. return SetFileSecurityW( lpFileName, SecurityInformation,
  5455. pSecurityDescriptor);
  5456. }
  5457. else
  5458. {
  5459. CStrIn strInFileName( lpFileName);
  5460. return SetFileSecurityA( strInFileName, SecurityInformation,
  5461. pSecurityDescriptor);
  5462. }
  5463. }
  5464. int WINAPIV wsprintfWrapW(
  5465. LPWSTR lpOut,
  5466. LPCWSTR lpFmt,
  5467. ...)
  5468. {
  5469. va_list arglist;
  5470. int ret;
  5471. va_start(arglist, lpFmt);
  5472. ret = wvsprintfWrapW(lpOut, lpFmt, arglist);
  5473. va_end(arglist);
  5474. return ret;
  5475. }
  5476. //This wrapper dynamically binds to shell32
  5477. //because the W or A functions are not necessarily available on 9x
  5478. STDAPI SHGetFolderPathWrapW(HWND hwnd, int csidl, HANDLE hToken,
  5479. DWORD dwFlags, LPWSTR pszPath)
  5480. {
  5481. HRESULT hr = E_NOTIMPL;
  5482. typedef HRESULT (STDAPICALLTYPE FNSHGetFolderPathW)(HWND, int, HANDLE, DWORD, LPWSTR);
  5483. typedef HRESULT (STDAPICALLTYPE FNSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
  5484. FNSHGetFolderPathW *pfnSHGetFolderPathW = NULL;
  5485. FNSHGetFolderPathA *pfnSHGetFolderPathA = NULL;
  5486. // get the handle to shell32.dll library
  5487. HMODULE hmodSH32DLL = LoadLibraryWrapW(TEXT("SHELL32.DLL"));
  5488. if (hmodSH32DLL != NULL)
  5489. {
  5490. // get the proc address for SHGetFolderPath
  5491. if(g_bRunningOnNT)
  5492. {
  5493. pfnSHGetFolderPathW = (FNSHGetFolderPathW*)GetProcAddress(hmodSH32DLL, "SHGetFolderPathW");
  5494. }
  5495. else
  5496. {
  5497. pfnSHGetFolderPathA = (FNSHGetFolderPathA*)GetProcAddress(hmodSH32DLL, "SHGetFolderPathA");
  5498. }
  5499. if (g_bRunningOnNT && pfnSHGetFolderPathW)
  5500. {
  5501. hr = (*pfnSHGetFolderPathW)( hwnd, csidl, hToken, dwFlags, pszPath);
  5502. }
  5503. else if(pfnSHGetFolderPathA)
  5504. {
  5505. CStrOut strPathOut(pszPath, MAX_PATH);
  5506. hr = (*pfnSHGetFolderPathA)( hwnd, csidl, hToken, dwFlags, strPathOut);
  5507. }
  5508. FreeLibrary(hmodSH32DLL);
  5509. }
  5510. return hr;
  5511. }
  5512. STDAPI StrRetToStrWrapW(STRRET *pstr,
  5513. LPCITEMIDLIST pidl,
  5514. LPWSTR* ppsz)
  5515. {
  5516. if(g_bRunningOnNT)
  5517. {
  5518. return StrRetToStrW( pstr, pidl, ppsz);
  5519. }
  5520. else
  5521. {
  5522. LPSTR szAnsiOut = NULL;
  5523. HRESULT hr = StrRetToStrA( pstr, pidl, &szAnsiOut);
  5524. if(SUCCEEDED(hr))
  5525. {
  5526. int numChars = strlen(szAnsiOut);
  5527. *ppsz = (LPWSTR) CoTaskMemAlloc( (numChars + 2) * sizeof(TCHAR) );
  5528. if(*ppsz)
  5529. {
  5530. SHAnsiToUnicode( szAnsiOut, *ppsz, numChars + 1);
  5531. //free temp
  5532. CoTaskMemFree( szAnsiOut );
  5533. return hr;
  5534. }
  5535. else
  5536. {
  5537. return E_OUTOFMEMORY;
  5538. }
  5539. }
  5540. else
  5541. {
  5542. return hr;
  5543. }
  5544. }
  5545. }
  5546. BOOL
  5547. WINAPI
  5548. GetVersionExWrapW(
  5549. IN OUT LPOSVERSIONINFOW lpVersionInformation
  5550. )
  5551. {
  5552. if(g_bRunningOnNT)
  5553. {
  5554. return GetVersionExW( lpVersionInformation );
  5555. }
  5556. else
  5557. {
  5558. //NOTE this API will behave exactly like win9x's
  5559. //i.e it doesn't process the OSVERSIONINFOEX fields
  5560. BOOL ret = FALSE;
  5561. OSVERSIONINFOA osvera;
  5562. osvera.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  5563. ret = GetVersionExA( &osvera );
  5564. if(ret)
  5565. {
  5566. lpVersionInformation->dwBuildNumber = osvera.dwBuildNumber;
  5567. lpVersionInformation->dwMajorVersion = osvera.dwMajorVersion;
  5568. lpVersionInformation->dwMinorVersion = osvera.dwMinorVersion;
  5569. lpVersionInformation->dwPlatformId = osvera.dwPlatformId;
  5570. SHAnsiToUnicode( osvera.szCSDVersion,
  5571. lpVersionInformation->szCSDVersion,
  5572. sizeof(lpVersionInformation->szCSDVersion)/sizeof(TCHAR));
  5573. return TRUE;
  5574. }
  5575. else
  5576. {
  5577. return FALSE;
  5578. }
  5579. }
  5580. }
  5581. BOOL
  5582. WINAPI
  5583. GetDefaultCommConfigWrapW(
  5584. IN LPCWSTR lpszName,
  5585. OUT LPCOMMCONFIG lpCC,
  5586. IN OUT LPDWORD lpdwSize
  5587. )
  5588. {
  5589. if(g_bRunningOnNT)
  5590. {
  5591. return GetDefaultCommConfigW( lpszName, lpCC, lpdwSize);
  5592. }
  5593. else
  5594. {
  5595. CStrIn strName( lpszName );
  5596. return GetDefaultCommConfigA( strName, lpCC, lpdwSize);
  5597. }
  5598. }
  5599. //
  5600. // IME thunks dyamically bind to IME dlls outside the unicode wrapper
  5601. // layer so we get passed in function pointers
  5602. //
  5603. UINT ImmGetIMEFileName_DynWrapW(
  5604. IN HKL hkl,
  5605. OUT LPWSTR szName,
  5606. IN UINT uBufLen,
  5607. IN PFN_ImmGetIMEFileNameW pfnImmGetIMEFileNameW,
  5608. IN PFN_ImmGetIMEFileNameA pfnImmGetIMEFileNameA)
  5609. {
  5610. UINT result = 0; //assume fail
  5611. if (g_bRunningOnNT)
  5612. {
  5613. if (pfnImmGetIMEFileNameW)
  5614. {
  5615. result = pfnImmGetIMEFileNameW(hkl, szName, uBufLen);
  5616. }
  5617. }
  5618. else
  5619. {
  5620. if (pfnImmGetIMEFileNameA)
  5621. {
  5622. CStrOut strOutName(szName, uBufLen/sizeof(WCHAR));
  5623. result = pfnImmGetIMEFileNameA(hkl, strOutName, uBufLen/2);
  5624. }
  5625. }
  5626. return result;
  5627. }
  5628. //
  5629. // IME thunks dyamically bind to IME dlls outside the unicode wrapper
  5630. // layer so we get passed in function pointers
  5631. //
  5632. BOOL ImpGetIME_DynWrapW(
  5633. IN HWND hWnd,
  5634. OUT LPIMEPROW lpImeProW,
  5635. IN PFN_IMPGetIMEW pfnIMPGetIMEW,
  5636. IN PFN_IMPGetIMEA pfnIMPGetIMEA)
  5637. {
  5638. BOOL fRes = FALSE;
  5639. if (g_bRunningOnNT)
  5640. {
  5641. if (pfnIMPGetIMEW)
  5642. {
  5643. fRes = pfnIMPGetIMEW(hWnd, lpImeProW);
  5644. }
  5645. }
  5646. else
  5647. {
  5648. if (pfnIMPGetIMEA)
  5649. {
  5650. IMEPROA imeProA;
  5651. fRes = pfnIMPGetIMEA(hWnd, &imeProA);
  5652. if (fRes)
  5653. {
  5654. lpImeProW->hWnd = imeProA.hWnd;
  5655. lpImeProW->InstDate = imeProA.InstDate;
  5656. lpImeProW->wVersion = imeProA.wVersion;
  5657. SHAnsiToUnicode( (LPCSTR)&imeProA.szDescription,
  5658. lpImeProW->szDescription,
  5659. sizeof(lpImeProW->szDescription)/sizeof(TCHAR));
  5660. SHAnsiToUnicode( (LPCSTR)&imeProA.szName,
  5661. lpImeProW->szName,
  5662. sizeof(lpImeProW->szName)/sizeof(TCHAR));
  5663. SHAnsiToUnicode( (LPCSTR)&imeProA.szOptions,
  5664. lpImeProW->szOptions,
  5665. sizeof(lpImeProW->szOptions)/sizeof(TCHAR));
  5666. }
  5667. }
  5668. }
  5669. return fRes;
  5670. }