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.

4745 lines
102 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993 - 1998
  5. //
  6. // File: widewrap.cxx
  7. //
  8. // Contents: Unicode wrapper API
  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. // History: 28-Dec-93 ErikGav Created
  20. // 06-14-94 KentCe Various Chicago build fixes.
  21. // 21-Dec-94 BruceMa Use olewcstombs + other fixes
  22. // 21-Feb-95 BruceMa Add support for AreFileApisANSI
  23. // 29-Feb-96 JeffE Add lots of wide character rtns
  24. // 15-Jul-98 SitaramR Fixed MultiByte <-> Unicode conversions
  25. //
  26. //----------------------------------------------------------------------------
  27. //
  28. // Bugs noticed don't have time to fix.
  29. // Feb 4th 1997
  30. //
  31. // 1. delete(FileX (and many others) why is it sz[MAX_PATH*2]?
  32. // 2. Return from UnicodeToAnsi/UnicodeToAnsiOem is being ignored
  33. // 3. Convert/ConvertOem - since return from UnicodeToAnsi[Oem] is
  34. // being ignored, bogus ANSI/OEM string could come back causing
  35. // problems later. E.g, in LoadLibraryX we could end up passing
  36. // bogus stuff to LoadLibraryA
  37. // 4. GetDriveTypeX (and many other places) "return 0" is the wrong
  38. // thing change if (sz == ERR) to return DRIVE_UNKNOWN
  39. // 5. SearchPathX do lpPath and lpExtension need to be ConvertOem?
  40. // 6. Convert/ConvertOem are bad names. Use better names.
  41. //
  42. //----------------------------------------------------------------------------
  43. #include "lib.h"
  44. #define HFINDFILE HANDLE
  45. #define ERR ((char*) -1)
  46. #define CairoleAssert // Review - replace with our asserts
  47. #define Win4Assert
  48. #undef ALLOC
  49. #undef FREE
  50. #ifdef __cplusplus
  51. extern "C" {
  52. #endif
  53. // notes:
  54. // ConvertWideCharToMultiByte if pass in null doesn't change output
  55. // string, should it set it to NULL.
  56. CRITICAL_SECTION g_CritSectCommonLib;
  57. BOOL g_fWideWrap_Unicode = FALSE;
  58. // list of wide functions not available on Win9x + IE4
  59. // Shell32!SHGetFileInfoW
  60. // Shell32!Shell_NotifyIconW
  61. typedef BOOL (WINAPI *SHELL_NOTIFYICONW)(DWORD dwMessage, PNOTIFYICONDATAW lpData );
  62. typedef BOOL (WINAPI *SHELL_NOTIFYICONA)(DWORD dwMessage, PNOTIFYICONDATAA lpData );
  63. typedef DWORD_PTR (WINAPI *SHGETFILEINFOW)(LPCWSTR pszPath,
  64. DWORD dwFileAttributes, SHFILEINFOW FAR *psfi,
  65. UINT cbFileInfo,UINT uFlags);
  66. typedef DWORD_PTR (WINAPI *SHGETFILEINFOA)(LPCSTR pszPath,
  67. DWORD dwFileAttributes, SHFILEINFOA FAR *psfi,
  68. UINT cbFileInfo,UINT uFlags);
  69. STRING_FILENAME(szShell32, "SHELL32.DLL");
  70. STRING_INTERFACE(szShell_NotifyIconW,"Shell_NotifyIconW");
  71. STRING_INTERFACE(szShell_NotifyIconA,"Shell_NotifyIconA");
  72. STRING_INTERFACE(szShGetFileInfoA,"SHGetFileInfoA");
  73. STRING_INTERFACE(szShGetFileInfoW,"SHGetFileInfoW");
  74. BOOL g_fLoadedShell32 = FALSE;
  75. HINSTANCE g_hinstShell32 = NULL;
  76. SHELL_NOTIFYICONW g_pfShell_NotifyIconW = NULL;
  77. SHELL_NOTIFYICONA g_pfShell_NotifyIconA = NULL;
  78. SHGETFILEINFOW g_pfShGetFileInfoW = NULL;
  79. SHGETFILEINFOA g_pfShGetFileInfoA = NULL;
  80. // list of exports we use from OleAut32.
  81. typedef BSTR (APIENTRY *PFNSYSALLOCSTRING)(const OLECHAR *);
  82. typedef void (APIENTRY *PFNSYSFREESTRING)(BSTR);
  83. typedef HRESULT (APIENTRY *PFNLOADREGTYPELIB)(REFGUID rguid,
  84. WORD wVerMajor,WORD wVerMinor,LCID lcid,ITypeLib FAR* FAR* pptlib);
  85. STRING_FILENAME(szOleAut32Dll, "OLEAUT32.DLL");
  86. STRING_INTERFACE(szSysAllocString,"SysAllocString");
  87. STRING_INTERFACE(szSysFreeString,"SysFreeString");
  88. STRING_INTERFACE(szLoadRegTypeLib,"LoadRegTypeLib");
  89. BOOL g_fLoadedOleAut32 = FALSE;
  90. HINSTANCE g_hinstOleAut32 = NULL;
  91. PFNSYSALLOCSTRING g_pfSysAllocString = NULL;
  92. PFNSYSFREESTRING g_pfSysFreeString = NULL;
  93. PFNLOADREGTYPELIB g_pfLoadRegTypeLib = NULL;
  94. // list of exports we use from UserEnv.
  95. typedef BOOL (APIENTRY *PFNGETUSERPROFILEDIRECTORY)(HANDLE hToken,LPWSTR lpProfileDir,LPDWORD lpcchSize);
  96. STRING_FILENAME(szUserEnvDll, "USERENV.DLL");
  97. STRING_INTERFACE(szGetUserProfileDirectory,"GetUserProfileDirectoryW");
  98. BOOL g_fLoadedUserEnv = FALSE;
  99. HINSTANCE g_hinstUserEnv = NULL;
  100. PFNGETUSERPROFILEDIRECTORY g_pfGetUserProfileDirectory = NULL;
  101. // list of exports used from User32.dll
  102. typedef BOOL (WINAPI *PFNALLOWSETFOREGROUNDWINDOW)(DWORD dwProcessId);
  103. STRING_FILENAME(szUser32Dll, "USER32.DLL");
  104. STRING_INTERFACE(szAllowSetForegroundWindow,"AllowSetForegroundWindow");
  105. BOOL g_fLoadedUser32 = FALSE;
  106. HINSTANCE g_hinstUser32 = NULL;
  107. PFNALLOWSETFOREGROUNDWINDOW g_pfAllowSetForegroundWindow = NULL;
  108. // delcartions for imports from imm32.dll
  109. typedef HIMC (WINAPI *PFNIMMASSOCIATECONTEXT)(HWND hWnd,HIMC hIMC);
  110. STRING_FILENAME(szIMM32Dll, "IMM32.DLL");
  111. STRING_INTERFACE(szImmAssociateContext,"ImmAssociateContext");
  112. BOOL g_fLoadedIMM32 = FALSE;
  113. HINSTANCE g_hinstIMM32 = NULL;
  114. PFNIMMASSOCIATECONTEXT g_pfImmAssociateContext = NULL;
  115. // global vars
  116. OSVERSIONINFOA g_OSVersionInfo; // osVersionInfo.
  117. // Note: this should really be in its own file but due to closeness
  118. // of IE5 release leave here for now.
  119. // must be called before any other routine to setup variables and
  120. // try to dynamically load wide exports not available on Win9x
  121. // globals shared by Common.
  122. // !!! InitCommonLib function is not thread safe. must be called on main thread before
  123. // other threads are created
  124. void InitCommonLib(BOOL fUnicode)
  125. {
  126. InitializeCriticalSection(&g_CritSectCommonLib);
  127. g_fWideWrap_Unicode = fUnicode;
  128. g_OSVersionInfo.dwOSVersionInfoSize = sizeof(g_OSVersionInfo);
  129. if (!GetVersionExA(&g_OSVersionInfo))
  130. {
  131. AssertSz(0,"GetVersionEx Failed");
  132. // if Can't get Version information base it off of Unicode Flag
  133. g_OSVersionInfo.dwPlatformId = fUnicode ?
  134. (VER_PLATFORM_WIN32_NT) : (VER_PLATFORM_WIN32_WINDOWS);
  135. }
  136. // g_fWideWrap_Unicode = FALSE;
  137. }
  138. // must be called to Uninit CommonLib.
  139. // !!Warning COM has already been unitialized at this point.
  140. // !!Warning, not thread safe.
  141. void UnInitCommonLib(void)
  142. {
  143. DeleteCriticalSection(&g_CritSectCommonLib);
  144. }
  145. // returns TRUE if WideWrap is set to Unicode, False if ANSI
  146. BOOL WideWrapIsUnicode()
  147. {
  148. BOOL fIsUnicode;
  149. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  150. cCritSect.Enter();
  151. fIsUnicode = g_fWideWrap_Unicode;
  152. cCritSect.Leave();
  153. return fIsUnicode;
  154. }
  155. //+---------------------------------------------------------------------------
  156. //
  157. // Function: GetUserTextualSid
  158. //
  159. // Synopsis: Get a user SID and convert to its string representation
  160. //
  161. //----------------------------------------------------------------------------
  162. BOOL
  163. GetUserTextualSid(
  164. LPTSTR TextualSid, // buffer for Textual representaion of Sid
  165. LPDWORD cchSidSize // required/provided TextualSid buffersize
  166. )
  167. {
  168. if (!g_fWideWrap_Unicode)
  169. {
  170. TextualSid[0] = TEXT('\0');
  171. *cchSidSize = 0;
  172. return TRUE;
  173. }
  174. HANDLE hToken;
  175. BYTE buf[MAX_PATH];
  176. PTOKEN_USER ptgUser = (PTOKEN_USER)buf;
  177. DWORD cbBuffer=MAX_PATH;
  178. BOOL bSuccess;
  179. PSID pSid;
  180. PSID_IDENTIFIER_AUTHORITY psia;
  181. DWORD dwSubAuthorities;
  182. DWORD dwCounter;
  183. DWORD cchSidCopy;
  184. //
  185. // obtain current process token
  186. //
  187. if(!OpenProcessToken(
  188. GetCurrentProcess(), // target current process
  189. TOKEN_QUERY, // TOKEN_QUERY access
  190. &hToken // resultant hToken
  191. ))
  192. {
  193. return FALSE;
  194. }
  195. //
  196. // obtain user identified by current process' access token
  197. //
  198. bSuccess = GetTokenInformation(
  199. hToken, // identifies access token
  200. TokenUser, // TokenUser info type
  201. ptgUser, // retrieved info buffer
  202. cbBuffer, // size of buffer passed-in
  203. &cbBuffer // required buffer size
  204. );
  205. // close token handle. do this even if error above
  206. CloseHandle(hToken);
  207. if(!bSuccess)
  208. {
  209. return FALSE;
  210. }
  211. pSid = ptgUser->User.Sid;
  212. //
  213. // test if Sid passed in is valid
  214. //
  215. if(!IsValidSid(pSid)) return FALSE;
  216. // obtain SidIdentifierAuthority
  217. psia = GetSidIdentifierAuthority(pSid);
  218. // obtain sidsubauthority count
  219. dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
  220. //
  221. // compute approximate buffer length
  222. // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
  223. //
  224. cchSidCopy = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
  225. //
  226. // check provided buffer length.
  227. // If not large enough, indicate proper size and setlasterror
  228. //
  229. if(*cchSidSize < cchSidCopy) {
  230. *cchSidSize = cchSidCopy;
  231. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  232. return FALSE;
  233. }
  234. //
  235. // prepare S-SID_REVISION-
  236. //
  237. cchSidCopy = wsprintf(TextualSid, TEXT("S-%lu-"), SID_REVISION );
  238. //
  239. // prepare SidIdentifierAuthority
  240. //
  241. if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) {
  242. cchSidCopy += wsprintf(TextualSid + cchSidCopy,
  243. TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
  244. (USHORT)psia->Value[0],
  245. (USHORT)psia->Value[1],
  246. (USHORT)psia->Value[2],
  247. (USHORT)psia->Value[3],
  248. (USHORT)psia->Value[4],
  249. (USHORT)psia->Value[5]);
  250. } else {
  251. cchSidCopy += wsprintf(TextualSid + cchSidCopy,
  252. TEXT("%lu"),
  253. (ULONG)(psia->Value[5] ) +
  254. (ULONG)(psia->Value[4] << 8) +
  255. (ULONG)(psia->Value[3] << 16) +
  256. (ULONG)(psia->Value[2] << 24) );
  257. }
  258. //
  259. // loop through SidSubAuthorities
  260. //
  261. for(dwCounter = 0 ; dwCounter < dwSubAuthorities ; dwCounter++) {
  262. cchSidCopy += wsprintf(TextualSid + cchSidCopy, TEXT("-%lu"),
  263. *GetSidSubAuthority(pSid, dwCounter) );
  264. }
  265. //
  266. // tell the caller how many chars we provided, not including NULL
  267. //
  268. *cchSidSize = cchSidCopy;
  269. return TRUE;
  270. }
  271. // loads exports we need from the shell32dll
  272. void LoadShell32Dll()
  273. {
  274. if (g_fLoadedShell32)
  275. return;
  276. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  277. cCritSect.Enter();
  278. // make sure not loaded again in case someone took lock first
  279. if (!g_fLoadedShell32)
  280. {
  281. g_hinstShell32 = LoadLibrary(szShell32);
  282. if (g_hinstShell32)
  283. {
  284. g_pfShell_NotifyIconW = (SHELL_NOTIFYICONW) GetProcAddress(g_hinstShell32, szShell_NotifyIconW);
  285. g_pfShell_NotifyIconA = (SHELL_NOTIFYICONA) GetProcAddress(g_hinstShell32, szShell_NotifyIconA);
  286. g_pfShGetFileInfoW = (SHGETFILEINFOW) GetProcAddress(g_hinstShell32, szShGetFileInfoW);
  287. g_pfShGetFileInfoA = (SHGETFILEINFOA) GetProcAddress(g_hinstShell32, szShGetFileInfoA);
  288. }
  289. // should always get the Ansi exports
  290. Assert(g_pfShell_NotifyIconA);
  291. Assert(g_pfShGetFileInfoA);
  292. g_fLoadedShell32 = TRUE;
  293. }
  294. cCritSect.Leave();
  295. }
  296. // load exports from OleAutomation
  297. // up to caller to check exports they need are valid after making this call
  298. void LoadOleAut32Dll()
  299. {
  300. if (g_fLoadedOleAut32)
  301. return;
  302. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  303. cCritSect.Enter();
  304. // make sure not loaded again in case someone took lock first
  305. if (!g_fLoadedOleAut32)
  306. {
  307. g_hinstOleAut32 = LoadLibrary(szOleAut32Dll);
  308. if (g_hinstOleAut32)
  309. {
  310. g_pfSysAllocString = (PFNSYSALLOCSTRING) GetProcAddress(g_hinstOleAut32, szSysAllocString);
  311. g_pfSysFreeString = (PFNSYSFREESTRING) GetProcAddress(g_hinstOleAut32, szSysFreeString);
  312. g_pfLoadRegTypeLib = (PFNLOADREGTYPELIB) GetProcAddress(g_hinstOleAut32, szLoadRegTypeLib);
  313. }
  314. // should always get the exports.
  315. Assert(g_pfSysAllocString);
  316. Assert(g_pfSysFreeString);
  317. Assert(g_pfLoadRegTypeLib);
  318. g_fLoadedOleAut32 = TRUE;
  319. }
  320. cCritSect.Leave();
  321. }
  322. STDAPI_(BSTR) SysAllocStringX(const OLECHAR *sz)
  323. {
  324. LoadOleAut32Dll();
  325. Assert(g_pfSysAllocString);
  326. if (g_pfSysAllocString)
  327. {
  328. return (*g_pfSysAllocString)(sz);
  329. }
  330. return NULL;
  331. }
  332. STDAPI_(void) SysFreeStringX(BSTR bsz)
  333. {
  334. LoadOleAut32Dll();
  335. Assert(g_pfSysFreeString);
  336. if (g_pfSysFreeString)
  337. {
  338. (*g_pfSysFreeString)(bsz);
  339. }
  340. }
  341. STDAPI LoadRegTypeLibX(REFGUID rguid, WORD wVerMajor, WORD wVerMinor,
  342. LCID lcid, ITypeLib ** pptlib)
  343. {
  344. LoadOleAut32Dll();
  345. Assert(g_pfLoadRegTypeLib);
  346. if (g_pfLoadRegTypeLib)
  347. {
  348. return (*g_pfLoadRegTypeLib)(rguid,wVerMajor,wVerMinor,lcid,pptlib);
  349. }
  350. return E_OUTOFMEMORY;
  351. }
  352. void LoadUserEnvDll()
  353. {
  354. if (g_fLoadedUserEnv)
  355. return;
  356. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  357. cCritSect.Enter();
  358. // make sure not loaded again in case someone took lock first
  359. if (!g_fLoadedUserEnv)
  360. {
  361. g_hinstUserEnv = LoadLibrary(szUserEnvDll);
  362. if (g_hinstUserEnv)
  363. {
  364. g_pfGetUserProfileDirectory = (PFNGETUSERPROFILEDIRECTORY) GetProcAddress(g_hinstUserEnv, szGetUserProfileDirectory);
  365. }
  366. // should always get the exports.
  367. Assert(g_pfGetUserProfileDirectory);
  368. g_fLoadedUserEnv = TRUE;
  369. }
  370. cCritSect.Leave();
  371. }
  372. BOOL
  373. WINAPI
  374. GetUserProfileDirectoryX(HANDLE hToken,LPWSTR lpProfileDir,LPDWORD lpcchSize)
  375. {
  376. LoadUserEnvDll();
  377. Assert(g_pfGetUserProfileDirectory);
  378. if (g_pfGetUserProfileDirectory)
  379. {
  380. return (*g_pfGetUserProfileDirectory)(hToken,lpProfileDir,lpcchSize);
  381. }
  382. // by definition on falue size is filled with necessary buffer size.
  383. // since we don't know this set it to zero. If caller then reallocates and
  384. // tries again it will still fail
  385. *lpcchSize = 0;
  386. return FALSE;
  387. }
  388. // delay load for User
  389. void LoadUser32Dll()
  390. {
  391. if (g_fLoadedUser32)
  392. return;
  393. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  394. cCritSect.Enter();
  395. // make sure not loaded again in case someone took lock first
  396. if (!g_fLoadedUser32)
  397. {
  398. g_hinstUser32 = LoadLibrary(szUser32Dll);
  399. if (g_hinstUser32)
  400. {
  401. g_pfAllowSetForegroundWindow =
  402. (PFNALLOWSETFOREGROUNDWINDOW) GetProcAddress(g_hinstUser32,
  403. szAllowSetForegroundWindow);
  404. }
  405. g_fLoadedUser32 = TRUE;
  406. }
  407. cCritSect.Leave();
  408. }
  409. BOOL WINAPI AllowSetForegroundWindowX(
  410. DWORD dwProcessId)
  411. {
  412. LoadUser32Dll();
  413. // okay to not get export since might not be on NT 5.0
  414. if (g_pfAllowSetForegroundWindow)
  415. {
  416. return (*g_pfAllowSetForegroundWindow)(dwProcessId);
  417. }
  418. return FALSE;
  419. }
  420. // delay load for IME calls
  421. void LoadIMM32Dll()
  422. {
  423. if (g_fLoadedIMM32)
  424. return;
  425. CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
  426. cCritSect.Enter();
  427. // make sure not loaded again in case someone took lock first
  428. if (!g_fLoadedIMM32)
  429. {
  430. g_hinstIMM32 = LoadLibrary(szIMM32Dll);
  431. if (g_hinstIMM32)
  432. {
  433. g_pfImmAssociateContext =
  434. (PFNIMMASSOCIATECONTEXT) GetProcAddress(g_hinstIMM32,
  435. szImmAssociateContext);
  436. }
  437. g_fLoadedIMM32 = TRUE;
  438. }
  439. cCritSect.Leave();
  440. }
  441. HIMC WINAPI ImmAssociateContextX(HWND hWnd,HIMC hIMC)
  442. {
  443. LoadIMM32Dll();
  444. // okay to not get export since might not be on NT 5.0
  445. if (g_pfImmAssociateContext)
  446. {
  447. return (*g_pfImmAssociateContext)(hWnd,hIMC);
  448. }
  449. return NULL;
  450. }
  451. int LoadStringX( HINSTANCE hInstance, UINT uID,LPWSTR lpwszBuffer,int nBufferMax)
  452. {
  453. int iReturn = 0;
  454. if (g_fWideWrap_Unicode)
  455. {
  456. iReturn = LoadStringW(hInstance,uID,lpwszBuffer,nBufferMax);
  457. return iReturn;
  458. }
  459. XArray<CHAR> xszString;
  460. BOOL fOk = xszString.Init( nBufferMax );
  461. if ( !fOk )
  462. {
  463. SetLastError( ERROR_OUTOFMEMORY );
  464. return 0;
  465. }
  466. iReturn = LoadStringA(hInstance, uID, xszString.Get(), nBufferMax);
  467. if ( iReturn == 0 )
  468. return 0;
  469. XArray<WCHAR> xwszBuffer;
  470. fOk = ConvertMultiByteToWideChar( xszString.Get(), iReturn+1, xwszBuffer );
  471. if ( !fOk )
  472. return 0;
  473. iReturn = lstrlenX( xwszBuffer.Get() );
  474. if ( iReturn >= nBufferMax)
  475. {
  476. //
  477. // Truncate to fit
  478. //
  479. iReturn = nBufferMax -1;
  480. lstrcpynX( lpwszBuffer, xwszBuffer.Get(), iReturn );
  481. lpwszBuffer[iReturn] = 0;
  482. }
  483. else
  484. lstrcpyX( lpwszBuffer, xwszBuffer.Get() );
  485. return iReturn;
  486. }
  487. #if 0
  488. HANDLE WINAPI CreateFileX(LPCWSTR pwsz, DWORD fdwAccess, DWORD fdwShareMask,
  489. LPSECURITY_ATTRIBUTES lpsa, DWORD fdwCreate, DWORD fdwAttrsAndFlags,
  490. HANDLE hTemplateFile)
  491. {
  492. #ifdef DEBUG_OUTPUT
  493. OutputDebugString("CreateFile\n");
  494. #endif
  495. CHAR sz[MAX_PATH * 2];
  496. UnicodeToAnsiOem(sz, pwsz, sizeof(sz));
  497. return CreateFileA(sz, fdwAccess, fdwShareMask, lpsa, fdwCreate,
  498. fdwAttrsAndFlags, hTemplateFile);
  499. }
  500. #endif
  501. BOOL WINAPI DeleteFileX(LPCWSTR pwsz)
  502. {
  503. BOOL fReturn = FALSE;
  504. Assert(pwsz);
  505. if (g_fWideWrap_Unicode)
  506. {
  507. fReturn = DeleteFileW(pwsz);
  508. }
  509. else
  510. {
  511. XArray<CHAR> xszString;
  512. BOOL fOk = ConvertWideCharToMultiByte( pwsz, xszString );
  513. if ( !fOk )
  514. {
  515. SetLastError( ERROR_OUTOFMEMORY );
  516. return FALSE;
  517. }
  518. fReturn = DeleteFileA(xszString.Get());
  519. }
  520. return fReturn;
  521. }
  522. BOOL WINAPI ExpandEnvironmentStringsX(
  523. LPCWSTR lpSrc,
  524. LPWSTR lpDstW,
  525. DWORD nSize
  526. )
  527. {
  528. BOOL fReturn = FALSE;
  529. Assert(lpSrc);
  530. Assert(lpDstW);
  531. if (g_fWideWrap_Unicode)
  532. {
  533. fReturn = ExpandEnvironmentStringsW(lpSrc,lpDstW,nSize);
  534. }
  535. else
  536. {
  537. XArray<CHAR> xszSrc;
  538. XArray<CHAR> xszDst;
  539. BOOL fOk = ConvertWideCharToMultiByte( lpSrc, xszSrc);
  540. if ( !fOk )
  541. {
  542. SetLastError( ERROR_OUTOFMEMORY );
  543. return FALSE;
  544. }
  545. fOk = xszDst.Init( nSize + 1);
  546. if ( !fOk )
  547. {
  548. SetLastError( ERROR_OUTOFMEMORY );
  549. return FALSE;
  550. }
  551. fReturn = ExpandEnvironmentStringsA(xszSrc.Get(), xszDst.Get(), nSize);
  552. XArray<WCHAR> xszDstW;
  553. fOk = ConvertMultiByteToWideChar( xszDst.Get(), xszDstW);
  554. if ( !fOk )
  555. {
  556. SetLastError( ERROR_OUTOFMEMORY );
  557. return FALSE;
  558. }
  559. wcscpy(lpDstW,xszDstW.Get());
  560. }
  561. return fReturn;
  562. }
  563. #if 0
  564. UINT WINAPI RegisterClipboardFormatX(LPCWSTR pwszFormat)
  565. {
  566. #ifdef DEBUG_OUTPUT
  567. OutputDebugString("RegisterClipboardFormat\n");
  568. #endif
  569. UINT ret;
  570. CHAR sz[200];
  571. UnicodeToAnsi(sz, pwszFormat, sizeof(sz));
  572. ret = RegisterClipboardFormatA(sz);
  573. return ret;
  574. }
  575. int WINAPI GetClipboardFormatNameX(UINT format, LPWSTR pwsz,
  576. int cchMaxCount)
  577. {
  578. #ifdef DEBUG_OUTPUT
  579. OutputDebugString("GetClipboardFormatName\n");
  580. #endif
  581. LPSTR sz;
  582. int i;
  583. sz = (char *) ALLOC(cchMaxCount*sizeof(char));
  584. if (sz == NULL)
  585. {
  586. return 0;
  587. }
  588. i = GetClipboardFormatNameA(format, sz, cchMaxCount);
  589. if (i)
  590. {
  591. AnsiToUnicode(pwsz, sz, lstrlenA(sz) + 1);
  592. }
  593. if (sz)
  594. {
  595. FREE( sz);
  596. }
  597. return i;
  598. }
  599. #endif
  600. LONG APIENTRY RegOpenKeyX(HKEY hKey, LPCWSTR pwszSubKey, PHKEY phkResult)
  601. {
  602. return RegOpenKeyEx(hKey,pwszSubKey,NULL,KEY_READ | KEY_WRITE,phkResult);
  603. }
  604. #if 0
  605. LONG APIENTRY RegQueryValueX(HKEY hKey, LPCWSTR pwszSubKey, LPWSTR pwszValue,
  606. PLONG lpcbValue)
  607. {
  608. LONG ret;
  609. if (g_fWideWrap_Unicode)
  610. {
  611. ret = RegQueryValueW(hKey, pwszSubKey, pwszValue, lpcbValue);
  612. return ret;
  613. }
  614. LONG cbOldSize = *lpcbValue;
  615. LONG cb;
  616. XArray<CHAR> xszSubKey;
  617. BOOL fOk = ConvertWideCharToMultiByte( pwszSubKey, xszSubKey );
  618. if ( !fOk )
  619. return ERROR_OUTOFMEMORY;
  620. ret = RegQueryValueA(hKey, xszSubKey.Get(), NULL, &cb);
  621. // If the caller was just asking for the size of the value, jump out
  622. // now, without actually retrieving and converting the value.
  623. if (pwszValue == NULL)
  624. {
  625. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  626. *lpcbValue = cb * sizeof(WCHAR);
  627. }
  628. if (ret == ERROR_SUCCESS)
  629. {
  630. // If the caller was asking for the value, but allocated too small
  631. // of a buffer, set the buffer size and jump out.
  632. if (*lpcbValue < (LONG) (cb * sizeof(WCHAR)))
  633. {
  634. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  635. *lpcbValue = cb * sizeof(WCHAR);
  636. return ERROR_MORE_DATA;
  637. }
  638. // Otherwise, retrieve and convert the value.
  639. XArray<CHAR> xszValue;
  640. fOk = xszValue.Init( cb );
  641. if ( !fOk )
  642. return ERROR_OUTOFMEMORY;
  643. ret = RegQueryValueA(hKey, xszSubKey.Get(), xszValue.Get(), &cb);
  644. if (ret == ERROR_SUCCESS)
  645. {
  646. XArray<WCHAR> xwszValueOut;
  647. fOk = ConvertMultiByteToWideChar( xszValue.Get(), xwszValueOut );
  648. if ( !fOk )
  649. return ERROR_OUTOFMEMORY;
  650. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  651. *lpcbValue = lstrlenX(xwszValueOut.Get()) * sizeof(WCHAR);
  652. if ( *lpcbValue < cbOldSize )
  653. lstrcpyX( pwszValue, xwszValueOut.Get() );
  654. else
  655. return ERROR_MORE_DATA;
  656. }
  657. }
  658. return ret;
  659. }
  660. #endif
  661. LONG APIENTRY RegSetValueExX(
  662. HKEY hKey,
  663. LPCWSTR lpValueName,
  664. DWORD Reserved,
  665. DWORD dwType,
  666. CONST BYTE* lpData,
  667. DWORD cbData
  668. )
  669. {
  670. LONG lResult = E_UNEXPECTED;
  671. if (g_fWideWrap_Unicode)
  672. {
  673. lResult = RegSetValueExW(hKey,lpValueName,Reserved,dwType,lpData,cbData);
  674. }
  675. else
  676. {
  677. LPSTR lpValueNameA = NULL;
  678. LPSTR lpDataA = NULL;
  679. Assert(0 == Reserved);
  680. Assert(lpData);
  681. // only supports dwType of REG_SZ and REG_DWORD
  682. if ( (dwType != REG_SZ) && (dwType != REG_DWORD) && (dwType != REG_BINARY))
  683. {
  684. Assert(dwType == REG_SZ || dwType == REG_DWORD || dwType == REG_BINARY);
  685. return E_INVALIDARG;
  686. }
  687. XArray<CHAR> xszValueName;
  688. BOOL fOk = ConvertWideCharToMultiByte( lpValueName, xszValueName );
  689. if ( !fOk )
  690. return ERROR_OUTOFMEMORY;
  691. lpValueNameA = xszValueName.Get();
  692. XArray<CHAR> xszData;
  693. if (dwType == REG_SZ)
  694. {
  695. fOk = ConvertWideCharToMultiByte( (WCHAR *)lpData, xszData );
  696. if ( !fOk )
  697. return ERROR_OUTOFMEMORY;
  698. lpDataA = xszData.Get();
  699. lpData = (BYTE *) lpDataA;
  700. if (lpDataA)
  701. {
  702. cbData = lstrlenA(lpDataA) + 1;
  703. }
  704. }
  705. if (lpData)
  706. {
  707. lResult = RegSetValueExA(hKey,lpValueNameA,Reserved,dwType,lpData,cbData);
  708. }
  709. }
  710. return lResult;
  711. }
  712. #if 0
  713. LONG APIENTRY RegSetValueX(HKEY hKey, LPCWSTR lpSubKey, DWORD dwType,
  714. LPCWSTR lpData, DWORD cbData)
  715. {
  716. LONG ret;
  717. if (g_fWideWrap_Unicode)
  718. {
  719. ret = RegSetValueW( hKey, lpSubKey, dwType, lpData, cbData);
  720. return ret;
  721. }
  722. XArray<CHAR> xszKey;
  723. BOOL fOk = ConvertWideCharToMultiByte( lpSubKey, xszKey );
  724. if ( !fOk )
  725. return ERROR_OUTOFMEMORY;
  726. if ( dwType == REG_EXPAND_SZ
  727. || dwType == REG_MULTI_SZ
  728. || dwType == REG_SZ )
  729. {
  730. //
  731. // Convert string data to multibyte
  732. //
  733. XArray<CHAR> xszValue;
  734. fOk = ConvertWideCharToMultiByte( lpData, cbData, xszValue );
  735. if ( !fOk )
  736. return ERROR_OUTOFMEMORY;
  737. ret = RegSetValueA(hKey, xszKey.Get(), dwType, xszValue.Get(), lstrlenA(xszValue.Get()) + 1 );
  738. }
  739. else
  740. ret = RegSetValueA(hKey, xszKey.Get(), dwType, (LPSTR)lpData, cbData);
  741. return ret;
  742. }
  743. #endif
  744. LONG
  745. APIENTRY
  746. RegDeleteValueX (
  747. HKEY hKey,
  748. LPCWSTR lpValueName
  749. )
  750. {
  751. LONG ret;
  752. if (g_fWideWrap_Unicode)
  753. {
  754. ret = RegDeleteValueW( hKey,lpValueName);
  755. return ret;
  756. }
  757. XArray<CHAR> xszValue;
  758. BOOL fOk = ConvertWideCharToMultiByte( lpValueName, xszValue );
  759. if ( !fOk )
  760. return ERROR_OUTOFMEMORY;
  761. ret = RegDeleteValueA(hKey,xszValue.Get());
  762. return ret;
  763. }
  764. LONG
  765. APIENTRY
  766. RegCreateKeyExXp(
  767. HKEY hKey,
  768. LPCWSTR lpSubKey,
  769. DWORD Reserved,
  770. LPWSTR lpClass,
  771. DWORD dwOptions,
  772. REGSAM samDesired,
  773. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  774. PHKEY phkResult,
  775. LPDWORD lpdwDisposition,
  776. BOOL fSetSecurity)
  777. {
  778. LONG lResult = E_UNEXPECTED;
  779. DWORD dwDispositionLocal;
  780. LPDWORD lpdwDispositionLocal;
  781. lpdwDispositionLocal = lpdwDisposition ? lpdwDisposition : &dwDispositionLocal;
  782. if (g_fWideWrap_Unicode)
  783. {
  784. lResult = RegCreateKeyExW(hKey,lpSubKey,Reserved,
  785. lpClass,dwOptions,samDesired,lpSecurityAttributes,
  786. phkResult,lpdwDispositionLocal);
  787. }
  788. else
  789. {
  790. lResult = ERROR_SUCCESS;
  791. XArray<CHAR> xszSubKey;
  792. XArray<CHAR> xszClass;
  793. LPSTR lpSubKeyA;
  794. LPSTR lpClassA;
  795. BOOL fOk = ConvertWideCharToMultiByte( lpSubKey, xszSubKey );
  796. if ( !fOk )
  797. {
  798. lResult = ERROR_OUTOFMEMORY;
  799. }
  800. if (ERROR_SUCCESS == lResult)
  801. {
  802. lpSubKeyA = xszSubKey.Get();
  803. fOk = ConvertWideCharToMultiByte( lpClass, xszClass );
  804. if ( !fOk )
  805. {
  806. lResult = ERROR_OUTOFMEMORY;
  807. }
  808. }
  809. if (ERROR_SUCCESS == lResult)
  810. {
  811. lpClassA = xszClass.Get();
  812. lResult = RegCreateKeyExA(hKey,lpSubKeyA,Reserved,
  813. lpClassA,dwOptions,samDesired,lpSecurityAttributes,
  814. phkResult,lpdwDispositionLocal);
  815. }
  816. }
  817. // On NT Set the Security of any keys we create to Access Everyone
  818. if (VER_PLATFORM_WIN32_NT == g_OSVersionInfo.dwPlatformId)
  819. {
  820. // on a success and the disposition is a new key setup the security.
  821. if ( (ERROR_SUCCESS == lResult) && (REG_CREATED_NEW_KEY == *lpdwDispositionLocal))
  822. {
  823. // NOTE; if create included subkeys \\connection\\clsid only the
  824. // last key is set by SetRegSecurity.
  825. #ifdef _SETSECURITY
  826. SetRegKeySecurityEveryone(hKey,lpSubKey);
  827. #endif // _SETSECURITY
  828. }
  829. }
  830. #ifdef _SETSECURITY
  831. if ((ERROR_ACCESS_DENIED == lResult) && (fSetSecurity) )
  832. {
  833. SyncMgrExecCmd_ResetRegSecurity();
  834. lResult = RegCreateKeyExXp(hKey,lpSubKey,Reserved,lpClass,dwOptions,samDesired,
  835. lpSecurityAttributes,phkResult,lpdwDisposition,FALSE /* fSetSecurity */);
  836. }
  837. #endif // _SETSECURITY
  838. return lResult;
  839. }
  840. LONG
  841. APIENTRY
  842. RegCreateKeyExX(
  843. HKEY hKey,
  844. LPCWSTR lpSubKey,
  845. DWORD Reserved,
  846. LPWSTR lpClass,
  847. DWORD dwOptions,
  848. REGSAM samDesired,
  849. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  850. PHKEY phkResult,
  851. LPDWORD lpdwDisposition
  852. )
  853. {
  854. return RegCreateKeyExXp(hKey,lpSubKey,Reserved,lpClass,dwOptions,samDesired,
  855. lpSecurityAttributes,phkResult,
  856. lpdwDisposition,FALSE /* fSetSecurity */);
  857. }
  858. BOOL GetUserNameX(
  859. LPWSTR lpBuffer,
  860. LPDWORD pnSize
  861. )
  862. {
  863. BOOL fReturn = FALSE;
  864. if (g_fWideWrap_Unicode)
  865. {
  866. fReturn = GetUserNameW(lpBuffer,pnSize);
  867. }
  868. else
  869. {
  870. DWORD dwSizeA = *pnSize;
  871. DWORD dwOldSize = dwSizeA;
  872. XArray<CHAR> xszBufIn;
  873. BOOL fOk = xszBufIn.Init( dwSizeA );
  874. if ( !fOk )
  875. {
  876. SetLastError( ERROR_OUTOFMEMORY );
  877. return FALSE;
  878. }
  879. fReturn = GetUserNameA( xszBufIn.Get(), &dwSizeA );
  880. if (fReturn)
  881. {
  882. XArray<WCHAR> xwszBufOut;
  883. fOk = ConvertMultiByteToWideChar( xszBufIn.Get(), xwszBufOut );
  884. if ( !fOk )
  885. {
  886. SetLastError( ERROR_OUTOFMEMORY );
  887. return FALSE;
  888. }
  889. *pnSize = lstrlenX(xwszBufOut.Get()) + 1;
  890. if ( *pnSize < dwOldSize )
  891. {
  892. lstrcpyX( lpBuffer, xwszBufOut.Get() );
  893. return TRUE;
  894. }
  895. else
  896. {
  897. SetLastError( ERROR_MORE_DATA );
  898. return FALSE;
  899. }
  900. }
  901. }
  902. return fReturn;
  903. }
  904. UINT WINAPI RegisterWindowMessageX(LPCWSTR lpString)
  905. {
  906. UINT ret;
  907. if (g_fWideWrap_Unicode)
  908. {
  909. ret = RegisterWindowMessageW(lpString);
  910. return ret;
  911. }
  912. XArray<CHAR> xszString;
  913. BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
  914. if ( !fOk )
  915. {
  916. SetLastError( ERROR_OUTOFMEMORY );
  917. return 0;
  918. }
  919. ret = RegisterWindowMessageA( xszString.Get() );
  920. return ret;
  921. }
  922. LONG
  923. APIENTRY
  924. RegOpenKeyExXp(
  925. HKEY hKey,
  926. LPCWSTR lpSubKey,
  927. DWORD ulOptions,
  928. REGSAM samDesired,
  929. PHKEY phkResult,
  930. BOOL fSetSecurity)
  931. {
  932. LONG ret;
  933. if (g_fWideWrap_Unicode)
  934. {
  935. ret = RegOpenKeyExW( hKey, lpSubKey, ulOptions, samDesired, phkResult );
  936. }
  937. else
  938. {
  939. XArray<CHAR> xszSubKey;
  940. BOOL fOk = ConvertWideCharToMultiByte( lpSubKey, xszSubKey );
  941. if ( !fOk )
  942. return ERROR_OUTOFMEMORY;
  943. ret = RegOpenKeyExA(hKey, xszSubKey.Get(), ulOptions, samDesired, phkResult);
  944. }
  945. #ifdef _SETSECURITY
  946. if ((ERROR_ACCESS_DENIED == ret) && (fSetSecurity) )
  947. {
  948. SyncMgrExecCmd_ResetRegSecurity();
  949. ret = RegOpenKeyExXp(hKey,lpSubKey,ulOptions,samDesired,phkResult,FALSE /* fSetSecurity */);
  950. }
  951. #endif // _SETSECURITY
  952. return ret;
  953. }
  954. LONG
  955. APIENTRY
  956. RegOpenKeyExX (
  957. HKEY hKey,
  958. LPCWSTR lpSubKey,
  959. DWORD ulOptions,
  960. REGSAM samDesired,
  961. PHKEY phkResult
  962. )
  963. {
  964. return RegOpenKeyExXp(hKey,lpSubKey,ulOptions,samDesired,phkResult,TRUE /* fSetSecurity */);
  965. }
  966. LONG
  967. APIENTRY
  968. RegQueryValueExX(
  969. HKEY hKey,
  970. LPCWSTR lpValueName,
  971. LPDWORD lpReserved,
  972. LPDWORD lpType,
  973. LPBYTE lpData,
  974. LPDWORD lpcbData
  975. )
  976. {
  977. LONG ret;
  978. if (g_fWideWrap_Unicode)
  979. {
  980. ret = RegQueryValueExW( hKey, lpValueName, lpReserved, lpType, lpData, lpcbData );
  981. return ret;
  982. }
  983. LPBYTE lpTempBuffer;
  984. DWORD dwTempType;
  985. DWORD cb, cbRequired;
  986. LPSTR sz;
  987. DWORD dwDataOldSize = 0;
  988. if ( lpcbData != NULL )
  989. dwDataOldSize = *lpcbData;
  990. XArray<CHAR> xszValueName;
  991. BOOL fOk = ConvertWideCharToMultiByte( lpValueName, xszValueName );
  992. if ( !fOk )
  993. return ERROR_OUTOFMEMORY;
  994. sz = xszValueName.Get();
  995. ret = RegQueryValueExA(hKey, sz, lpReserved, &dwTempType, NULL, &cb);
  996. // If the caller was just asking for the size of the value, jump out
  997. // now, without actually retrieving and converting the value.
  998. if (lpData == NULL)
  999. {
  1000. switch (dwTempType)
  1001. {
  1002. case REG_EXPAND_SZ:
  1003. case REG_MULTI_SZ:
  1004. case REG_SZ:
  1005. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  1006. if (lpcbData != NULL)
  1007. *lpcbData = cb * sizeof(WCHAR);
  1008. break;
  1009. default:
  1010. if (lpcbData != NULL)
  1011. *lpcbData = cb;
  1012. break;
  1013. }
  1014. // Set the type, if required.
  1015. if (lpType != NULL)
  1016. {
  1017. *lpType = dwTempType;
  1018. }
  1019. goto Exit;
  1020. }
  1021. if (ret == ERROR_SUCCESS)
  1022. {
  1023. //
  1024. // Determine the size of buffer needed
  1025. //
  1026. switch (dwTempType)
  1027. {
  1028. case REG_EXPAND_SZ:
  1029. case REG_MULTI_SZ:
  1030. case REG_SZ:
  1031. cbRequired = cb * sizeof(WCHAR);
  1032. break;
  1033. default:
  1034. cbRequired = cb;
  1035. break;
  1036. }
  1037. // If the caller was asking for the value, but allocated too small
  1038. // of a buffer, set the buffer size and jump out.
  1039. if (lpcbData != NULL && *lpcbData < cbRequired)
  1040. {
  1041. // Adjust size of buffer to report, to account for CHAR -> WCHAR
  1042. *lpcbData = cbRequired;
  1043. // Set the type, if required.
  1044. if (lpType != NULL)
  1045. {
  1046. *lpType = dwTempType;
  1047. }
  1048. ret = ERROR_MORE_DATA;
  1049. goto Exit;
  1050. }
  1051. // Otherwise, retrieve and convert the value.
  1052. XArray<CHAR> xszTempBuffer;
  1053. XArray<WCHAR> xwszValueOut;
  1054. BOOL fOk;
  1055. switch (dwTempType)
  1056. {
  1057. case REG_EXPAND_SZ:
  1058. case REG_MULTI_SZ:
  1059. case REG_SZ:
  1060. fOk = xszTempBuffer.Init( cbRequired );
  1061. if ( !fOk )
  1062. return ERROR_OUTOFMEMORY;
  1063. lpTempBuffer = (BYTE *) xszTempBuffer.Get();
  1064. ret = RegQueryValueExA(hKey,
  1065. sz,
  1066. lpReserved,
  1067. &dwTempType,
  1068. lpTempBuffer,
  1069. &cb);
  1070. if (ret == ERROR_SUCCESS)
  1071. {
  1072. switch (dwTempType)
  1073. {
  1074. case REG_EXPAND_SZ:
  1075. case REG_SZ:
  1076. fOk = ConvertMultiByteToWideChar( (char *) lpTempBuffer,
  1077. cb,
  1078. xwszValueOut );
  1079. if ( !fOk )
  1080. return ERROR_OUTOFMEMORY;
  1081. *lpcbData = (lstrlenX(xwszValueOut.Get()) + 1) * sizeof(WCHAR);
  1082. if ( *lpcbData < dwDataOldSize )
  1083. lstrcpyX( (WCHAR *)lpData, xwszValueOut.Get() );
  1084. else
  1085. return ERROR_MORE_DATA;
  1086. // Set the type, if required.
  1087. if (lpType != NULL)
  1088. {
  1089. *lpType = dwTempType;
  1090. }
  1091. break;
  1092. case REG_MULTI_SZ:
  1093. AssertSz(0,"E_NOTIMPL");
  1094. #if MULTI_SZ
  1095. LPWSTR pwszTempWide;
  1096. LPSTR pszTempNarrow;
  1097. ULONG ulStringLength;
  1098. Assert( !"MultiToWideChar conversion is improper" );
  1099. pszTempNarrow = (LPSTR) lpTempBuffer;
  1100. pwszTempWide = (LPWSTR) lpData;
  1101. while (*pszTempNarrow != NULL)
  1102. {
  1103. ulStringLength = lstrlenA(pszTempNarrow) + 1;
  1104. AnsiToUnicode(pwszTempWide,
  1105. pszTempNarrow,
  1106. ulStringLength);
  1107. // Compiler will scale appropriately here
  1108. pszTempNarrow += ulStringLength;
  1109. pwszTempWide += ulStringLength;
  1110. }
  1111. *pwszTempWide = NULL; // let's not forget MULTI_SZ end NULL
  1112. #endif // MULTI_SZ
  1113. break;
  1114. }
  1115. }
  1116. break;
  1117. default:
  1118. //
  1119. // No conversion of out parameters needed. Just call narrow
  1120. // version with args passed in, and return directly.
  1121. //
  1122. ret = RegQueryValueExA(hKey,
  1123. sz,
  1124. lpReserved,
  1125. lpType,
  1126. lpData,
  1127. lpcbData);
  1128. }
  1129. }
  1130. Exit:
  1131. return ret;
  1132. }
  1133. HWND
  1134. WINAPI
  1135. CreateWindowExX( DWORD dwExStyle,
  1136. LPCWSTR lpClassName,
  1137. LPCWSTR lpWindowName,
  1138. DWORD dwStyle,
  1139. int X,
  1140. int Y,
  1141. int nWidth,
  1142. int nHeight,
  1143. HWND hWndParent ,
  1144. HMENU hMenu,
  1145. HINSTANCE hInstance,
  1146. LPVOID lpParam )
  1147. {
  1148. HWND ret = NULL;
  1149. if (g_fWideWrap_Unicode)
  1150. {
  1151. ret = CreateWindowExW( dwExStyle,
  1152. lpClassName,
  1153. lpWindowName,
  1154. dwStyle,
  1155. X,
  1156. Y,
  1157. nWidth,
  1158. nHeight,
  1159. hWndParent,
  1160. hMenu,
  1161. hInstance,
  1162. lpParam );
  1163. return ret;
  1164. }
  1165. LPSTR szClass;
  1166. BOOL fOk;
  1167. XArray<CHAR> xszClass;
  1168. if (HIWORD(lpClassName) == 0)
  1169. szClass = (LPSTR) lpClassName;
  1170. else
  1171. {
  1172. fOk = ConvertWideCharToMultiByte( lpClassName, xszClass );
  1173. if ( !fOk )
  1174. {
  1175. SetLastError( ERROR_OUTOFMEMORY );
  1176. return NULL;
  1177. }
  1178. szClass = xszClass.Get();
  1179. }
  1180. XArray<CHAR> xszWindow;
  1181. fOk = ConvertWideCharToMultiByte( lpWindowName, xszWindow );
  1182. if ( !fOk )
  1183. {
  1184. SetLastError( ERROR_OUTOFMEMORY );
  1185. return NULL;
  1186. }
  1187. ret = CreateWindowExA ( dwExStyle,
  1188. szClass,
  1189. xszWindow.Get(),
  1190. dwStyle,
  1191. X,
  1192. Y,
  1193. nWidth,
  1194. nHeight,
  1195. hWndParent,
  1196. hMenu,
  1197. hInstance,
  1198. lpParam);
  1199. return ret;
  1200. }
  1201. #if 0
  1202. HWND
  1203. WINAPI
  1204. CreateWindowX( LPCWSTR lpClassName,
  1205. LPCWSTR lpWindowName,
  1206. DWORD dwStyle,
  1207. int X,
  1208. int Y,
  1209. int nWidth,
  1210. int nHeight,
  1211. HWND hWndParent ,
  1212. HMENU hMenu,
  1213. HINSTANCE hInstance,
  1214. LPVOID lpParam )
  1215. {
  1216. #ifdef DEBUG_OUTPUT
  1217. OutputDebugString("CreateWindow\n");
  1218. #endif
  1219. return CreateWindowExX(0, lpClassName, lpWindowName, dwStyle, X, Y,
  1220. nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
  1221. }
  1222. #endif
  1223. HWND WINAPI CreateDialogParamX(
  1224. HINSTANCE hInstance,
  1225. LPCWSTR lpwszTemplateName,
  1226. HWND hWndParent,
  1227. DLGPROC lpDialogFunc,
  1228. LPARAM dwInitParam
  1229. )
  1230. {
  1231. HWND hwndDialog = NULL;
  1232. if (g_fWideWrap_Unicode)
  1233. {
  1234. hwndDialog = CreateDialogParamW( hInstance,
  1235. lpwszTemplateName,
  1236. hWndParent,
  1237. lpDialogFunc,
  1238. dwInitParam );
  1239. return hwndDialog;
  1240. }
  1241. LPSTR pszTemplateName;
  1242. XArray<CHAR> xszTemplate;
  1243. if (HIWORD(lpwszTemplateName) == 0)
  1244. {
  1245. //
  1246. // Is it an atom?
  1247. //
  1248. pszTemplateName = (LPSTR) lpwszTemplateName;
  1249. }
  1250. else
  1251. {
  1252. //
  1253. // Otherwise convert the string
  1254. //
  1255. BOOL fOk = ConvertWideCharToMultiByte( lpwszTemplateName, xszTemplate );
  1256. if ( !fOk )
  1257. {
  1258. SetLastError( ERROR_OUTOFMEMORY );
  1259. return NULL;
  1260. }
  1261. pszTemplateName = xszTemplate.Get();
  1262. }
  1263. if (pszTemplateName)
  1264. hwndDialog = CreateDialogParamA(hInstance,pszTemplateName,hWndParent,lpDialogFunc,dwInitParam);
  1265. return hwndDialog;
  1266. }
  1267. INT_PTR
  1268. WINAPI
  1269. DialogBoxParamX(
  1270. IN HINSTANCE hInstance,
  1271. IN LPCWSTR lpTemplateName,
  1272. IN HWND hWndParent,
  1273. IN DLGPROC lpDialogFunc,
  1274. IN LPARAM dwInitParam)
  1275. {
  1276. INT_PTR iReturn = -1;
  1277. if (g_fWideWrap_Unicode)
  1278. {
  1279. iReturn = DialogBoxParamW(hInstance,lpTemplateName,hWndParent,lpDialogFunc,dwInitParam);
  1280. }
  1281. else
  1282. {
  1283. LPSTR lpTemplateNameA;
  1284. Assert(0 == HIWORD(lpTemplateName)); // only support atoms
  1285. if (0 == HIWORD(lpTemplateName))
  1286. {
  1287. lpTemplateNameA = (LPSTR) lpTemplateName;
  1288. iReturn = DialogBoxParamA(hInstance,lpTemplateNameA,hWndParent,lpDialogFunc,dwInitParam);
  1289. }
  1290. }
  1291. return iReturn;
  1292. }
  1293. ATOM
  1294. WINAPI
  1295. RegisterClassX(
  1296. CONST WNDCLASSW *lpWndClass)
  1297. {
  1298. ATOM ret;
  1299. if (g_fWideWrap_Unicode)
  1300. {
  1301. ret = RegisterClassW( lpWndClass );
  1302. return ret;
  1303. }
  1304. WNDCLASSA wc;
  1305. Win4Assert(sizeof(WNDCLASSA) == sizeof(WNDCLASSW));
  1306. memcpy(&wc, lpWndClass, sizeof(WNDCLASS));
  1307. XArray<CHAR> xszMenu;
  1308. BOOL fOk = ConvertWideCharToMultiByte( lpWndClass->lpszMenuName, xszMenu );
  1309. if ( !fOk )
  1310. {
  1311. SetLastError( ERROR_OUTOFMEMORY );
  1312. return 0;
  1313. }
  1314. wc.lpszMenuName = xszMenu.Get();
  1315. XArray<CHAR> xszClass;
  1316. if (HIWORD(lpWndClass->lpszClassName) == 0)
  1317. wc.lpszClassName = (LPSTR) lpWndClass->lpszClassName;
  1318. else
  1319. {
  1320. fOk = ConvertWideCharToMultiByte( lpWndClass->lpszClassName, xszClass );
  1321. if ( !fOk )
  1322. {
  1323. SetLastError( ERROR_OUTOFMEMORY );
  1324. return 0;
  1325. }
  1326. wc.lpszClassName = xszClass.Get();
  1327. }
  1328. ret = RegisterClassA(&wc);
  1329. return ret;
  1330. }
  1331. #if 0
  1332. BOOL
  1333. WINAPI
  1334. UnregisterClassX(
  1335. LPCWSTR lpClassName,
  1336. HINSTANCE hInstance)
  1337. {
  1338. #ifdef DEBUG_OUTPUT
  1339. OutputDebugString("UnregisterClass\n");
  1340. #endif
  1341. LPSTR sz;
  1342. BOOL ret;
  1343. BOOL fAtom = FALSE;
  1344. if (HIWORD(lpClassName) == 0)
  1345. {
  1346. sz = (LPSTR) lpClassName;
  1347. fAtom = TRUE;
  1348. }
  1349. else
  1350. {
  1351. sz = Convert(lpClassName);
  1352. if (sz == ERR)
  1353. return FALSE;
  1354. }
  1355. ret = UnregisterClassA(sz, hInstance);
  1356. if (!fAtom) FREE(sz);
  1357. return ret;
  1358. }
  1359. HANDLE
  1360. WINAPI
  1361. GetPropX(
  1362. HWND hWnd,
  1363. LPCWSTR lpString)
  1364. {
  1365. #ifdef DEBUG_OUTPUT
  1366. OutputDebugString("GetProp\n");
  1367. #endif
  1368. HANDLE ret;
  1369. LPSTR sz;
  1370. BOOL fAtom = FALSE;
  1371. if (HIWORD(lpString)==0)
  1372. {
  1373. fAtom = TRUE;
  1374. sz = (LPSTR) lpString;
  1375. }
  1376. else
  1377. {
  1378. sz = Convert(lpString);
  1379. if (sz == ERR)
  1380. return NULL;
  1381. }
  1382. ret = GetPropA(hWnd, sz);
  1383. if (!fAtom) FREE(sz);
  1384. return ret;
  1385. }
  1386. BOOL
  1387. WINAPI
  1388. SetPropX(
  1389. HWND hWnd,
  1390. LPCWSTR lpString,
  1391. HANDLE hData)
  1392. {
  1393. #ifdef DEBUG_OUTPUT
  1394. OutputDebugString("SetProp\n");
  1395. #endif
  1396. BOOL ret;
  1397. LPSTR sz;
  1398. BOOL fAtom = FALSE;
  1399. if (HIWORD(lpString)==0)
  1400. {
  1401. sz = (LPSTR) lpString;
  1402. fAtom = TRUE;
  1403. }
  1404. else
  1405. {
  1406. sz = Convert(lpString);
  1407. if (sz == ERR)
  1408. return NULL;
  1409. }
  1410. ret = SetPropA(hWnd, sz, hData);
  1411. if (!fAtom) FREE(sz);
  1412. return ret;
  1413. }
  1414. HANDLE
  1415. WINAPI
  1416. RemovePropX(
  1417. HWND hWnd,
  1418. LPCWSTR lpString)
  1419. {
  1420. #ifdef DEBUG_OUTPUT
  1421. OutputDebugString("RemoveProp\n");
  1422. #endif
  1423. HANDLE ret;
  1424. LPSTR sz;
  1425. BOOL fAtom = FALSE;
  1426. if (HIWORD(lpString)==0)
  1427. {
  1428. sz = (LPSTR) lpString;
  1429. fAtom = TRUE;
  1430. }
  1431. else
  1432. {
  1433. sz = Convert(lpString);
  1434. if (sz == ERR)
  1435. return NULL;
  1436. }
  1437. ret = RemovePropA(hWnd, sz);
  1438. if (!fAtom) FREE(sz);
  1439. return ret;
  1440. }
  1441. UINT
  1442. WINAPI
  1443. GetProfileIntX(
  1444. LPCWSTR lpAppName,
  1445. LPCWSTR lpKeyName,
  1446. INT nDefault
  1447. )
  1448. {
  1449. #ifdef DEBUG_OUTPUT
  1450. OutputDebugString("GetProfileInt\n");
  1451. #endif
  1452. LPSTR szApp;
  1453. LPSTR szKey;
  1454. UINT ret;
  1455. szApp = Convert(lpAppName);
  1456. if (szApp==ERR)
  1457. {
  1458. return nDefault;
  1459. }
  1460. szKey = Convert(lpKeyName);
  1461. if (szApp==ERR)
  1462. {
  1463. if (szApp)
  1464. FREE( szApp);
  1465. return nDefault;
  1466. }
  1467. ret = GetProfileIntA(szApp, szKey, nDefault);
  1468. if (szApp)
  1469. FREE( szApp);
  1470. if (szKey)
  1471. FREE( szKey);
  1472. return ret;
  1473. }
  1474. ATOM
  1475. WINAPI
  1476. GlobalAddAtomX(
  1477. LPCWSTR lpString
  1478. )
  1479. {
  1480. #ifdef DEBUG_OUTPUT
  1481. OutputDebugString("GlobalAddAtom\n");
  1482. #endif
  1483. ATOM ret;
  1484. LPSTR sz;
  1485. sz = Convert(lpString);
  1486. if (sz==ERR)
  1487. {
  1488. return NULL;
  1489. }
  1490. ret = GlobalAddAtomA(sz);
  1491. if (sz)
  1492. FREE(sz);
  1493. return ret;
  1494. }
  1495. UINT
  1496. WINAPI
  1497. GlobalGetAtomNameX(
  1498. ATOM nAtom,
  1499. LPWSTR pwszBuffer,
  1500. int nSize
  1501. )
  1502. {
  1503. #ifdef DEBUG_OUTPUT
  1504. OutputDebugString("GlobalGetAtomName\n");
  1505. #endif
  1506. LPSTR sz;
  1507. UINT ret;
  1508. sz = (char *) ALLOC(nSize*sizeof(char));
  1509. if (sz == NULL)
  1510. {
  1511. return 0;
  1512. }
  1513. ret = GlobalGetAtomNameA(nAtom, sz, nSize);
  1514. if (ret)
  1515. {
  1516. AnsiToUnicode(pwszBuffer, sz, lstrlenA(sz) + 1);
  1517. }
  1518. if (sz)
  1519. FREE(sz);
  1520. return ret;
  1521. }
  1522. #endif
  1523. DWORD
  1524. WINAPI
  1525. GetModuleFileNameX(
  1526. HINSTANCE hModule,
  1527. LPWSTR pwszFilename,
  1528. DWORD nSize
  1529. )
  1530. {
  1531. DWORD ret;
  1532. if (g_fWideWrap_Unicode)
  1533. {
  1534. ret = GetModuleFileNameW( hModule, pwszFilename, nSize );
  1535. return ret;
  1536. }
  1537. XArray<CHAR> xszFileName;
  1538. BOOL fOk = xszFileName.Init( nSize );
  1539. if ( !fOk )
  1540. {
  1541. SetLastError( ERROR_OUTOFMEMORY );
  1542. return 0;
  1543. }
  1544. ret = GetModuleFileNameA(hModule, xszFileName.Get(), nSize);
  1545. if (ret == 0 )
  1546. return ret;
  1547. XArray<WCHAR> xwszName;
  1548. fOk = ConvertMultiByteToWideChar( xszFileName.Get(), ret, xwszName );
  1549. if ( !fOk )
  1550. {
  1551. SetLastError( ERROR_OUTOFMEMORY );
  1552. return 0;
  1553. }
  1554. ret = lstrlenX( xwszName.Get() );
  1555. if ( ret >= nSize)
  1556. {
  1557. //
  1558. // Truncate to fit
  1559. //
  1560. ret = nSize -1;
  1561. lstrcpynX( pwszFilename, xwszName.Get(), ret );
  1562. pwszFilename[ret] = 0;
  1563. }
  1564. else
  1565. lstrcpyX( pwszFilename, xwszName.Get() );
  1566. return ret;
  1567. }
  1568. #if 0
  1569. LPWSTR
  1570. WINAPI
  1571. CharPrevX(
  1572. LPCWSTR lpszStart,
  1573. LPCWSTR lpszCurrent)
  1574. {
  1575. #ifdef DEBUG_OUTPUT
  1576. OutputDebugString("CharPrev\n");
  1577. #endif
  1578. if (lpszCurrent == lpszStart)
  1579. {
  1580. return (LPWSTR) lpszStart;
  1581. }
  1582. else
  1583. {
  1584. return (LPWSTR) lpszCurrent - 1;
  1585. }
  1586. }
  1587. HFONT WINAPI CreateFontX(int a, int b, int c, int d, int e, DWORD f,
  1588. DWORD g, DWORD h, DWORD i, DWORD j, DWORD k,
  1589. DWORD l, DWORD m, LPCWSTR pwsz)
  1590. {
  1591. #ifdef DEBUG_OUTPUT
  1592. OutputDebugString("CreateFont\n");
  1593. #endif
  1594. LPSTR sz;
  1595. HFONT ret;
  1596. sz = Convert(pwsz);
  1597. if (sz == ERR)
  1598. {
  1599. return NULL;
  1600. }
  1601. ret = CreateFontA(a,b,c,d,e,f,g,h,i,j,k,l,m,sz);
  1602. if (sz)
  1603. FREE(sz);
  1604. return ret;
  1605. }
  1606. #endif
  1607. HINSTANCE
  1608. WINAPI
  1609. LoadLibraryX(
  1610. LPCWSTR pwszFileName
  1611. )
  1612. {
  1613. HINSTANCE ret;
  1614. if (g_fWideWrap_Unicode)
  1615. {
  1616. ret = LoadLibraryW( pwszFileName );
  1617. return ret;
  1618. }
  1619. XArray<CHAR> xszName;
  1620. BOOL fOk = ConvertWideCharToMultiByte( pwszFileName, xszName, TRUE );
  1621. if ( !fOk )
  1622. {
  1623. SetLastError( ERROR_OUTOFMEMORY );
  1624. return NULL;
  1625. }
  1626. ret = LoadLibraryA( xszName.Get() );
  1627. return ret;
  1628. }
  1629. #if 0
  1630. HMODULE
  1631. WINAPI
  1632. LoadLibraryExX(
  1633. LPCWSTR lpLibFileName,
  1634. HANDLE hFile,
  1635. DWORD dwFlags
  1636. )
  1637. {
  1638. #ifdef DEBUG_OUTPUT
  1639. OutputDebugString("LoadLibrary\n");
  1640. #endif
  1641. HINSTANCE ret;
  1642. LPSTR sz;
  1643. sz = ConvertOem(lpLibFileName);
  1644. if (sz == ERR)
  1645. {
  1646. return NULL;
  1647. }
  1648. ret = LoadLibraryExA(sz, hFile, dwFlags);
  1649. if (sz)
  1650. FREE(sz);
  1651. return ret;
  1652. }
  1653. #endif
  1654. LONG
  1655. APIENTRY
  1656. RegDeleteKeyXp(
  1657. HKEY hKey,
  1658. LPCWSTR pwszSubKey,
  1659. BOOL fSetSecurity
  1660. )
  1661. {
  1662. LONG ret;
  1663. if (g_fWideWrap_Unicode)
  1664. {
  1665. ret = RegDeleteKeyW( hKey, pwszSubKey );
  1666. }
  1667. else
  1668. {
  1669. XArray<CHAR> xszSubKey;
  1670. BOOL fOk = ConvertWideCharToMultiByte( pwszSubKey, xszSubKey );
  1671. if ( !fOk )
  1672. return ERROR_OUTOFMEMORY;
  1673. ret = RegDeleteKeyA(hKey, xszSubKey.Get() );
  1674. }
  1675. if ((ERROR_ACCESS_DENIED == ret) && (fSetSecurity) )
  1676. {
  1677. SyncMgrExecCmd_ResetRegSecurity();
  1678. ret = RegDeleteKeyXp(hKey,pwszSubKey,FALSE /*fSetSecurity*/);
  1679. }
  1680. return ret;
  1681. }
  1682. LONG
  1683. APIENTRY
  1684. RegDeleteKeyX(
  1685. HKEY hKey,
  1686. LPCWSTR pwszSubKey
  1687. )
  1688. {
  1689. return RegDeleteKeyXp(hKey,pwszSubKey,TRUE /*fSetSecurity*/);
  1690. }
  1691. BOOL
  1692. APIENTRY
  1693. CreateProcessX(
  1694. LPCWSTR lpApplicationName,
  1695. LPWSTR lpCommandLine,
  1696. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  1697. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  1698. BOOL bInheritHandles,
  1699. DWORD dwCreationFlags,
  1700. LPVOID lpEnvironment,
  1701. LPCWSTR lpCurrentDirectory,
  1702. LPSTARTUPINFOW lpStartupInfo,
  1703. LPPROCESS_INFORMATION lpProcessInformation
  1704. )
  1705. {
  1706. BOOL ret = FALSE;
  1707. if (g_fWideWrap_Unicode)
  1708. {
  1709. ret = CreateProcessW( lpApplicationName,
  1710. lpCommandLine,
  1711. lpProcessAttributes,
  1712. lpThreadAttributes,
  1713. bInheritHandles,
  1714. dwCreationFlags,
  1715. lpEnvironment,
  1716. lpCurrentDirectory,
  1717. lpStartupInfo,
  1718. lpProcessInformation );
  1719. return ret;
  1720. }
  1721. STARTUPINFOA si;
  1722. LPSTR szApp = NULL;
  1723. LPSTR szCommand = NULL;
  1724. LPSTR szDir = NULL;
  1725. memcpy(&si, lpStartupInfo, sizeof(STARTUPINFO));
  1726. si.lpTitle = NULL;
  1727. XArray<CHAR> xszDesktop;
  1728. BOOL fOk = ConvertWideCharToMultiByte( lpStartupInfo->lpDesktop, xszDesktop );
  1729. if ( !fOk )
  1730. {
  1731. SetLastError( ERROR_OUTOFMEMORY );
  1732. return 0;
  1733. }
  1734. si.lpDesktop = xszDesktop.Get();
  1735. XArray<CHAR> xszTitle;
  1736. fOk = ConvertWideCharToMultiByte( lpStartupInfo->lpTitle, xszTitle );
  1737. if ( !fOk )
  1738. {
  1739. SetLastError( ERROR_OUTOFMEMORY );
  1740. return 0;
  1741. }
  1742. si.lpTitle = xszTitle.Get();
  1743. XArray<CHAR> xszAppName;
  1744. fOk = ConvertWideCharToMultiByte( lpApplicationName, xszAppName, TRUE );
  1745. if ( !fOk )
  1746. {
  1747. SetLastError( ERROR_OUTOFMEMORY );
  1748. return 0;
  1749. }
  1750. szApp = xszAppName.Get();
  1751. XArray<CHAR> xszCommand;
  1752. fOk = ConvertWideCharToMultiByte( lpCommandLine, xszCommand, TRUE );
  1753. if ( !fOk )
  1754. {
  1755. SetLastError( ERROR_OUTOFMEMORY );
  1756. return 0;
  1757. }
  1758. szCommand = xszCommand.Get();
  1759. XArray<CHAR> xszCurDir;
  1760. fOk = ConvertWideCharToMultiByte( lpCurrentDirectory, xszCurDir, TRUE );
  1761. if ( !fOk )
  1762. {
  1763. SetLastError( ERROR_OUTOFMEMORY );
  1764. return 0;
  1765. }
  1766. szDir = xszCurDir.Get();
  1767. ret = CreateProcessA(szApp, szCommand, lpProcessAttributes,
  1768. lpThreadAttributes, bInheritHandles, dwCreationFlags,
  1769. lpEnvironment, szDir, &si, lpProcessInformation);
  1770. return ret;
  1771. }
  1772. LONG
  1773. APIENTRY
  1774. RegEnumKeyExX(
  1775. HKEY hKey,
  1776. DWORD dwIndex,
  1777. LPWSTR lpName,
  1778. LPDWORD lpcbName,
  1779. LPDWORD lpReserved,
  1780. LPWSTR lpClass,
  1781. LPDWORD lpcbClass,
  1782. PFILETIME lpftLastWriteTime
  1783. )
  1784. {
  1785. LONG ret = ERROR_OUTOFMEMORY;
  1786. if (g_fWideWrap_Unicode)
  1787. {
  1788. ret = RegEnumKeyExW( hKey,
  1789. dwIndex,
  1790. lpName,
  1791. lpcbName,
  1792. lpReserved,
  1793. lpClass,
  1794. lpcbClass,
  1795. lpftLastWriteTime );
  1796. return ret;
  1797. }
  1798. LPSTR szName;
  1799. XArray<CHAR> xszName;
  1800. BOOL fOk = xszName.Init( *lpcbName );
  1801. if ( !fOk )
  1802. return ERROR_OUTOFMEMORY;
  1803. szName = xszName.Get();
  1804. DWORD dwNameOldSize = *lpcbName;
  1805. DWORD dwClassOldSize = 0;
  1806. LPSTR szClass = NULL;
  1807. XArray<CHAR> xszClass;
  1808. if (lpClass != NULL)
  1809. {
  1810. fOk = xszClass.Init( *lpcbClass );
  1811. if ( !fOk )
  1812. return ERROR_OUTOFMEMORY;
  1813. szClass = xszClass.Get();
  1814. dwClassOldSize = *lpcbClass;
  1815. }
  1816. //
  1817. // Return lengths do not include zero char.
  1818. //
  1819. ret = RegEnumKeyExA(hKey, dwIndex, szName, lpcbName, lpReserved,
  1820. szClass, lpcbClass, lpftLastWriteTime);
  1821. if (ret == ERROR_SUCCESS)
  1822. {
  1823. XArray<WCHAR> xwszNameOut;
  1824. fOk = ConvertMultiByteToWideChar( szName,
  1825. *lpcbName + 1,
  1826. xwszNameOut );
  1827. if ( !fOk )
  1828. return ERROR_OUTOFMEMORY;
  1829. if ( lstrlenX(xwszNameOut.Get()) < dwNameOldSize )
  1830. lstrcpyX( lpName, xwszNameOut.Get() );
  1831. else
  1832. return ERROR_MORE_DATA;
  1833. if (szClass)
  1834. {
  1835. XArray<WCHAR> xwszClassOut;
  1836. fOk = ConvertMultiByteToWideChar( szClass,
  1837. *lpcbClass + 1,
  1838. xwszClassOut );
  1839. if ( !fOk )
  1840. return ERROR_OUTOFMEMORY;
  1841. if ( lstrlenX(xwszClassOut.Get()) < dwClassOldSize)
  1842. lstrcpyX( lpClass, xwszClassOut.Get() );
  1843. else
  1844. return ERROR_MORE_DATA;
  1845. }
  1846. }
  1847. return ret;
  1848. }
  1849. #if 0
  1850. BOOL
  1851. WINAPI
  1852. AppendMenuX(
  1853. HMENU hMenu,
  1854. UINT uFlags,
  1855. UINT uIDnewItem,
  1856. LPCWSTR lpnewItem
  1857. )
  1858. {
  1859. #ifdef DEBUG_OUTPUT
  1860. OutputDebugString("AppendMenu\n");
  1861. #endif
  1862. BOOL ret;
  1863. LPSTR sz;
  1864. if (uFlags == MF_STRING)
  1865. {
  1866. sz = Convert(lpnewItem);
  1867. if (sz==ERR)
  1868. {
  1869. return FALSE;
  1870. }
  1871. }
  1872. else
  1873. {
  1874. sz = (LPSTR) lpnewItem;
  1875. }
  1876. ret = AppendMenuA(hMenu, uFlags, uIDnewItem, sz);
  1877. if (uFlags == MF_STRING)
  1878. {
  1879. if (sz)
  1880. FREE(sz);
  1881. }
  1882. return ret;
  1883. }
  1884. HANDLE
  1885. WINAPI
  1886. OpenEventX(
  1887. DWORD dwDesiredAccess,
  1888. BOOL bInheritHandle,
  1889. LPCWSTR lpName
  1890. )
  1891. {
  1892. #ifdef DEBUG_OUTPUT
  1893. OutputDebugString("OpenEvent\n");
  1894. #endif
  1895. LPSTR sz;
  1896. HANDLE ret;
  1897. sz = Convert(lpName);
  1898. if (sz == ERR)
  1899. {
  1900. return NULL;
  1901. }
  1902. ret = OpenEventA(dwDesiredAccess, bInheritHandle, sz);
  1903. if (sz)
  1904. FREE(sz);
  1905. return ret;
  1906. }
  1907. #endif
  1908. HANDLE
  1909. WINAPI
  1910. CreateEventX(
  1911. LPSECURITY_ATTRIBUTES lpEventAttributes,
  1912. BOOL bManualReset,
  1913. BOOL bInitialState,
  1914. LPCWSTR lpName
  1915. )
  1916. {
  1917. HANDLE ret;
  1918. if (g_fWideWrap_Unicode)
  1919. {
  1920. ret = CreateEventW( lpEventAttributes,
  1921. bManualReset,
  1922. bInitialState,
  1923. lpName );
  1924. return ret;
  1925. }
  1926. XArray<CHAR> xszName;
  1927. BOOL fOk = ConvertWideCharToMultiByte( lpName, xszName );
  1928. if ( !fOk )
  1929. {
  1930. SetLastError( ERROR_OUTOFMEMORY );
  1931. return 0;
  1932. }
  1933. ret = CreateEventA(lpEventAttributes, bManualReset, bInitialState, xszName.Get() );
  1934. return ret;
  1935. }
  1936. HANDLE
  1937. WINAPI
  1938. CreateMutexX(
  1939. LPSECURITY_ATTRIBUTES lpEventAttributes,
  1940. BOOL bInitialOwner,
  1941. LPCWSTR lpName
  1942. )
  1943. {
  1944. HANDLE ret;
  1945. if (g_fWideWrap_Unicode)
  1946. {
  1947. ret = CreateMutexW( lpEventAttributes,
  1948. bInitialOwner,
  1949. lpName );
  1950. return ret;
  1951. }
  1952. XArray<CHAR> xszName;
  1953. BOOL fOk = ConvertWideCharToMultiByte( lpName, xszName );
  1954. if ( !fOk )
  1955. {
  1956. SetLastError( ERROR_OUTOFMEMORY );
  1957. return 0;
  1958. }
  1959. ret = CreateMutexA(lpEventAttributes,bInitialOwner, xszName.Get() );
  1960. return ret;
  1961. }
  1962. #if 0
  1963. UINT
  1964. WINAPI
  1965. GetDriveTypeX(
  1966. LPCWSTR lpRootPathName
  1967. )
  1968. {
  1969. #ifdef DEBUG_OUTPUT
  1970. OutputDebugString("GetDriveType\n");
  1971. #endif
  1972. LPSTR sz;
  1973. UINT ret;
  1974. sz = ConvertOem(lpRootPathName);
  1975. if (sz == ERR)
  1976. {
  1977. return 0;
  1978. }
  1979. ret = GetDriveTypeA(sz);
  1980. if (sz)
  1981. FREE(sz);
  1982. return ret;
  1983. }
  1984. DWORD
  1985. WINAPI
  1986. GetFileAttributesX(
  1987. LPCWSTR lpFileName
  1988. )
  1989. {
  1990. #ifdef DEBUG_OUTPUT
  1991. OutputDebugString("GetFileAttributes\n");
  1992. #endif
  1993. LPSTR sz;
  1994. DWORD ret;
  1995. sz = ConvertOem(lpFileName);
  1996. if (sz == ERR)
  1997. return 0xFFFFFFFF;
  1998. ret = GetFileAttributesA(sz);
  1999. if (sz)
  2000. FREE(sz);
  2001. return ret;
  2002. }
  2003. #endif
  2004. LONG
  2005. APIENTRY
  2006. RegEnumKeyX(
  2007. HKEY hKey,
  2008. DWORD dwIndex,
  2009. LPWSTR lpName,
  2010. DWORD cbName
  2011. )
  2012. {
  2013. LONG ret;
  2014. if (g_fWideWrap_Unicode)
  2015. {
  2016. ret = RegEnumKeyW( hKey,
  2017. dwIndex,
  2018. lpName,
  2019. cbName );
  2020. return ret;
  2021. }
  2022. CHAR sz[MAX_PATH+1];
  2023. //
  2024. // Return lengths do not include zero char.
  2025. //
  2026. Assert( cbName <= MAX_PATH + 1 );
  2027. ret = RegEnumKeyA(hKey, dwIndex, sz, cbName);
  2028. if (ret == ERROR_SUCCESS)
  2029. {
  2030. XArray<WCHAR> xwszName;
  2031. BOOL fOk = ConvertMultiByteToWideChar( sz, xwszName );
  2032. if ( !fOk )
  2033. return ERROR_OUTOFMEMORY;
  2034. if ( lstrlenX(xwszName.Get()) < cbName)
  2035. {
  2036. lstrcpyX( lpName, xwszName.Get() );
  2037. }
  2038. else
  2039. return ERROR_MORE_DATA;
  2040. }
  2041. return ret;
  2042. }
  2043. #if 0
  2044. LONG
  2045. APIENTRY
  2046. RegEnumValueX(
  2047. HKEY hkey,
  2048. DWORD dwIndex,
  2049. LPWSTR wszName,
  2050. LPDWORD pcbName,
  2051. LPDWORD pReserved,
  2052. LPDWORD ptype,
  2053. LPBYTE pValue,
  2054. LPDWORD pcbValue)
  2055. {
  2056. #ifdef DEBUG_OUTPUT
  2057. OutputDebugString("RegEnumValue\n");
  2058. #endif
  2059. // CHAR szName[KEY_LEN+1];
  2060. CHAR szName[MAX_PATH+1]; // reiview this length
  2061. LONG ret;
  2062. DWORD dwGivenSize= *pcbName;
  2063. Win4Assert(dwGivenSize <= MAX_PATH+1);
  2064. //
  2065. // Return lengths do not include zero char.
  2066. //
  2067. ret = RegEnumValueA(hkey, dwIndex, szName, pcbName, pReserved, ptype, pValue, pcbValue);
  2068. if (ret == ERROR_SUCCESS)
  2069. {
  2070. AnsiToUnicode(wszName, szName, dwGivenSize);
  2071. }
  2072. return ret;
  2073. }
  2074. HFINDFILE
  2075. WINAPI
  2076. FindFirstFileX(
  2077. LPCWSTR lpFileName,
  2078. LPWIN32_FIND_DATAW pwszFd
  2079. )
  2080. {
  2081. #ifdef DEBUG_OUTPUT
  2082. OutputDebugString("FindFirstFile\n");
  2083. #endif
  2084. WIN32_FIND_DATAA fd;
  2085. CHAR sz[MAX_PATH * 2];
  2086. HFINDFILE ret;
  2087. int len = lstrlenX(lpFileName) + 1;
  2088. UnicodeToAnsiOem(sz, lpFileName, sizeof(sz));
  2089. ret = FindFirstFileA(sz, &fd);
  2090. if (ret != INVALID_HANDLE_VALUE)
  2091. {
  2092. memcpy(pwszFd, &fd, sizeof(FILETIME)*3 + sizeof(DWORD)*5);
  2093. AnsiToUnicodeOem(pwszFd->cFileName, fd.cFileName,
  2094. lstrlenA(fd.cFileName) + 1);
  2095. AnsiToUnicodeOem(pwszFd->cAlternateFileName, fd.cAlternateFileName,
  2096. 14);
  2097. }
  2098. return ret;
  2099. }
  2100. #endif
  2101. //+---------------------------------------------------------------------------
  2102. //
  2103. // Function: wsprintfX
  2104. //
  2105. // Synopsis: internal implementation of wsprintf
  2106. //
  2107. // Arguments: [pwszOut] --
  2108. // [pwszFormat] --
  2109. // [...] --
  2110. //
  2111. // Returns: size of string.
  2112. //
  2113. // History: 26-Aug-98 Rogerg
  2114. //
  2115. //
  2116. //----------------------------------------------------------------------------
  2117. #ifndef _M_ALPHA
  2118. int WINAPIV wsprintfX(LPWSTR pwszOut, LPCWSTR pwszFormat, ...)
  2119. {
  2120. va_list arglist;
  2121. LPCWSTR pwszFmtPos;
  2122. LPWSTR pwszBufPos;
  2123. ULONG cbSkipLen;
  2124. // need to loop through format pushing items into the out buffer.
  2125. // Then use the out buffer string as what is actually passed to
  2126. // the real API.
  2127. pwszFmtPos = pwszFormat;
  2128. pwszBufPos = pwszOut;
  2129. va_start(arglist, pwszFormat);
  2130. while (*pwszFmtPos) {
  2131. cbSkipLen = 0;
  2132. if (*(pwszFmtPos) == '%')
  2133. {
  2134. switch (*(pwszFmtPos + 1))
  2135. {
  2136. case 'l':
  2137. {
  2138. Assert('u' == *(pwszFmtPos + 2));
  2139. cbSkipLen = 3; // go ahead and skip %lu
  2140. //fall through
  2141. }
  2142. case 'u':
  2143. {
  2144. DWORD dw = va_arg(arglist,ULONG);
  2145. _ltow(dw, pwszBufPos, 10 );
  2146. pwszBufPos += lstrlenX(pwszBufPos);
  2147. if (0 == cbSkipLen)
  2148. {
  2149. cbSkipLen = 2; // if no %lu case, skip %u
  2150. }
  2151. break;
  2152. }
  2153. case 'w':
  2154. {
  2155. Assert('s' == *(pwszFmtPos + 2));
  2156. cbSkipLen = 3; // go ahead and skip %ws
  2157. // fall through
  2158. }
  2159. case 's':
  2160. {
  2161. DWORD cch;
  2162. WCHAR *pwsz = va_arg(arglist, LPWSTR);
  2163. if (0 == cbSkipLen)
  2164. {
  2165. cbSkipLen = 2; // if no %ws case, skip %s
  2166. }
  2167. Assert(pwsz);
  2168. if (pwsz)
  2169. {
  2170. cch = lstrlenX(pwsz);
  2171. lstrcpynX(pwszBufPos,pwsz,cch);
  2172. pwszBufPos += cch;
  2173. }
  2174. break;
  2175. }
  2176. case 'd':
  2177. {
  2178. DWORD dw = va_arg(arglist,long);
  2179. _itow(dw, pwszBufPos, 10 );
  2180. pwszBufPos += lstrlenX(pwszBufPos);
  2181. cbSkipLen = 2; // go ahead and skip %d
  2182. break;
  2183. }
  2184. default:
  2185. AssertSz(0,"Uknown % passed to wsprintf");
  2186. break;
  2187. }
  2188. }
  2189. if (cbSkipLen)
  2190. {
  2191. pwszFmtPos += cbSkipLen;
  2192. }
  2193. else
  2194. {
  2195. *pwszBufPos = *pwszFmtPos;
  2196. *pwszBufPos++;
  2197. *pwszFmtPos++;
  2198. }
  2199. }
  2200. *pwszBufPos = NULL; // terminate the string.
  2201. return lstrlenX(pwszOut);
  2202. }
  2203. #endif // #ifndef _M_ALPHA
  2204. BOOL
  2205. WINAPI
  2206. GetComputerNameX(
  2207. LPWSTR pwszName,
  2208. LPDWORD lpcchBuffer
  2209. )
  2210. {
  2211. BOOL ret;
  2212. if (g_fWideWrap_Unicode)
  2213. {
  2214. ret = GetComputerNameW( pwszName, lpcchBuffer );
  2215. return ret;
  2216. }
  2217. DWORD OldSize = *lpcchBuffer;
  2218. XArray<CHAR> xszNameIn;
  2219. BOOL fOk = xszNameIn.Init( OldSize );
  2220. if ( !fOk )
  2221. {
  2222. SetLastError( ERROR_OUTOFMEMORY );
  2223. return 0;
  2224. }
  2225. ret = GetComputerNameA( xszNameIn.Get(), lpcchBuffer );
  2226. if ( ret == 0 )
  2227. return ret;
  2228. XArray<WCHAR> xwszNameOut;
  2229. fOk = ConvertMultiByteToWideChar( xszNameIn.Get(), xwszNameOut );
  2230. if ( !fOk )
  2231. {
  2232. SetLastError( ERROR_OUTOFMEMORY );
  2233. return 0;
  2234. }
  2235. *lpcchBuffer = lstrlenX( xwszNameOut.Get() );
  2236. if ( *lpcchBuffer < OldSize - 1 )
  2237. {
  2238. lstrcpyX( pwszName, xwszNameOut.Get() );
  2239. return ret;
  2240. }
  2241. else
  2242. {
  2243. SetLastError( ERROR_MORE_DATA );
  2244. return 0;
  2245. }
  2246. }
  2247. LRESULT
  2248. DefWindowProcX(
  2249. HWND hWnd,
  2250. UINT Msg,
  2251. WPARAM wParam,
  2252. LPARAM lParam)
  2253. {
  2254. if (g_fWideWrap_Unicode)
  2255. {
  2256. return DefWindowProcW(hWnd,Msg,wParam,lParam);
  2257. }
  2258. else
  2259. {
  2260. return DefWindowProcA(hWnd,Msg,wParam,lParam);
  2261. }
  2262. }
  2263. #if 0
  2264. DWORD
  2265. WINAPI
  2266. GetFullPathNameX(
  2267. LPCWSTR lpFileName,
  2268. DWORD cchBuffer,
  2269. LPWSTR lpPathBuffer,
  2270. LPWSTR *lppFilePart
  2271. )
  2272. {
  2273. #ifdef DEBUG_OUTPUT
  2274. OutputDebugString("GetFullPathName\n");
  2275. #endif
  2276. LPSTR szFileName;
  2277. CHAR szPathBuffer[MAX_PATH];
  2278. LPSTR szFilePart;
  2279. DWORD ret;
  2280. szFileName = ConvertOem(lpFileName);
  2281. if (szFileName == ERR)
  2282. return 0;
  2283. ret = GetFullPathNameA(szFileName, cchBuffer, szPathBuffer, &szFilePart);
  2284. AnsiToUnicodeOem(lpPathBuffer, szPathBuffer, cchBuffer);
  2285. *lppFilePart = lpPathBuffer + (szFilePart - szPathBuffer);
  2286. if (szFileName)
  2287. FREE( szFileName);
  2288. return ret;
  2289. }
  2290. DWORD
  2291. WINAPI
  2292. GetShortPathNameX(
  2293. LPCWSTR lpszFullPath,
  2294. LPWSTR lpszShortPath,
  2295. DWORD cchBuffer
  2296. )
  2297. {
  2298. #ifdef DEBUG_OUTPUT
  2299. OutputDebugString("GetShortPathName\n");
  2300. #endif
  2301. LPSTR szFullPath;
  2302. CHAR szShortBuffer[MAX_PATH];
  2303. DWORD ret;
  2304. szFullPath = Convert(lpszFullPath);
  2305. if (szFullPath == ERR)
  2306. return 0;
  2307. if (lpszShortPath == NULL)
  2308. {
  2309. ret = GetShortPathNameA(szFullPath, NULL, cchBuffer);
  2310. }
  2311. else
  2312. {
  2313. ret = GetShortPathNameA(szFullPath, szShortBuffer, sizeof(szShortBuffer));
  2314. if (ret != 0)
  2315. {
  2316. //
  2317. // Only convert the actual data, not the whole buffer.
  2318. //
  2319. if (cchBuffer > ret + 1)
  2320. cchBuffer = ret + 1;
  2321. AnsiToUnicode(lpszShortPath, szShortBuffer, cchBuffer);
  2322. }
  2323. }
  2324. FREE( szFullPath);
  2325. return ret;
  2326. }
  2327. #endif
  2328. DWORD
  2329. WINAPI
  2330. SearchPathX(
  2331. LPCWSTR lpPath,
  2332. LPCWSTR lpFileName,
  2333. LPCWSTR lpExtension,
  2334. DWORD nBufferLength,
  2335. LPWSTR lpBuffer,
  2336. LPWSTR *lpFilePart
  2337. )
  2338. {
  2339. DWORD ret;
  2340. if (g_fWideWrap_Unicode)
  2341. {
  2342. ret = SearchPathW( lpPath,
  2343. lpFileName,
  2344. lpExtension,
  2345. nBufferLength,
  2346. lpBuffer,
  2347. lpFilePart );
  2348. return ret;
  2349. }
  2350. LPSTR lpszFileName;
  2351. CHAR szBuffer[MAX_PATH];
  2352. XArray<CHAR> xszFileName;
  2353. BOOL fOk = ConvertWideCharToMultiByte( lpFileName, xszFileName, TRUE );
  2354. if ( !fOk )
  2355. {
  2356. SetLastError( ERROR_OUTOFMEMORY );
  2357. return 0;
  2358. }
  2359. lpszFileName = xszFileName.Get();
  2360. ret = SearchPathA(NULL, lpszFileName, NULL, sizeof(szBuffer), szBuffer, NULL);
  2361. if ( ret == 0 )
  2362. return ret;
  2363. XArray<WCHAR> xwszBufOut;
  2364. fOk = ConvertMultiByteToWideChar( szBuffer, xwszBufOut, TRUE );
  2365. if ( !fOk )
  2366. {
  2367. SetLastError( ERROR_OUTOFMEMORY );
  2368. return FALSE;
  2369. }
  2370. if ( lstrlenX(xwszBufOut.Get()) < nBufferLength )
  2371. {
  2372. lstrcpyX( lpBuffer, xwszBufOut.Get() );
  2373. return ret;
  2374. }
  2375. else
  2376. {
  2377. SetLastError( ERROR_MORE_DATA );
  2378. return 0;
  2379. }
  2380. return ret;
  2381. }
  2382. #if 0
  2383. ATOM
  2384. WINAPI
  2385. GlobalFindAtomX(
  2386. LPCWSTR lpString
  2387. )
  2388. {
  2389. LPSTR lpszString;
  2390. ATOM retAtom;
  2391. #ifdef DEBUG_OUTPUT
  2392. OutputDebugString("GlobalFindAtom\n");
  2393. #endif
  2394. lpszString = Convert(lpString);
  2395. if (lpszString == ERR)
  2396. return 0;
  2397. retAtom = GlobalFindAtomA(lpszString);
  2398. FREE( lpszString);
  2399. return retAtom;
  2400. }
  2401. int
  2402. WINAPI
  2403. GetClassNameX(
  2404. HWND hWnd,
  2405. LPWSTR lpClassName,
  2406. int nMaxCount)
  2407. {
  2408. LPSTR lpszClassName = NULL;
  2409. int ret;
  2410. #ifdef DEBUG_OUTPUT
  2411. OutputDebugString("GetClassName\n");
  2412. #endif
  2413. lpszClassName = (CHAR *) ALLOC(nMaxCount);
  2414. if (lpszClassName == NULL)
  2415. {
  2416. SetLastError (ERROR_NOT_ENOUGH_MEMORY);
  2417. return 0;
  2418. }
  2419. ret = GetClassNameA(hWnd, lpszClassName, nMaxCount);
  2420. if (ret)
  2421. {
  2422. AnsiToUnicode(lpClassName, lpszClassName, lstrlenA(lpszClassName) + 1);
  2423. }
  2424. FREE( lpszClassName);
  2425. return ret;
  2426. }
  2427. LPWSTR
  2428. WINAPI
  2429. CharLowerX(
  2430. LPWSTR lpsz)
  2431. {
  2432. if (((DWORD)lpsz & 0xffff0000) == 0)
  2433. {
  2434. return (LPWSTR)towlower ((wchar_t)lpsz);
  2435. } else {
  2436. return _wcslwr (lpsz);
  2437. }
  2438. }
  2439. LPWSTR
  2440. WINAPI
  2441. CharUpperX(
  2442. LPWSTR lpsz)
  2443. {
  2444. if (((DWORD)lpsz & 0xffff0000) == 0)
  2445. {
  2446. return (LPWSTR)towupper ((wchar_t)lpsz);
  2447. } else {
  2448. return _wcsupr (lpsz);
  2449. }
  2450. }
  2451. BOOL
  2452. WINAPI
  2453. GetStringTypeX(
  2454. DWORD dwInfoType,
  2455. LPCWSTR lpSrcStr,
  2456. int cchSrc,
  2457. LPWORD lpCharType)
  2458. {
  2459. // Convert the source string to MBS. If we don't get the same number
  2460. // of characters, this algorithm doesn't work.
  2461. int OriginalLength = cchSrc == -1 ? lstrlenX (lpSrcStr) + 1 : cchSrc;
  2462. LPSTR lpConvertedString = (LPSTR) ALLOC(OriginalLength+1);
  2463. if (lpConvertedString == NULL)
  2464. {
  2465. SetLastError (ERROR_NOT_ENOUGH_MEMORY);
  2466. return FALSE;
  2467. }
  2468. if (WideCharToMultiByte (CP_ACP,
  2469. WC_COMPOSITECHECK,
  2470. lpSrcStr,
  2471. cchSrc,
  2472. lpConvertedString,
  2473. OriginalLength,
  2474. NULL,
  2475. NULL) != OriginalLength)
  2476. {
  2477. FREE( lpConvertedString);
  2478. SetLastError (ERROR_NO_UNICODE_TRANSLATION);
  2479. return FALSE;
  2480. }
  2481. BOOL Result;
  2482. Result = GetStringTypeA (GetThreadLocale (),
  2483. dwInfoType,
  2484. lpConvertedString,
  2485. OriginalLength,
  2486. lpCharType);
  2487. FREE( lpConvertedString);
  2488. return Result;
  2489. }
  2490. BOOL
  2491. WINAPI
  2492. IsCharAlphaX(
  2493. WCHAR ch)
  2494. {
  2495. return iswctype (ch, _UPPER | _LOWER);
  2496. }
  2497. BOOL
  2498. WINAPI
  2499. IsCharAlphaNumericX(
  2500. WCHAR ch)
  2501. {
  2502. return iswctype (ch, _UPPER | _LOWER | _DIGIT);
  2503. }
  2504. #endif
  2505. LPWSTR
  2506. WINAPI
  2507. lstrcatX(
  2508. LPWSTR lpString1,
  2509. LPCWSTR lpString2
  2510. )
  2511. {
  2512. LPWSTR lpDest = lpString1;
  2513. Assert(lpString1);
  2514. Assert(lpString2);
  2515. while (*lpDest) {
  2516. lpDest++;
  2517. }
  2518. while (*lpDest++ = *lpString2++) ;
  2519. return lpString1;
  2520. }
  2521. int
  2522. WINAPI
  2523. lstrcmpX(
  2524. LPCWSTR lpString1,
  2525. LPCWSTR lpString2
  2526. )
  2527. {
  2528. Assert(lpString1);
  2529. Assert(lpString2);
  2530. return wcscmp(lpString1, lpString2);
  2531. }
  2532. int
  2533. strnicmpX(
  2534. LPWSTR lpString1,
  2535. LPWSTR lpString2,
  2536. size_t count
  2537. )
  2538. {
  2539. int nRet = 0;
  2540. Assert(lpString1);
  2541. Assert(lpString2);
  2542. while (count-- &&
  2543. !(nRet = toupper(*lpString1)
  2544. - toupper(*lpString2)) &&
  2545. *lpString1)
  2546. {
  2547. lpString1++;
  2548. lpString2++;
  2549. }
  2550. return nRet;
  2551. }
  2552. LPWSTR
  2553. WINAPI
  2554. lstrcpyX(
  2555. LPWSTR lpString1,
  2556. LPCWSTR lpString2
  2557. )
  2558. {
  2559. LPWSTR lpDest = lpString1;
  2560. Assert(lpString1);
  2561. Assert(lpString2);
  2562. while( *lpDest++ = *lpString2++ )
  2563. ;
  2564. return lpString1;
  2565. }
  2566. LPWSTR
  2567. WINAPI
  2568. lstrcpynX(
  2569. LPWSTR lpString1,
  2570. LPCWSTR lpString2,
  2571. int iMaxLength
  2572. )
  2573. {
  2574. LPWSTR dst;
  2575. Assert(lpString1);
  2576. Assert(lpString2);
  2577. if (iMaxLength)
  2578. {
  2579. dst = lpString1;
  2580. while (iMaxLength && *lpString2)
  2581. {
  2582. *dst++ = *lpString2++;
  2583. iMaxLength--;
  2584. }
  2585. *dst = L'\0';
  2586. }
  2587. return lpString1;
  2588. }
  2589. int
  2590. WINAPI
  2591. lstrcmpiX(
  2592. LPCWSTR lpString1,
  2593. LPCWSTR lpString2
  2594. )
  2595. {
  2596. Assert(lpString1);
  2597. Assert(lpString2);
  2598. return _wcsicmp(lpString1, lpString2);
  2599. }
  2600. DWORD
  2601. WINAPI
  2602. lstrlenX(
  2603. LPCWSTR lpString
  2604. )
  2605. {
  2606. LPWSTR eos = (LPWSTR) lpString;
  2607. Assert(lpString)
  2608. if (!lpString)
  2609. return 0;
  2610. __try
  2611. {
  2612. while (*eos++);
  2613. }
  2614. __except (EXCEPTION_EXECUTE_HANDLER)
  2615. {
  2616. AssertSz(0,"Invalid String");
  2617. return 0;
  2618. }
  2619. return (int) (eos - lpString - 1);
  2620. }
  2621. BOOL
  2622. WINAPI
  2623. SetFileAttributesX(
  2624. LPCWSTR lpFileName,
  2625. DWORD dwFileAttributes
  2626. )
  2627. {
  2628. BOOL fReturn = FALSE;
  2629. if (g_fWideWrap_Unicode)
  2630. {
  2631. return SetFileAttributesW(lpFileName,dwFileAttributes);
  2632. }
  2633. else
  2634. {
  2635. XArray<CHAR> xszFileName;
  2636. BOOL fOk;
  2637. fOk = ConvertWideCharToMultiByte(lpFileName,xszFileName);
  2638. if ( !fOk )
  2639. {
  2640. SetLastError( ERROR_OUTOFMEMORY );
  2641. return 0;
  2642. }
  2643. fReturn = SetFileAttributesA(xszFileName.Get(),dwFileAttributes);
  2644. }
  2645. return fReturn;
  2646. }
  2647. int
  2648. WINAPI
  2649. MessageBoxX(
  2650. HWND hWnd,
  2651. LPCWSTR lpText,
  2652. LPCWSTR lpCaption,
  2653. UINT uType)
  2654. {
  2655. int iReturn = 0; // MessageBox returns 0 if fails because out of memory
  2656. if (g_fWideWrap_Unicode)
  2657. {
  2658. return MessageBoxW(hWnd,lpText,lpCaption,uType);
  2659. }
  2660. else
  2661. {
  2662. XArray<CHAR> xszText;
  2663. XArray<CHAR> xszCaption;
  2664. BOOL fOkText,fOkCaption;
  2665. Assert(lpText && lpCaption);
  2666. fOkText = ConvertWideCharToMultiByte(lpText,xszText);
  2667. fOkCaption = ConvertWideCharToMultiByte(lpCaption,xszCaption);
  2668. if (!fOkText || !fOkCaption)
  2669. {
  2670. SetLastError( ERROR_OUTOFMEMORY );
  2671. return 0;
  2672. }
  2673. iReturn = MessageBoxA(hWnd,xszText.Get(),xszCaption.Get(),uType);
  2674. }
  2675. return iReturn;
  2676. }
  2677. #if 0
  2678. HANDLE
  2679. WINAPI
  2680. CreateFileMappingX(
  2681. HANDLE hFile,
  2682. LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  2683. DWORD flProtect,
  2684. DWORD dwMaximumSizeHigh,
  2685. DWORD dwMaximumSizeLow,
  2686. LPCWSTR lpName
  2687. )
  2688. {
  2689. LPSTR lpszAName=NULL;
  2690. HANDLE ret;
  2691. #ifdef DEBUG_OUTPUT
  2692. OutputDebugString("CreateFileMapping\n");
  2693. #endif
  2694. lpszAName = Convert(lpName);
  2695. if (lpszAName == ERR)
  2696. {
  2697. return 0;
  2698. }
  2699. ret = CreateFileMappingA(
  2700. hFile,
  2701. lpFileMappingAttributes,
  2702. flProtect,
  2703. dwMaximumSizeHigh,
  2704. dwMaximumSizeLow,
  2705. lpszAName);
  2706. if(NULL != lpszAName)
  2707. FREE( lpszAName);
  2708. return ret;
  2709. }
  2710. HANDLE
  2711. WINAPI
  2712. OpenFileMappingX(
  2713. DWORD dwDesiredAccess,
  2714. BOOL bInheritHandle,
  2715. LPCWSTR lpName
  2716. )
  2717. {
  2718. LPSTR lpszAName=NULL;
  2719. HANDLE ret;
  2720. #ifdef DEBUG_OUTPUT
  2721. OutputDebugString("CreateFileMapping\n");
  2722. #endif
  2723. lpszAName = Convert(lpName);
  2724. if (lpszAName == ERR)
  2725. {
  2726. return 0;
  2727. }
  2728. ret = OpenFileMappingA(
  2729. dwDesiredAccess,
  2730. bInheritHandle,
  2731. lpszAName);
  2732. if(NULL != lpszAName)
  2733. FREE( lpszAName);
  2734. return ret;
  2735. }
  2736. #endif
  2737. DWORD_PTR
  2738. WINAPI
  2739. SHGetFileInfoX(
  2740. LPCWSTR pszPath,
  2741. DWORD dwFileAttributes,
  2742. SHFILEINFOW FAR *psfi,
  2743. UINT cbFileInfo,
  2744. UINT uFlags)
  2745. {
  2746. DWORD_PTR dw = 0;
  2747. LoadShell32Dll();
  2748. if (g_fWideWrap_Unicode && g_pfShGetFileInfoW)
  2749. {
  2750. dw = g_pfShGetFileInfoW( pszPath,
  2751. dwFileAttributes,
  2752. psfi,
  2753. cbFileInfo,
  2754. uFlags );
  2755. return dw;
  2756. }
  2757. if (NULL == g_pfShGetFileInfoA)
  2758. {
  2759. Assert(g_pfShGetFileInfoA); // should always have the ansi export
  2760. return 0;
  2761. }
  2762. XArray<CHAR> xszPath;
  2763. BOOL fOk = ConvertWideCharToMultiByte( pszPath, xszPath, TRUE );
  2764. if ( !fOk )
  2765. {
  2766. SetLastError( ERROR_OUTOFMEMORY );
  2767. return 0;
  2768. }
  2769. SHFILEINFOA sfi;
  2770. Assert(cbFileInfo == sizeof(SHFILEINFOW));
  2771. Assert(psfi);
  2772. memset(&sfi, 0, sizeof(sfi));
  2773. dw = g_pfShGetFileInfoA( xszPath.Get(), dwFileAttributes, &sfi, sizeof(sfi), uFlags);
  2774. if (dw)
  2775. {
  2776. psfi->hIcon = sfi.hIcon;
  2777. psfi->iIcon = sfi.iIcon;
  2778. psfi->dwAttributes = sfi.dwAttributes;
  2779. XArray<WCHAR> xwszDisplay;
  2780. fOk = ConvertMultiByteToWideChar( sfi.szDisplayName, xwszDisplay, TRUE );
  2781. if ( !fOk )
  2782. {
  2783. SetLastError( ERROR_OUTOFMEMORY );
  2784. return 0;
  2785. }
  2786. XArray<WCHAR> xwszType;
  2787. fOk = ConvertMultiByteToWideChar( sfi.szTypeName, xwszType, TRUE );
  2788. if ( !fOk )
  2789. {
  2790. SetLastError( ERROR_OUTOFMEMORY );
  2791. return 0;
  2792. }
  2793. if ( lstrlenX(xwszDisplay.Get()) < ARRAY_SIZE(psfi->szDisplayName)
  2794. && lstrlenX(xwszType.Get()) < ARRAY_SIZE(psfi->szTypeName) )
  2795. {
  2796. lstrcpyX( psfi->szDisplayName, xwszDisplay.Get() );
  2797. lstrcpyX( psfi->szTypeName, xwszType.Get() );
  2798. return dw;
  2799. }
  2800. else
  2801. return 0;
  2802. }
  2803. return 0;
  2804. }
  2805. HICON LoadIconX(
  2806. HINSTANCE hInstance,
  2807. LPCWSTR lpIconName
  2808. )
  2809. {
  2810. Assert(0 == HIWORD(lpIconName)); // only support resource IDs
  2811. return LoadIconA(hInstance,(LPSTR) lpIconName);
  2812. }
  2813. HCURSOR LoadCursorX(
  2814. HINSTANCE hInstance,
  2815. LPCWSTR lpCursorName
  2816. )
  2817. {
  2818. Assert(0 == HIWORD(lpCursorName)); // only support resource IDs
  2819. return LoadCursorA(hInstance,(LPSTR) lpCursorName);
  2820. }
  2821. HANDLE LoadImageX(
  2822. HINSTANCE hinst,
  2823. LPCWSTR lpszName,
  2824. UINT uType,
  2825. int cxDesired,
  2826. int cyDesired,
  2827. UINT fuLoad
  2828. )
  2829. {
  2830. HANDLE hReturn = NULL;
  2831. if (g_fWideWrap_Unicode)
  2832. {
  2833. return LoadImageW(hinst,lpszName,uType,cxDesired,cyDesired,fuLoad);
  2834. }
  2835. else
  2836. {
  2837. XArray<CHAR> xszName;
  2838. LPSTR pszNameA;
  2839. BOOL fOk = TRUE;
  2840. Assert(lpszName);
  2841. if (0 == HIWORD(lpszName))
  2842. {
  2843. pszNameA = (LPSTR) lpszName;
  2844. }
  2845. else
  2846. {
  2847. fOk = ConvertWideCharToMultiByte(lpszName,xszName);
  2848. if (!fOk)
  2849. {
  2850. SetLastError(E_OUTOFMEMORY);
  2851. return NULL;
  2852. }
  2853. pszNameA = xszName.Get();
  2854. }
  2855. hReturn = LoadImageA(hinst,pszNameA,uType,cxDesired,cyDesired,fuLoad);
  2856. }
  2857. return hReturn;
  2858. }
  2859. HRSRC FindResourceX(
  2860. HMODULE hModule,
  2861. LPCWSTR lpName,
  2862. LPCWSTR lpType
  2863. )
  2864. {
  2865. HRSRC hResult = NULL;
  2866. if (g_fWideWrap_Unicode)
  2867. {
  2868. return FindResourceW(hModule,lpName,lpType);
  2869. }
  2870. else
  2871. {
  2872. XArray<CHAR> xszName;
  2873. XArray<CHAR> xszType;
  2874. LPSTR pszNameA,pszTypeA;
  2875. BOOL fOkName = TRUE,fOkType = TRUE;
  2876. Assert(lpType && lpName);
  2877. // if hiword is zero it is an ID
  2878. if (0 == HIWORD(lpName))
  2879. {
  2880. pszNameA = (LPSTR) lpName;
  2881. }
  2882. else
  2883. {
  2884. fOkName = ConvertWideCharToMultiByte(lpName,xszName);
  2885. }
  2886. if (0 == HIWORD(lpType))
  2887. {
  2888. pszTypeA = (LPSTR) lpType;
  2889. }
  2890. else
  2891. {
  2892. fOkType = ConvertWideCharToMultiByte(lpType,xszType);
  2893. }
  2894. if (!fOkName || !fOkType)
  2895. {
  2896. SetLastError(E_OUTOFMEMORY);
  2897. return NULL;
  2898. }
  2899. hResult = FindResourceA(hModule,pszNameA,pszTypeA);
  2900. }
  2901. return hResult;
  2902. }
  2903. BOOL
  2904. WINAPI
  2905. Shell_NotifyIconX(
  2906. DWORD dwMessage,
  2907. PNOTIFYICONDATAW lpData)
  2908. {
  2909. BOOL fResult = FALSE;
  2910. LoadShell32Dll();
  2911. if (g_fWideWrap_Unicode && g_pfShell_NotifyIconW)
  2912. {
  2913. fResult = g_pfShell_NotifyIconW( dwMessage, lpData );
  2914. return fResult;
  2915. }
  2916. if (NULL == g_pfShell_NotifyIconA)
  2917. {
  2918. Assert(g_pfShell_NotifyIconA); // should always have the ansi export
  2919. return FALSE;
  2920. }
  2921. NOTIFYICONDATAA DataA;
  2922. DataA.cbSize = sizeof(NOTIFYICONDATAA);
  2923. DataA.hWnd = lpData->hWnd;
  2924. DataA.uID = lpData->uID;
  2925. DataA.uFlags = lpData->uFlags;
  2926. DataA.uCallbackMessage = lpData->uCallbackMessage;
  2927. DataA.hIcon = lpData->hIcon;
  2928. *DataA.szTip = '\0';
  2929. if (DataA.uFlags & NIF_TIP)
  2930. {
  2931. XArray<CHAR> xszTip;
  2932. BOOL fOk = ConvertWideCharToMultiByte( lpData->szTip, xszTip );
  2933. if ( !fOk )
  2934. {
  2935. SetLastError( ERROR_OUTOFMEMORY );
  2936. return FALSE;
  2937. }
  2938. ULONG ccLen = lstrlenA( xszTip.Get() );
  2939. if ( ccLen >= ARRAY_SIZE(DataA.szTip) )
  2940. ccLen = ARRAY_SIZE(DataA.szTip) - 1;
  2941. strncpy( DataA.szTip, xszTip.Get(), ccLen+1 );
  2942. }
  2943. fResult = g_pfShell_NotifyIconA(dwMessage,&DataA);
  2944. return fResult;
  2945. }
  2946. // helper function for sending listview item messages
  2947. BOOL ListView_SendItemMessage(HWND hwnd,UINT MsgW,UINT MsgA,LV_ITEMW *pItem,
  2948. BOOL fInParam,BOOL fOutParam)
  2949. {
  2950. BOOL fReturn = FALSE;
  2951. if (g_fWideWrap_Unicode /* ListView_GetUnicodeFormat(hwnd) */)
  2952. {
  2953. fReturn = (BOOL)SendMessageW((hwnd), MsgW, 0, (LPARAM)(LV_ITEMW FAR*)(pItem));
  2954. }
  2955. else
  2956. {
  2957. LV_ITEMA itemA;
  2958. Assert(sizeof(LV_ITEMA) == sizeof(LV_ITEMW))
  2959. memcpy(&itemA,pItem,sizeof(LV_ITEMA));
  2960. DWORD dwOldSize = pItem->cchTextMax;
  2961. BOOL fOk;
  2962. XArray<CHAR> xszText;
  2963. if ((itemA.mask & LVIF_TEXT) && (LPSTR_TEXTCALLBACKA != itemA.pszText))
  2964. {
  2965. itemA.pszText = NULL;
  2966. if (fInParam)
  2967. {
  2968. fOk = ConvertWideCharToMultiByte( pItem->pszText, xszText );
  2969. if ( !fOk )
  2970. {
  2971. SetLastError( ERROR_OUTOFMEMORY );
  2972. return FALSE;
  2973. }
  2974. itemA.pszText = xszText.Get();
  2975. itemA.cchTextMax = lstrlenA(itemA.pszText) + 1;
  2976. }
  2977. else
  2978. {
  2979. fOk = xszText.Init( itemA.cchTextMax );
  2980. if ( !fOk )
  2981. {
  2982. SetLastError( ERROR_OUTOFMEMORY );
  2983. return FALSE;
  2984. }
  2985. itemA.pszText = xszText.Get();
  2986. }
  2987. }
  2988. if (itemA.pszText || !(itemA.mask & LVIF_TEXT) )
  2989. {
  2990. fReturn = (BOOL)SendMessageA((hwnd), MsgA, 0, (LPARAM)(LV_ITEMA FAR*)(&itemA));
  2991. if (fOutParam && fReturn)
  2992. {
  2993. LPWSTR pszTextW = pItem->pszText;
  2994. memcpy(pItem,&itemA,sizeof(LV_ITEMA));
  2995. pItem->pszText = pszTextW;
  2996. if ( (itemA.mask & LVIF_TEXT) )
  2997. {
  2998. XArray<WCHAR> xwszTextOut;
  2999. fOk = ConvertMultiByteToWideChar( itemA.pszText, xwszTextOut );
  3000. if ( !fOk )
  3001. {
  3002. SetLastError( ERROR_OUTOFMEMORY );
  3003. return FALSE;
  3004. }
  3005. if ( lstrlenX(xwszTextOut.Get()) >= dwOldSize )
  3006. return FALSE;
  3007. lstrcpyX( pItem->pszText, xwszTextOut.Get() );
  3008. }
  3009. }
  3010. }
  3011. }
  3012. return fReturn;
  3013. }
  3014. BOOL
  3015. ListView_GetItemX(
  3016. HWND hwnd,
  3017. LV_ITEM * pitem)
  3018. {
  3019. return ListView_SendItemMessage(hwnd,LVM_GETITEMW,LVM_GETITEMA,pitem,FALSE,TRUE);
  3020. }
  3021. BOOL
  3022. ListView_SetItemX(
  3023. HWND hwnd,
  3024. LV_ITEM * pitem)
  3025. {
  3026. return ListView_SendItemMessage(hwnd,LVM_SETITEMW,LVM_SETITEMA,pitem,TRUE,FALSE);
  3027. }
  3028. BOOL
  3029. ListView_InsertItemX(
  3030. HWND hwnd,
  3031. LV_ITEM * pitem)
  3032. {
  3033. return ListView_SendItemMessage(hwnd,LVM_INSERTITEMW,LVM_INSERTITEMA,pitem,TRUE,FALSE);
  3034. }
  3035. // helper function for sending listview column messages
  3036. BOOL ListView_SendColumnMessage(HWND hwnd,int iCol,UINT MsgW,UINT MsgA,LV_COLUMN *pColumn,
  3037. BOOL fInParam,BOOL fOutParam,BOOL fReturnsIndex)
  3038. {
  3039. BOOL fReturn = FALSE;
  3040. if (g_fWideWrap_Unicode /* ListView_GetUnicodeFormat(hwnd) */)
  3041. {
  3042. fReturn = (BOOL)SendMessageW((hwnd), MsgW, iCol, (LPARAM)(LV_COLUMNW FAR*)(pColumn));
  3043. }
  3044. else
  3045. {
  3046. LV_COLUMNA ColumnA;
  3047. Assert(sizeof(LV_COLUMNA) == sizeof(LV_COLUMNW))
  3048. memcpy(&ColumnA,pColumn,sizeof(LV_COLUMNA));
  3049. ColumnA.pszText = NULL;
  3050. DWORD dwOldSize = pColumn->cchTextMax;
  3051. BOOL fOk;
  3052. XArray<CHAR> xszText;
  3053. if (ColumnA.mask & LVCF_TEXT)
  3054. {
  3055. if (fInParam)
  3056. {
  3057. fOk = ConvertWideCharToMultiByte( pColumn->pszText, xszText );
  3058. if ( !fOk )
  3059. {
  3060. SetLastError( ERROR_OUTOFMEMORY );
  3061. return FALSE;
  3062. }
  3063. ColumnA.pszText = xszText.Get();
  3064. ColumnA.cchTextMax = lstrlenA(ColumnA.pszText) + 1;
  3065. }
  3066. else
  3067. {
  3068. fOk = xszText.Init( ColumnA.cchTextMax );
  3069. if ( !fOk )
  3070. {
  3071. SetLastError( ERROR_OUTOFMEMORY );
  3072. return FALSE;
  3073. }
  3074. ColumnA.pszText = xszText.Get();
  3075. }
  3076. }
  3077. if (ColumnA.pszText || !(ColumnA.mask & LVCF_TEXT))
  3078. {
  3079. fReturn = (BOOL)SendMessageA((hwnd), MsgA,iCol, (LPARAM)(LV_COLUMNA FAR*)(&ColumnA));
  3080. if ( ((fReturnsIndex && fReturn != -1)
  3081. || (fReturn && !fReturnsIndex)) && fOutParam)
  3082. {
  3083. LPWSTR pszTextW = pColumn->pszText;
  3084. memcpy(pColumn,&ColumnA,sizeof(LV_COLUMNA));
  3085. pColumn->pszText = pszTextW;
  3086. if (ColumnA.mask & LVCF_TEXT)
  3087. {
  3088. XArray<WCHAR> xwszTextOut;
  3089. fOk = ConvertMultiByteToWideChar( ColumnA.pszText, xwszTextOut );
  3090. if ( !fOk )
  3091. {
  3092. SetLastError( ERROR_OUTOFMEMORY );
  3093. return FALSE;
  3094. }
  3095. if ( lstrlenX(xwszTextOut.Get()) >= dwOldSize )
  3096. return FALSE;
  3097. lstrcpyX( pColumn->pszText, xwszTextOut.Get() );
  3098. }
  3099. }
  3100. }
  3101. }
  3102. return fReturn;
  3103. }
  3104. BOOL
  3105. ListView_SetColumnX(
  3106. HWND hwnd,
  3107. int iCol,
  3108. LV_COLUMN * pColumn)
  3109. {
  3110. return ListView_SendColumnMessage(hwnd,iCol,LVM_SETCOLUMNW,LVM_SETCOLUMNA,pColumn,TRUE,FALSE,FALSE);
  3111. }
  3112. int
  3113. ListView_InsertColumnX(
  3114. HWND hwnd,
  3115. int iCol,
  3116. LV_COLUMN * pColumn)
  3117. {
  3118. return ListView_SendColumnMessage(hwnd,iCol,LVM_INSERTCOLUMNW,LVM_INSERTCOLUMNA,pColumn,TRUE,FALSE,TRUE);
  3119. }
  3120. HPROPSHEETPAGE
  3121. WINAPI CreatePropertySheetPageX(LPCPROPSHEETPAGEW ppsh)
  3122. {
  3123. HPROPSHEETPAGE fhReturn = NULL;
  3124. if (g_fWideWrap_Unicode)
  3125. {
  3126. fhReturn = CreatePropertySheetPageW(ppsh);
  3127. }
  3128. else
  3129. {
  3130. // only support pages that don't have any strings to convert
  3131. Assert(sizeof(LPCPROPSHEETPAGEW) == sizeof(LPCPROPSHEETPAGEA));
  3132. Assert(0 == HIWORD(ppsh->pszTemplate));
  3133. Assert(0 == HIWORD(ppsh->pszIcon));
  3134. Assert(0 == HIWORD(ppsh->pszTitle));
  3135. Assert(NULL == ppsh->pszHeaderTitle); // these aren't defined in _WIN32_IE < 0x0400
  3136. Assert(NULL == ppsh->pszHeaderSubTitle);
  3137. // since not strings can call Ansi version
  3138. fhReturn = CreatePropertySheetPageA((LPCPROPSHEETPAGEA) ppsh);
  3139. }
  3140. return fhReturn;
  3141. }
  3142. INT_PTR
  3143. WINAPI PropertySheetX(
  3144. LPCPROPSHEETHEADERW ppsh)
  3145. {
  3146. INT_PTR piReturn = -1;
  3147. // don't support passing in an array or property sheet structures
  3148. // or loading the icon
  3149. Assert(!(ppsh->dwFlags & PSH_PROPSHEETPAGE));
  3150. Assert(!(ppsh->dwFlags & PSH_USEICONID));
  3151. if (g_fWideWrap_Unicode)
  3152. {
  3153. piReturn = PropertySheetW(ppsh);
  3154. }
  3155. else
  3156. {
  3157. PROPSHEETHEADERA pshA;
  3158. Assert(sizeof(PROPSHEETHEADERA) == sizeof(PROPSHEETHEADERW));
  3159. memcpy(&pshA,ppsh,sizeof(pshA));
  3160. // if have a title an not a resource id allocate a string
  3161. XArray<CHAR> xszCaption;
  3162. if (0 != HIWORD(ppsh->pszCaption))
  3163. {
  3164. BOOL fOk = ConvertWideCharToMultiByte( ppsh->pszCaption, xszCaption );
  3165. if ( !fOk )
  3166. {
  3167. SetLastError( ERROR_OUTOFMEMORY );
  3168. return piReturn;
  3169. }
  3170. pshA.pszCaption = xszCaption.Get();
  3171. }
  3172. piReturn = PropertySheetA(&pshA);
  3173. }
  3174. return piReturn;
  3175. }
  3176. // helper function for sending listview column messages
  3177. BOOL ComboEx_SendComboMessage(
  3178. HWND hwnd,UINT MsgW,UINT MsgA,
  3179. PCCOMBOEXITEMW pComboExItemW,
  3180. BOOL fInParam,BOOL fOutParam,BOOL fReturnsIndex)
  3181. {
  3182. BOOL fReturn = FALSE;
  3183. if (g_fWideWrap_Unicode)
  3184. {
  3185. fReturn = (BOOL)SendMessageW((hwnd), MsgW, 0, (LPARAM) pComboExItemW);
  3186. }
  3187. else
  3188. {
  3189. COMBOBOXEXITEMA ComboExItemA;
  3190. Assert(sizeof(COMBOBOXEXITEMA) == sizeof(COMBOBOXEXITEMW))
  3191. memcpy(&ComboExItemA,pComboExItemW,sizeof(COMBOBOXEXITEMA));
  3192. ComboExItemA.pszText = NULL;
  3193. DWORD dwOldSize = pComboExItemW->cchTextMax;
  3194. BOOL fOk;
  3195. XArray<CHAR> xszText;
  3196. if (ComboExItemA.mask & CBEIF_TEXT )
  3197. {
  3198. if (fInParam)
  3199. {
  3200. fOk = ConvertWideCharToMultiByte( pComboExItemW->pszText, xszText );
  3201. if ( !fOk )
  3202. {
  3203. SetLastError( ERROR_OUTOFMEMORY );
  3204. return FALSE;
  3205. }
  3206. ComboExItemA.pszText = xszText.Get();
  3207. ComboExItemA.cchTextMax = lstrlenA(ComboExItemA.pszText) + 1;
  3208. }
  3209. else
  3210. {
  3211. fOk = xszText.Init( ComboExItemA.cchTextMax );
  3212. if ( !fOk )
  3213. {
  3214. SetLastError( ERROR_OUTOFMEMORY );
  3215. return FALSE;
  3216. }
  3217. ComboExItemA.pszText = xszText.Get();
  3218. }
  3219. }
  3220. if (ComboExItemA.pszText || !(ComboExItemA.mask & CBEIF_TEXT ))
  3221. {
  3222. fReturn = (BOOL)SendMessageA((hwnd), MsgA, 0, (LPARAM) &ComboExItemA);
  3223. if ( ((fReturnsIndex && fReturn != -1)
  3224. || (fReturn && !fReturnsIndex)) && fOutParam)
  3225. {
  3226. LPWSTR pszTextW = pComboExItemW->pszText;
  3227. memcpy((void*) pComboExItemW,&ComboExItemA,sizeof(COMBOBOXEXITEMA));
  3228. (LPWSTR) pComboExItemW->pszText = pszTextW;
  3229. if (ComboExItemA.mask & CBEIF_TEXT )
  3230. {
  3231. XArray<WCHAR> xwszTextOut;
  3232. fOk = ConvertMultiByteToWideChar( ComboExItemA.pszText, xwszTextOut );
  3233. if ( !fOk )
  3234. {
  3235. SetLastError( ERROR_OUTOFMEMORY );
  3236. return FALSE;
  3237. }
  3238. if ( lstrlenX(xwszTextOut.Get()) >= dwOldSize )
  3239. return FALSE;
  3240. lstrcpyX( pComboExItemW->pszText, xwszTextOut.Get() );
  3241. }
  3242. }
  3243. }
  3244. }
  3245. return fReturn;
  3246. }
  3247. int ComboEx_InsertItemX(HWND hwnd,PCCOMBOEXITEMW pComboExItemW)
  3248. {
  3249. return ComboEx_SendComboMessage(hwnd,CBEM_INSERTITEMW,CBEM_INSERTITEMA,
  3250. pComboExItemW,TRUE,FALSE,TRUE);
  3251. }
  3252. BOOL ComboEx_GetItemX(HWND hwnd,PCCOMBOEXITEMW pComboExItemW)
  3253. {
  3254. return ComboEx_SendComboMessage(hwnd,CBEM_GETITEMW,CBEM_GETITEMA,
  3255. pComboExItemW,FALSE,TRUE,FALSE);
  3256. }
  3257. int TabCtrl_InsertItemX(HWND hwnd,int iItem,LPTCITEMW ptcItem)
  3258. {
  3259. int iReturn = -1;
  3260. if (g_fWideWrap_Unicode)
  3261. {
  3262. iReturn = (int)SendMessage(hwnd,TCM_INSERTITEMW, (WPARAM)iItem,
  3263. (LPARAM) ptcItem);
  3264. }
  3265. else
  3266. {
  3267. TCITEMA tcItemA;
  3268. XArray<CHAR> xszText;
  3269. BOOL fOk;
  3270. Assert(sizeof(TCITEMA) == sizeof(TCITEMW));
  3271. memcpy(&tcItemA,ptcItem,sizeof(tcItemA));
  3272. if (ptcItem->mask & TCIF_TEXT)
  3273. {
  3274. fOk = ConvertWideCharToMultiByte( ptcItem->pszText, xszText);
  3275. if ( !fOk )
  3276. {
  3277. return -1;
  3278. }
  3279. tcItemA.pszText = xszText.Get();
  3280. }
  3281. iReturn = (int)SendMessage(hwnd,TCM_INSERTITEMA,(WPARAM)iItem,(LPARAM) &tcItemA);
  3282. }
  3283. return iReturn;
  3284. }
  3285. BOOL Animate_OpenX(HWND hwnd,LPWSTR szName)
  3286. {
  3287. // only support resource IDs
  3288. Assert(0 == HIWORD(szName));
  3289. return (BOOL)SendMessage(hwnd,ACM_OPENA,0,(LPARAM) szName);
  3290. }
  3291. BOOL
  3292. DateTime_SetFormatX(
  3293. HWND hwnd,
  3294. LPCWSTR pszTimeFormat)
  3295. {
  3296. BOOL fReturn = FALSE;
  3297. if (g_fWideWrap_Unicode)
  3298. {
  3299. return (BOOL)SendMessage(hwnd,DTM_SETFORMATW,0,(LPARAM) pszTimeFormat);
  3300. }
  3301. else
  3302. {
  3303. XArray<CHAR> xszTimeFormat;
  3304. BOOL fOk;
  3305. Assert(pszTimeFormat);
  3306. fOk = ConvertWideCharToMultiByte(pszTimeFormat,xszTimeFormat);
  3307. if (!fOk)
  3308. {
  3309. SetLastError(E_OUTOFMEMORY);
  3310. return FALSE;
  3311. }
  3312. fReturn = (BOOL)SendMessage(hwnd,DTM_SETFORMATA,0,(LPARAM) xszTimeFormat.Get());
  3313. }
  3314. return fReturn;
  3315. }
  3316. int
  3317. WINAPI
  3318. GetDateFormatX(
  3319. LCID Locale,
  3320. DWORD dwFlags,
  3321. CONST SYSTEMTIME *lpDate,
  3322. LPCWSTR lpFormat,
  3323. LPWSTR lpDateStr,
  3324. int cchDate)
  3325. {
  3326. int iReturn = 0;
  3327. if (g_fWideWrap_Unicode)
  3328. {
  3329. return GetDateFormatW(Locale,dwFlags,lpDate,lpFormat,lpDateStr,cchDate);
  3330. }
  3331. else
  3332. {
  3333. XArray<CHAR> xszFormat;
  3334. XArray<CHAR> xszDateStr;
  3335. BOOL fOkFormat,fOkDateStr = TRUE;
  3336. Assert(lpDateStr || cchDate == 0);
  3337. fOkFormat = ConvertWideCharToMultiByte(lpFormat,xszFormat);
  3338. if (cchDate)
  3339. {
  3340. fOkDateStr = xszDateStr.Init(cchDate);
  3341. }
  3342. if (!fOkFormat || !fOkDateStr)
  3343. {
  3344. SetLastError(E_OUTOFMEMORY);
  3345. return FALSE;
  3346. }
  3347. iReturn = GetDateFormatA(Locale,dwFlags,lpDate,xszFormat.Get(),xszDateStr.Get(),cchDate);
  3348. if (iReturn && cchDate)
  3349. {
  3350. XArray<WCHAR> xwszDateStr;
  3351. BOOL fOk;
  3352. fOk = ConvertMultiByteToWideChar(xszDateStr.Get(), xwszDateStr );
  3353. if ( !fOk )
  3354. {
  3355. SetLastError( ERROR_OUTOFMEMORY );
  3356. return 0;
  3357. }
  3358. int cwcLen = lstrlenX( xwszDateStr.Get() );
  3359. if ( cwcLen >= cchDate)
  3360. {
  3361. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  3362. return 0;
  3363. }
  3364. else
  3365. {
  3366. iReturn = cwcLen+1;
  3367. lstrcpynX( lpDateStr, xwszDateStr.Get(),iReturn);
  3368. }
  3369. }
  3370. }
  3371. return iReturn;
  3372. }
  3373. int
  3374. WINAPI
  3375. GetTimeFormatX(
  3376. LCID Locale,
  3377. DWORD dwFlags,
  3378. CONST SYSTEMTIME *lpTime,
  3379. LPCWSTR lpFormat,
  3380. LPWSTR lpTimeStr,
  3381. int cchTime)
  3382. {
  3383. int iReturn = 0;
  3384. if (g_fWideWrap_Unicode)
  3385. {
  3386. return GetTimeFormatW(Locale,dwFlags,lpTime,lpFormat,lpTimeStr,cchTime);
  3387. }
  3388. else
  3389. {
  3390. XArray<CHAR> xszFormat;
  3391. XArray<CHAR> xszTimeStr;
  3392. BOOL fOkFormat,fOkTimeStr = TRUE;
  3393. Assert(lpTimeStr || cchTime == 0);
  3394. fOkFormat = ConvertWideCharToMultiByte(lpFormat,xszFormat);
  3395. if (cchTime)
  3396. {
  3397. fOkTimeStr = xszTimeStr.Init(cchTime);
  3398. }
  3399. if (!fOkFormat || !fOkTimeStr)
  3400. {
  3401. SetLastError(E_OUTOFMEMORY);
  3402. return 0;
  3403. }
  3404. iReturn = GetTimeFormatA(Locale,dwFlags,lpTime,xszFormat.Get(),xszTimeStr.Get(),cchTime);
  3405. if (iReturn && cchTime)
  3406. {
  3407. XArray<WCHAR> xwszTimeStr;
  3408. BOOL fOk = ConvertMultiByteToWideChar(xszTimeStr.Get(), xwszTimeStr );
  3409. if ( !fOk )
  3410. {
  3411. SetLastError( ERROR_OUTOFMEMORY );
  3412. return 0;
  3413. }
  3414. int cwcLen = lstrlenX( xwszTimeStr.Get() );
  3415. if ( cwcLen >= cchTime)
  3416. {
  3417. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  3418. return 0;
  3419. }
  3420. iReturn = cwcLen + 1;
  3421. lstrcpynX( lpTimeStr, xwszTimeStr.Get(),iReturn);
  3422. }
  3423. }
  3424. return iReturn;
  3425. }
  3426. int DrawTextX(
  3427. HDC hDC,
  3428. LPCWSTR lpString,
  3429. int nCount,
  3430. LPRECT lpRect,
  3431. UINT uFormat
  3432. )
  3433. {
  3434. int iReturn = 0;
  3435. if (g_fWideWrap_Unicode)
  3436. {
  3437. iReturn = DrawTextW(hDC,lpString,nCount,lpRect,uFormat);
  3438. }
  3439. else
  3440. {
  3441. XArray<CHAR> xszString;
  3442. BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
  3443. if ( !fOk )
  3444. {
  3445. SetLastError( ERROR_OUTOFMEMORY );
  3446. return 0;
  3447. }
  3448. nCount = lstrlenA(xszString.Get());
  3449. iReturn = DrawTextA(hDC,xszString.Get(),nCount,lpRect,uFormat);
  3450. }
  3451. return iReturn;
  3452. }
  3453. HWND
  3454. WINAPI
  3455. FindWindowExX(
  3456. HWND hwndParent,
  3457. HWND hwndChildAfter,
  3458. LPCWSTR lpszClass,
  3459. LPCWSTR lpszWindow
  3460. )
  3461. {
  3462. HWND hwnd = NULL;
  3463. if (g_fWideWrap_Unicode)
  3464. {
  3465. hwnd = FindWindowExW(hwndParent,hwndChildAfter,lpszClass,
  3466. lpszWindow);
  3467. }
  3468. else
  3469. {
  3470. LPSTR lpszWindowA;
  3471. XArray<CHAR> xszWindow;
  3472. if ( lpszWindow )
  3473. {
  3474. BOOL fOk = ConvertWideCharToMultiByte( lpszWindow, xszWindow );
  3475. if ( !fOk )
  3476. {
  3477. SetLastError( ERROR_OUTOFMEMORY );
  3478. return NULL;
  3479. }
  3480. lpszWindowA = xszWindow.Get();
  3481. }
  3482. else
  3483. lpszWindowA = NULL;
  3484. LPSTR lpszClassA = NULL;
  3485. LPSTR ClassArg = NULL;
  3486. XArray<CHAR> xszClass;
  3487. if (0 != HIWORD(lpszClass))
  3488. {
  3489. BOOL fOk = ConvertWideCharToMultiByte( lpszClass, xszClass );
  3490. if ( !fOk )
  3491. {
  3492. SetLastError( ERROR_OUTOFMEMORY );
  3493. return NULL;
  3494. }
  3495. ClassArg = lpszClassA = xszClass.Get();
  3496. }
  3497. else
  3498. {
  3499. ClassArg = (LPSTR) lpszClass;
  3500. }
  3501. hwnd = FindWindowExA(hwndParent,hwndChildAfter,ClassArg,
  3502. lpszWindowA);
  3503. }
  3504. return hwnd;
  3505. }
  3506. HWND
  3507. WINAPI
  3508. FindWindowX(
  3509. IN LPCWSTR lpszClass,
  3510. IN LPCWSTR lpszWindow)
  3511. {
  3512. HWND hwnd = NULL;
  3513. if (g_fWideWrap_Unicode)
  3514. {
  3515. hwnd = FindWindowW(lpszClass,lpszWindow);
  3516. }
  3517. else
  3518. {
  3519. LPSTR lpszWindowA;
  3520. XArray<CHAR> xszWindow;
  3521. if ( lpszWindow )
  3522. {
  3523. BOOL fOk = ConvertWideCharToMultiByte( lpszWindow, xszWindow );
  3524. if ( !fOk )
  3525. {
  3526. SetLastError( ERROR_OUTOFMEMORY );
  3527. return NULL;
  3528. }
  3529. lpszWindowA = xszWindow.Get();
  3530. }
  3531. else
  3532. lpszWindowA = NULL;
  3533. LPSTR lpszClassA = NULL;
  3534. LPSTR ClassArg = NULL;
  3535. XArray<CHAR> xszClass;
  3536. if (0 != HIWORD(lpszClass))
  3537. {
  3538. BOOL fOk = ConvertWideCharToMultiByte( lpszClass, xszClass );
  3539. if ( !fOk )
  3540. {
  3541. SetLastError( ERROR_OUTOFMEMORY );
  3542. return NULL;
  3543. }
  3544. ClassArg = lpszClassA = xszClass.Get();
  3545. }
  3546. else
  3547. {
  3548. ClassArg = (LPSTR) lpszClass;
  3549. }
  3550. hwnd = FindWindowA(ClassArg,lpszWindowA);
  3551. }
  3552. return hwnd;
  3553. }
  3554. BOOL SetWindowTextX(
  3555. HWND hWnd,
  3556. LPCWSTR lpString
  3557. )
  3558. {
  3559. BOOL fReturn = FALSE;
  3560. Assert(lpString);
  3561. if (g_fWideWrap_Unicode)
  3562. {
  3563. fReturn = SetWindowTextW(hWnd,lpString);
  3564. }
  3565. else
  3566. {
  3567. XArray<CHAR> xszString;
  3568. BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
  3569. if ( !fOk )
  3570. {
  3571. SetLastError( ERROR_OUTOFMEMORY );
  3572. return FALSE;
  3573. }
  3574. // !!! This function turns around and calls WM_SETTEXT which doesn't
  3575. // have a A and W version so if have a misatch between what the
  3576. // window expects and us sending Ansi garbage will appear.
  3577. fReturn = SetWindowTextA(hWnd,xszString.Get());
  3578. }
  3579. return fReturn;
  3580. }
  3581. int ListBox_AddStringX(
  3582. HWND hWnd,
  3583. LPCWSTR lpString
  3584. )
  3585. {
  3586. int iReturn;
  3587. Assert(lpString);
  3588. if (g_fWideWrap_Unicode)
  3589. {
  3590. iReturn = (int)SendMessageW(hWnd,LB_ADDSTRING, 0L, (LPARAM)(LPCTSTR)(lpString));
  3591. }
  3592. else
  3593. {
  3594. XArray<CHAR> xszString;
  3595. BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
  3596. if ( !fOk )
  3597. {
  3598. SetLastError( ERROR_OUTOFMEMORY );
  3599. return FALSE;
  3600. }
  3601. // !!! This function turns around and sends LB_ADDSTRING which doesn't
  3602. // have a A and W version so if have a misatch between what the
  3603. // window expects and us sending Ansi garbage will appear.
  3604. iReturn = (int)SendMessageA(hWnd,LB_ADDSTRING, 0L, (LPARAM)(LPCSTR)(xszString.Get()));
  3605. }
  3606. return iReturn;
  3607. }
  3608. int GetWindowTextX(
  3609. HWND hWnd,
  3610. LPTSTR lpString,
  3611. int nMaxCount
  3612. )
  3613. {
  3614. int iReturn = 0;
  3615. Assert(lpString && (nMaxCount > 0));
  3616. if (g_fWideWrap_Unicode)
  3617. {
  3618. iReturn = GetWindowTextW(hWnd,lpString,nMaxCount);
  3619. }
  3620. else
  3621. {
  3622. int nMaxCountA = nMaxCount;
  3623. XArray<CHAR> xszString;
  3624. BOOL fOk = xszString.Init( nMaxCountA );
  3625. if ( !fOk )
  3626. {
  3627. SetLastError( ERROR_OUTOFMEMORY );
  3628. return 0;
  3629. }
  3630. LPSTR lpStringA = xszString.Get();
  3631. if (lpStringA)
  3632. {
  3633. *lpString = NULL;
  3634. iReturn = GetWindowTextA(hWnd,lpStringA,nMaxCountA);
  3635. if (iReturn)
  3636. {
  3637. XArray<WCHAR> xwszStringOut;
  3638. BOOL fOk = ConvertMultiByteToWideChar( lpStringA, xwszStringOut );
  3639. if ( !fOk )
  3640. {
  3641. SetLastError( ERROR_OUTOFMEMORY );
  3642. return 0;
  3643. }
  3644. int cwcLen = lstrlenX( xwszStringOut.Get() );
  3645. if ( cwcLen >= nMaxCount )
  3646. cwcLen = nMaxCount - 1;
  3647. iReturn = cwcLen + 1;
  3648. lstrcpynX( lpString, xwszStringOut.Get(),iReturn);
  3649. }
  3650. }
  3651. }
  3652. return iReturn;
  3653. }
  3654. BOOL
  3655. WINAPI
  3656. WinHelpX(
  3657. HWND hWndMain,
  3658. LPCWSTR lpszHelp,
  3659. UINT uCommand,
  3660. ULONG_PTR dwData
  3661. )
  3662. {
  3663. if (g_fWideWrap_Unicode)
  3664. {
  3665. WinHelpW(hWndMain,lpszHelp,uCommand,dwData);
  3666. }
  3667. else
  3668. {
  3669. LPSTR lpszHelpA = NULL;
  3670. XArray<CHAR> xszHelp;
  3671. if (lpszHelp)
  3672. {
  3673. BOOL fOk = ConvertWideCharToMultiByte( lpszHelp, xszHelp );
  3674. if ( !fOk )
  3675. {
  3676. SetLastError( ERROR_OUTOFMEMORY );
  3677. return FALSE;
  3678. }
  3679. lpszHelpA = xszHelp.Get();
  3680. }
  3681. if (lpszHelpA || (NULL == lpszHelp))
  3682. {
  3683. WinHelpA(hWndMain,lpszHelpA,uCommand,dwData);
  3684. }
  3685. }
  3686. return FALSE;
  3687. }
  3688. HFONT
  3689. WINAPI
  3690. CreateFontIndirectX(
  3691. CONST LOGFONTW *pLogFontW)
  3692. {
  3693. HFONT hfReturn = NULL;
  3694. if (g_fWideWrap_Unicode)
  3695. {
  3696. return CreateFontIndirectW(pLogFontW);
  3697. }
  3698. else
  3699. {
  3700. LOGFONTA LogFontA;
  3701. XArray<CHAR> xszLogFont;
  3702. BOOL fOk = ConvertWideCharToMultiByte( pLogFontW->lfFaceName, xszLogFont);
  3703. int cchFontA;
  3704. // all items in the logFont structure up
  3705. // until the lfFaceName are the same
  3706. memcpy(&LogFontA,pLogFontW,sizeof(LogFontA));
  3707. if (!fOk)
  3708. {
  3709. return NULL;
  3710. }
  3711. cchFontA = lstrlenA(xszLogFont.Get());
  3712. if (cchFontA >= LF_FACESIZE)
  3713. {
  3714. return NULL;
  3715. }
  3716. strncpy(LogFontA.lfFaceName,xszLogFont.Get(),cchFontA + 1);
  3717. hfReturn = CreateFontIndirectA(&LogFontA);
  3718. }
  3719. return hfReturn;
  3720. }
  3721. DWORD
  3722. WINAPI
  3723. FormatMessageX(
  3724. DWORD dwFlags,
  3725. LPCVOID lpSource,
  3726. DWORD dwMessageId,
  3727. DWORD dwLanguageId,
  3728. LPWSTR lpBuffer,
  3729. DWORD nSize,
  3730. va_list *Arguments
  3731. )
  3732. {
  3733. DWORD dwReturn = 0;
  3734. // we don't support arguments
  3735. Assert(NULL == Arguments);
  3736. Assert(lpBuffer);
  3737. if (Arguments || (NULL == lpBuffer))
  3738. {
  3739. return 0;
  3740. }
  3741. if (g_fWideWrap_Unicode)
  3742. {
  3743. return FormatMessageW(dwFlags,lpSource,dwMessageId,dwLanguageId,
  3744. lpBuffer,nSize,Arguments);
  3745. }
  3746. else
  3747. {
  3748. XArray<CHAR> xszBuffer;
  3749. BOOL fOk = xszBuffer.Init(nSize);
  3750. if (!fOk)
  3751. {
  3752. return 0;
  3753. }
  3754. dwReturn = FormatMessageA(dwFlags,lpSource,dwMessageId,dwLanguageId,
  3755. xszBuffer.Get(),nSize,Arguments);
  3756. if (dwReturn)
  3757. {
  3758. XArray<WCHAR> xwszStringOut;
  3759. BOOL fOk = ConvertMultiByteToWideChar(xszBuffer.Get(), xwszStringOut );
  3760. *lpBuffer = NULL;
  3761. if ( !fOk )
  3762. {
  3763. SetLastError( ERROR_OUTOFMEMORY );
  3764. return 0;
  3765. }
  3766. // if buffer isn't big enough fail
  3767. int cwcLen = lstrlenX( xwszStringOut.Get() );
  3768. if ( cwcLen >= (int) nSize )
  3769. {
  3770. return 0;
  3771. }
  3772. dwReturn = cwcLen + 1;
  3773. lstrcpynX( lpBuffer, xwszStringOut.Get(),dwReturn);
  3774. }
  3775. }
  3776. return dwReturn;
  3777. }
  3778. // code stolen from base\process.cp
  3779. BOOL
  3780. WINAPI
  3781. IsBadStringPtrX(
  3782. LPCWSTR lpsz,
  3783. UINT cchMax
  3784. )
  3785. {
  3786. LPCWSTR EndAddress;
  3787. LPCWSTR StartAddress;
  3788. WCHAR c;
  3789. // If the structure has zero length, then do not probe the structure for
  3790. // read accessibility.
  3791. if (cchMax != 0)
  3792. {
  3793. if (lpsz == NULL)
  3794. {
  3795. return TRUE;
  3796. }
  3797. StartAddress = lpsz;
  3798. EndAddress = (LPCWSTR)((PSZ)StartAddress + (cchMax*2) - 2);
  3799. __try
  3800. {
  3801. c = *(WCHAR *)StartAddress;
  3802. while ( c && StartAddress != EndAddress )
  3803. {
  3804. StartAddress++;
  3805. c = *(WCHAR *)StartAddress;
  3806. }
  3807. }
  3808. __except(EXCEPTION_EXECUTE_HANDLER)
  3809. {
  3810. return TRUE;
  3811. }
  3812. }
  3813. return FALSE;
  3814. }
  3815. BOOL
  3816. APIENTRY
  3817. GetTextExtentPointX(
  3818. HDC hdc,
  3819. LPCWSTR lpszStr,
  3820. int cchString, // specifies length of in param string.
  3821. LPSIZE lpSize
  3822. )
  3823. {
  3824. BOOL fReturn = FALSE;
  3825. if (g_fWideWrap_Unicode)
  3826. {
  3827. return GetTextExtentPointW(hdc,lpszStr,cchString,lpSize);
  3828. }
  3829. else
  3830. {
  3831. XArray<CHAR> xsStr;
  3832. int cchStringA;
  3833. BOOL fOk;
  3834. Assert(lpszStr && (cchString > 0));
  3835. // verify cchString is the stringLength or
  3836. // the calculation of cchStringA will not be accurate.
  3837. Assert(cchString == (int) lstrlenX(lpszStr));
  3838. fOk = ConvertWideCharToMultiByte(lpszStr,xsStr);
  3839. if (!fOk)
  3840. {
  3841. SetLastError(E_OUTOFMEMORY);
  3842. return FALSE;
  3843. }
  3844. cchStringA = lstrlenA(xsStr.Get());
  3845. fReturn = GetTextExtentPointA(hdc,xsStr.Get(),cchStringA,lpSize);
  3846. }
  3847. return fReturn;
  3848. }
  3849. #ifdef __cplusplus
  3850. }
  3851. #endif