Source code of Windows XP (NT5)
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.

1840 lines
33 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993 - 1993.
  5. //
  6. // File: widewrap.cxx
  7. //
  8. // Contents: Unicode wrapper API, used only on Chicago
  9. //
  10. // Functions: About fifty Win32 function wrappers
  11. //
  12. // Notes: 'sz' is used instead of the "correct" hungarian 'psz'
  13. // throughout to enhance readability.
  14. //
  15. // Not all of every Win32 function is wrapped here. Some
  16. // obscurely-documented features may not be handled correctly
  17. // in these wrappers. Caller beware.
  18. //
  19. // These are privately exported for use by the Shell.
  20. //
  21. // History: 28-Dec-93 ErikGav Created
  22. // 06-14-94 KentCe Various Chicago build fixes.
  23. // 21-Dec-94 BruceMa Use olewcstombs + other fixes
  24. // 21-Feb-95 BruceMa Add support for AreFileApisANSI
  25. //
  26. //----------------------------------------------------------------------------
  27. #include <windows.h>
  28. #include "widewrap.h"
  29. size_t olembstowcs(WCHAR *pwsz, const char *psz, size_t cCh);
  30. size_t olewcstombs(char *psz, const WCHAR *pwsz , size_t cCh);
  31. inline size_t olembstowcs(WCHAR *pwsz, const char *psz, size_t cCh)
  32. {
  33. return MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, psz, -1, pwsz, cCh);
  34. }
  35. inline size_t olewcstombs(char *psz, const WCHAR *pwsz , size_t cCh)
  36. {
  37. return WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, psz,
  38. cCh, NULL, NULL);
  39. }
  40. #ifdef _CHICAGO_
  41. #define HFINDFILE HANDLE
  42. #define ERR ((char*) -1)
  43. //
  44. // BUGBUG: 9869
  45. //
  46. // The length of a Unicode string (in chars) and a DBCS string are not
  47. // always equal. We need to review all WideChar to MultiByte conversions
  48. // logic to verify that the proper result buffer size is used.
  49. //
  50. // Make the below Win95 only change to get the Win95 FE build out.
  51. //
  52. int UnicodeToAnsi(LPSTR sz, LPCWSTR pwsz, LONG cb)
  53. {
  54. int ret;
  55. ret = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, sz, cb, NULL, NULL);
  56. #if DBG==1
  57. if (ret == -1)
  58. {
  59. DebugBreak();
  60. }
  61. #endif
  62. return ret;
  63. }
  64. int UnicodeToAnsiOem(LPSTR sz, LPCWSTR pwsz, LONG cb)
  65. {
  66. int ret;
  67. if (AreFileApisANSI())
  68. {
  69. ret = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, sz,
  70. cb, NULL, NULL);
  71. }
  72. else
  73. {
  74. ret = WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, pwsz, -1, sz,
  75. cb, NULL, NULL);
  76. }
  77. #if DBG==1
  78. if (ret == -1)
  79. {
  80. DebugBreak();
  81. }
  82. #endif
  83. return ret;
  84. }
  85. #if DBG==1
  86. int AnsiToUnicode(LPWSTR pwsz, LPCSTR sz, LONG cb)
  87. {
  88. int ret;
  89. ret = olembstowcs(pwsz, sz, cb);
  90. if (ret == -1)
  91. {
  92. DebugBreak();
  93. }
  94. return ret;
  95. }
  96. #else
  97. #define AnsiToUnicode olembstowcs
  98. #endif
  99. int AnsiToUnicodeOem(LPWSTR pwsz, LPCSTR sz, LONG cb)
  100. {
  101. int ret;
  102. if (AreFileApisANSI())
  103. {
  104. ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, cb, pwsz, cb);
  105. }
  106. else
  107. {
  108. ret = MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, sz, cb, pwsz, cb);
  109. }
  110. #if DBG==1
  111. if (ret == -1)
  112. {
  113. DebugBreak();
  114. }
  115. #endif
  116. return ret;
  117. }
  118. LPSTR Convert(LPCWSTR pwsz)
  119. {
  120. LONG len;
  121. LPSTR sz = NULL;
  122. if (pwsz == NULL)
  123. goto Exit;
  124. #if DBG==1
  125. // some Win32 API accept atoms in their string parameters
  126. #endif
  127. len = (wcslen(pwsz) + 1) * 2;
  128. sz = new CHAR[len];
  129. if (sz==NULL)
  130. {
  131. sz = ERR;
  132. goto Exit;
  133. }
  134. __try
  135. {
  136. UnicodeToAnsi(sz, pwsz, len);
  137. }
  138. __except(EXCEPTION_EXECUTE_HANDLER)
  139. {
  140. #if DBG==1
  141. MessageBoxA(NULL, "GP fault in unicode conversion -- caught",
  142. NULL, MB_OK);
  143. #endif
  144. if (sz)
  145. delete sz;
  146. sz = ERR;
  147. }
  148. Exit:
  149. return sz;
  150. }
  151. LPSTR ConvertOem(LPCWSTR pwsz)
  152. {
  153. LONG len;
  154. LPSTR sz = NULL;
  155. if (pwsz == NULL)
  156. goto Exit;
  157. #if DBG==1
  158. // some Win32 API accept atoms in their string parameters
  159. #endif
  160. len = (wcslen(pwsz) + 1) * 2;
  161. sz = new CHAR[len];
  162. if (sz==NULL)
  163. {
  164. sz = ERR;
  165. goto Exit;
  166. }
  167. __try
  168. {
  169. UnicodeToAnsiOem(sz, pwsz, len);
  170. }
  171. __except(EXCEPTION_EXECUTE_HANDLER)
  172. {
  173. #if DBG==1
  174. MessageBoxA(NULL, "GP fault in unicode conversion -- caught",
  175. NULL, MB_OK);
  176. #endif
  177. if (sz)
  178. delete sz;
  179. sz = ERR;
  180. }
  181. Exit:
  182. return sz;
  183. }
  184. HANDLE WINAPI CreateFileX(LPCWSTR pwsz, DWORD fdwAccess, DWORD fdwShareMask,
  185. LPSECURITY_ATTRIBUTES lpsa, DWORD fdwCreate, DWORD fdwAttrsAndFlags,
  186. HANDLE hTemplateFile)
  187. {
  188. #ifdef DEBUG_OUTPUT
  189. OutputDebugString("CreateFile\n");
  190. #endif
  191. CHAR sz[MAX_PATH * 2];
  192. UnicodeToAnsiOem(sz, pwsz, sizeof(sz));
  193. return CreateFileA(sz, fdwAccess, fdwShareMask, lpsa, fdwCreate,
  194. fdwAttrsAndFlags, hTemplateFile);
  195. }
  196. BOOL WINAPI DeleteFileX(LPCWSTR pwsz)
  197. {
  198. #ifdef DEBUG_OUTPUT
  199. OutputDebugString("DeleteFile\n");
  200. #endif
  201. CHAR sz[MAX_PATH * 2];
  202. UnicodeToAnsi(sz, pwsz, sizeof(sz));
  203. return DeleteFileA(sz);
  204. }
  205. LONG APIENTRY RegOpenKeyX(HKEY hKey, LPCWSTR pwszSubKey, PHKEY phkResult)
  206. {
  207. #ifdef DEBUG_OUTPUT
  208. OutputDebugString("RegOpenKey\n");
  209. #endif
  210. LONG ret;
  211. LPSTR sz;
  212. sz = Convert(pwszSubKey);
  213. if (sz == ERR)
  214. {
  215. return ERROR_OUTOFMEMORY;
  216. }
  217. ret = RegOpenKeyA(hKey, sz, phkResult);
  218. if (sz)
  219. delete sz;
  220. return ret;
  221. }
  222. LONG APIENTRY RegQueryValueX(HKEY hKey, LPCWSTR pwszSubKey, LPWSTR pwszValue,
  223. PLONG lpcbValue)
  224. {
  225. #ifdef DEBUG_OUTPUT
  226. OutputDebugString("RegQueryValue\n");
  227. #endif
  228. LONG cb, ret;
  229. LPSTR szValue = NULL;
  230. LPSTR sz;
  231. sz = Convert(pwszSubKey);
  232. if (sz == ERR)
  233. {
  234. return ERROR_OUTOFMEMORY;
  235. }
  236. ret = RegQueryValueA(hKey, sz, NULL, &cb);
  237. // If the caller was just asking for the size of the value, jump out
  238. // now, without actually retrieving and converting the value.
  239. if (pwszValue == NULL)
  240. {
  241. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  242. *lpcbValue = cb * sizeof(WCHAR);
  243. goto Exit;
  244. }
  245. if (ret == ERROR_SUCCESS)
  246. {
  247. // If the caller was asking for the value, but allocated too small
  248. // of a buffer, set the buffer size and jump out.
  249. if (*lpcbValue < (LONG) (cb * sizeof(WCHAR)))
  250. {
  251. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  252. *lpcbValue = cb * sizeof(WCHAR);
  253. ret = ERROR_MORE_DATA;
  254. goto Exit;
  255. }
  256. // Otherwise, retrieve and convert the value.
  257. szValue = new CHAR[cb];
  258. if (szValue == NULL)
  259. {
  260. ret = ERROR_OUTOFMEMORY;
  261. goto Exit;
  262. }
  263. ret = RegQueryValueA(hKey, sz, szValue, &cb);
  264. if (ret == ERROR_SUCCESS)
  265. {
  266. AnsiToUnicode(pwszValue, szValue, cb);
  267. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  268. *lpcbValue = cb * sizeof(WCHAR);
  269. }
  270. }
  271. Exit:
  272. if (szValue)
  273. delete szValue;
  274. if (sz)
  275. delete sz;
  276. return ret;
  277. }
  278. LONG APIENTRY RegSetValueX(HKEY hKey, LPCWSTR lpSubKey, DWORD dwType,
  279. LPCWSTR lpData, DWORD cbData)
  280. {
  281. #ifdef DEBUG_OUTPUT
  282. OutputDebugString("RegSetValue\n");
  283. #endif
  284. LPSTR szKey = NULL;
  285. LPSTR szValue = NULL;
  286. LONG ret = ERROR_OUTOFMEMORY;
  287. szKey = Convert(lpSubKey);
  288. if (szKey == ERR)
  289. {
  290. szKey = NULL;
  291. goto Exit;
  292. }
  293. szValue = Convert(lpData);
  294. if (szValue == ERR)
  295. {
  296. szValue = NULL;
  297. goto Exit;
  298. }
  299. ret = RegSetValueA(hKey, szKey, dwType, szValue, cbData);
  300. Exit:
  301. if (szKey)
  302. delete szKey;
  303. if (szValue)
  304. delete szValue;
  305. return ret;
  306. }
  307. LONG APIENTRY RegSetValueExX(HKEY hKey,
  308. LPCWSTR lpSubKey,
  309. DWORD dwReserved,
  310. DWORD dwType,
  311. LPBYTE lpData,
  312. DWORD cbData)
  313. {
  314. #ifdef DEBUG_OUTPUT
  315. OutputDebugString("RegSetValueEx\n");
  316. #endif
  317. LPSTR szKey = NULL;
  318. LPBYTE szValue = lpData;
  319. LONG ret = ERROR_OUTOFMEMORY;
  320. szKey = Convert(lpSubKey);
  321. if (szKey == ERR)
  322. {
  323. szKey = NULL;
  324. goto Exit;
  325. }
  326. if (dwType == REG_SZ)
  327. {
  328. szValue = (LPBYTE) Convert((LPWSTR)lpData);
  329. }
  330. if (szValue == (LPBYTE) ERR)
  331. {
  332. szValue = NULL;
  333. goto Exit;
  334. }
  335. ret = RegSetValueExA(hKey, szKey, dwReserved, dwType, szValue, cbData);
  336. Exit:
  337. if (szKey)
  338. delete szKey;
  339. if ((szValue != lpData) && (szValue != (LPBYTE)ERR))
  340. delete szValue;
  341. return ret;
  342. }
  343. UINT WINAPI RegisterWindowMessageX(LPCWSTR lpString)
  344. {
  345. #ifdef DEBUG_OUTPUT
  346. OutputDebugString("RegisterWindowMessage\n");
  347. #endif
  348. UINT ret;
  349. #if 0
  350. LPSTR sz;
  351. sz = Convert(lpString);
  352. if (sz == ERR)
  353. {
  354. return 0;
  355. }
  356. #else
  357. // BUGBUG: CairOLE calls this from libmain -- have to use static buffer
  358. CHAR sz[200];
  359. UnicodeToAnsi(sz, lpString, sizeof(sz));
  360. #endif
  361. ret = RegisterWindowMessageA(sz);
  362. #if 0
  363. delete sz;
  364. #endif
  365. return ret;
  366. }
  367. LONG
  368. APIENTRY
  369. RegOpenKeyExX (
  370. HKEY hKey,
  371. LPCWSTR lpSubKey,
  372. DWORD ulOptions,
  373. REGSAM samDesired,
  374. PHKEY phkResult
  375. )
  376. {
  377. #ifdef DEBUG_OUTPUT
  378. OutputDebugString("RegOpenKeyEx\n");
  379. #endif
  380. LONG ret;
  381. LPSTR sz;
  382. sz = Convert(lpSubKey);
  383. if (sz == ERR)
  384. {
  385. return ERROR_OUTOFMEMORY;
  386. }
  387. ret = RegOpenKeyExA(hKey, sz, ulOptions, samDesired, phkResult);
  388. if (sz)
  389. delete sz;
  390. return ret;
  391. }
  392. LONG
  393. APIENTRY
  394. RegQueryValueExX(
  395. HKEY hKey,
  396. LPWSTR lpValueName,
  397. LPDWORD lpReserved,
  398. LPDWORD lpType,
  399. LPBYTE lpData,
  400. LPDWORD lpcbData
  401. )
  402. {
  403. #ifdef DEBUG_OUTPUT
  404. OutputDebugString("RegQueryValueEx\n");
  405. #endif
  406. LPBYTE lpTempBuffer;
  407. DWORD dwTempType;
  408. DWORD cb, cbRequired;
  409. LONG ret;
  410. LPSTR sz;
  411. LPWSTR pwszTempWide;
  412. LPSTR pszTempNarrow;
  413. ULONG ulStringLength;
  414. sz = Convert(lpValueName);
  415. if (sz == ERR)
  416. {
  417. return ERROR_OUTOFMEMORY;
  418. }
  419. ret = RegQueryValueExA(hKey, sz, lpReserved, &dwTempType, NULL, &cb);
  420. // If the caller was just asking for the size of the value, jump out
  421. // now, without actually retrieving and converting the value.
  422. if (lpData == NULL)
  423. {
  424. switch (dwTempType)
  425. {
  426. case REG_EXPAND_SZ:
  427. case REG_MULTI_SZ:
  428. case REG_SZ:
  429. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  430. if (lpcbData != NULL)
  431. *lpcbData = cb * sizeof(WCHAR);
  432. break;
  433. default:
  434. if (lpcbData != NULL)
  435. *lpcbData = cb;
  436. break;
  437. }
  438. // Set the type, if required.
  439. if (lpType != NULL)
  440. {
  441. *lpType = dwTempType;
  442. }
  443. goto Exit;
  444. }
  445. if (ret == ERROR_SUCCESS)
  446. {
  447. //
  448. // Determine the size of buffer needed
  449. //
  450. switch (dwTempType)
  451. {
  452. case REG_EXPAND_SZ:
  453. case REG_MULTI_SZ:
  454. case REG_SZ:
  455. cbRequired = cb * sizeof(WCHAR);
  456. break;
  457. default:
  458. cbRequired = cb;
  459. break;
  460. }
  461. // If the caller was asking for the value, but allocated too small
  462. // of a buffer, set the buffer size and jump out.
  463. if (lpcbData != NULL && *lpcbData < cbRequired)
  464. {
  465. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  466. *lpcbData = cbRequired;
  467. // Set the type, if required.
  468. if (lpType != NULL)
  469. {
  470. *lpType = dwTempType;
  471. }
  472. ret = ERROR_MORE_DATA;
  473. goto Exit;
  474. }
  475. // Otherwise, retrieve and convert the value.
  476. switch (dwTempType)
  477. {
  478. case REG_EXPAND_SZ:
  479. case REG_MULTI_SZ:
  480. case REG_SZ:
  481. lpTempBuffer = new BYTE[cbRequired];
  482. if (lpTempBuffer == NULL)
  483. {
  484. return ERROR_OUTOFMEMORY;
  485. }
  486. ret = RegQueryValueExA(hKey,
  487. sz,
  488. lpReserved,
  489. &dwTempType,
  490. lpTempBuffer,
  491. &cb);
  492. if (ret == ERROR_SUCCESS)
  493. {
  494. switch (dwTempType)
  495. {
  496. case REG_EXPAND_SZ:
  497. case REG_SZ:
  498. AnsiToUnicode((LPWSTR) lpData, (LPSTR) lpTempBuffer, cb);
  499. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  500. *lpcbData = cbRequired;
  501. // Set the type, if required.
  502. if (lpType != NULL)
  503. {
  504. *lpType = dwTempType;
  505. }
  506. break;
  507. case REG_MULTI_SZ:
  508. pszTempNarrow = (LPSTR) lpTempBuffer;
  509. pwszTempWide = (LPWSTR) lpData;
  510. while (pszTempNarrow != NULL)
  511. {
  512. ulStringLength = strlen(pszTempNarrow) + 1;
  513. AnsiToUnicode(pwszTempWide,
  514. pszTempNarrow,
  515. ulStringLength);
  516. // Compiler will scale appropriately here
  517. pszTempNarrow += ulStringLength;
  518. pwszTempWide += ulStringLength;
  519. }
  520. break;
  521. }
  522. }
  523. if (lpTempBuffer)
  524. delete lpTempBuffer;
  525. break;
  526. default:
  527. //
  528. // No conversion of out parameters needed. Just call narrow
  529. // version with args passed in, and return directly.
  530. //
  531. ret = RegQueryValueExA(hKey,
  532. sz,
  533. lpReserved,
  534. lpType,
  535. lpData,
  536. lpcbData);
  537. }
  538. }
  539. Exit:
  540. if (sz)
  541. delete sz;
  542. return ret;
  543. }
  544. ATOM
  545. WINAPI
  546. RegisterClassX(
  547. CONST WNDCLASSW *lpWndClass)
  548. {
  549. #ifdef DEBUG_OUTPUT
  550. OutputDebugString("RegisterClass\n");
  551. #endif
  552. WNDCLASSA wc;
  553. ATOM ret;
  554. BOOL fAtom = FALSE;
  555. memcpy(&wc, lpWndClass, sizeof(WNDCLASS));
  556. wc.lpszMenuName = Convert(lpWndClass->lpszMenuName);
  557. if (wc.lpszMenuName==ERR)
  558. {
  559. return NULL;
  560. }
  561. if (HIWORD(lpWndClass->lpszClassName) == 0)
  562. {
  563. wc.lpszClassName = (LPSTR) lpWndClass->lpszClassName;
  564. fAtom = TRUE;
  565. }
  566. else
  567. {
  568. wc.lpszClassName = Convert(lpWndClass->lpszClassName);
  569. if (wc.lpszClassName==ERR)
  570. {
  571. if ((LPSTR) wc.lpszMenuName)
  572. delete (LPSTR) wc.lpszMenuName;
  573. return NULL;
  574. }
  575. }
  576. ret = RegisterClassA(&wc);
  577. if ((LPSTR) wc.lpszMenuName)
  578. delete (LPSTR) wc.lpszMenuName;
  579. if (!fAtom) delete (LPSTR) wc.lpszClassName;
  580. return ret;
  581. }
  582. BOOL
  583. WINAPI
  584. UnregisterClassX(
  585. LPCWSTR lpClassName,
  586. HINSTANCE hInstance)
  587. {
  588. #ifdef DEBUG_OUTPUT
  589. OutputDebugString("UnregisterClass\n");
  590. #endif
  591. LPSTR sz;
  592. BOOL ret;
  593. BOOL fAtom = FALSE;
  594. if (HIWORD(lpClassName) == 0)
  595. {
  596. sz = (LPSTR) lpClassName;
  597. fAtom = TRUE;
  598. }
  599. else
  600. {
  601. sz = Convert(lpClassName);
  602. if (sz == ERR)
  603. return FALSE;
  604. }
  605. ret = UnregisterClassA(sz, hInstance);
  606. if (!fAtom) delete sz;
  607. return ret;
  608. }
  609. HANDLE
  610. WINAPI
  611. GetPropX(
  612. HWND hWnd,
  613. LPCWSTR lpString)
  614. {
  615. #ifdef DEBUG_OUTPUT
  616. OutputDebugString("GetProp\n");
  617. #endif
  618. HANDLE ret;
  619. LPSTR sz;
  620. BOOL fAtom = FALSE;
  621. if (HIWORD(lpString)==0)
  622. {
  623. fAtom = TRUE;
  624. sz = (LPSTR) lpString;
  625. }
  626. else
  627. {
  628. sz = Convert(lpString);
  629. if (sz == ERR)
  630. return NULL;
  631. }
  632. ret = GetPropA(hWnd, sz);
  633. if (!fAtom) delete sz;
  634. return ret;
  635. }
  636. BOOL
  637. WINAPI
  638. SetPropX(
  639. HWND hWnd,
  640. LPCWSTR lpString,
  641. HANDLE hData)
  642. {
  643. #ifdef DEBUG_OUTPUT
  644. OutputDebugString("SetProp\n");
  645. #endif
  646. BOOL ret;
  647. LPSTR sz;
  648. BOOL fAtom = FALSE;
  649. if (HIWORD(lpString)==0)
  650. {
  651. sz = (LPSTR) lpString;
  652. fAtom = TRUE;
  653. }
  654. else
  655. {
  656. sz = Convert(lpString);
  657. if (sz == ERR)
  658. return NULL;
  659. }
  660. ret = SetPropA(hWnd, sz, hData);
  661. if (!fAtom) delete sz;
  662. return ret;
  663. }
  664. HANDLE
  665. WINAPI
  666. RemovePropX(
  667. HWND hWnd,
  668. LPCWSTR lpString)
  669. {
  670. #ifdef DEBUG_OUTPUT
  671. OutputDebugString("RemoveProp\n");
  672. #endif
  673. HANDLE ret;
  674. LPSTR sz;
  675. BOOL fAtom = FALSE;
  676. if (HIWORD(lpString)==0)
  677. {
  678. sz = (LPSTR) lpString;
  679. fAtom = TRUE;
  680. }
  681. else
  682. {
  683. sz = Convert(lpString);
  684. if (sz == ERR)
  685. return NULL;
  686. }
  687. ret = RemovePropA(hWnd, sz);
  688. if (!fAtom) delete sz;
  689. return ret;
  690. }
  691. UINT
  692. WINAPI
  693. GetProfileIntX(
  694. LPCWSTR lpAppName,
  695. LPCWSTR lpKeyName,
  696. INT nDefault
  697. )
  698. {
  699. #ifdef DEBUG_OUTPUT
  700. OutputDebugString("GetProfileInt\n");
  701. #endif
  702. LPSTR szApp;
  703. LPSTR szKey;
  704. UINT ret;
  705. szApp = Convert(lpAppName);
  706. if (szApp==ERR)
  707. {
  708. return nDefault;
  709. }
  710. szKey = Convert(lpKeyName);
  711. if (szApp==ERR)
  712. {
  713. if (szApp)
  714. delete szApp;
  715. return nDefault;
  716. }
  717. ret = GetProfileIntA(szApp, szKey, nDefault);
  718. if (szApp)
  719. delete szApp;
  720. if (szKey)
  721. delete szKey;
  722. return ret;
  723. }
  724. ATOM
  725. WINAPI
  726. GlobalAddAtomX(
  727. LPCWSTR lpString
  728. )
  729. {
  730. #ifdef DEBUG_OUTPUT
  731. OutputDebugString("GlobalAddAtom\n");
  732. #endif
  733. ATOM ret;
  734. LPSTR sz;
  735. sz = Convert(lpString);
  736. if (sz==ERR)
  737. {
  738. return NULL;
  739. }
  740. ret = GlobalAddAtomA(sz);
  741. if (sz)
  742. delete sz;
  743. return ret;
  744. }
  745. UINT
  746. WINAPI
  747. GlobalGetAtomNameX(
  748. ATOM nAtom,
  749. LPWSTR pwszBuffer,
  750. int nSize
  751. )
  752. {
  753. #ifdef DEBUG_OUTPUT
  754. OutputDebugString("GlobalGetAtomName\n");
  755. #endif
  756. LPSTR sz;
  757. UINT ret;
  758. sz = new CHAR[nSize];
  759. if (sz == NULL)
  760. {
  761. return 0;
  762. }
  763. ret = GlobalGetAtomNameA(nAtom, sz, nSize);
  764. if (ret)
  765. {
  766. AnsiToUnicode(pwszBuffer, sz, lstrlenA(sz) + 1);
  767. }
  768. if (sz)
  769. delete sz;
  770. return ret;
  771. }
  772. DWORD
  773. WINAPI
  774. GetModuleFileNameX(
  775. HINSTANCE hModule,
  776. LPWSTR pwszFilename,
  777. DWORD nSize
  778. )
  779. {
  780. #ifdef DEBUG_OUTPUT
  781. OutputDebugString("GetModuleFileName\n");
  782. #endif
  783. LPSTR sz;
  784. DWORD ret;
  785. sz = new CHAR[nSize];
  786. if (sz == NULL)
  787. {
  788. return 0;
  789. }
  790. ret = GetModuleFileNameA(hModule, sz, nSize);
  791. if (ret)
  792. {
  793. AnsiToUnicode(pwszFilename, sz, lstrlenA(sz) + 1);
  794. }
  795. if (sz)
  796. delete sz;
  797. return ret;
  798. }
  799. LPWSTR
  800. WINAPI
  801. CharPrevX(
  802. LPCWSTR lpszStart,
  803. LPCWSTR lpszCurrent)
  804. {
  805. #ifdef DEBUG_OUTPUT
  806. OutputDebugString("CharPrev\n");
  807. #endif
  808. if (lpszCurrent == lpszStart)
  809. {
  810. return (LPWSTR) lpszStart;
  811. }
  812. else
  813. {
  814. return (LPWSTR) lpszCurrent - 1;
  815. }
  816. }
  817. HFONT WINAPI CreateFontX(int a, int b, int c, int d, int e, DWORD f,
  818. DWORD g, DWORD h, DWORD i, DWORD j, DWORD k,
  819. DWORD l, DWORD m, LPCWSTR pwsz)
  820. {
  821. #ifdef DEBUG_OUTPUT
  822. OutputDebugString("CreateFont\n");
  823. #endif
  824. LPSTR sz;
  825. HFONT ret;
  826. sz = Convert(pwsz);
  827. if (sz == ERR)
  828. {
  829. return NULL;
  830. }
  831. ret = CreateFontA(a,b,c,d,e,f,g,h,i,j,k,l,m,sz);
  832. if (sz)
  833. delete sz;
  834. return ret;
  835. }
  836. HINSTANCE
  837. WINAPI
  838. LoadLibraryX(
  839. LPCWSTR pwszFileName
  840. )
  841. {
  842. #ifdef DEBUG_OUTPUT
  843. OutputDebugString("LoadLibrary\n");
  844. #endif
  845. HINSTANCE ret;
  846. LPSTR sz;
  847. sz = Convert(pwszFileName);
  848. if (sz == ERR)
  849. {
  850. return NULL;
  851. }
  852. ret = LoadLibraryA(sz);
  853. if (sz)
  854. delete sz;
  855. return ret;
  856. }
  857. HMODULE
  858. WINAPI
  859. LoadLibraryExX(
  860. LPCWSTR lpLibFileName,
  861. HANDLE hFile,
  862. DWORD dwFlags
  863. )
  864. {
  865. #ifdef DEBUG_OUTPUT
  866. OutputDebugString("LoadLibrary\n");
  867. #endif
  868. HINSTANCE ret;
  869. LPSTR sz;
  870. sz = ConvertOem(lpLibFileName);
  871. if (sz == ERR)
  872. {
  873. return NULL;
  874. }
  875. ret = LoadLibraryExA(sz, hFile, dwFlags);
  876. if (sz)
  877. delete sz;
  878. return ret;
  879. }
  880. LONG
  881. APIENTRY
  882. RegDeleteKeyX(
  883. HKEY hKey,
  884. LPCWSTR pwszSubKey
  885. )
  886. {
  887. #ifdef DEBUG_OUTPUT
  888. OutputDebugString("RegDeleteKey\n");
  889. #endif
  890. LONG ret;
  891. LPSTR sz;
  892. sz = Convert(pwszSubKey);
  893. if (sz == ERR)
  894. {
  895. return ERROR_OUTOFMEMORY;
  896. }
  897. ret = RegDeleteKeyA(hKey, sz);
  898. if (sz)
  899. delete sz;
  900. return ret;
  901. }
  902. BOOL
  903. APIENTRY
  904. CreateProcessX(
  905. LPCWSTR lpApplicationName,
  906. LPWSTR lpCommandLine,
  907. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  908. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  909. BOOL bInheritHandles,
  910. DWORD dwCreationFlags,
  911. LPVOID lpEnvironment,
  912. LPCWSTR lpCurrentDirectory,
  913. LPSTARTUPINFOW lpStartupInfo,
  914. LPPROCESS_INFORMATION lpProcessInformation
  915. )
  916. {
  917. #ifdef DEBUG_OUTPUT
  918. OutputDebugString("CreateProcess\n");
  919. #endif
  920. STARTUPINFOA si;
  921. BOOL ret = FALSE;
  922. LPSTR szApp = NULL;
  923. LPSTR szCommand = NULL;
  924. LPSTR szDir = NULL;
  925. memcpy(&si, lpStartupInfo, sizeof(STARTUPINFO));
  926. si.lpTitle = NULL;
  927. si.lpDesktop = Convert(lpStartupInfo->lpDesktop);
  928. if (si.lpDesktop == ERR)
  929. {
  930. si.lpDesktop = NULL;
  931. goto Error;
  932. }
  933. si.lpTitle = Convert(lpStartupInfo->lpTitle);
  934. if (si.lpTitle == ERR)
  935. {
  936. si.lpTitle = NULL;
  937. goto Error;
  938. }
  939. szApp = Convert(lpApplicationName);
  940. if (szApp == ERR)
  941. {
  942. szApp = NULL;
  943. goto Error;
  944. }
  945. szCommand = ConvertOem(lpCommandLine);
  946. if (szCommand == ERR)
  947. {
  948. szCommand = NULL;
  949. goto Error;
  950. }
  951. szDir = Convert(lpCurrentDirectory);
  952. if (szDir == ERR)
  953. {
  954. szDir = NULL;
  955. goto Error;
  956. }
  957. ret = CreateProcessA(szApp, szCommand, lpProcessAttributes,
  958. lpThreadAttributes, bInheritHandles, dwCreationFlags,
  959. lpEnvironment, szDir, &si, lpProcessInformation);
  960. Error:
  961. if (si.lpDesktop)
  962. delete si.lpDesktop;
  963. if (si.lpTitle)
  964. delete si.lpTitle;
  965. if (szApp)
  966. delete szApp;
  967. if (szCommand)
  968. delete szCommand;
  969. if (szDir)
  970. delete szDir;
  971. return ret;
  972. }
  973. LONG
  974. APIENTRY
  975. RegEnumKeyExX(
  976. HKEY hKey,
  977. DWORD dwIndex,
  978. LPWSTR lpName,
  979. LPDWORD lpcbName,
  980. LPDWORD lpReserved,
  981. LPWSTR lpClass,
  982. LPDWORD lpcbClass,
  983. PFILETIME lpftLastWriteTime
  984. )
  985. {
  986. #ifdef DEBUG_OUTPUT
  987. OutputDebugString("RegEnumKeyEx\n");
  988. #endif
  989. LPSTR szName;
  990. LPSTR szClass = NULL;
  991. LONG ret = ERROR_OUTOFMEMORY;
  992. szName = new CHAR[*lpcbName];
  993. if (szName == NULL)
  994. goto Exit;
  995. if (lpClass != NULL)
  996. {
  997. szClass = new CHAR[*lpcbClass + 1];
  998. if (szName == NULL)
  999. goto Exit;
  1000. }
  1001. //
  1002. // Return lengths do not include zero char.
  1003. //
  1004. ret = RegEnumKeyExA(hKey, dwIndex, szName, lpcbName, lpReserved,
  1005. szClass, lpcbClass, lpftLastWriteTime);
  1006. if (ret == ERROR_SUCCESS)
  1007. {
  1008. AnsiToUnicode(lpName, szName, *lpcbName + 1);
  1009. if (szClass)
  1010. {
  1011. AnsiToUnicode(lpClass, szClass, *lpcbClass + 1);
  1012. }
  1013. }
  1014. Exit:
  1015. return ret;
  1016. }
  1017. BOOL
  1018. WINAPI
  1019. AppendMenuX(
  1020. HMENU hMenu,
  1021. UINT uFlags,
  1022. UINT uIDnewItem,
  1023. LPCWSTR lpnewItem
  1024. )
  1025. {
  1026. #ifdef DEBUG_OUTPUT
  1027. OutputDebugString("AppendMenu\n");
  1028. #endif
  1029. BOOL ret;
  1030. LPSTR sz;
  1031. if (uFlags == MF_STRING)
  1032. {
  1033. sz = Convert(lpnewItem);
  1034. if (sz==ERR)
  1035. {
  1036. return FALSE;
  1037. }
  1038. }
  1039. else
  1040. {
  1041. sz = (LPSTR) lpnewItem;
  1042. }
  1043. ret = AppendMenuA(hMenu, uFlags, uIDnewItem, sz);
  1044. if (uFlags == MF_STRING)
  1045. {
  1046. if (sz)
  1047. delete sz;
  1048. }
  1049. return ret;
  1050. }
  1051. HANDLE
  1052. WINAPI
  1053. OpenEventX(
  1054. DWORD dwDesiredAccess,
  1055. BOOL bInheritHandle,
  1056. LPCWSTR lpName
  1057. )
  1058. {
  1059. #ifdef DEBUG_OUTPUT
  1060. OutputDebugString("OpenEvent\n");
  1061. #endif
  1062. LPSTR sz;
  1063. HANDLE ret;
  1064. sz = Convert(lpName);
  1065. if (sz == ERR)
  1066. {
  1067. return NULL;
  1068. }
  1069. ret = OpenEventA(dwDesiredAccess, bInheritHandle, sz);
  1070. if (sz)
  1071. delete sz;
  1072. return ret;
  1073. }
  1074. HANDLE
  1075. WINAPI
  1076. CreateEventX(
  1077. LPSECURITY_ATTRIBUTES lpEventAttributes,
  1078. BOOL bManualReset,
  1079. BOOL bInitialState,
  1080. LPCWSTR lpName
  1081. )
  1082. {
  1083. #ifdef DEBUG_OUTPUT
  1084. OutputDebugString("CreateEvent\n");
  1085. #endif
  1086. LPSTR sz;
  1087. HANDLE ret;
  1088. sz = Convert(lpName);
  1089. if (sz == ERR)
  1090. {
  1091. return NULL;
  1092. }
  1093. ret = CreateEventA(lpEventAttributes, bManualReset, bInitialState, sz);
  1094. if (sz)
  1095. delete sz;
  1096. return ret;
  1097. }
  1098. UINT
  1099. WINAPI
  1100. GetDriveTypeX(
  1101. LPCWSTR lpRootPathName
  1102. )
  1103. {
  1104. #ifdef DEBUG_OUTPUT
  1105. OutputDebugString("GetDriveType\n");
  1106. #endif
  1107. LPSTR sz;
  1108. UINT ret;
  1109. sz = Convert(lpRootPathName);
  1110. if (sz == ERR)
  1111. {
  1112. return 0;
  1113. }
  1114. ret = GetDriveTypeA(sz);
  1115. if (sz)
  1116. delete sz;
  1117. return ret;
  1118. }
  1119. DWORD
  1120. WINAPI
  1121. GetFileAttributesX(
  1122. LPCWSTR lpFileName
  1123. )
  1124. {
  1125. #ifdef DEBUG_OUTPUT
  1126. OutputDebugString("GetFileAttributes\n");
  1127. #endif
  1128. LPSTR sz;
  1129. DWORD ret;
  1130. sz = ConvertOem(lpFileName);
  1131. if (sz == ERR)
  1132. return 0xFFFFFFFF;
  1133. ret = GetFileAttributesA(sz);
  1134. if (sz)
  1135. delete sz;
  1136. return ret;
  1137. }
  1138. LONG
  1139. APIENTRY
  1140. RegEnumKeyX(
  1141. HKEY hKey,
  1142. DWORD dwIndex,
  1143. LPWSTR lpName,
  1144. DWORD cbName
  1145. )
  1146. {
  1147. #ifdef DEBUG_OUTPUT
  1148. OutputDebugString("RegEnumKey\n");
  1149. #endif
  1150. CHAR sz[MAX_PATH+1];
  1151. LONG ret;
  1152. //
  1153. // Return lengths do not include zero char.
  1154. //
  1155. ret = RegEnumKeyA(hKey, dwIndex, sz, cbName);
  1156. if (ret == ERROR_SUCCESS)
  1157. {
  1158. AnsiToUnicode(lpName, sz, lstrlenA(sz) + 1);
  1159. }
  1160. return ret;
  1161. }
  1162. HFINDFILE
  1163. WINAPI
  1164. FindFirstFileX(
  1165. LPCWSTR lpFileName,
  1166. LPWIN32_FIND_DATAW pwszFd
  1167. )
  1168. {
  1169. #ifdef DEBUG_OUTPUT
  1170. OutputDebugString("FindFirstFile\n");
  1171. #endif
  1172. WIN32_FIND_DATAA fd;
  1173. CHAR sz[MAX_PATH * 2];
  1174. HFINDFILE ret;
  1175. int len = wcslen(lpFileName) + 1;
  1176. UnicodeToAnsiOem(sz, lpFileName, sizeof(sz));
  1177. ret = FindFirstFileA(sz, &fd);
  1178. if (ret != INVALID_HANDLE_VALUE)
  1179. {
  1180. memcpy(pwszFd, &fd, sizeof(FILETIME)*3 + sizeof(DWORD)*5);
  1181. AnsiToUnicodeOem(pwszFd->cFileName, fd.cFileName,
  1182. lstrlenA(fd.cFileName) + 1);
  1183. AnsiToUnicodeOem(pwszFd->cAlternateFileName, fd.cAlternateFileName,
  1184. 14);
  1185. }
  1186. return ret;
  1187. }
  1188. //+---------------------------------------------------------------------------
  1189. //
  1190. // Function: wsprintfX
  1191. //
  1192. // Synopsis: Nightmare string function
  1193. //
  1194. // Arguments: [pwszOut] --
  1195. // [pwszFormat] --
  1196. // [...] --
  1197. //
  1198. // Returns:
  1199. //
  1200. // History: 1-06-94 ErikGav Created
  1201. //
  1202. // Notes: If you're reading this, you're probably having a problem with
  1203. // this function. Make sure that your "%s" in the format string
  1204. // says "%ws" if you are passing wide strings.
  1205. //
  1206. // %s on NT means "wide string"
  1207. // %s on Chicago means "ANSI string"
  1208. //
  1209. //----------------------------------------------------------------------------
  1210. int WINAPIV wsprintfX(LPWSTR pwszOut, LPCWSTR pwszFormat, ...)
  1211. {
  1212. #ifdef DEBUG_OUTPUT
  1213. OutputDebugString("wsprintf\n");
  1214. #endif
  1215. LPSTR szFormat;
  1216. LPWSTR pwszTemp = NULL;
  1217. int i = 0;
  1218. // Convert the format string over
  1219. szFormat = Convert(pwszFormat);
  1220. if (szFormat == ERR)
  1221. {
  1222. szFormat = NULL;
  1223. goto Exit;
  1224. }
  1225. // magic voodoo follows:
  1226. //
  1227. // 1. Call wvsprintf passing the varargs
  1228. // 2. Use the pwszOut as a temp buffer to hold the ANSI output
  1229. // 3. Save the returned characters
  1230. i = wvsprintfA((LPSTR) pwszOut, szFormat,
  1231. (LPSTR) ((BYTE*)&pwszFormat) + sizeof(pwszFormat));
  1232. // allocate a buffer for the Ansi to Unicode conversion
  1233. pwszTemp = new WCHAR[i+1];
  1234. // convert the string
  1235. AnsiToUnicode(pwszTemp, (LPSTR) pwszOut, i+1);
  1236. // copy it to the out buffer
  1237. wcsncpy(pwszOut, pwszTemp, i+1);
  1238. Exit:
  1239. if (pwszTemp)
  1240. delete pwszTemp;
  1241. if (szFormat)
  1242. delete szFormat;
  1243. return i;
  1244. }
  1245. BOOL
  1246. WINAPI
  1247. GetComputerNameX(
  1248. LPWSTR pwszName,
  1249. LPDWORD lpcchBuffer
  1250. )
  1251. {
  1252. #ifdef DEBUG_OUTPUT
  1253. OutputDebugString("GetComputerName\n");
  1254. #endif
  1255. BOOL ret;
  1256. LPSTR sz;
  1257. sz = new CHAR[*lpcchBuffer];
  1258. ret = GetComputerNameA(sz, lpcchBuffer);
  1259. if (ret)
  1260. {
  1261. AnsiToUnicode(pwszName, sz, *lpcchBuffer);
  1262. }
  1263. if (sz)
  1264. delete sz;
  1265. return ret;
  1266. }
  1267. DWORD
  1268. WINAPI
  1269. GetFullPathNameX(
  1270. LPCWSTR lpFileName,
  1271. DWORD cchBuffer,
  1272. LPWSTR lpPathBuffer,
  1273. LPWSTR *lppFilePart
  1274. )
  1275. {
  1276. #ifdef DEBUG_OUTPUT
  1277. OutputDebugString("GetFullPathName\n");
  1278. #endif
  1279. LPSTR szFileName;
  1280. CHAR szPathBuffer[MAX_PATH];
  1281. LPSTR szFilePart;
  1282. DWORD ret;
  1283. szFileName = ConvertOem(lpFileName);
  1284. if (szFileName == ERR)
  1285. return 0;
  1286. ret = GetFullPathNameA(szFileName, cchBuffer, szPathBuffer, &szFilePart);
  1287. AnsiToUnicode(lpPathBuffer, szPathBuffer, cchBuffer);
  1288. *lppFilePart = lpPathBuffer + (szFilePart - szPathBuffer);
  1289. if (szFileName)
  1290. delete szFileName;
  1291. return ret;
  1292. }
  1293. DWORD
  1294. WINAPI
  1295. GetShortPathNameX(
  1296. LPCWSTR lpszFullPath,
  1297. LPWSTR lpszShortPath,
  1298. DWORD cchBuffer
  1299. )
  1300. {
  1301. #ifdef DEBUG_OUTPUT
  1302. OutputDebugString("GetShortPathName\n");
  1303. #endif
  1304. LPSTR szFullPath;
  1305. CHAR szShortBuffer[MAX_PATH];
  1306. DWORD ret;
  1307. szFullPath = Convert(lpszFullPath);
  1308. if (szFullPath == ERR)
  1309. return 0;
  1310. if (lpszShortPath == NULL)
  1311. {
  1312. ret = GetShortPathNameA(szFullPath, NULL, cchBuffer);
  1313. }
  1314. else
  1315. {
  1316. ret = GetShortPathNameA(szFullPath, szShortBuffer, sizeof(szShortBuffer));
  1317. //
  1318. // Only convert the actual data, not the whole buffer.
  1319. //
  1320. if (cchBuffer > ret + 1)
  1321. cchBuffer = ret + 1;
  1322. AnsiToUnicode(lpszShortPath, szShortBuffer, cchBuffer);
  1323. }
  1324. delete szFullPath;
  1325. return ret;
  1326. }
  1327. DWORD
  1328. WINAPI
  1329. SearchPathX(
  1330. LPCWSTR lpPath,
  1331. LPCWSTR lpFileName,
  1332. LPCWSTR lpExtension,
  1333. DWORD nBufferLength,
  1334. LPWSTR lpBuffer,
  1335. LPWSTR *lpFilePart
  1336. )
  1337. {
  1338. LPSTR lpszFileName;
  1339. CHAR szBuffer[MAX_PATH];
  1340. DWORD ret;
  1341. #ifdef DEBUG_OUTPUT
  1342. OutputDebugString("SearchPath\n");
  1343. #endif
  1344. lpszFileName = Convert(lpFileName);
  1345. if (lpszFileName == ERR)
  1346. return 0;
  1347. ret = SearchPathA(NULL, lpszFileName, NULL, sizeof(szBuffer), szBuffer, NULL);
  1348. AnsiToUnicode(lpBuffer, szBuffer, lstrlenA(szBuffer) + 1);
  1349. delete lpszFileName;
  1350. return ret;
  1351. }
  1352. ATOM
  1353. WINAPI
  1354. GlobalFindAtomX(
  1355. LPCWSTR lpString
  1356. )
  1357. {
  1358. LPSTR lpszString;
  1359. ATOM retAtom;
  1360. #ifdef DEBUG_OUTPUT
  1361. OutputDebugString("GlobalFindAtom\n");
  1362. #endif
  1363. lpszString = Convert(lpString);
  1364. if (lpszString == ERR)
  1365. return 0;
  1366. retAtom = GlobalFindAtomA(lpszString);
  1367. delete lpszString;
  1368. return retAtom;
  1369. }
  1370. int
  1371. WINAPI
  1372. GetClassNameX(
  1373. HWND hWnd,
  1374. LPWSTR lpClassName,
  1375. int nMaxCount)
  1376. {
  1377. LPSTR lpszClassName;
  1378. int ret;
  1379. #ifdef DEBUG_OUTPUT
  1380. OutputDebugString("GetClassName\n");
  1381. #endif
  1382. lpszClassName = Convert(lpClassName);
  1383. if (lpszClassName == ERR)
  1384. return 0;
  1385. ret = GetClassNameA(hWnd, lpszClassName, nMaxCount);
  1386. delete lpszClassName;
  1387. return ret;
  1388. }
  1389. int
  1390. WINAPI
  1391. lstrlenX(LPCWSTR lpString)
  1392. {
  1393. return wcslen(lpString);
  1394. }
  1395. LPWSTR
  1396. WINAPI
  1397. lstrcatX(
  1398. LPWSTR lpString1,
  1399. LPCWSTR lpString2)
  1400. {
  1401. return wcscat(lpString1, lpString2);
  1402. }
  1403. int
  1404. WINAPI
  1405. lstrcmpX(
  1406. LPCWSTR lpString1,
  1407. LPCWSTR lpString2
  1408. )
  1409. {
  1410. return wcscmp(lpString1, lpString2);
  1411. }
  1412. int
  1413. WINAPI
  1414. lstrcmpiX(
  1415. LPCWSTR lpString1,
  1416. LPCWSTR lpString2
  1417. )
  1418. {
  1419. return _wcsicmp(lpString1, lpString2);
  1420. }
  1421. LPWSTR
  1422. WINAPI
  1423. lstrcpyX(
  1424. LPWSTR lpString1,
  1425. LPCWSTR lpString2
  1426. )
  1427. {
  1428. return wcscpy(lpString1, lpString2);
  1429. }
  1430. HANDLE
  1431. WINAPI
  1432. CreateFileMappingX(
  1433. HANDLE hFile,
  1434. LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  1435. DWORD flProtect,
  1436. DWORD dwMaximumSizeHigh,
  1437. DWORD dwMaximumSizeLow,
  1438. LPCWSTR lpName
  1439. )
  1440. {
  1441. LPSTR lpszAName;
  1442. HANDLE ret;
  1443. #ifdef DEBUG_OUTPUT
  1444. OutputDebugString("CreateFileMapping\n");
  1445. #endif
  1446. lpszAName = Convert(lpName);
  1447. if (lpszAName == ERR)
  1448. {
  1449. return 0;
  1450. }
  1451. ret = CreateFileMappingA(
  1452. hFile,
  1453. lpFileMappingAttributes,
  1454. flProtect,
  1455. dwMaximumSizeHigh,
  1456. dwMaximumSizeLow,
  1457. lpszAName);
  1458. delete lpszAName;
  1459. return ret;
  1460. }
  1461. HANDLE
  1462. WINAPI
  1463. OpenFileMappingX(
  1464. DWORD dwDesiredAccess,
  1465. BOOL bInheritHandle,
  1466. LPCWSTR lpName
  1467. )
  1468. {
  1469. LPSTR lpszAName;
  1470. HANDLE ret;
  1471. #ifdef DEBUG_OUTPUT
  1472. OutputDebugString("CreateFileMapping\n");
  1473. #endif
  1474. lpszAName = Convert(lpName);
  1475. if (lpszAName == ERR)
  1476. {
  1477. return 0;
  1478. }
  1479. ret = OpenFileMappingA(
  1480. dwDesiredAccess,
  1481. bInheritHandle,
  1482. lpszAName);
  1483. delete lpszAName;
  1484. return ret;
  1485. }
  1486. #endif // CHICAGO
  1487.