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

2365 lines
55 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: user.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <windows.h>
  11. #include "unicode.h"
  12. #include "crtem.h"
  13. #include <stddef.h>
  14. #ifdef _M_IX86
  15. #define MAX_STRING_RSC_SIZE 512
  16. int WINAPI LoadString9x(
  17. HINSTANCE hInstance, // handle of module containing string resource
  18. UINT uID, // resource identifier
  19. LPWSTR lpBuffer, // address of buffer for resource
  20. int nBufferMax // size of buffer
  21. ) {
  22. char rgch[MAX_STRING_RSC_SIZE];
  23. int cchW;
  24. LONG err;
  25. err = LoadStringA(
  26. hInstance,
  27. uID,
  28. rgch,
  29. MAX_STRING_RSC_SIZE);
  30. if (err == 0)
  31. return err;
  32. return MultiByteToWideChar(
  33. 0, // codepage
  34. 0, // dwFlags
  35. rgch,
  36. err + 1,
  37. lpBuffer,
  38. nBufferMax);
  39. }
  40. int WINAPI LoadStringU(
  41. HINSTANCE hInstance, // handle of module containing string resource
  42. UINT uID, // resource identifier
  43. LPWSTR lpBuffer, // address of buffer for resource
  44. int nBufferMax // size of buffer
  45. ) {
  46. if(FIsWinNT())
  47. return( LoadStringW(
  48. hInstance,
  49. uID,
  50. lpBuffer,
  51. nBufferMax
  52. ));
  53. else
  54. return( LoadString9x(
  55. hInstance,
  56. uID,
  57. lpBuffer,
  58. nBufferMax
  59. ));
  60. }
  61. BOOL
  62. WINAPI
  63. InsertMenu9x(
  64. HMENU hMenu,
  65. UINT uPosition,
  66. UINT uFlags,
  67. UINT_PTR uIDNewItem,
  68. LPCWSTR lpNewItem
  69. )
  70. {
  71. LPSTR pszNewItem=NULL;
  72. BOOL fReturn=FALSE;
  73. if( (0 == (uFlags & MF_BITMAP)) &&
  74. (0 == (uFlags & MF_OWNERDRAW))
  75. )
  76. {
  77. if(!MkMBStr(NULL, 0, lpNewItem, &pszNewItem))
  78. return FALSE;
  79. fReturn=InsertMenuA(
  80. hMenu,
  81. uPosition,
  82. uFlags,
  83. uIDNewItem,
  84. (LPCSTR)pszNewItem);
  85. }
  86. else
  87. {
  88. fReturn=InsertMenuA(
  89. hMenu,
  90. uPosition,
  91. uFlags,
  92. uIDNewItem,
  93. (LPCSTR)lpNewItem);
  94. }
  95. if(pszNewItem)
  96. FreeMBStr(NULL, pszNewItem);
  97. return fReturn;
  98. }
  99. BOOL
  100. WINAPI
  101. InsertMenuU(
  102. HMENU hMenu,
  103. UINT uPosition,
  104. UINT uFlags,
  105. UINT_PTR uIDNewItem,
  106. LPCWSTR lpNewItem
  107. )
  108. {
  109. if(FIsWinNT())
  110. return InsertMenuW(
  111. hMenu,
  112. uPosition,
  113. uFlags,
  114. uIDNewItem,
  115. lpNewItem);
  116. else
  117. return InsertMenu9x(
  118. hMenu,
  119. uPosition,
  120. uFlags,
  121. uIDNewItem,
  122. lpNewItem);
  123. }
  124. //-------------------------------------------------------------------------
  125. //
  126. // FormatMessageU
  127. // This function assume any patten of !S! or !s! in lpSource are used for
  128. // formatting purpose only.
  129. //
  130. //--------------------------------------------------------------------------
  131. DWORD WINAPI FormatMessage9x(
  132. DWORD dwFlags, // source and processing options
  133. LPCVOID lpSource, // pointer to message source
  134. DWORD dwMessageId, // requested message identifier
  135. DWORD dwLanguageId, // language identifier for requested message
  136. LPWSTR lpBuffer, // pointer to message buffer
  137. DWORD nSize, // maximum size of message buffer
  138. va_list *Arguments // address of array of message inserts
  139. )
  140. {
  141. DWORD cb=0;
  142. LPSTR pChar=NULL;
  143. DWORD dwSize=0;
  144. LPSTR pszSource=NULL;
  145. LPSTR pszBuffer=NULL;
  146. LPWSTR pwszBuffer=NULL;
  147. //we need to change the lpSource
  148. if((dwFlags & FORMAT_MESSAGE_FROM_STRING) &&
  149. (0 == (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS))
  150. )
  151. {
  152. //get the ascii version of the string
  153. if((lpSource == NULL) || !MkMBStr(NULL, 0, (LPWSTR)lpSource, &pszSource))
  154. goto CLEANUP;
  155. //we change "!S!" to "!s!" and "!s!" to "!S!"
  156. pChar = pszSource;
  157. while((*pChar) != '\0')
  158. {
  159. if((*pChar) == '!')
  160. {
  161. if((*(pChar+1)) == 's')
  162. {
  163. if((*(pChar+2)) == '!')
  164. *(pChar+1)='S';
  165. }
  166. else
  167. {
  168. if((*(pChar+1)) == 'S')
  169. {
  170. if((*(pChar+2)) == '!')
  171. *(pChar+1)='s';
  172. }
  173. }
  174. }
  175. pChar++;
  176. }
  177. }
  178. if(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER)
  179. {
  180. cb = FormatMessageA(
  181. dwFlags,
  182. pszSource,
  183. dwMessageId,
  184. dwLanguageId,
  185. (LPSTR)&pszBuffer,
  186. nSize,
  187. Arguments);
  188. if(cb)
  189. {
  190. if(NULL == (pwszBuffer=MkWStr(pszBuffer)))
  191. {
  192. cb=0;
  193. goto CLEANUP;
  194. }
  195. dwSize=sizeof(WCHAR)*(wcslen(pwszBuffer) +1);
  196. *((LPWSTR *)lpBuffer)=(LPWSTR)LocalAlloc(LPTR, dwSize);
  197. if(NULL == (*lpBuffer))
  198. {
  199. cb=0;
  200. goto CLEANUP;
  201. }
  202. wcscpy((*((LPWSTR *)lpBuffer)), pwszBuffer);
  203. cb=wcslen(pwszBuffer);
  204. }
  205. }
  206. else
  207. {
  208. pszBuffer=(LPSTR)LocalAlloc(LPTR, sizeof(CHAR) * nSize);
  209. if (NULL == pszBuffer)
  210. goto CLEANUP;
  211. cb = FormatMessageA(
  212. dwFlags,
  213. pszSource,
  214. dwMessageId,
  215. dwLanguageId,
  216. pszBuffer,
  217. nSize,
  218. Arguments);
  219. if(cb)
  220. {
  221. if(NULL == (pwszBuffer=MkWStr(pszBuffer)))
  222. {
  223. cb=0;
  224. goto CLEANUP;
  225. }
  226. wcscpy((LPWSTR)lpBuffer, pwszBuffer);
  227. cb=wcslen(pwszBuffer);
  228. }
  229. }
  230. CLEANUP:
  231. if(pszSource)
  232. FreeMBStr(NULL,pszSource);
  233. if(pszBuffer)
  234. LocalFree((HLOCAL)pszBuffer);
  235. if(pwszBuffer)
  236. FreeWStr(pwszBuffer);
  237. return(cb);
  238. }
  239. DWORD WINAPI FormatMessageU(
  240. DWORD dwFlags, // source and processing options
  241. LPCVOID lpSource, // pointer to message source
  242. DWORD dwMessageId, // requested message identifier
  243. DWORD dwLanguageId, // language identifier for requested message
  244. LPWSTR lpBuffer, // pointer to message buffer
  245. DWORD nSize, // maximum size of message buffer
  246. va_list *Arguments // address of array of message inserts
  247. )
  248. {
  249. if(FIsWinNT())
  250. return( FormatMessageW(
  251. dwFlags,
  252. lpSource,
  253. dwMessageId,
  254. dwLanguageId,
  255. lpBuffer,
  256. nSize,
  257. Arguments
  258. ));
  259. else
  260. return( FormatMessage9x(
  261. dwFlags,
  262. lpSource,
  263. dwMessageId,
  264. dwLanguageId,
  265. lpBuffer,
  266. nSize,
  267. Arguments
  268. ));
  269. }
  270. //-------------------------------------------------------------------------
  271. //
  272. // CompareStringU
  273. // This function only handles the case where cchCount1==-1 and cchCount==-1.
  274. //
  275. //--------------------------------------------------------------------------
  276. int
  277. WINAPI
  278. CompareString9x(
  279. LCID Locale,
  280. DWORD dwCmpFlags,
  281. LPCWSTR lpString1,
  282. int cchCount1,
  283. LPCWSTR lpString2,
  284. int cchCount2)
  285. {
  286. int iReturn=0;
  287. int cb1=0;
  288. int cb2=0;
  289. LPSTR psz1=NULL;
  290. LPSTR psz2=NULL;
  291. cb1 = WideCharToMultiByte(
  292. 0,
  293. 0,
  294. lpString1,
  295. cchCount1,
  296. NULL,
  297. 0,
  298. NULL,
  299. NULL);
  300. if(NULL==(psz1=(LPSTR)malloc(cb1)))
  301. {
  302. SetLastError(E_OUTOFMEMORY);
  303. goto CLEANUP;
  304. }
  305. if(0 == (cb1 = WideCharToMultiByte(
  306. 0,
  307. 0,
  308. lpString1,
  309. cchCount1,
  310. psz1,
  311. cb1,
  312. NULL,
  313. NULL)))
  314. goto CLEANUP;
  315. cb2 = WideCharToMultiByte(
  316. 0,
  317. 0,
  318. lpString2,
  319. cchCount2,
  320. NULL,
  321. 0,
  322. NULL,
  323. NULL);
  324. if(NULL == (psz2=(LPSTR)malloc(cb2)))
  325. {
  326. SetLastError(E_OUTOFMEMORY);
  327. goto CLEANUP;
  328. }
  329. if(0 == (cb2 = WideCharToMultiByte(
  330. 0,
  331. 0,
  332. lpString2,
  333. cchCount2,
  334. psz2,
  335. cb2,
  336. NULL,
  337. NULL)))
  338. goto CLEANUP;
  339. iReturn = CompareStringA(Locale,
  340. dwCmpFlags,
  341. psz1,
  342. cb1,
  343. psz2,
  344. cb2);
  345. CLEANUP:
  346. if(psz1)
  347. free(psz1);
  348. if(psz2)
  349. free(psz2);
  350. return iReturn;
  351. }
  352. int
  353. WINAPI
  354. CompareStringU(
  355. LCID Locale,
  356. DWORD dwCmpFlags,
  357. LPCWSTR lpString1,
  358. int cchCount1,
  359. LPCWSTR lpString2,
  360. int cchCount2)
  361. {
  362. if(FIsWinNT())
  363. return CompareStringW(
  364. Locale,
  365. dwCmpFlags,
  366. lpString1,
  367. cchCount1,
  368. lpString2,
  369. cchCount2);
  370. else
  371. return CompareString9x(
  372. Locale,
  373. dwCmpFlags,
  374. lpString1,
  375. cchCount1,
  376. lpString2,
  377. cchCount2);
  378. }
  379. //-------------------------------------------------------------------------
  380. //
  381. // PropertySheetU
  382. //
  383. //--------------------------------------------------------------------------
  384. typedef INT_PTR (WINAPI *PFPropertySheetA)(LPCPROPSHEETHEADERA);
  385. typedef INT_PTR (WINAPI *PFPropertySheetW)(LPCPROPSHEETHEADERW);
  386. INT_PTR WINAPI PropertySheet9x(
  387. LPPROPSHEETHEADERW lppsph)
  388. {
  389. PROPSHEETHEADERA PropHeaderA;
  390. INT_PTR iReturn=-1;
  391. DWORD dwIndex=0;
  392. UINT nPages=0;
  393. DWORD dwSize=0;
  394. LPPROPSHEETPAGEA pPropSheetA=NULL;
  395. LPSTR pszCaption=NULL;
  396. LPSTR pszTitle=NULL;
  397. HMODULE hModule=NULL;
  398. PFPropertySheetA pfPropertySheetA=NULL;
  399. //load the comctl.32 since many dlls in ispu project
  400. //use unicode.lib, just do not link to comctl32.dll
  401. if(NULL == (hModule=LoadLibrary("comctl32.dll")))
  402. return iReturn;
  403. memcpy(&PropHeaderA, lppsph, sizeof(PROPSHEETHEADERA));
  404. if(lppsph->pszCaption)
  405. {
  406. if(!MkMBStr(NULL, 0, (LPWSTR)(lppsph->pszCaption), &pszCaption))
  407. goto CLEANUP;
  408. PropHeaderA.pszCaption=pszCaption;
  409. }
  410. //convert the property sheets
  411. if(PSH_PROPSHEETPAGE & lppsph->dwFlags)
  412. {
  413. nPages = lppsph->nPages;
  414. if(nPages)
  415. {
  416. dwSize=sizeof(PROPSHEETPAGEA) * nPages;
  417. pPropSheetA=(LPPROPSHEETPAGEA)LocalAlloc(LPTR, dwSize);
  418. if(NULL == pPropSheetA)
  419. goto CLEANUP;
  420. memcpy(pPropSheetA, lppsph->ppsp, dwSize);
  421. //pre-set the title
  422. for(dwIndex=0; dwIndex < (DWORD)nPages; dwIndex++)
  423. {
  424. pPropSheetA[dwIndex].pszTitle=NULL;
  425. }
  426. for(dwIndex=0; dwIndex < (DWORD)nPages; dwIndex++)
  427. {
  428. if((lppsph->ppsp)[dwIndex].pszTitle)
  429. {
  430. if(!MkMBStr(NULL, 0, (LPWSTR)((lppsph->ppsp)[dwIndex].pszTitle),
  431. &pszTitle))
  432. goto CLEANUP;
  433. pPropSheetA[dwIndex].pszTitle=pszTitle;
  434. }
  435. }
  436. PropHeaderA.ppsp=pPropSheetA;
  437. }
  438. }
  439. if(NULL != (pfPropertySheetA=(PFPropertySheetA)GetProcAddress(hModule, "PropertySheetA")))
  440. {
  441. iReturn=pfPropertySheetA(&PropHeaderA);
  442. }
  443. CLEANUP:
  444. if(pszCaption)
  445. FreeMBStr(NULL, pszCaption);
  446. //free the title
  447. if(PropHeaderA.nPages)
  448. {
  449. for(dwIndex=0; dwIndex < PropHeaderA.nPages; dwIndex++)
  450. {
  451. if(pPropSheetA[dwIndex].pszTitle)
  452. FreeMBStr(NULL, (LPSTR)((pPropSheetA[dwIndex]).pszTitle));
  453. }
  454. }
  455. if(pPropSheetA)
  456. LocalFree((HLOCAL)pPropSheetA);
  457. if(hModule)
  458. FreeLibrary(hModule);
  459. return iReturn;
  460. }
  461. INT_PTR WINAPI PropertySheetU(
  462. LPPROPSHEETHEADERW lppsph)
  463. {
  464. INT_PTR iReturn=-1;
  465. HMODULE hModule=NULL;
  466. PFPropertySheetW pfPropertySheetW=NULL;
  467. if(FIsWinNT())
  468. {
  469. //load the comctl.32 since many dlls in ispu project
  470. //use unicode.lib, just do not link to comctl32.dll
  471. if(NULL == (hModule=LoadLibrary("comctl32.dll")))
  472. return iReturn;
  473. if(NULL != (pfPropertySheetW=(PFPropertySheetW)GetProcAddress(hModule, "PropertySheetW")))
  474. {
  475. iReturn=pfPropertySheetW(lppsph);
  476. }
  477. FreeLibrary(hModule);
  478. }
  479. else
  480. {
  481. iReturn=PropertySheet9x(lppsph);
  482. }
  483. return iReturn;
  484. }
  485. //-------------------------------------------------------------------------
  486. //
  487. // DragQueryFileU
  488. //
  489. //--------------------------------------------------------------------------
  490. typedef UINT (WINAPI *PFDragQueryFileA)(HDROP,UINT,LPSTR,UINT);
  491. typedef UINT (WINAPI *PFDragQueryFileW)(HDROP,UINT,LPWSTR,UINT);
  492. UINT WINAPI DragQueryFileU(
  493. HDROP hDrop,
  494. UINT iFile,
  495. LPWSTR lpwszFile,
  496. UINT cch)
  497. {
  498. PFDragQueryFileA pfA=NULL;
  499. PFDragQueryFileW pfW=NULL;
  500. HMODULE hModule=NULL;
  501. UINT iReturn=0;
  502. LPSTR psz=NULL;
  503. //load the shell32.dll since many dlls in ispu project
  504. //use unicode.lib, just do not link to comctl32.dll
  505. if(NULL == (hModule=LoadLibrary("shell32.dll")))
  506. return iReturn;
  507. if(FIsWinNT())
  508. {
  509. if(NULL != (pfW=(PFDragQueryFileW)GetProcAddress(hModule, "DragQueryFileW")))
  510. {
  511. iReturn=pfW(hDrop, iFile, lpwszFile, cch);
  512. }
  513. FreeLibrary(hModule);
  514. return iReturn;
  515. }
  516. //allocate memory
  517. if(0xFFFFFFFF != iFile)
  518. {
  519. if(lpwszFile)
  520. {
  521. //allocate a big enough buffer
  522. psz=(LPSTR)malloc(sizeof(WCHAR) * cch);
  523. if(NULL == psz)
  524. goto CLEANUP;
  525. }
  526. }
  527. if(NULL == (pfA=(PFDragQueryFileA)GetProcAddress(hModule, "DragQueryFileA")))
  528. goto CLEANUP;
  529. iReturn=pfA(hDrop, iFile, psz, cch);
  530. if(0 != iReturn)
  531. {
  532. if(0xFFFFFFFF != iFile)
  533. {
  534. if(lpwszFile && psz)
  535. {
  536. iReturn = MultiByteToWideChar(
  537. 0, // codepage
  538. 0, // dwFlags
  539. psz,
  540. iReturn+1,
  541. lpwszFile,
  542. cch);
  543. //we should return the # of characters excluding the NULL terminator
  544. if(0 != iReturn)
  545. iReturn--;
  546. }
  547. }
  548. }
  549. CLEANUP:
  550. if(psz)
  551. free(psz);
  552. return iReturn;
  553. }
  554. //-------------------------------------------------------------------------
  555. //
  556. // CreatePropertySheetPageU
  557. //
  558. // Notice: This function assumes that the LPCPROPSHEETPAGEW and
  559. // LPCPROPSHEETPAGEA are equivalent.
  560. //
  561. //--------------------------------------------------------------------------
  562. typedef HPROPSHEETPAGE (WINAPI *PFCreatePropertySheetPageA)(LPCPROPSHEETPAGEA);
  563. typedef HPROPSHEETPAGE (WINAPI *PFCreatePropertySheetPageW)(LPCPROPSHEETPAGEW);
  564. HPROPSHEETPAGE WINAPI CreatePropertySheetPageU(LPCPROPSHEETPAGEW pPage)
  565. {
  566. PFCreatePropertySheetPageA pfA=NULL;
  567. PFCreatePropertySheetPageW pfW=NULL;
  568. HMODULE hModule=NULL;
  569. HPROPSHEETPAGE hPage=NULL;
  570. //load the comctl.32 since many dlls in ispu project
  571. //use unicode.lib, just do not link to comctl32.dll
  572. if(NULL == (hModule=LoadLibrary("comctl32.dll")))
  573. return hPage;
  574. if(FIsWinNT())
  575. {
  576. if(NULL != (pfW=(PFCreatePropertySheetPageW)GetProcAddress(hModule, "CreatePropertySheetPageW")))
  577. {
  578. hPage=pfW(pPage);
  579. }
  580. FreeLibrary(hModule);
  581. return hPage;
  582. }
  583. if(NULL != (pfA=(PFCreatePropertySheetPageA)GetProcAddress(hModule, "CreatePropertySheetPageA")))
  584. {
  585. hPage=pfA((LPCPROPSHEETPAGEA)pPage);
  586. }
  587. FreeLibrary(hModule);
  588. return hPage;
  589. }
  590. BOOL WINAPI SetWindowText9x(
  591. HWND hWnd, // handle of window or control
  592. LPCWSTR lpString // address of string
  593. ) {
  594. BYTE rgb1[_MAX_PATH];
  595. char * szString = NULL;
  596. LONG err = 0;
  597. if (lpString == NULL) {
  598. SetLastError(ERROR_INVALID_PARAMETER);
  599. return(0);
  600. }
  601. if( MkMBStr(rgb1, _MAX_PATH, lpString, &szString) &&
  602. (szString != NULL)) {
  603. err = SetWindowTextA(
  604. hWnd,
  605. szString);
  606. }
  607. if (szString != NULL)
  608. FreeMBStr(rgb1, szString);
  609. return(err);
  610. }
  611. BOOL WINAPI SetWindowTextU(
  612. HWND hWnd, // handle of window or control
  613. LPCWSTR lpString // address of string
  614. ) {
  615. if(FIsWinNT())
  616. return( SetWindowTextW(hWnd, lpString));
  617. else
  618. return( SetWindowText9x(hWnd, lpString));
  619. }
  620. int WINAPI GetWindowText9x(
  621. HWND hWnd,
  622. LPWSTR lpString,
  623. int nMaxCount
  624. )
  625. {
  626. LPSTR psz;
  627. int ret;
  628. psz = (LPSTR) malloc(nMaxCount);
  629. if (psz == NULL)
  630. {
  631. return (0);
  632. }
  633. ret = GetWindowTextA(hWnd, psz, nMaxCount);
  634. if (ret != 0)
  635. {
  636. MultiByteToWideChar(0, 0, psz, -1, lpString, nMaxCount);
  637. }
  638. else
  639. {
  640. free(psz);
  641. return (0);
  642. }
  643. free(psz);
  644. return (ret);
  645. }
  646. int WINAPI GetWindowTextU(
  647. HWND hWnd,
  648. LPWSTR lpString,
  649. int nMaxCount
  650. )
  651. {
  652. if (FIsWinNT())
  653. return (GetWindowTextW(hWnd, lpString, nMaxCount));
  654. else
  655. return (GetWindowText9x(hWnd, lpString, nMaxCount));
  656. }
  657. UINT WINAPI GetDlgItemText9x(
  658. HWND hDlg, // handle of dialog box
  659. int nIDDlgItem, // identifier of control
  660. LPWSTR lpString, // address of buffer for text
  661. int nMaxCount // maximum size of string
  662. ) {
  663. char *szBuffer;
  664. int cchW;
  665. LONG err;
  666. szBuffer = (char *) malloc(nMaxCount);
  667. if(!szBuffer)
  668. {
  669. SetLastError(ERROR_OUTOFMEMORY);
  670. return 0;
  671. }
  672. err = GetDlgItemTextA(
  673. hDlg,
  674. nIDDlgItem,
  675. szBuffer,
  676. nMaxCount);
  677. if (err != 0)
  678. {
  679. err = MultiByteToWideChar(
  680. 0, // codepage
  681. 0, // dwFlags
  682. szBuffer,
  683. err+1,
  684. lpString,
  685. nMaxCount);
  686. }
  687. else if (nMaxCount >= 1)
  688. {
  689. lpString[0] = 0;
  690. }
  691. free(szBuffer);
  692. return(err);
  693. }
  694. UINT WINAPI GetDlgItemTextU(
  695. HWND hDlg, // handle of dialog box
  696. int nIDDlgItem, // identifier of control
  697. LPWSTR lpString, // address of buffer for text
  698. int nMaxCount // maximum size of string
  699. ) {
  700. if(FIsWinNT())
  701. return( GetDlgItemTextW(
  702. hDlg,
  703. nIDDlgItem,
  704. lpString,
  705. nMaxCount
  706. ));
  707. else
  708. return( GetDlgItemText9x(
  709. hDlg,
  710. nIDDlgItem,
  711. lpString,
  712. nMaxCount
  713. ));
  714. }
  715. BOOL WINAPI SetDlgItemText9x(
  716. HWND hDlg,
  717. int nIDDlgItem,
  718. LPCWSTR lpString
  719. )
  720. {
  721. LPSTR szString = NULL;
  722. DWORD cbszString = 0;
  723. BOOL fRet;
  724. cbszString = WideCharToMultiByte(
  725. 0, // codepage
  726. 0, // dwFlags
  727. lpString,
  728. -1,
  729. NULL,
  730. 0,
  731. NULL,
  732. NULL);
  733. if (cbszString == 0)
  734. {
  735. return FALSE;
  736. }
  737. if (NULL == (szString = (LPSTR) malloc(cbszString)))
  738. {
  739. return FALSE;
  740. }
  741. cbszString = WideCharToMultiByte(
  742. 0, // codepage
  743. 0, // dwFlags
  744. lpString,
  745. -1,
  746. szString,
  747. cbszString,
  748. NULL,
  749. NULL);
  750. if (cbszString == 0)
  751. {
  752. free(szString);
  753. return FALSE;
  754. }
  755. fRet = SetDlgItemTextA(
  756. hDlg,
  757. nIDDlgItem,
  758. szString
  759. );
  760. free(szString);
  761. return (fRet);
  762. }
  763. BOOL WINAPI SetDlgItemTextU(
  764. HWND hDlg,
  765. int nIDDlgItem,
  766. LPCWSTR lpString
  767. )
  768. {
  769. if(FIsWinNT())
  770. return(SetDlgItemTextW(
  771. hDlg,
  772. nIDDlgItem,
  773. lpString
  774. ));
  775. else
  776. return(SetDlgItemText9x(
  777. hDlg,
  778. nIDDlgItem,
  779. lpString
  780. ));
  781. }
  782. int WINAPI DialogBoxParam9x(
  783. HINSTANCE hInstance,
  784. LPCWSTR lpTemplateName,
  785. HWND hWndParent,
  786. DLGPROC lpDialogFunc,
  787. LPARAM dwInitParam
  788. )
  789. {
  790. LPSTR szString = NULL;
  791. DWORD cbszString = 0;
  792. int iRet;
  793. //now, lpTemplateName can either be a WORD from MAKEINTRESOURCE(..)
  794. //or a NULL terminated string
  795. if (0xFFFF >= ((DWORD_PTR)lpTemplateName))
  796. {
  797. return(DialogBoxParamA(
  798. hInstance,
  799. (LPCSTR)lpTemplateName,
  800. hWndParent,
  801. lpDialogFunc,
  802. dwInitParam
  803. ));
  804. }
  805. cbszString = WideCharToMultiByte(
  806. 0, // codepage
  807. 0, // dwFlags
  808. lpTemplateName,
  809. -1,
  810. NULL,
  811. 0,
  812. NULL,
  813. NULL);
  814. if (cbszString == 0)
  815. {
  816. return FALSE;
  817. }
  818. if (NULL == (szString = (LPSTR) malloc(cbszString)))
  819. {
  820. return FALSE;
  821. }
  822. cbszString = WideCharToMultiByte(
  823. 0, // codepage
  824. 0, // dwFlags
  825. lpTemplateName,
  826. -1,
  827. szString,
  828. cbszString,
  829. NULL,
  830. NULL);
  831. if (cbszString == 0)
  832. {
  833. free(szString);
  834. return FALSE;
  835. }
  836. iRet = DialogBoxParamA(
  837. hInstance,
  838. szString,
  839. hWndParent,
  840. lpDialogFunc,
  841. dwInitParam
  842. );
  843. free(szString);
  844. return (iRet);
  845. }
  846. int WINAPI DialogBoxParamU(
  847. HINSTANCE hInstance,
  848. LPCWSTR lpTemplateName,
  849. HWND hWndParent,
  850. DLGPROC lpDialogFunc,
  851. LPARAM dwInitParam
  852. )
  853. {
  854. if(FIsWinNT())
  855. return(DialogBoxParamW(
  856. hInstance,
  857. lpTemplateName,
  858. hWndParent,
  859. lpDialogFunc,
  860. dwInitParam
  861. ));
  862. else
  863. return(DialogBoxParam9x(
  864. hInstance,
  865. lpTemplateName,
  866. hWndParent,
  867. lpDialogFunc,
  868. dwInitParam
  869. ));
  870. }
  871. int WINAPI DialogBox9x(
  872. HINSTANCE hInstance,
  873. LPCWSTR lpTemplateName,
  874. HWND hWndParent,
  875. DLGPROC lpDialogFunc
  876. )
  877. {
  878. LPSTR szString = NULL;
  879. DWORD cbszString = 0;
  880. int iRet;
  881. //now, lpTemplateName can either be a WORD from MAKEINTRESOURCE(..)
  882. //or a NULL terminated string
  883. if (0xFFFF >= ((DWORD_PTR)lpTemplateName))
  884. {
  885. return(DialogBoxA(
  886. hInstance,
  887. (LPCSTR)lpTemplateName,
  888. hWndParent,
  889. lpDialogFunc
  890. ));
  891. }
  892. cbszString = WideCharToMultiByte(
  893. 0, // codepage
  894. 0, // dwFlags
  895. lpTemplateName,
  896. -1,
  897. NULL,
  898. 0,
  899. NULL,
  900. NULL);
  901. if (cbszString == 0)
  902. {
  903. return FALSE;
  904. }
  905. if (NULL == (szString = (LPSTR) malloc(cbszString)))
  906. {
  907. return FALSE;
  908. }
  909. cbszString = WideCharToMultiByte(
  910. 0, // codepage
  911. 0, // dwFlags
  912. lpTemplateName,
  913. -1,
  914. szString,
  915. cbszString,
  916. NULL,
  917. NULL);
  918. if (cbszString == 0)
  919. {
  920. free(szString);
  921. return FALSE;
  922. }
  923. iRet = DialogBoxA(
  924. hInstance,
  925. szString,
  926. hWndParent,
  927. lpDialogFunc
  928. );
  929. free(szString);
  930. return (iRet);
  931. }
  932. int WINAPI DialogBoxU(
  933. HINSTANCE hInstance,
  934. LPCWSTR lpTemplateName,
  935. HWND hWndParent,
  936. DLGPROC lpDialogFunc
  937. )
  938. {
  939. if(FIsWinNT())
  940. return(DialogBoxW(
  941. hInstance,
  942. lpTemplateName,
  943. hWndParent,
  944. lpDialogFunc
  945. ));
  946. else
  947. return(DialogBox9x(
  948. hInstance,
  949. lpTemplateName,
  950. hWndParent,
  951. lpDialogFunc
  952. ));
  953. }
  954. int WINAPI MessageBox9x(
  955. HWND hWnd,
  956. LPCWSTR lpText,
  957. LPCWSTR lpCaption,
  958. UINT uType
  959. ) {
  960. BYTE rgb1[_MAX_PATH];
  961. char * szString1 = NULL;
  962. BYTE rgb2[_MAX_PATH];
  963. char * szString2 = NULL;
  964. int err;
  965. if (lpText == NULL) {
  966. SetLastError(ERROR_INVALID_PARAMETER);
  967. return(0);
  968. }
  969. err = 0;
  970. if(MkMBStr(rgb1, _MAX_PATH, lpText, &szString1))
  971. {
  972. MkMBStr(rgb2, _MAX_PATH, lpCaption, &szString2);
  973. err = MessageBoxA(
  974. hWnd,
  975. szString1,
  976. szString2,
  977. uType);
  978. }
  979. if (szString1 != NULL)
  980. FreeMBStr(rgb1, szString1);
  981. if (szString2 != NULL)
  982. FreeMBStr(rgb2, szString2);
  983. return(err);
  984. }
  985. int WINAPI MessageBoxU(
  986. HWND hWnd,
  987. LPCWSTR lpText,
  988. LPCWSTR lpCaption,
  989. UINT uType
  990. ) {
  991. if(FIsWinNT())
  992. return( MessageBoxW(
  993. hWnd,
  994. lpText,
  995. lpCaption,
  996. uType));
  997. else
  998. return( MessageBox9x(
  999. hWnd,
  1000. lpText,
  1001. lpCaption,
  1002. uType));
  1003. }
  1004. int WINAPI LCMapString9x(
  1005. LCID Locale, // locale identifier
  1006. DWORD dwMapFlags, // mapping transformation type
  1007. LPCWSTR lpSrcStr, // address of source string
  1008. int cchSrc, // number of characters in source string
  1009. LPWSTR lpDestStr, // address of destination buffer
  1010. int cchDest // size of destination buffer
  1011. ) {
  1012. BYTE rgb1[_MAX_PATH];
  1013. char * szBuffer = NULL;
  1014. LPSTR szBuffer1 = NULL;
  1015. int cbConverted;
  1016. LONG err = GetLastError();
  1017. LONG cb = 0;
  1018. SetLastError(ERROR_OUTOFMEMORY);
  1019. // translate lpSrcStr to src ANSI szBuffer
  1020. if(MkMBStrEx(rgb1, _MAX_PATH, lpSrcStr, cchSrc, &szBuffer, &cbConverted) )
  1021. {
  1022. // Malloc the intermediate ANSI buf
  1023. if( NULL != (szBuffer1 = (LPSTR) malloc(cchDest)) ) {
  1024. // do translation from szBuffer into lpDestStr
  1025. cb = LCMapStringA(
  1026. Locale,
  1027. dwMapFlags,
  1028. szBuffer,
  1029. cbConverted,
  1030. szBuffer1,
  1031. cchDest);
  1032. }
  1033. }
  1034. // free src ANSI szBuffer, handles NULLs
  1035. FreeMBStr(rgb1, szBuffer);
  1036. if(cb != 0) {
  1037. // translate resultant ANSI szBuffer1 to UNICODE
  1038. cb = MultiByteToWideChar(
  1039. 0, // codepage
  1040. 0, // dwFlags
  1041. szBuffer1, // src (ANSI)
  1042. cb, // already incl NULL
  1043. lpDestStr, // dest (UNICODE)
  1044. cchDest);
  1045. }
  1046. if(szBuffer1 != NULL)
  1047. free(szBuffer1);
  1048. if(cb != 0)
  1049. SetLastError(err);
  1050. return(cb);
  1051. }
  1052. int WINAPI LCMapStringU(
  1053. LCID Locale, // locale identifier
  1054. DWORD dwMapFlags, // mapping transformation type
  1055. LPCWSTR lpSrcStr, // address of source string
  1056. int cchSrc, // number of characters in source string
  1057. LPWSTR lpDestStr, // address of destination buffer
  1058. int cchDest // size of destination buffer
  1059. ) {
  1060. if(FIsWinNT())
  1061. return( LCMapStringW(
  1062. Locale,
  1063. dwMapFlags,
  1064. lpSrcStr,
  1065. cchSrc,
  1066. lpDestStr,
  1067. cchDest));
  1068. else
  1069. return( LCMapString9x(
  1070. Locale,
  1071. dwMapFlags,
  1072. lpSrcStr,
  1073. cchSrc,
  1074. lpDestStr,
  1075. cchDest));
  1076. }
  1077. int WINAPI GetDateFormat9x(
  1078. LCID Locale,
  1079. DWORD dwFlags,
  1080. CONST SYSTEMTIME *lpDate,
  1081. LPCWSTR lpFormat,
  1082. LPWSTR lpDateStr,
  1083. int cchDate
  1084. )
  1085. {
  1086. LPSTR szFormatString = NULL;
  1087. LPSTR szDateString = NULL;
  1088. DWORD cbszFormatString = 0;
  1089. DWORD cbszDateString = 0;
  1090. int iRet;
  1091. if (lpFormat != NULL)
  1092. {
  1093. cbszFormatString = WideCharToMultiByte(
  1094. 0, // codepage
  1095. 0, // dwFlags
  1096. lpFormat,
  1097. -1,
  1098. NULL,
  1099. 0,
  1100. NULL,
  1101. NULL);
  1102. if (cbszFormatString == 0)
  1103. {
  1104. return FALSE;
  1105. }
  1106. if (NULL == (szFormatString = (LPSTR) malloc(cbszFormatString)))
  1107. {
  1108. return FALSE;
  1109. }
  1110. cbszFormatString = WideCharToMultiByte(
  1111. 0, // codepage
  1112. 0, // dwFlags
  1113. lpFormat,
  1114. -1,
  1115. szFormatString,
  1116. cbszFormatString,
  1117. NULL,
  1118. NULL);
  1119. if (cbszFormatString == 0)
  1120. {
  1121. free(szFormatString);
  1122. return FALSE;
  1123. }
  1124. }
  1125. if (cchDate == 0)
  1126. {
  1127. iRet = GetDateFormatA(
  1128. Locale,
  1129. dwFlags,
  1130. lpDate,
  1131. szFormatString,
  1132. NULL,
  1133. 0
  1134. );
  1135. }
  1136. else
  1137. {
  1138. szDateString = (LPSTR) malloc(cchDate);
  1139. if (szDateString == NULL)
  1140. {
  1141. if (szFormatString)
  1142. free(szFormatString);
  1143. return FALSE;
  1144. }
  1145. iRet = GetDateFormatA(
  1146. Locale,
  1147. dwFlags,
  1148. lpDate,
  1149. szFormatString,
  1150. szDateString,
  1151. cchDate
  1152. );
  1153. MultiByteToWideChar(
  1154. 0,
  1155. 0,
  1156. szDateString,
  1157. -1,
  1158. lpDateStr,
  1159. cchDate
  1160. );
  1161. }
  1162. if (szFormatString)
  1163. free(szFormatString);
  1164. if (szDateString)
  1165. free(szDateString);
  1166. return (iRet);
  1167. }
  1168. int WINAPI GetDateFormatU(
  1169. LCID Locale,
  1170. DWORD dwFlags,
  1171. CONST SYSTEMTIME *lpDate,
  1172. LPCWSTR lpFormat,
  1173. LPWSTR lpDateStr,
  1174. int cchDate
  1175. )
  1176. {
  1177. if(FIsWinNT())
  1178. return(GetDateFormatW(
  1179. Locale,
  1180. dwFlags,
  1181. lpDate,
  1182. lpFormat,
  1183. lpDateStr,
  1184. cchDate
  1185. ));
  1186. else
  1187. return(GetDateFormat9x(
  1188. Locale,
  1189. dwFlags,
  1190. lpDate,
  1191. lpFormat,
  1192. lpDateStr,
  1193. cchDate
  1194. ));
  1195. }
  1196. int WINAPI GetTimeFormat9x(
  1197. LCID Locale,
  1198. DWORD dwFlags,
  1199. CONST SYSTEMTIME *lpTime,
  1200. LPCWSTR lpFormat,
  1201. LPWSTR lpTimeStr,
  1202. int cchTime
  1203. )
  1204. {
  1205. LPSTR szFormatString = NULL;
  1206. LPSTR szTimeString = NULL;
  1207. DWORD cbszFormatString = 0;
  1208. DWORD cbszTimeString = 0;
  1209. int iRet;
  1210. if (lpFormat != NULL)
  1211. {
  1212. cbszFormatString = WideCharToMultiByte(
  1213. 0, // codepage
  1214. 0, // dwFlags
  1215. lpFormat,
  1216. -1,
  1217. NULL,
  1218. 0,
  1219. NULL,
  1220. NULL);
  1221. if (cbszFormatString == 0)
  1222. {
  1223. return FALSE;
  1224. }
  1225. if (NULL == (szFormatString = (LPSTR) malloc(cbszFormatString)))
  1226. {
  1227. return FALSE;
  1228. }
  1229. cbszFormatString = WideCharToMultiByte(
  1230. 0, // codepage
  1231. 0, // dwFlags
  1232. lpFormat,
  1233. -1,
  1234. szFormatString,
  1235. cbszFormatString,
  1236. NULL,
  1237. NULL);
  1238. if (cbszFormatString == 0)
  1239. {
  1240. free(szFormatString);
  1241. return FALSE;
  1242. }
  1243. }
  1244. if (cchTime == 0)
  1245. {
  1246. iRet = GetTimeFormatA(
  1247. Locale,
  1248. dwFlags,
  1249. lpTime,
  1250. szFormatString,
  1251. NULL,
  1252. 0
  1253. );
  1254. }
  1255. else
  1256. {
  1257. szTimeString = (LPSTR) malloc(cchTime);
  1258. if (szTimeString == NULL)
  1259. {
  1260. if (szFormatString)
  1261. free(szFormatString);
  1262. return FALSE;
  1263. }
  1264. iRet = GetTimeFormatA(
  1265. Locale,
  1266. dwFlags,
  1267. lpTime,
  1268. szFormatString,
  1269. szTimeString,
  1270. cchTime
  1271. );
  1272. MultiByteToWideChar(
  1273. 0,
  1274. 0,
  1275. szTimeString,
  1276. -1,
  1277. lpTimeStr,
  1278. cchTime
  1279. );
  1280. }
  1281. if (szFormatString != NULL)
  1282. free(szFormatString);
  1283. if (szTimeString != NULL)
  1284. free(szTimeString);
  1285. return (iRet);
  1286. }
  1287. int WINAPI GetTimeFormatU(
  1288. LCID Locale,
  1289. DWORD dwFlags,
  1290. CONST SYSTEMTIME *lpTime,
  1291. LPCWSTR lpFormat,
  1292. LPWSTR lpTimeStr,
  1293. int cchTime
  1294. )
  1295. {
  1296. if(FIsWinNT())
  1297. return(GetTimeFormatW(
  1298. Locale,
  1299. dwFlags,
  1300. lpTime,
  1301. lpFormat,
  1302. lpTimeStr,
  1303. cchTime
  1304. ));
  1305. else
  1306. return(GetTimeFormat9x(
  1307. Locale,
  1308. dwFlags,
  1309. lpTime,
  1310. lpFormat,
  1311. lpTimeStr,
  1312. cchTime
  1313. ));
  1314. }
  1315. BOOL WINAPI WinHelp9x(
  1316. HWND hWndMain,
  1317. LPCWSTR lpszHelp,
  1318. UINT uCommand,
  1319. DWORD dwData
  1320. )
  1321. {
  1322. LPSTR szHelpString = NULL;
  1323. DWORD cbszHelpString = 0;
  1324. BOOL bRet;
  1325. cbszHelpString = WideCharToMultiByte(
  1326. 0, // codepage
  1327. 0, // dwFlags
  1328. lpszHelp,
  1329. -1,
  1330. NULL,
  1331. 0,
  1332. NULL,
  1333. NULL);
  1334. if (cbszHelpString == 0)
  1335. {
  1336. return FALSE;
  1337. }
  1338. if (NULL == (szHelpString = (LPSTR) malloc(cbszHelpString)))
  1339. {
  1340. return FALSE;
  1341. }
  1342. cbszHelpString = WideCharToMultiByte(
  1343. 0, // codepage
  1344. 0, // dwFlags
  1345. lpszHelp,
  1346. -1,
  1347. szHelpString,
  1348. cbszHelpString,
  1349. NULL,
  1350. NULL);
  1351. if (cbszHelpString == 0)
  1352. {
  1353. free(szHelpString);
  1354. return FALSE;
  1355. }
  1356. bRet = WinHelpA(
  1357. hWndMain,
  1358. szHelpString,
  1359. uCommand,
  1360. dwData
  1361. );
  1362. free(szHelpString);
  1363. return (bRet);
  1364. }
  1365. BOOL WINAPI WinHelpU(
  1366. HWND hWndMain,
  1367. LPCWSTR lpszHelp,
  1368. UINT uCommand,
  1369. DWORD dwData
  1370. )
  1371. {
  1372. if(FIsWinNT())
  1373. return(WinHelpW(
  1374. hWndMain,
  1375. lpszHelp,
  1376. uCommand,
  1377. dwData
  1378. ));
  1379. else
  1380. return(WinHelp9x(
  1381. hWndMain,
  1382. lpszHelp,
  1383. uCommand,
  1384. dwData
  1385. ));
  1386. }
  1387. LRESULT WINAPI SendMessageU(
  1388. HWND hWnd,
  1389. UINT Msg,
  1390. WPARAM wParam,
  1391. LPARAM lParam
  1392. )
  1393. {
  1394. if(FIsWinNT())
  1395. {
  1396. return(SendMessageW(
  1397. hWnd,
  1398. Msg,
  1399. wParam,
  1400. lParam
  1401. ));
  1402. }
  1403. else
  1404. {
  1405. return(SendMessageA(
  1406. hWnd,
  1407. Msg,
  1408. wParam,
  1409. lParam
  1410. ));
  1411. }
  1412. }
  1413. LONG
  1414. WINAPI
  1415. SendDlgItemMessageU(
  1416. HWND hDlg,
  1417. int nIDDlgItem,
  1418. UINT Msg,
  1419. WPARAM wParam,
  1420. LPARAM lParam
  1421. )
  1422. {
  1423. LPSTR szString = NULL;
  1424. DWORD cbszString = 0;
  1425. LONG lRet;
  1426. // only do string conversion for string type messages
  1427. if (Msg != LB_ADDSTRING &&
  1428. Msg != CB_INSERTSTRING &&
  1429. Msg != WM_SETTEXT &&
  1430. Msg != CB_FINDSTRINGEXACT &&
  1431. Msg != CB_ADDSTRING)
  1432. {
  1433. return(SendDlgItemMessageA(
  1434. hDlg,
  1435. nIDDlgItem,
  1436. Msg,
  1437. wParam,
  1438. lParam
  1439. ));
  1440. }
  1441. if(FIsWinNT())
  1442. {
  1443. return(SendDlgItemMessageW(
  1444. hDlg,
  1445. nIDDlgItem,
  1446. Msg,
  1447. wParam,
  1448. lParam
  1449. ));
  1450. }
  1451. cbszString = WideCharToMultiByte(
  1452. 0, // codepage
  1453. 0, // dwFlags
  1454. (LPWSTR) lParam,
  1455. -1,
  1456. NULL,
  1457. 0,
  1458. NULL,
  1459. NULL);
  1460. if (cbszString == 0)
  1461. {
  1462. return LB_ERR;
  1463. }
  1464. if (NULL == (szString = (LPSTR) malloc(cbszString)))
  1465. {
  1466. return LB_ERR;
  1467. }
  1468. cbszString = WideCharToMultiByte(
  1469. 0, // codepage
  1470. 0, // dwFlags
  1471. (LPWSTR) lParam,
  1472. -1,
  1473. szString,
  1474. cbszString,
  1475. NULL,
  1476. NULL);
  1477. if (cbszString == 0)
  1478. {
  1479. free(szString);
  1480. return LB_ERR;
  1481. }
  1482. lRet = SendDlgItemMessageA(
  1483. hDlg,
  1484. nIDDlgItem,
  1485. Msg,
  1486. wParam,
  1487. (LPARAM) szString
  1488. );
  1489. free(szString);
  1490. return (lRet);
  1491. }
  1492. LPWSTR
  1493. WINAPI
  1494. GetCommandLineU(void)
  1495. {
  1496. LPSTR szCmdLine = NULL;
  1497. LPWSTR wszCmdLine = NULL;
  1498. if (FIsWinNT())
  1499. return (GetCommandLineW());
  1500. szCmdLine = GetCommandLineA();
  1501. wszCmdLine = MkWStr(szCmdLine);
  1502. return (wszCmdLine);
  1503. }
  1504. BOOL
  1505. WINAPI
  1506. IsBadStringPtr9x(IN LPWSTR lpsz, UINT ucchMax)
  1507. {
  1508. BYTE rgb[2048];
  1509. char *sz = NULL;
  1510. BOOL bResult = FALSE;
  1511. if (MkMBStr(rgb, _MAX_PATH, lpsz, &sz))
  1512. bResult = IsBadStringPtrA(sz, ucchMax);
  1513. FreeMBStr(rgb, sz);
  1514. return (bResult);
  1515. }
  1516. BOOL
  1517. WINAPI
  1518. IsBadStringPtrU(IN LPWSTR lpsz, UINT ucchMax)
  1519. {
  1520. if (FIsWinNT())
  1521. return (IsBadStringPtrW(lpsz, ucchMax));
  1522. else
  1523. return (IsBadStringPtr9x(lpsz, ucchMax));
  1524. }
  1525. void
  1526. WINAPI
  1527. OutputDebugString9x(IN LPWSTR lpwsz)
  1528. {
  1529. BYTE rgb[_MAX_PATH];
  1530. char *sz = NULL;
  1531. if (MkMBStr(rgb, _MAX_PATH, lpwsz, &sz))
  1532. OutputDebugStringA(sz);
  1533. FreeMBStr(rgb, sz);
  1534. return;
  1535. }
  1536. void
  1537. WINAPI
  1538. OutputDebugStringU(IN LPWSTR lpwsz)
  1539. {
  1540. //DSIE: bug 171074.
  1541. if (!lpwsz)
  1542. return;
  1543. if (FIsWinNT())
  1544. OutputDebugStringW(lpwsz);
  1545. else
  1546. OutputDebugString9x(lpwsz);
  1547. }
  1548. int
  1549. WINAPI
  1550. DrawText9x(
  1551. HDC hDC,
  1552. LPCWSTR lpString,
  1553. int nCount,
  1554. LPRECT lpRect,
  1555. UINT uFormat
  1556. )
  1557. {
  1558. LPSTR pszText;
  1559. int ret;
  1560. if (NULL == (pszText = (LPSTR) malloc(wcslen(lpString)+1)))
  1561. {
  1562. SetLastError(ERROR_OUTOFMEMORY);
  1563. return(0);
  1564. }
  1565. WideCharToMultiByte(
  1566. 0,
  1567. 0,
  1568. lpString,
  1569. -1,
  1570. pszText,
  1571. wcslen(lpString)+1,
  1572. NULL,
  1573. NULL);
  1574. ret = DrawTextA(hDC, pszText, nCount, lpRect, uFormat);
  1575. free(pszText);
  1576. return ret;
  1577. }
  1578. int
  1579. WINAPI
  1580. DrawTextU(
  1581. HDC hDC,
  1582. LPCWSTR lpString,
  1583. int nCount,
  1584. LPRECT lpRect,
  1585. UINT uFormat
  1586. )
  1587. {
  1588. if (FIsWinNT())
  1589. return (DrawTextW(hDC, lpString, nCount, lpRect, uFormat));
  1590. else
  1591. return (DrawText9x(hDC, lpString, nCount, lpRect, uFormat));
  1592. }
  1593. void CleanUpOpenFileNameA(LPOPENFILENAMEA pOpenFileNameA)
  1594. {
  1595. if (pOpenFileNameA->lpstrFilter != NULL)
  1596. free((void *) pOpenFileNameA->lpstrFilter);
  1597. if (pOpenFileNameA->lpstrCustomFilter != NULL)
  1598. free((void *) pOpenFileNameA->lpstrCustomFilter);
  1599. if (pOpenFileNameA->lpstrFile != NULL)
  1600. free((void *) pOpenFileNameA->lpstrFile);
  1601. if (pOpenFileNameA->lpstrFileTitle)
  1602. free((void *) pOpenFileNameA->lpstrFileTitle);
  1603. if (pOpenFileNameA->lpstrInitialDir)
  1604. free((void *) pOpenFileNameA->lpstrInitialDir);
  1605. if (pOpenFileNameA->lpstrTitle)
  1606. free((void *) pOpenFileNameA->lpstrTitle);
  1607. if (pOpenFileNameA->lpstrDefExt)
  1608. free((void *) pOpenFileNameA->lpstrDefExt);
  1609. }
  1610. //
  1611. // NOTE the following fields in LPOPENFILENAMEW are NOT supported:
  1612. // nFileOffset
  1613. // nFileExtension
  1614. // lpTemplateName
  1615. //
  1616. BOOL ConvertToOpenFileNameA(LPOPENFILENAMEW pOpenFileNameW, LPOPENFILENAMEA pOpenFileNameA)
  1617. {
  1618. int i;
  1619. int cb, cb1, cb2;
  1620. LPSTR pszTemp;
  1621. BOOL fResult = TRUE;
  1622. memset(pOpenFileNameA, 0, sizeof(OPENFILENAMEA));
  1623. pOpenFileNameA->lStructSize = offsetof(OPENFILENAMEA, lpTemplateName) + sizeof(LPCSTR);
  1624. pOpenFileNameA->hwndOwner = pOpenFileNameW->hwndOwner;
  1625. pOpenFileNameA->hInstance = pOpenFileNameW->hInstance;
  1626. //
  1627. // the lpstrFilter field is a list of pairs of NULL terminated strings
  1628. //
  1629. if (pOpenFileNameW->lpstrFilter != NULL)
  1630. {
  1631. i = 0;
  1632. cb = 0;
  1633. while (pOpenFileNameW->lpstrFilter[i] != L'\0')
  1634. {
  1635. cb += WideCharToMultiByte(
  1636. 0,
  1637. 0,
  1638. &(pOpenFileNameW->lpstrFilter[i]),
  1639. -1,
  1640. NULL,
  1641. 0,
  1642. NULL,
  1643. NULL);
  1644. i += wcslen(&(pOpenFileNameW->lpstrFilter[i])) + 1;
  1645. }
  1646. pOpenFileNameA->lpstrFilter = (LPSTR) malloc(cb + 1);
  1647. if (pOpenFileNameA->lpstrFilter == NULL)
  1648. {
  1649. goto OutOfMemory;
  1650. }
  1651. WideCharToMultiByte(
  1652. 0,
  1653. 0,
  1654. pOpenFileNameW->lpstrFilter,
  1655. i + 1,
  1656. (LPSTR)pOpenFileNameA->lpstrFilter,
  1657. cb + 1,
  1658. NULL,
  1659. NULL);
  1660. }
  1661. else
  1662. {
  1663. pOpenFileNameA->lpstrFilter = NULL;
  1664. }
  1665. //
  1666. // the lpstrCustomFilter field is a pair of NULL terminated strings
  1667. //
  1668. if (pOpenFileNameW->lpstrCustomFilter != NULL)
  1669. {
  1670. cb1 = WideCharToMultiByte(
  1671. 0,
  1672. 0,
  1673. pOpenFileNameW->lpstrCustomFilter,
  1674. -1,
  1675. NULL,
  1676. 0,
  1677. NULL,
  1678. NULL);
  1679. cb2 = WideCharToMultiByte(
  1680. 0,
  1681. 0,
  1682. &(pOpenFileNameW->lpstrCustomFilter[wcslen(pOpenFileNameW->lpstrCustomFilter)+1]),
  1683. -1,
  1684. NULL,
  1685. 0,
  1686. NULL,
  1687. NULL);
  1688. pOpenFileNameA->lpstrCustomFilter = (LPSTR) malloc(cb1 + cb2);
  1689. if (pOpenFileNameA->lpstrCustomFilter == NULL)
  1690. {
  1691. goto OutOfMemory;
  1692. }
  1693. WideCharToMultiByte(
  1694. 0,
  1695. 0,
  1696. pOpenFileNameW->lpstrCustomFilter,
  1697. -1,
  1698. pOpenFileNameA->lpstrCustomFilter,
  1699. cb1,
  1700. NULL,
  1701. NULL);
  1702. WideCharToMultiByte(
  1703. 0,
  1704. 0,
  1705. &(pOpenFileNameW->lpstrCustomFilter[wcslen(pOpenFileNameW->lpstrCustomFilter)+1]),
  1706. -1,
  1707. &(pOpenFileNameA->lpstrCustomFilter[cb1]),
  1708. cb2,
  1709. NULL,
  1710. NULL);
  1711. pOpenFileNameA->nMaxCustFilter = cb1 + cb2;
  1712. }
  1713. else
  1714. {
  1715. pOpenFileNameA->lpstrCustomFilter = NULL;
  1716. pOpenFileNameA->nMaxCustFilter = 0;
  1717. }
  1718. pOpenFileNameA->nFilterIndex = pOpenFileNameW->nFilterIndex;
  1719. pOpenFileNameA->lpstrFile = (LPSTR) malloc(pOpenFileNameW->nMaxFile);
  1720. if (pOpenFileNameA->lpstrFile == NULL)
  1721. {
  1722. goto OutOfMemory;
  1723. }
  1724. WideCharToMultiByte(
  1725. 0,
  1726. 0,
  1727. pOpenFileNameW->lpstrFile,
  1728. -1,
  1729. pOpenFileNameA->lpstrFile,
  1730. pOpenFileNameW->nMaxFile,
  1731. NULL,
  1732. NULL);
  1733. pOpenFileNameA->nMaxFile = pOpenFileNameW->nMaxFile;
  1734. if (pOpenFileNameW->lpstrFileTitle != NULL)
  1735. {
  1736. pOpenFileNameA->lpstrFileTitle = (LPSTR) malloc(pOpenFileNameW->nMaxFileTitle);
  1737. if (pOpenFileNameA->lpstrFileTitle == NULL)
  1738. {
  1739. goto OutOfMemory;
  1740. }
  1741. }
  1742. else
  1743. {
  1744. pOpenFileNameA->lpstrFileTitle = NULL;
  1745. }
  1746. pOpenFileNameA->nMaxFileTitle = pOpenFileNameW->nMaxFileTitle;
  1747. if (pOpenFileNameW->lpstrInitialDir != NULL)
  1748. {
  1749. cb = WideCharToMultiByte(
  1750. 0,
  1751. 0,
  1752. pOpenFileNameW->lpstrInitialDir,
  1753. -1,
  1754. NULL,
  1755. 0,
  1756. NULL,
  1757. NULL);
  1758. pOpenFileNameA->lpstrInitialDir = (LPSTR) malloc(cb);
  1759. if (pOpenFileNameA->lpstrInitialDir == NULL)
  1760. {
  1761. goto OutOfMemory;
  1762. }
  1763. WideCharToMultiByte(
  1764. 0,
  1765. 0,
  1766. pOpenFileNameW->lpstrInitialDir,
  1767. -1,
  1768. (LPSTR) pOpenFileNameA->lpstrInitialDir,
  1769. cb,
  1770. NULL,
  1771. NULL);
  1772. }
  1773. else
  1774. {
  1775. pOpenFileNameW->lpstrInitialDir = NULL;
  1776. }
  1777. if (pOpenFileNameW->lpstrTitle != NULL)
  1778. {
  1779. cb = WideCharToMultiByte(
  1780. 0,
  1781. 0,
  1782. pOpenFileNameW->lpstrTitle,
  1783. -1,
  1784. NULL,
  1785. 0,
  1786. NULL,
  1787. NULL);
  1788. pOpenFileNameA->lpstrTitle = (LPSTR) malloc(cb);
  1789. if (pOpenFileNameA->lpstrTitle == NULL)
  1790. {
  1791. goto OutOfMemory;
  1792. }
  1793. WideCharToMultiByte(
  1794. 0,
  1795. 0,
  1796. pOpenFileNameW->lpstrTitle,
  1797. -1,
  1798. (LPSTR) pOpenFileNameA->lpstrTitle,
  1799. cb,
  1800. NULL,
  1801. NULL);
  1802. }
  1803. else
  1804. {
  1805. pOpenFileNameW->lpstrTitle = NULL;
  1806. }
  1807. pOpenFileNameA->Flags = pOpenFileNameW->Flags;
  1808. pOpenFileNameA->nFileOffset = 0;
  1809. pOpenFileNameA->nFileExtension = 0;
  1810. if (pOpenFileNameW->lpstrDefExt != NULL)
  1811. {
  1812. cb = WideCharToMultiByte(
  1813. 0,
  1814. 0,
  1815. pOpenFileNameW->lpstrDefExt,
  1816. -1,
  1817. NULL,
  1818. 0,
  1819. NULL,
  1820. NULL);
  1821. pOpenFileNameA->lpstrDefExt = (LPSTR) malloc(cb);
  1822. if (pOpenFileNameA->lpstrDefExt == NULL)
  1823. {
  1824. goto OutOfMemory;
  1825. }
  1826. WideCharToMultiByte(
  1827. 0,
  1828. 0,
  1829. pOpenFileNameW->lpstrDefExt,
  1830. -1,
  1831. (LPSTR) pOpenFileNameA->lpstrDefExt,
  1832. cb,
  1833. NULL,
  1834. NULL);
  1835. }
  1836. else
  1837. {
  1838. pOpenFileNameW->lpstrDefExt = NULL;
  1839. }
  1840. pOpenFileNameA->lCustData = pOpenFileNameW->lCustData;
  1841. pOpenFileNameA->lpfnHook = pOpenFileNameW->lpfnHook;
  1842. pOpenFileNameA->lpTemplateName = NULL;
  1843. goto Return;
  1844. OutOfMemory:
  1845. CleanUpOpenFileNameA(pOpenFileNameA);
  1846. SetLastError(E_OUTOFMEMORY);
  1847. fResult = FALSE;
  1848. Return:
  1849. return (fResult);
  1850. }
  1851. typedef BOOL (WINAPI * PFNCGETSAVEFILENAMEW)(LPOPENFILENAMEW pOpenFileName);
  1852. typedef BOOL (WINAPI * PFNCGETSAVEFILENAMEA)(LPOPENFILENAMEA pOpenFileName);
  1853. BOOL
  1854. GetSaveFileName9x(
  1855. LPOPENFILENAMEW pOpenFileName
  1856. )
  1857. {
  1858. OPENFILENAMEA OpenFileNameA;
  1859. HINSTANCE h_module;
  1860. PFNCGETSAVEFILENAMEA pfncGetSaveFileNameA;
  1861. BOOL fRet;
  1862. h_module = LoadLibraryA("comdlg32.dll");
  1863. if (h_module == NULL)
  1864. {
  1865. return FALSE;
  1866. }
  1867. if (!ConvertToOpenFileNameA(pOpenFileName, &OpenFileNameA))
  1868. {
  1869. return FALSE;
  1870. }
  1871. pfncGetSaveFileNameA = (PFNCGETSAVEFILENAMEA) GetProcAddress(h_module, "GetSaveFileNameA");
  1872. if (pfncGetSaveFileNameA == NULL)
  1873. {
  1874. CleanUpOpenFileNameA(&OpenFileNameA);
  1875. return FALSE;
  1876. }
  1877. fRet = pfncGetSaveFileNameA(&OpenFileNameA);
  1878. DWORD dwErr = GetLastError();
  1879. if (fRet)
  1880. {
  1881. MultiByteToWideChar(
  1882. 0,
  1883. 0,
  1884. OpenFileNameA.lpstrFile,
  1885. -1,
  1886. pOpenFileName->lpstrFile,
  1887. pOpenFileName->nMaxFile);
  1888. }
  1889. CleanUpOpenFileNameA(&OpenFileNameA);
  1890. FreeLibrary(h_module);
  1891. return fRet;
  1892. }
  1893. BOOL
  1894. GetSaveFileNameU(
  1895. LPOPENFILENAMEW pOpenFileName
  1896. )
  1897. {
  1898. HINSTANCE h_module;
  1899. PFNCGETSAVEFILENAMEW pfncGetSaveFileNameW;
  1900. BOOL fRet;
  1901. if (FIsWinNT())
  1902. {
  1903. h_module = LoadLibraryA("comdlg32.dll");
  1904. if (h_module == NULL)
  1905. {
  1906. return FALSE;
  1907. }
  1908. pfncGetSaveFileNameW = (PFNCGETSAVEFILENAMEW) GetProcAddress(h_module, "GetSaveFileNameW");
  1909. if (pfncGetSaveFileNameW == NULL)
  1910. {
  1911. fRet = FALSE;
  1912. }
  1913. else
  1914. {
  1915. fRet = pfncGetSaveFileNameW(pOpenFileName);
  1916. }
  1917. FreeLibrary(h_module);
  1918. }
  1919. else
  1920. {
  1921. fRet = GetSaveFileName9x(pOpenFileName);
  1922. }
  1923. return fRet;
  1924. }
  1925. typedef BOOL (WINAPI * PFNCGETOPENFILENAMEW)(LPOPENFILENAMEW pOpenFileName);
  1926. typedef BOOL (WINAPI * PFNCGETOPENFILENAMEA)(LPOPENFILENAMEA pOpenFileName);
  1927. BOOL
  1928. GetOpenFileName9x(
  1929. LPOPENFILENAMEW pOpenFileName
  1930. )
  1931. {
  1932. OPENFILENAMEA OpenFileNameA;
  1933. HINSTANCE h_module;
  1934. PFNCGETOPENFILENAMEA pfncGetOpenFileNameA;
  1935. BOOL fRet;
  1936. h_module = LoadLibraryA("comdlg32.dll");
  1937. if (h_module == NULL)
  1938. {
  1939. return FALSE;
  1940. }
  1941. if (!ConvertToOpenFileNameA(pOpenFileName, &OpenFileNameA))
  1942. {
  1943. return FALSE;
  1944. }
  1945. pfncGetOpenFileNameA = (PFNCGETOPENFILENAMEA) GetProcAddress(h_module, "GetOpenFileNameA");
  1946. if (pfncGetOpenFileNameA == NULL)
  1947. {
  1948. return FALSE;
  1949. }
  1950. fRet = pfncGetOpenFileNameA(&OpenFileNameA);
  1951. DWORD dwErr = GetLastError();
  1952. MultiByteToWideChar(
  1953. 0,
  1954. 0,
  1955. OpenFileNameA.lpstrFile,
  1956. -1,
  1957. pOpenFileName->lpstrFile,
  1958. pOpenFileName->nMaxFile);
  1959. CleanUpOpenFileNameA(&OpenFileNameA);
  1960. FreeLibrary(h_module);
  1961. return fRet;
  1962. }
  1963. BOOL
  1964. GetOpenFileNameU(
  1965. LPOPENFILENAMEW pOpenFileName
  1966. )
  1967. {
  1968. HINSTANCE h_module;
  1969. PFNCGETOPENFILENAMEW pfncGetOpenFileNameW;
  1970. BOOL fRet;
  1971. if (FIsWinNT())
  1972. {
  1973. h_module = LoadLibraryA("comdlg32.dll");
  1974. if (h_module == NULL)
  1975. {
  1976. return FALSE;
  1977. }
  1978. pfncGetOpenFileNameW = (PFNCGETOPENFILENAMEW) GetProcAddress(h_module, "GetOpenFileNameW");
  1979. if (pfncGetOpenFileNameW == NULL)
  1980. {
  1981. fRet = FALSE;
  1982. }
  1983. else
  1984. {
  1985. fRet = pfncGetOpenFileNameW(pOpenFileName);
  1986. }
  1987. FreeLibrary(h_module);
  1988. }
  1989. else
  1990. {
  1991. fRet = GetOpenFileName9x(pOpenFileName);
  1992. }
  1993. return fRet;
  1994. }
  1995. #endif // _M_IX86