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.

4634 lines
148 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: cmutoa.cpp
  4. //
  5. // Module: CMUTOA.DLL
  6. //
  7. // Synopsis: This dll is a Unicode to Ansi wrapper that exports AU functions
  8. // that have the function header of the W version of a windows API
  9. // but internally do all the conversions necessary so that the Ansi
  10. // version of the API (A version) can be called. This dll was implemented
  11. // so that a Unicode CM could still run on win9x. The idea was borrowed
  12. // from F. Avery Bishop's April 1999 MSJ article "Design a Single Unicode
  13. // App that Runs on Both Windows 98 and Windows 2000"
  14. //
  15. // Copyright (c) 1999 Microsoft Corporation
  16. //
  17. // Author: quintinb Created 04/25/99
  18. //
  19. //+----------------------------------------------------------------------------
  20. #include <windows.h>
  21. #include <tchar.h>
  22. #include <stdio.h>
  23. #include <shlobj.h>
  24. #include <ras.h>
  25. #include <raserror.h>
  26. #include <shellapi.h>
  27. #include "cmutoa.h"
  28. #include "cmdebug.h"
  29. #include "cm_def.h"
  30. #include "cmutil.h"
  31. #include "cmras.h"
  32. #include "raslink.h"
  33. // raslink text constants
  34. #define _CMUTOA_MODULE
  35. #include "raslink.cpp"
  36. //
  37. // Globals
  38. //
  39. DWORD g_dwTlsIndex;
  40. //
  41. // Function Headers
  42. //
  43. LRESULT WINAPI SendMessageAU(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  44. int WINAPI wvsprintfAU(OUT LPWSTR pszwDest, IN LPCWSTR pszwFmt, IN va_list arglist);
  45. int WINAPI lstrlenAU(IN LPCWSTR lpString);
  46. //+----------------------------------------------------------------------------
  47. //
  48. // Function: DllMain
  49. //
  50. // Synopsis: Main Entry point for the DLL, notice that we use thread local
  51. // storage and initialize it here.
  52. //
  53. // Arguments: HANDLE hDll - instance handle to the dll
  54. // DWORD dwReason - reason the function was called
  55. // LPVOID lpReserved -
  56. //
  57. // Returns: BOOL - TRUE on success
  58. //
  59. // History: quintinb Created 6/24/99
  60. //
  61. //+----------------------------------------------------------------------------
  62. BOOL APIENTRY DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  63. {
  64. if (dwReason == DLL_PROCESS_ATTACH)
  65. {
  66. CMTRACE(TEXT("====================================================="));
  67. CMTRACE1(TEXT(" CMUTOA.DLL - LOADING - Process ID is 0x%x "), GetCurrentProcessId());
  68. CMTRACE(TEXT("====================================================="));
  69. g_dwTlsIndex = TlsAlloc();
  70. if (g_dwTlsIndex == TLS_OUT_OF_INDEXES)
  71. {
  72. return FALSE;
  73. }
  74. DisableThreadLibraryCalls((HMODULE) hDll);
  75. }
  76. else if (dwReason == DLL_PROCESS_DETACH)
  77. {
  78. CMTRACE(TEXT("====================================================="));
  79. CMTRACE1(TEXT(" CMUTOA.DLL - UNLOADING - Process ID is 0x%x "), GetCurrentProcessId());
  80. CMTRACE(TEXT("====================================================="));
  81. //
  82. // free the tls index
  83. //
  84. if (g_dwTlsIndex != TLS_OUT_OF_INDEXES)
  85. {
  86. TlsFree(g_dwTlsIndex);
  87. }
  88. }
  89. return TRUE;
  90. }
  91. //+----------------------------------------------------------------------------
  92. //
  93. // Function: CharNextAU
  94. //
  95. // Synopsis: Unicode to Ansi wrapper for the win32 CharNext API.
  96. //
  97. // Arguments: LPCWSTR lpsz - The string to return the next character of
  98. //
  99. // Returns: LPWSTR -- the Next character in the string, unless the current
  100. // char is a NULL terminator and then the input param
  101. // is returned.
  102. //
  103. // History: quintinb Created 6/24/99
  104. //
  105. //+----------------------------------------------------------------------------
  106. LPWSTR WINAPI CharNextAU(IN LPCWSTR lpsz)
  107. {
  108. LPWSTR pszReturn = (LPWSTR)lpsz;
  109. if (lpsz && (L'\0' != *lpsz))
  110. {
  111. pszReturn++; // this is what _wcsinc does
  112. }
  113. return pszReturn;
  114. }
  115. //+----------------------------------------------------------------------------
  116. //
  117. // Function: CharPrevAU
  118. //
  119. // Synopsis: Unicode to Ansi wrapper for the win32 CharPrev API.
  120. //
  121. // Arguments: LPCWSTR lpszStart - start of the string
  122. // LPCWSTR lpsz - The current position in the string for which we
  123. // want the previous char of
  124. //
  125. //
  126. // Returns: LPWSTR -- the Previous character in the string, unless the current
  127. // char is less than or equal to the Start of the string or
  128. // a NULL string is passed to the function, then lpszStart
  129. // is returned.
  130. //
  131. // History: quintinb Created 6/24/99
  132. //
  133. //+----------------------------------------------------------------------------
  134. LPWSTR WINAPI CharPrevAU(IN LPCWSTR lpszStart, IN LPCWSTR lpszCurrent)
  135. {
  136. LPWSTR pszReturn = (LPWSTR)lpszCurrent;
  137. if (lpszStart && lpszCurrent && (lpszCurrent > lpszStart))
  138. {
  139. pszReturn--; // this is what _wcsdec does
  140. }
  141. else
  142. {
  143. CMASSERTMSG(FALSE, TEXT("NULL String passed to CharPrevAU"));
  144. pszReturn = (LPWSTR)lpszStart;
  145. }
  146. return pszReturn;
  147. }
  148. typedef WINUSERAPI LPSTR (WINAPI *CharLowerOrUpperA)(LPSTR);
  149. //+----------------------------------------------------------------------------
  150. //
  151. // Function: LowerOrUpperHelper
  152. //
  153. // Synopsis: Helper function called by either CharLowerAU or CharUpperAU which have
  154. // basically the same functionality except for the calling of CharLowerA or
  155. // CharUpperA, respectively.
  156. //
  157. // Arguments: LPWSTR lpsz -- either a pointer to a string to convert to its
  158. // lower/upper character version or a single character stored
  159. // in the low word of the pointer to find the lowercase/uppercase
  160. // character for.
  161. //
  162. // Returns: LPWSTR -- lower/upper case version of the string passed in (same as lpsz
  163. // because it is converted in place) or lower/upper case version
  164. // of the character stored in the Low word of lpsz.
  165. //
  166. // History: quintinb Created 01/03/2000
  167. //
  168. //+----------------------------------------------------------------------------
  169. LPWSTR WINAPI LowerOrUpperHelper(IN OUT LPWSTR lpsz, CharLowerOrUpperA pfnLowerOrUpper)
  170. {
  171. LPWSTR pszwReturn = lpsz;
  172. LPSTR pszAnsiTmp = NULL;
  173. if (lpsz)
  174. {
  175. //
  176. // CharLower/CharUpper can be used in two ways. There is a Character mode where the Loword of the
  177. // pointer passed in actually stores the numeric value of the character to get the lowercase/uppercase
  178. // value of. There is also the traditional use, where the whole string is passed in. Thus
  179. // we have to detect which mode we are in and handle it accordingly.
  180. //
  181. if (0 == HIWORD(lpsz))
  182. {
  183. //
  184. // Character Mode
  185. //
  186. CHAR szAnsiTmp[2];
  187. WCHAR szwWideTmp[2];
  188. szwWideTmp[0] = (WCHAR)LOWORD(lpsz);
  189. szwWideTmp[1] = L'\0';
  190. int iChars = WzToSz(szwWideTmp, szAnsiTmp, 2);
  191. if (iChars && (iChars <= 2))
  192. {
  193. pfnLowerOrUpper(szAnsiTmp);
  194. iChars = SzToWz(szAnsiTmp, szwWideTmp, 2);
  195. if (iChars && (iChars <= 2))
  196. {
  197. lpsz = (LPWSTR) ((WORD)szwWideTmp[0]);
  198. pszwReturn = lpsz;
  199. }
  200. else
  201. {
  202. CMASSERTMSG(FALSE, TEXT("LowerOrUpperHelper-- Failed to convert szAnsiTmp back to szwWideTmp."));
  203. }
  204. }
  205. else
  206. {
  207. CMASSERTMSG(FALSE, TEXT("LowerOrUpperHelper -- Failed to convert szwWideTmp to szAnsiTmp."));
  208. }
  209. }
  210. else
  211. {
  212. //
  213. // String Mode
  214. //
  215. pszAnsiTmp = WzToSzWithAlloc(lpsz);
  216. if (!pszAnsiTmp)
  217. {
  218. goto exit;
  219. }
  220. pfnLowerOrUpper(pszAnsiTmp);
  221. //
  222. // Convert back into UNICODE chars in lpsz
  223. //
  224. int iCharCount = (lstrlenAU(lpsz) + 1); // include NULL
  225. int iChars = SzToWz(pszAnsiTmp, lpsz, iCharCount);
  226. if (!iChars || (iChars > iCharCount))
  227. {
  228. CMASSERTMSG(FALSE, TEXT("LowerOrUpperHelper -- Failed to convert pszAnsiTmp to lpsz."));
  229. goto exit;
  230. }
  231. }
  232. }
  233. exit:
  234. CmFree(pszAnsiTmp);
  235. return pszwReturn;
  236. }
  237. //+----------------------------------------------------------------------------
  238. //
  239. // Function: CharLowerAU
  240. //
  241. // Synopsis: Unicode to Ansi wrapper for the win32 CharLower API. Notice that
  242. // we support both the string input parameter and the single character
  243. // input method.
  244. //
  245. // Arguments: LPWSTR lpsz -- either a pointer to a string to convert to its
  246. // lower character version or a single character stored
  247. // in the low word of the pointer to find the lowercase
  248. // character for.
  249. //
  250. // Returns: LPWSTR -- lower case version of the string passed in (same as lpsz
  251. // because it is converted in place) or lower case version
  252. // of the character stored in the Low word of lpsz.
  253. //
  254. // History: quintinb Created 6/24/99
  255. //
  256. //+----------------------------------------------------------------------------
  257. LPWSTR WINAPI CharLowerAU(IN OUT LPWSTR lpsz)
  258. {
  259. return LowerOrUpperHelper(lpsz, CharLowerA);
  260. }
  261. //+----------------------------------------------------------------------------
  262. //
  263. // Function: CharUpperAU
  264. //
  265. // Synopsis: Unicode to Ansi wrapper for the win32 CharUpper API. Notice that
  266. // we support both the string input parameter and the single character
  267. // input method.
  268. //
  269. // Arguments: LPWSTR lpsz -- either a pointer to a string to convert to its
  270. // upper character version or a single character stored
  271. // in the low word of the pointer to find the uppercase
  272. // character for.
  273. //
  274. // Returns: LPWSTR -- upper case version of the string passed in (same as lpsz
  275. // because it is converted in place) or upper case version
  276. // of the character stored in the Low word of lpsz.
  277. //
  278. // History: quintinb Created 6/24/99
  279. //
  280. //+----------------------------------------------------------------------------
  281. LPWSTR WINAPI CharUpperAU(IN OUT LPWSTR lpsz)
  282. {
  283. return LowerOrUpperHelper(lpsz, CharUpperA);
  284. }
  285. //+----------------------------------------------------------------------------
  286. //
  287. // Function: CreateDialogParamAU
  288. //
  289. // Synopsis: Unicode to Ansi wrapper for the win32 CreateDialogParam API. Notice that
  290. // we support both a full string for the lpTemplateName param or only
  291. // a int from MAKEINTRESOURCE (a resource identifier stored in the string
  292. // pointer var).
  293. //
  294. // Arguments: See the win32 API definition
  295. //
  296. // Returns: See the win32 API definition
  297. //
  298. // History: quintinb Created 6/24/99
  299. //
  300. //+----------------------------------------------------------------------------
  301. HWND WINAPI CreateDialogParamAU(IN HINSTANCE hInstance, IN LPCWSTR lpTemplateName, IN HWND hWndParent,
  302. IN DLGPROC lpDialogFunc, IN LPARAM dwInitParam)
  303. {
  304. HWND hWndReturn = NULL;
  305. CHAR szAnsiTemplateName[MAX_PATH+1];
  306. LPSTR pszAnsiTemplateName;
  307. MYDBGASSERT(hInstance);
  308. MYDBGASSERT(lpTemplateName);
  309. MYDBGASSERT(lpDialogFunc);
  310. if (hInstance && lpTemplateName && lpDialogFunc)
  311. {
  312. if (HIWORD(lpTemplateName))
  313. {
  314. //
  315. // We have a full template name that we must convert
  316. //
  317. pszAnsiTemplateName = szAnsiTemplateName;
  318. int iChars = WzToSz(lpTemplateName, pszAnsiTemplateName, MAX_PATH);
  319. if (!iChars || (MAX_PATH < iChars))
  320. {
  321. goto exit;
  322. }
  323. }
  324. else
  325. {
  326. //
  327. // All we need is a cast
  328. //
  329. pszAnsiTemplateName = (LPSTR)lpTemplateName;
  330. }
  331. hWndReturn = CreateDialogParamA(hInstance, pszAnsiTemplateName, hWndParent,
  332. lpDialogFunc, dwInitParam);
  333. }
  334. exit:
  335. return hWndReturn;
  336. }
  337. //+----------------------------------------------------------------------------
  338. //
  339. // Function: CreateDirectoryAU
  340. //
  341. // Synopsis: Unicode to Ansi wrapper for the win32 CreateDirectory API.
  342. //
  343. // Arguments: See the win32 API definition
  344. //
  345. // Returns: See the win32 API definition
  346. //
  347. // History: quintinb Created 6/24/99
  348. //
  349. //+----------------------------------------------------------------------------
  350. BOOL WINAPI CreateDirectoryAU(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  351. {
  352. BOOL bRet = FALSE;
  353. LPSTR pszPathName = WzToSzWithAlloc(lpPathName);
  354. if (pszPathName)
  355. {
  356. bRet = CreateDirectoryA(pszPathName, lpSecurityAttributes);
  357. CmFree(pszPathName);
  358. }
  359. return bRet;
  360. }
  361. //+----------------------------------------------------------------------------
  362. //
  363. // Function: CreateEventAU
  364. //
  365. // Synopsis: Unicode to Ansi wrapper for the win32 CreateEvent API.
  366. //
  367. // Arguments: See the win32 API definition
  368. //
  369. // Returns: See the win32 API definition
  370. //
  371. // History: quintinb Created 6/24/99
  372. //
  373. //+----------------------------------------------------------------------------
  374. HANDLE WINAPI CreateEventAU(IN LPSECURITY_ATTRIBUTES lpEventAttributes, IN BOOL bManualReset,
  375. IN BOOL bInitialState, IN LPCWSTR lpName)
  376. {
  377. CHAR szAnsiName[MAX_PATH+1]; // lpName is limited to MAX_PATH chars according to the docs.
  378. HANDLE hReturn = NULL;
  379. LPSTR pszAnsiName = NULL;
  380. if (lpName) // lpName could be NULL
  381. {
  382. pszAnsiName = szAnsiName;
  383. int uNumChars = WzToSz(lpName, pszAnsiName, MAX_PATH);
  384. if (!uNumChars || (MAX_PATH < uNumChars))
  385. {
  386. CMTRACE(TEXT("CreateEventAU -- Unable to convert lpName"));
  387. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  388. goto exit;
  389. }
  390. }
  391. hReturn = CreateEventA(lpEventAttributes, bManualReset, bInitialState, pszAnsiName);
  392. exit:
  393. return hReturn;
  394. }
  395. //+----------------------------------------------------------------------------
  396. //
  397. // Function: CreateFileMappingAU
  398. //
  399. // Synopsis: Unicode to Ansi wrapper for the win32 CreateFileMapping API.
  400. //
  401. // Arguments: See the win32 API definition
  402. //
  403. // Returns: See the win32 API definition
  404. //
  405. // History: quintinb Created 6/24/99
  406. //
  407. //+----------------------------------------------------------------------------
  408. HANDLE WINAPI CreateFileMappingAU(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  409. IN DWORD flProtect, IN DWORD dwMaximumSizeHigh,
  410. IN DWORD dwMaximumSizeLow, IN LPCWSTR lpName)
  411. {
  412. HANDLE hHandle = NULL;
  413. LPSTR pszName = NULL;
  414. if (lpName) // could be NULL
  415. {
  416. pszName = WzToSzWithAlloc(lpName);
  417. }
  418. if (pszName || (NULL == lpName))
  419. {
  420. hHandle = CreateFileMappingA(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh,
  421. dwMaximumSizeLow, pszName);
  422. CmFree(pszName);
  423. }
  424. return hHandle;
  425. }
  426. //+----------------------------------------------------------------------------
  427. //
  428. // Function: CreateFileAU
  429. //
  430. // Synopsis: Unicode to Ansi wrapper for the win32 CreateFile API.
  431. //
  432. // Arguments: See the win32 API definition
  433. //
  434. // Returns: See the win32 API definition
  435. //
  436. // History: quintinb Created 6/24/99
  437. //
  438. //+----------------------------------------------------------------------------
  439. HANDLE WINAPI CreateFileAU(IN LPCWSTR lpFileName, IN DWORD dwDesiredAccess, IN DWORD dwShareMode,
  440. IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  441. IN DWORD dwCreationDisposition, IN DWORD dwFlagsAndAttributes,
  442. IN HANDLE hTemplateFile)
  443. {
  444. HANDLE hHandle = INVALID_HANDLE_VALUE;
  445. LPSTR pszFileName = WzToSzWithAlloc(lpFileName);
  446. if (pszFileName)
  447. {
  448. hHandle = CreateFileA(pszFileName, dwDesiredAccess, dwShareMode,
  449. lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
  450. hTemplateFile);
  451. CmFree(pszFileName);
  452. }
  453. return hHandle;
  454. }
  455. //+----------------------------------------------------------------------------
  456. //
  457. // Function: CreateMutexAU
  458. //
  459. // Synopsis: Unicode to Ansi wrapper for the win32 CreateMutex API.
  460. //
  461. // Arguments: See the win32 API definition
  462. //
  463. // Returns: See the win32 API definition
  464. //
  465. // History: quintinb Created 6/24/99
  466. //
  467. //+----------------------------------------------------------------------------
  468. HANDLE WINAPI CreateMutexAU(IN LPSECURITY_ATTRIBUTES lpMutexAttributes, IN BOOL bInitialOwner,
  469. IN LPCWSTR lpName)
  470. {
  471. HANDLE hHandle = NULL;
  472. LPSTR pszName = NULL;
  473. if (lpName) // lpName can be NULL, creates an unnamed mutex
  474. {
  475. pszName = WzToSzWithAlloc(lpName);
  476. }
  477. if (pszName || (NULL == lpName))
  478. {
  479. hHandle = CreateMutexA(lpMutexAttributes, bInitialOwner, pszName);
  480. CmFree(pszName);
  481. }
  482. return hHandle;
  483. }
  484. //+----------------------------------------------------------------------------
  485. //
  486. // Function: CreateProcessAU
  487. //
  488. // Synopsis: Unicode to Ansi wrapper for the win32 CreateProcess API.
  489. //
  490. // Arguments: See the win32 API definition
  491. //
  492. // Returns: See the win32 API definition
  493. //
  494. // History: quintinb Created 6/24/99
  495. //
  496. //+----------------------------------------------------------------------------
  497. BOOL WINAPI CreateProcessAU(IN LPCWSTR lpApplicationName, IN LPWSTR lpCommandLine,
  498. IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
  499. IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
  500. IN BOOL bInheritHandles, IN DWORD dwCreationFlags,
  501. IN LPVOID lpEnvironment, IN LPCWSTR lpCurrentDirectory,
  502. IN LPSTARTUPINFOW lpStartupInfo,
  503. OUT LPPROCESS_INFORMATION lpProcessInformation)
  504. {
  505. BOOL bSuccess = FALSE;
  506. //
  507. // Convert the string parameters. Since the environment block is controlled by
  508. // a flag (whether it is Ansi or Unicode) we shouldn't have to touch it here.
  509. //
  510. LPSTR pszAppName = WzToSzWithAlloc(lpApplicationName); // WzToSzWithAlloc will return NULL if the input is NULL
  511. LPSTR pszCmdLine = WzToSzWithAlloc(lpCommandLine);
  512. LPSTR pszCurrentDir = WzToSzWithAlloc(lpCurrentDirectory);
  513. //
  514. // Set up the StartUp Info struct. Note that we don't convert it but pass a blank
  515. // structure. If someone needs startupinfo then they will have to write the conversion
  516. // code. We currently don't use it anywhere.
  517. //
  518. STARTUPINFOA StartUpInfoA;
  519. ZeroMemory(&StartUpInfoA, sizeof(STARTUPINFOA));
  520. StartUpInfoA.cb = sizeof(STARTUPINFOA);
  521. #ifdef DEBUG
  522. STARTUPINFOW CompareStartupInfoWStruct;
  523. ZeroMemory(&CompareStartupInfoWStruct, sizeof(STARTUPINFOW));
  524. CompareStartupInfoWStruct.cb = sizeof(STARTUPINFOW);
  525. CMASSERTMSG((0 == memcmp(lpStartupInfo, &CompareStartupInfoWStruct, sizeof(STARTUPINFOW))), TEXT("CreateProcessAU -- Non-NULL STARTUPINFOW struct passed. Conversion code needs to be written."));
  526. #endif
  527. //
  528. // If we have the Command Line or an App Name go ahead
  529. //
  530. if (pszAppName || pszCmdLine)
  531. {
  532. bSuccess = CreateProcessA(pszAppName, pszCmdLine,
  533. lpProcessAttributes, lpThreadAttributes,
  534. bInheritHandles, dwCreationFlags,
  535. lpEnvironment, pszCurrentDir,
  536. &StartUpInfoA, lpProcessInformation);
  537. }
  538. //
  539. // Cleanup
  540. //
  541. CmFree(pszAppName);
  542. CmFree(pszCmdLine);
  543. CmFree(pszCurrentDir);
  544. return bSuccess;
  545. }
  546. //+----------------------------------------------------------------------------
  547. //
  548. // Function: CreateWindowExAU
  549. //
  550. // Synopsis: Unicode to Ansi wrapper for the win32 CreateWindowEx API. Note that
  551. // we only allow MAX_PATH chars for the ClassName and the WindowName
  552. //
  553. // Arguments: See the win32 API definition
  554. //
  555. // Returns: See the win32 API definition
  556. //
  557. // History: quintinb Created 6/24/99
  558. //
  559. //+----------------------------------------------------------------------------
  560. HWND WINAPI CreateWindowExAU(DWORD dwExStyle, LPCWSTR lpClassNameW, LPCWSTR lpWindowNameW, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  561. {
  562. CHAR szClassNameA [MAX_PATH+1];
  563. CHAR szWindowNameA[MAX_PATH+1];
  564. HWND hReturn = NULL;
  565. if (lpClassNameW && lpWindowNameW)
  566. {
  567. MYDBGASSERT(MAX_PATH >= lstrlenAU(lpClassNameW));
  568. MYDBGASSERT(MAX_PATH >= lstrlenAU(lpWindowNameW));
  569. if (WzToSz(lpClassNameW, szClassNameA, MAX_PATH))
  570. {
  571. if (WzToSz(lpWindowNameW, szWindowNameA, MAX_PATH))
  572. {
  573. hReturn = CreateWindowExA(dwExStyle, szClassNameA, szWindowNameA, dwStyle, x, y,
  574. nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
  575. }
  576. }
  577. }
  578. return hReturn;
  579. }
  580. //+----------------------------------------------------------------------------
  581. //
  582. // Function: DeleteFileAU
  583. //
  584. // Synopsis: Unicode to Ansi wrapper for the win32 DeleteFile API.
  585. //
  586. // Arguments: See the win32 API definition
  587. //
  588. // Returns: See the win32 API definition
  589. //
  590. // History: quintinb Created 6/24/99
  591. //
  592. //+----------------------------------------------------------------------------
  593. BOOL WINAPI DeleteFileAU(IN LPCWSTR lpFileName)
  594. {
  595. BOOL bReturn = FALSE;
  596. LPSTR pszAnsiFileName = WzToSzWithAlloc(lpFileName); // WzToSzWithAlloc will return NULL if lpFileName is NULL
  597. if (pszAnsiFileName)
  598. {
  599. DeleteFileA(pszAnsiFileName);
  600. CmFree(pszAnsiFileName);
  601. }
  602. return bReturn;
  603. }
  604. //+----------------------------------------------------------------------------
  605. //
  606. // Function: DialogBoxParamAU
  607. //
  608. // Synopsis: Unicode to Ansi wrapper for the win32 DialogBoxParam API. Note that
  609. // we don't support the use of a full string name, only ints for the
  610. // lpTemplateName param. We will assert if one is used.
  611. //
  612. // Arguments: See the win32 API definition
  613. //
  614. // Returns: See the win32 API definition
  615. //
  616. // History: quintinb Created 6/24/99
  617. //
  618. //+----------------------------------------------------------------------------
  619. INT_PTR WINAPI DialogBoxParamAU(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
  620. {
  621. MYDBGASSERT(0 == HIWORD(lpTemplateName)); // we don't support or use the full string name
  622. return DialogBoxParamA(hInstance, (LPCSTR) lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
  623. }
  624. //+----------------------------------------------------------------------------
  625. //
  626. // Function: ExpandEnvironmentStringsAU
  627. //
  628. // Synopsis: Unicode to Ansi wrapper for the win32 ExpandEnvironmentStrings API.
  629. // We support allowing the user to size the string by passing in the
  630. // following Str, NULL, 0 just as the API reference mentions.
  631. //
  632. // Arguments: See the win32 API definition
  633. //
  634. // Returns: See the win32 API definition
  635. //
  636. // History: quintinb Created 6/24/99
  637. //
  638. //+----------------------------------------------------------------------------
  639. DWORD WINAPI ExpandEnvironmentStringsAU(IN LPCWSTR lpSrc, OUT LPWSTR lpDst, IN DWORD nSize)
  640. {
  641. DWORD dwReturn = 0;
  642. if (lpSrc)
  643. {
  644. //
  645. //
  646. // Since the user could pass in 0 for the size and a NULL pszAnsiDst because they
  647. // want to size the destination string, we want to handle that case. However,
  648. // Win98 and Win95 machines (not counting WinME) don't honor sizing the buffer
  649. // using a NULL lpDst. We will "fool" these machines by using a buffer of size 1.
  650. // Thus they could call it with Str, NULL, 0 and then allocate the correct size and
  651. // call again. Note that we will return an error if the user passes Str, NULL, x
  652. // because we have no buffer to copy the data returned from ExpandEnvironmentStringsA
  653. // into.
  654. //
  655. LPSTR pszAnsiSrc = WzToSzWithAlloc(lpSrc);
  656. LPSTR pszAnsiDst = (LPSTR)CmMalloc((nSize+1)*sizeof(CHAR));
  657. if (pszAnsiSrc && pszAnsiDst)
  658. {
  659. dwReturn = ExpandEnvironmentStringsA(pszAnsiSrc, pszAnsiDst, nSize);
  660. if (dwReturn && (dwReturn <= nSize))
  661. {
  662. //
  663. // Then the function succeeded and there was sufficient buffer space to hold
  664. // the expanded string. Thus we should convert the results and store it back
  665. // in lpDst.
  666. if (lpDst)
  667. {
  668. if (!SzToWz(pszAnsiDst, lpDst, nSize))
  669. {
  670. CMTRACE(TEXT("ExpandEnvironmentStringsAU -- SzToWz conversion of output param failed."));
  671. dwReturn = 0;
  672. }
  673. }
  674. else
  675. {
  676. CMTRACE(TEXT("ExpandEnvironmentStringsAU -- NULL pointer passed for lpDst"));
  677. dwReturn = 0;
  678. SetLastError(ERROR_INVALID_PARAMETER);
  679. }
  680. }
  681. }
  682. else
  683. {
  684. CMTRACE(TEXT("ExpandEnvironmentStringsAU -- NULL pointer returned for pszAnsiSrc or pszAnsiDst"));
  685. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  686. }
  687. CmFree(pszAnsiSrc);
  688. CmFree(pszAnsiDst);
  689. }
  690. else
  691. {
  692. CMTRACE(TEXT("ExpandEnvironmentStringsAU -- NULL pointer passed for lpSrc"));
  693. SetLastError(ERROR_INVALID_PARAMETER);
  694. }
  695. return dwReturn;
  696. }
  697. //+----------------------------------------------------------------------------
  698. //
  699. // Function: FindResourceExAU
  700. //
  701. // Synopsis: Unicode to Ansi wrapper for the win32 FindResourceEx API.
  702. //
  703. // Arguments: See the win32 API definition
  704. //
  705. // Returns: See the win32 API definition
  706. //
  707. // History: quintinb Created 6/24/99
  708. //
  709. //+----------------------------------------------------------------------------
  710. HRSRC WINAPI FindResourceExAU(IN HMODULE hModule, IN LPCWSTR lpType, IN LPCWSTR lpName, IN WORD wLanguage)
  711. {
  712. HRSRC hReturn = NULL;
  713. LPSTR pszType = NULL;
  714. LPSTR pszName = NULL;
  715. //
  716. // Check the input parameters
  717. //
  718. if (lpType && lpName)
  719. {
  720. //
  721. // Two cases for the lpType and the lpName params. These could just be identifiers. We will know
  722. // if the high word is zero. In that case we just need to do a cast and pass it through. If not
  723. // then we need to actually convert the strings.
  724. //
  725. if (0 == HIWORD(lpType))
  726. {
  727. pszType = (LPSTR)lpType;
  728. }
  729. else
  730. {
  731. pszType = WzToSzWithAlloc(lpType);
  732. }
  733. if (0 == HIWORD(lpName))
  734. {
  735. pszName = (LPSTR)lpName;
  736. }
  737. else
  738. {
  739. pszName = WzToSzWithAlloc(lpName);
  740. }
  741. //
  742. // Finally call FindResourceEx
  743. //
  744. if (pszName && pszType)
  745. {
  746. hReturn = FindResourceExA(hModule, pszType, pszName, wLanguage);
  747. }
  748. else
  749. {
  750. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  751. }
  752. }
  753. else
  754. {
  755. SetLastError(ERROR_INVALID_PARAMETER);
  756. }
  757. //
  758. // Clean up
  759. //
  760. if (0 != HIWORD(pszType))
  761. {
  762. CmFree(pszType);
  763. }
  764. if (0 != HIWORD(pszName))
  765. {
  766. CmFree(pszName);
  767. }
  768. return hReturn;
  769. }
  770. //+----------------------------------------------------------------------------
  771. //
  772. // Function: FindWindowExAU
  773. //
  774. // Synopsis: Unicode to Ansi wrapper for the win32 FindWindowEx API.
  775. //
  776. // Arguments: See the win32 API definition
  777. //
  778. // Returns: See the win32 API definition
  779. //
  780. // History: quintinb Created 6/24/99
  781. //
  782. //+----------------------------------------------------------------------------
  783. HWND WINAPI FindWindowExAU(IN HWND hwndParent, IN HWND hwndChildAfter, IN LPCWSTR pszClass, IN LPCWSTR pszWindow)
  784. {
  785. HWND hReturn = NULL;
  786. LPSTR pszAnsiWindow = NULL;
  787. LPSTR pszAnsiClass = NULL;
  788. if (pszClass)
  789. {
  790. //
  791. // We have two cases for pszClass. It can either be a resource ID (high word zero,
  792. // low word contains the ID) in which case we just need to do a cast or
  793. // it could be a NULL terminated string.
  794. //
  795. if (0 == HIWORD(pszClass))
  796. {
  797. pszAnsiClass = (LPSTR)pszClass;
  798. }
  799. else
  800. {
  801. pszAnsiClass = WzToSzWithAlloc(pszClass);
  802. }
  803. //
  804. // pszWindow could be NULL. That will match all Window titles.
  805. //
  806. if (pszWindow)
  807. {
  808. pszAnsiWindow = WzToSzWithAlloc(pszWindow);
  809. }
  810. //
  811. // Check our allocations and call FindWindowExA
  812. //
  813. if (pszAnsiClass && (!pszWindow || pszAnsiWindow))
  814. {
  815. hReturn = FindWindowExA(hwndParent, hwndChildAfter, pszAnsiClass, pszAnsiWindow);
  816. }
  817. else
  818. {
  819. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  820. }
  821. }
  822. else
  823. {
  824. SetLastError(ERROR_INVALID_PARAMETER);
  825. }
  826. //
  827. // Cleanup
  828. //
  829. if (0 != HIWORD(pszAnsiClass))
  830. {
  831. CmFree(pszAnsiClass);
  832. }
  833. CmFree(pszAnsiWindow);
  834. return hReturn;
  835. }
  836. //+----------------------------------------------------------------------------
  837. //
  838. // Function: GetDateFormatAU
  839. //
  840. // Synopsis: Unicode to Ansi wrapper for the win32 GetDateFormat API.
  841. //
  842. // Arguments: See the win32 API definition
  843. //
  844. // Returns: See the win32 API definition
  845. //
  846. // History: sumitc Created 11/20/00
  847. //
  848. //+----------------------------------------------------------------------------
  849. int WINAPI GetDateFormatAU(IN LCID Locale, IN DWORD dwFlags,
  850. IN CONST SYSTEMTIME *lpDate, IN LPCWSTR lpFormat,
  851. OUT LPWSTR lpDateStr, IN int cchDate)
  852. {
  853. int iReturn = 0;
  854. LPSTR pszAnsiFormat = NULL;
  855. LPSTR pszAnsiBuffer = NULL;
  856. if (lpFormat)
  857. {
  858. pszAnsiFormat = WzToSzWithAlloc(lpFormat);
  859. if (!pszAnsiFormat)
  860. {
  861. CMASSERTMSG(FALSE, TEXT("GetDateFormatAU -- Conversion of lpFormat Failed."));
  862. goto exit;
  863. }
  864. }
  865. else
  866. {
  867. pszAnsiFormat = (LPSTR)lpFormat; // Could be NULL
  868. }
  869. if (lpDateStr && cchDate)
  870. {
  871. pszAnsiBuffer = (LPSTR) CmMalloc(cchDate * sizeof(CHAR));
  872. }
  873. iReturn = GetDateFormatA(Locale, dwFlags, lpDate, pszAnsiFormat, pszAnsiBuffer, cchDate);
  874. if (iReturn && lpDateStr && cchDate && pszAnsiBuffer)
  875. {
  876. SzToWz(pszAnsiBuffer, lpDateStr, cchDate);
  877. }
  878. exit:
  879. CmFree(pszAnsiFormat);
  880. CmFree(pszAnsiBuffer);
  881. return iReturn;
  882. }
  883. //+----------------------------------------------------------------------------
  884. //
  885. // Function: GetDlgItemTextAU
  886. //
  887. // Synopsis: Unicode to Ansi wrapper for the win32 GetDlgItemText API. Note that
  888. // this function makes a WM_GETTEXT window message call using GetDlgItem
  889. // and SendMessageAU. This is how the win32 API function is implemented.
  890. //
  891. // Arguments: See the win32 API definition
  892. //
  893. // Returns: See the win32 API definition
  894. //
  895. // History: quintinb Created 6/24/99
  896. //
  897. //+----------------------------------------------------------------------------
  898. UINT WINAPI GetDlgItemTextAU(IN HWND hDlg, IN int nIDDlgItem, OUT LPWSTR pszwString, IN int nMaxCount)
  899. {
  900. return (int) SendMessageAU(GetDlgItem(hDlg, nIDDlgItem), WM_GETTEXT, (WPARAM) nMaxCount, (LPARAM) pszwString);
  901. }
  902. //+----------------------------------------------------------------------------
  903. //
  904. // Function: GetFileAttributesAU
  905. //
  906. // Synopsis: Unicode to Ansi wrapper for the win32 GetFileAttributes API.
  907. //
  908. // Arguments: See the win32 API definition
  909. //
  910. // Returns: See the win32 API definition
  911. //
  912. // History: sumitc Created 11/08/00
  913. //
  914. //+----------------------------------------------------------------------------
  915. DWORD WINAPI GetFileAttributesAU(LPCWSTR lpFileName)
  916. {
  917. DWORD dwReturn = -1;
  918. LPSTR pszAnsiFileName = WzToSzWithAlloc(lpFileName);
  919. if (pszAnsiFileName)
  920. {
  921. dwReturn = GetFileAttributesA(pszAnsiFileName);
  922. CmFree(pszAnsiFileName);
  923. }
  924. return dwReturn;
  925. }
  926. //+----------------------------------------------------------------------------
  927. //
  928. // Function: GetModuleFileNameAU
  929. //
  930. // Synopsis: Unicode to Ansi wrapper for the win32 GetModuleFileName API.
  931. // Note that we only allow MAX_PATH chars for the module name.
  932. //
  933. // Arguments: See the win32 API definition
  934. //
  935. // Returns: See the win32 API definition
  936. //
  937. // History: quintinb Created 6/24/99
  938. //
  939. //+----------------------------------------------------------------------------
  940. DWORD WINAPI GetModuleFileNameAU(HMODULE hModule, LPWSTR lpFileName, DWORD nSize)
  941. {
  942. DWORD dwReturn = 0;
  943. CHAR pszAnsiFileName[MAX_PATH] = {'\0'} ;
  944. MYDBGASSERT(MAX_PATH >= nSize);
  945. dwReturn = GetModuleFileNameA(hModule, pszAnsiFileName, __min(nSize, MAX_PATH));
  946. if(dwReturn && lpFileName)
  947. {
  948. SzToWz(pszAnsiFileName, lpFileName, __min(nSize, MAX_PATH));
  949. }
  950. return dwReturn;
  951. }
  952. //+----------------------------------------------------------------------------
  953. //
  954. // Function: GetModuleHandleAU
  955. //
  956. // Synopsis: Unicode to Ansi wrapper for the win32 GetModuleHandle API.
  957. // Note that we only allow MAX_PATH chars for the module name.
  958. //
  959. // Arguments: See the win32 API definition
  960. //
  961. // Returns: See the win32 API definition
  962. //
  963. // History: sumitc Created 10/20/2000
  964. //
  965. //+----------------------------------------------------------------------------
  966. HMODULE WINAPI GetModuleHandleAU(LPCWSTR lpModuleName)
  967. {
  968. HMODULE hMod = NULL;
  969. LPSTR pszAnsiModuleName = WzToSzWithAlloc(lpModuleName);
  970. if (pszAnsiModuleName)
  971. {
  972. hMod = GetModuleHandleA(pszAnsiModuleName);
  973. CmFree(pszAnsiModuleName);
  974. }
  975. return hMod;
  976. }
  977. //+----------------------------------------------------------------------------
  978. //
  979. // Function: GetPrivateProfileIntAU
  980. //
  981. // Synopsis: Unicode to Ansi wrapper for the win32 GetPrivateProfileInt API.
  982. //
  983. // Arguments: See the win32 API definition
  984. //
  985. // Returns: See the win32 API definition
  986. //
  987. // History: quintinb Created 6/24/99
  988. //
  989. //+----------------------------------------------------------------------------
  990. UINT WINAPI GetPrivateProfileIntAU(IN LPCWSTR lpAppName, IN LPCWSTR lpKeyName, IN INT nDefault,
  991. IN LPCWSTR lpFileName)
  992. {
  993. UINT uReturn = nDefault;
  994. if (lpAppName && lpKeyName && lpFileName)
  995. {
  996. CHAR pszAnsiAppName[MAX_PATH+1];
  997. CHAR pszAnsiKeyName[MAX_PATH+1];
  998. CHAR pszAnsiFileName[MAX_PATH+1];
  999. BOOL bSuccess = TRUE;
  1000. int nChars;
  1001. nChars = WzToSz(lpAppName, pszAnsiAppName, MAX_PATH);
  1002. bSuccess = bSuccess && nChars && (MAX_PATH >= nChars);
  1003. nChars = WzToSz(lpKeyName, pszAnsiKeyName, MAX_PATH);
  1004. bSuccess = bSuccess && nChars && (MAX_PATH >= nChars);
  1005. nChars = WzToSz(lpFileName, pszAnsiFileName, MAX_PATH);
  1006. bSuccess = bSuccess && nChars && (MAX_PATH >= nChars);
  1007. if (bSuccess)
  1008. {
  1009. uReturn = GetPrivateProfileIntA(pszAnsiAppName, pszAnsiKeyName, nDefault,
  1010. pszAnsiFileName);
  1011. }
  1012. CMASSERTMSG(bSuccess, TEXT("GetPrivateProfileIntAU -- Failed to convert lpAppName, lpKeyName, or lpFileName"));
  1013. }
  1014. return uReturn;
  1015. }
  1016. //+----------------------------------------------------------------------------
  1017. //
  1018. // Function: GetPrivateProfileStringAU
  1019. //
  1020. // Synopsis: Unicode to Ansi wrapper for the win32 GetPrivateProfileString API.
  1021. // Note that either lpAppName or lpKeyName could be NULL. This means
  1022. // that our return buffer will contain multiple lines of NULL terminated
  1023. // text. We must use MultiByteToWideChar directly with a size param
  1024. // to properly convert such a situation.
  1025. //
  1026. // Arguments: See the win32 API definition
  1027. //
  1028. // Returns: See the win32 API definition
  1029. //
  1030. // History: quintinb Created 6/24/99
  1031. //
  1032. //+----------------------------------------------------------------------------
  1033. DWORD WINAPI GetPrivateProfileStringAU(IN LPCWSTR lpAppName, IN LPCWSTR lpKeyName,
  1034. IN LPCWSTR lpDefault, OUT LPWSTR lpReturnedString,
  1035. IN DWORD nSize, IN LPCWSTR lpFileName)
  1036. {
  1037. //
  1038. // Declare all the temp vars we need
  1039. //
  1040. LPSTR pszAnsiAppName = NULL;
  1041. LPSTR pszAnsiKeyName = NULL;
  1042. LPSTR pszAnsiReturnedString = NULL;
  1043. CHAR szAnsiAppName[MAX_PATH+1];
  1044. CHAR szAnsiKeyName[MAX_PATH+1];
  1045. CHAR szAnsiDefault[MAX_PATH+1];
  1046. CHAR szAnsiFileName[MAX_PATH+1];
  1047. DWORD dwReturn = 0;
  1048. int nChars;
  1049. //
  1050. // Check the inputs, note that either lpAppName or lpKeyName may be NULL (or both)
  1051. //
  1052. if (lpDefault && lpReturnedString && nSize && lpFileName)
  1053. {
  1054. if (lpAppName) // pszAnsiAppName already initialized to NULL
  1055. {
  1056. pszAnsiAppName = szAnsiAppName;
  1057. nChars = WzToSz(lpAppName, pszAnsiAppName, MAX_PATH);
  1058. if (!nChars || (MAX_PATH < nChars))
  1059. {
  1060. //
  1061. // Conversion failed.
  1062. //
  1063. goto exit;
  1064. }
  1065. }
  1066. if (lpKeyName) // pszAnsiKeyName already initialized to NULL
  1067. {
  1068. pszAnsiKeyName = szAnsiKeyName;
  1069. nChars = WzToSz(lpKeyName, szAnsiKeyName, MAX_PATH);
  1070. if (!nChars || (MAX_PATH < nChars))
  1071. {
  1072. //
  1073. // Conversion failed.
  1074. //
  1075. goto exit;
  1076. }
  1077. }
  1078. nChars = WzToSz(lpDefault, szAnsiDefault, MAX_PATH);
  1079. if (!nChars || (MAX_PATH < nChars))
  1080. {
  1081. goto exit;
  1082. }
  1083. nChars = WzToSz(lpFileName, szAnsiFileName, MAX_PATH);
  1084. if (!nChars || (MAX_PATH < nChars))
  1085. {
  1086. goto exit;
  1087. }
  1088. //
  1089. // Alloc the Ansi return Buffer
  1090. //
  1091. pszAnsiReturnedString = (LPSTR)CmMalloc(nSize*sizeof(CHAR));
  1092. if (pszAnsiReturnedString)
  1093. {
  1094. dwReturn = GetPrivateProfileStringA(pszAnsiAppName, pszAnsiKeyName, szAnsiDefault,
  1095. pszAnsiReturnedString, nSize, szAnsiFileName);
  1096. if (dwReturn)
  1097. {
  1098. if (pszAnsiAppName && pszAnsiKeyName)
  1099. {
  1100. if (!SzToWz(pszAnsiReturnedString, lpReturnedString, nSize))
  1101. {
  1102. dwReturn = 0;
  1103. }
  1104. }
  1105. else
  1106. {
  1107. //
  1108. // We have multiple lines of text in the return buffer, use MultiByteToWideChar
  1109. // with a size specifier
  1110. //
  1111. if (!MultiByteToWideChar(CP_ACP, 0, pszAnsiReturnedString, dwReturn,
  1112. lpReturnedString, nSize))
  1113. {
  1114. dwReturn = 0;
  1115. }
  1116. }
  1117. }
  1118. }
  1119. }
  1120. exit:
  1121. CmFree(pszAnsiReturnedString);
  1122. return dwReturn;
  1123. }
  1124. //+----------------------------------------------------------------------------
  1125. //
  1126. // Function: GetStringTypeExAU
  1127. //
  1128. // Synopsis: Unicode to Ansi wrapper for the win32 GetStringTypeEx API. Note
  1129. // that because we only use one char at a time with this API, I have
  1130. // limited it to a 10 char static buffer to make it faster.
  1131. //
  1132. // Arguments: See the win32 API definition
  1133. //
  1134. // Returns: See the win32 API definition
  1135. //
  1136. // History: quintinb Created 6/24/99
  1137. //
  1138. //+----------------------------------------------------------------------------
  1139. BOOL WINAPI GetStringTypeExAU(IN LCID Locale, IN DWORD dwInfoType, IN LPCWSTR lpSrcStr,
  1140. IN int cchSrc, OUT LPWORD lpCharType)
  1141. {
  1142. BOOL bReturn = FALSE;
  1143. CHAR szAnsiString[10]; // We should only be using 1 char at a time with this
  1144. if (lpSrcStr && cchSrc)
  1145. {
  1146. MYDBGASSERT(cchSrc <= 10);
  1147. int nCount = WideCharToMultiByte(CP_ACP, 0, lpSrcStr, cchSrc, szAnsiString,
  1148. 9, NULL, NULL);
  1149. if (nCount) // nCount may not exactly equal cchSrc if DBCS chars were necessary
  1150. {
  1151. bReturn = GetStringTypeExA(Locale, dwInfoType, szAnsiString, nCount, lpCharType);
  1152. }
  1153. }
  1154. return bReturn;
  1155. }
  1156. //+----------------------------------------------------------------------------
  1157. //
  1158. // Function: GetSystemDirectoryAU
  1159. //
  1160. // Synopsis: Unicode to Ansi wrapper for the win32 GetSystemDirectory API.
  1161. //
  1162. // Arguments: See the win32 API definition
  1163. //
  1164. // Returns: See the win32 API definition
  1165. //
  1166. // History: quintinb Created 6/24/99
  1167. //
  1168. //+----------------------------------------------------------------------------
  1169. UINT WINAPI GetSystemDirectoryAU(OUT LPWSTR lpBuffer, IN UINT uSize)
  1170. {
  1171. UINT uReturn = 0;
  1172. LPSTR pszAnsiSystemDir;
  1173. pszAnsiSystemDir = uSize ? (LPSTR)CmMalloc(uSize*sizeof(CHAR)) : NULL;
  1174. if (pszAnsiSystemDir || (0 == uSize))
  1175. {
  1176. uReturn = GetSystemDirectoryA(pszAnsiSystemDir, uSize);
  1177. CMASSERTMSG(uReturn, TEXT("GetSystemDirectoryAU -- GetSystemDirectoryAU failed."));
  1178. if (uReturn && lpBuffer && (uSize >= uReturn))
  1179. {
  1180. if (!SzToWz(pszAnsiSystemDir, lpBuffer, uSize))
  1181. {
  1182. //
  1183. // Conversion failed.
  1184. //
  1185. CMASSERTMSG(FALSE, TEXT("GetSystemDirectoryAU -- SzToWz conversion failed."));
  1186. uReturn = 0;
  1187. }
  1188. }
  1189. }
  1190. CmFree(pszAnsiSystemDir);
  1191. return uReturn;
  1192. }
  1193. //+----------------------------------------------------------------------------
  1194. //
  1195. // Function: GetTempFileNameAU
  1196. //
  1197. // Synopsis: Unicode to Ansi wrapper for the win32 GetTempFileName API.
  1198. //
  1199. // Arguments: See the win32 API definition
  1200. //
  1201. // Returns: See the win32 API definition
  1202. //
  1203. // History: quintinb Created 6/24/99
  1204. //
  1205. //+----------------------------------------------------------------------------
  1206. UINT WINAPI GetTempFileNameAU(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique,
  1207. OUT LPWSTR lpTempFileName)
  1208. {
  1209. UINT uReturn = 0;
  1210. if (lpPathName && lpPrefixString && lpTempFileName)
  1211. {
  1212. CHAR szAnsiTempFileName[MAX_PATH+1];
  1213. CHAR szPathName[MAX_PATH+1];
  1214. CHAR szPrefixString[MAX_PATH+1];
  1215. BOOL bSuccess = TRUE;
  1216. int nChars;
  1217. nChars = WzToSz(lpPathName, szPathName, MAX_PATH);
  1218. bSuccess = bSuccess && nChars && (MAX_PATH >= nChars);
  1219. nChars = WzToSz(lpPrefixString, szPrefixString, MAX_PATH);
  1220. bSuccess = bSuccess && nChars && (MAX_PATH >= nChars);
  1221. if (bSuccess)
  1222. {
  1223. uReturn = GetTempFileNameA(szPathName, szPrefixString, uUnique, szAnsiTempFileName);
  1224. if (uReturn)
  1225. {
  1226. if (!SzToWz(szAnsiTempFileName, lpTempFileName, MAX_PATH))
  1227. {
  1228. CMASSERTMSG(FALSE, TEXT("GetTempFileNameAU -- conversion of output buffer failed."));
  1229. uReturn = 0;
  1230. }
  1231. }
  1232. }
  1233. else
  1234. {
  1235. CMASSERTMSG(FALSE, TEXT("GetTempFileNameAU -- conversion of inputs failed."));
  1236. SetLastError(ERROR_INVALID_PARAMETER);
  1237. }
  1238. }
  1239. else
  1240. {
  1241. SetLastError(ERROR_INVALID_PARAMETER);
  1242. }
  1243. return uReturn;
  1244. }
  1245. //+----------------------------------------------------------------------------
  1246. //
  1247. // Function: GetTempPathAU
  1248. //
  1249. // Synopsis: Unicode to Ansi wrapper for the win32 GetTempPath API.
  1250. //
  1251. // Arguments: See the win32 API definition
  1252. //
  1253. // Returns: See the win32 API definition
  1254. //
  1255. // History: quintinb Created 6/24/99
  1256. //
  1257. //+----------------------------------------------------------------------------
  1258. DWORD WINAPI GetTempPathAU(IN DWORD nBufferLength, OUT LPWSTR lpBuffer)
  1259. {
  1260. UINT uReturn = 0;
  1261. LPSTR pszAnsiBuffer = (LPSTR)CmMalloc(nBufferLength*sizeof(CHAR));
  1262. if (pszAnsiBuffer)
  1263. {
  1264. uReturn = GetTempPathA(nBufferLength, pszAnsiBuffer);
  1265. if (uReturn)
  1266. {
  1267. if (!SzToWz(pszAnsiBuffer, lpBuffer, nBufferLength))
  1268. {
  1269. CMASSERTMSG(FALSE, TEXT("GetTempPathAU -- conversion of output buffer failed."));
  1270. uReturn = 0;
  1271. }
  1272. }
  1273. CmFree(pszAnsiBuffer);
  1274. }
  1275. return uReturn;
  1276. }
  1277. //+----------------------------------------------------------------------------
  1278. //
  1279. // Function: GetTimeFormatAU
  1280. //
  1281. // Synopsis: Unicode to Ansi wrapper for the win32 GetTimeFormat API.
  1282. //
  1283. // Arguments: See the win32 API definition
  1284. //
  1285. // Returns: See the win32 API definition
  1286. //
  1287. // History: sumitc Created 11/20/00
  1288. //
  1289. //+----------------------------------------------------------------------------
  1290. int WINAPI GetTimeFormatAU(IN LCID Locale, IN DWORD dwFlags,
  1291. IN CONST SYSTEMTIME *lpTime, IN LPCWSTR lpFormat,
  1292. OUT LPWSTR lpTimeStr, IN int cchTime)
  1293. {
  1294. int iReturn = 0;
  1295. LPSTR pszAnsiFormat = NULL;
  1296. LPSTR pszAnsiBuffer = NULL;
  1297. if (lpFormat)
  1298. {
  1299. pszAnsiFormat = WzToSzWithAlloc(lpFormat);
  1300. if (!pszAnsiFormat)
  1301. {
  1302. CMASSERTMSG(FALSE, TEXT("GetTimeFormatAU -- Conversion of lpFormat Failed."));
  1303. goto exit;
  1304. }
  1305. }
  1306. else
  1307. {
  1308. pszAnsiFormat = (LPSTR)lpFormat; // Could be NULL
  1309. }
  1310. if (lpTimeStr && cchTime)
  1311. {
  1312. pszAnsiBuffer = (LPSTR) CmMalloc(cchTime * sizeof(CHAR));
  1313. }
  1314. iReturn = GetTimeFormatA(Locale, dwFlags, lpTime, pszAnsiFormat, pszAnsiBuffer, cchTime);
  1315. if (iReturn && lpTimeStr && cchTime && pszAnsiBuffer)
  1316. {
  1317. SzToWz(pszAnsiBuffer, lpTimeStr, cchTime);
  1318. }
  1319. exit:
  1320. CmFree(pszAnsiFormat);
  1321. CmFree(pszAnsiBuffer);
  1322. return iReturn;
  1323. }
  1324. //+----------------------------------------------------------------------------
  1325. //
  1326. // Function: GetUserNameAU
  1327. //
  1328. // Synopsis: Unicode to Ansi wrapper for the win32 GetUserName API.
  1329. // Note that we assume the user name will fit in MAX_PATH chars.
  1330. //
  1331. // Arguments: See the win32 API definition
  1332. //
  1333. // Returns: See the win32 API definition
  1334. //
  1335. // History: quintinb Created 6/24/99
  1336. //
  1337. //+----------------------------------------------------------------------------
  1338. BOOL WINAPI GetUserNameAU(OUT LPWSTR lpBuffer, IN OUT LPDWORD pdwSize)
  1339. {
  1340. BOOL bReturn = FALSE;
  1341. if (lpBuffer && pdwSize && *pdwSize)
  1342. {
  1343. MYDBGASSERT(MAX_PATH >= *pdwSize);
  1344. CHAR szAnsiBuffer[MAX_PATH+1]; // API says UNLEN+1 needed but this is less than MAX_PATH
  1345. DWORD dwTemp = MAX_PATH;
  1346. bReturn = GetUserNameA(szAnsiBuffer, &dwTemp);
  1347. if (bReturn)
  1348. {
  1349. if (!SzToWz(szAnsiBuffer, lpBuffer, *pdwSize))
  1350. {
  1351. bReturn = FALSE;
  1352. }
  1353. else
  1354. {
  1355. *pdwSize = lstrlenAU(lpBuffer) + 1;
  1356. }
  1357. }
  1358. }
  1359. else
  1360. {
  1361. SetLastError(ERROR_INVALID_PARAMETER);
  1362. }
  1363. CMASSERTMSG(bReturn, TEXT("GetUserNameAU Failed."));
  1364. return bReturn;
  1365. }
  1366. //+----------------------------------------------------------------------------
  1367. //
  1368. // Function: GetVersionExAU
  1369. //
  1370. // Synopsis: Unicode to Ansi wrapper for the win32 GetVersionEx API. Note that
  1371. // we check to make sure we aren't passed an OSVERSIONINFOEXW struct
  1372. // because that struct is currently NT5 only.
  1373. //
  1374. // Arguments: See the win32 API definition
  1375. //
  1376. // Returns: See the win32 API definition
  1377. //
  1378. // History: quintinb Created 6/24/99
  1379. //
  1380. //+----------------------------------------------------------------------------
  1381. BOOL WINAPI GetVersionExAU(IN OUT LPOSVERSIONINFOW lpVersionInformation)
  1382. {
  1383. BOOL bReturn = FALSE;
  1384. if (lpVersionInformation)
  1385. {
  1386. OSVERSIONINFOA AnsiVersionInfo;
  1387. //
  1388. // Check to make sure we didn't get an OSVERSIONINFOEXW struct instead of a OSVERSIONINFO
  1389. // the EX version is NT5 only we shouldn't be calling this on NT5.
  1390. //
  1391. MYDBGASSERT(lpVersionInformation->dwOSVersionInfoSize != sizeof(_OSVERSIONINFOEXW));
  1392. AnsiVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  1393. bReturn = GetVersionExA(&AnsiVersionInfo);
  1394. if (bReturn)
  1395. {
  1396. //lpVersionInformation.dwOSVersionInfoSize; // should be set appropriately already
  1397. lpVersionInformation->dwMajorVersion = AnsiVersionInfo.dwMajorVersion;
  1398. lpVersionInformation->dwMinorVersion = AnsiVersionInfo.dwMinorVersion;
  1399. lpVersionInformation->dwBuildNumber = AnsiVersionInfo.dwBuildNumber;
  1400. lpVersionInformation->dwPlatformId = AnsiVersionInfo.dwPlatformId;
  1401. if (!SzToWz(AnsiVersionInfo.szCSDVersion, lpVersionInformation->szCSDVersion, 128-1))
  1402. {
  1403. bReturn = FALSE;
  1404. }
  1405. }
  1406. }
  1407. CMASSERTMSG(bReturn, TEXT("GetVersionExAU Failed"));
  1408. return bReturn;
  1409. }
  1410. //+----------------------------------------------------------------------------
  1411. //
  1412. // Function: GetWindowTextAU
  1413. //
  1414. // Synopsis: Unicode to Ansi wrapper for the win32 GetWindowText API. This API
  1415. // is implemented as a WM_GETTEXT message just as the real windows
  1416. // API is.
  1417. //
  1418. // Arguments: See the win32 API definition
  1419. //
  1420. // Returns: See the win32 API definition
  1421. //
  1422. // History: quintinb Created 6/24/99
  1423. //
  1424. //+----------------------------------------------------------------------------
  1425. int WINAPI GetWindowTextAU(HWND hWnd, LPWSTR lpStringW, int nMaxChars)
  1426. {
  1427. return (int) SendMessageAU(hWnd, WM_GETTEXT, (WPARAM) nMaxChars, (LPARAM) lpStringW);
  1428. }
  1429. //+----------------------------------------------------------------------------
  1430. //
  1431. // Function: GetWindowTextAU
  1432. //
  1433. // Synopsis: Unicode to Ansi wrapper for the win32 GetWindowText API. This API
  1434. // is implemented as a WM_GETTEXT message just as the real windows
  1435. // API is. Note that since MF_STRING is 0, we must check to make sure
  1436. // that it isn't one of the other menu item choices (MF_OWNERDRAW,
  1437. // MF_BITMAP, or MF_SEPARATOR). The other MF_ flags are just modifiers
  1438. // for the above basic types.
  1439. //
  1440. // Arguments: See the win32 API definition
  1441. //
  1442. // Returns: See the win32 API definition
  1443. //
  1444. // History: quintinb Created 6/24/99
  1445. //
  1446. //+----------------------------------------------------------------------------
  1447. BOOL WINAPI InsertMenuAU(IN HMENU hMenu, IN UINT uPosition, IN UINT uFlags,
  1448. IN UINT_PTR uIDNewItem, IN LPCWSTR lpNewItem)
  1449. {
  1450. BOOL bReturn = FALSE;
  1451. LPSTR pszAnsiNewItem = NULL;
  1452. BOOL bFreeAnsiNewItem = FALSE;
  1453. if (hMenu)
  1454. {
  1455. //
  1456. // Since MF_STRING == 0, we must check that it is not MF_OWNERDRAW or MF_BITMAP or
  1457. // that it is not MF_SEPARATOR
  1458. //
  1459. if ((0 == (uFlags & MF_BITMAP)) && (0 == (uFlags & MF_OWNERDRAW)) &&
  1460. (0 == (uFlags & MF_SEPARATOR)) && lpNewItem)
  1461. {
  1462. //
  1463. // Then the menu item actually contains a string and we must convert it.
  1464. //
  1465. pszAnsiNewItem = WzToSzWithAlloc(lpNewItem);
  1466. if (!pszAnsiNewItem)
  1467. {
  1468. CMASSERTMSG(FALSE, TEXT("InsertMenuAU -- Conversion of lpNewItem Failed."));
  1469. goto exit;
  1470. }
  1471. bFreeAnsiNewItem = TRUE;
  1472. }
  1473. else
  1474. {
  1475. pszAnsiNewItem = (LPSTR)lpNewItem; // Could be NULL
  1476. }
  1477. bReturn = InsertMenuA(hMenu, uPosition, uFlags, uIDNewItem, pszAnsiNewItem);
  1478. }
  1479. exit:
  1480. if (bFreeAnsiNewItem)
  1481. {
  1482. CmFree(pszAnsiNewItem);
  1483. }
  1484. return bReturn;
  1485. }
  1486. //+----------------------------------------------------------------------------
  1487. //
  1488. // Function: LoadCursorAU
  1489. //
  1490. // Synopsis: Unicode to Ansi wrapper for the win32 LoadCursor API. Note that
  1491. // lpCursorName could be a string or it could be a resource ID from
  1492. // MAKEINTRESOURCE. We assume the cursor name will fit in MAX_PATH
  1493. // chars if it is a string.
  1494. //
  1495. // Arguments: See the win32 API definition
  1496. //
  1497. // Returns: See the win32 API definition
  1498. //
  1499. // History: quintinb Created 6/24/99
  1500. //
  1501. //+----------------------------------------------------------------------------
  1502. HCURSOR WINAPI LoadCursorAU(IN HINSTANCE hInstance, IN LPCWSTR lpCursorName)
  1503. {
  1504. LPSTR pszCursorName;
  1505. CHAR szCursorName[MAX_PATH+1];
  1506. HCURSOR hReturn = NULL;
  1507. if (lpCursorName)
  1508. {
  1509. BOOL bSuccess = TRUE;
  1510. if (0 == HIWORD(lpCursorName))
  1511. {
  1512. pszCursorName = (LPSTR)lpCursorName;
  1513. }
  1514. else
  1515. {
  1516. int nChars;
  1517. pszCursorName = szCursorName;
  1518. nChars = WzToSz(lpCursorName, pszCursorName, MAX_PATH);
  1519. bSuccess = bSuccess && nChars && (MAX_PATH >= nChars);
  1520. }
  1521. if (bSuccess)
  1522. {
  1523. hReturn = LoadCursorA(hInstance, pszCursorName);
  1524. }
  1525. }
  1526. else
  1527. {
  1528. SetLastError(ERROR_INVALID_PARAMETER);
  1529. }
  1530. return hReturn;
  1531. }
  1532. //+----------------------------------------------------------------------------
  1533. //
  1534. // Function: LoadIconAU
  1535. //
  1536. // Synopsis: Unicode to Ansi wrapper for the win32 LoadIcon API. Note that
  1537. // lpIconName could be a string or it could be a resource ID from
  1538. // MAKEINTRESOURCE. We assume the icon name will fit in MAX_PATH
  1539. // chars if it is a string.
  1540. //
  1541. // Arguments: See the win32 API definition
  1542. //
  1543. // Returns: See the win32 API definition
  1544. //
  1545. // History: quintinb Created 6/24/99
  1546. //
  1547. //+----------------------------------------------------------------------------
  1548. HICON WINAPI LoadIconAU(IN HINSTANCE hInstance, IN LPCWSTR lpIconName)
  1549. {
  1550. LPSTR pszIconName;
  1551. CHAR szIconName[MAX_PATH+1];
  1552. HICON hReturn = NULL;
  1553. if (hInstance && lpIconName)
  1554. {
  1555. BOOL bSuccess = TRUE;
  1556. if (0 == HIWORD(lpIconName))
  1557. {
  1558. pszIconName = (LPSTR)lpIconName;
  1559. }
  1560. else
  1561. {
  1562. int nChars;
  1563. pszIconName = szIconName;
  1564. nChars = WzToSz(lpIconName, pszIconName, MAX_PATH);
  1565. bSuccess = bSuccess && nChars && (MAX_PATH >= nChars);
  1566. }
  1567. if (bSuccess)
  1568. {
  1569. hReturn = LoadIconA(hInstance, pszIconName);
  1570. }
  1571. }
  1572. else
  1573. {
  1574. SetLastError(ERROR_INVALID_PARAMETER);
  1575. }
  1576. return hReturn;
  1577. }
  1578. //+----------------------------------------------------------------------------
  1579. //
  1580. // Function: LoadImageAU
  1581. //
  1582. // Synopsis: Unicode to Ansi wrapper for the win32 LoadImage API. Note that
  1583. // pszwName could be a string or it could be a resource ID from
  1584. // MAKEINTRESOURCE. We assume the image name will fit in MAX_PATH
  1585. // chars if it is a string.
  1586. //
  1587. // Arguments: See the win32 API definition
  1588. //
  1589. // Returns: See the win32 API definition
  1590. //
  1591. // History: quintinb Created 6/24/99
  1592. //
  1593. //+----------------------------------------------------------------------------
  1594. HANDLE WINAPI LoadImageAU(IN HINSTANCE hInst, IN LPCWSTR pszwName, IN UINT uType, IN int cxDesired,
  1595. IN int cyDesired, IN UINT fuLoad)
  1596. {
  1597. HANDLE hReturn = NULL;
  1598. MYDBGASSERT(hInst || (LR_LOADFROMFILE & fuLoad)); // we don't support loading OEM images -- implement it if you need it.
  1599. if (pszwName)
  1600. {
  1601. CHAR szAnsiName [MAX_PATH+1];
  1602. LPSTR pszAnsiName;
  1603. if (0 == HIWORD(pszwName))
  1604. {
  1605. pszAnsiName = LPSTR(pszwName);
  1606. }
  1607. else
  1608. {
  1609. pszAnsiName = szAnsiName;
  1610. int iChars = WzToSz(pszwName, pszAnsiName, MAX_PATH);
  1611. if (!iChars || (MAX_PATH < iChars))
  1612. {
  1613. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1614. goto exit;
  1615. }
  1616. }
  1617. hReturn = LoadImageA(hInst, pszAnsiName, uType, cxDesired, cyDesired, fuLoad);
  1618. }
  1619. exit:
  1620. return hReturn;
  1621. }
  1622. //+----------------------------------------------------------------------------
  1623. //
  1624. // Function: LoadLibraryExAU
  1625. //
  1626. // Synopsis: Unicode to Ansi wrapper for the win32 LoadLibraryEx API. Note that
  1627. // we expect the library name to fit in MAX_PATH ANSI chars.
  1628. //
  1629. // Arguments: See the win32 API definition
  1630. //
  1631. // Returns: See the win32 API definition
  1632. //
  1633. // History: quintinb Created 6/24/99
  1634. //
  1635. //+----------------------------------------------------------------------------
  1636. HMODULE WINAPI LoadLibraryExAU(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
  1637. {
  1638. CHAR pszLibFileName[MAX_PATH+1];
  1639. HMODULE hReturn = NULL;
  1640. if (lpLibFileName && (NULL == hFile)) // hFile is reserved, it must be NULL
  1641. {
  1642. if(WzToSz(lpLibFileName, pszLibFileName, MAX_PATH))
  1643. {
  1644. hReturn = LoadLibraryExA(pszLibFileName, hFile, dwFlags);
  1645. }
  1646. }
  1647. return hReturn;
  1648. }
  1649. //+----------------------------------------------------------------------------
  1650. //
  1651. // Function: LoadMenuAU
  1652. //
  1653. // Synopsis: Unicode to Ansi wrapper for the win32 LoadMenu API. Note that
  1654. // lpMenuName could be a string or it could be a resource ID from
  1655. // MAKEINTRESOURCE. We assume the menu name will fit in MAX_PATH
  1656. // chars if it is a string.
  1657. //
  1658. // Arguments: See the win32 API definition
  1659. //
  1660. // Returns: See the win32 API definition
  1661. //
  1662. // History: quintinb Created 6/24/99
  1663. //
  1664. //+----------------------------------------------------------------------------
  1665. HMENU WINAPI LoadMenuAU(IN HINSTANCE hInstance, IN LPCWSTR lpMenuName)
  1666. {
  1667. HMENU hMenuReturn = NULL;
  1668. LPSTR pszAnsiMenuName;
  1669. CHAR szAnsiMenuName[MAX_PATH+1];
  1670. if (hInstance && lpMenuName)
  1671. {
  1672. if (HIWORD(lpMenuName))
  1673. {
  1674. pszAnsiMenuName = szAnsiMenuName;
  1675. int iChars = WzToSz(lpMenuName, pszAnsiMenuName, MAX_PATH);
  1676. if (!iChars || (MAX_PATH < iChars))
  1677. {
  1678. goto exit;
  1679. }
  1680. }
  1681. else
  1682. {
  1683. pszAnsiMenuName = (LPSTR)lpMenuName;
  1684. }
  1685. hMenuReturn = LoadMenuA(hInstance, pszAnsiMenuName);
  1686. }
  1687. exit:
  1688. return hMenuReturn;
  1689. }
  1690. //+----------------------------------------------------------------------------
  1691. //
  1692. // Function: LoadStringAU
  1693. //
  1694. // Synopsis: Unicode to Ansi wrapper for the win32 LoadString API.
  1695. //
  1696. // Arguments: See the win32 API definition
  1697. //
  1698. // Returns: See the win32 API definition
  1699. //
  1700. // History: quintinb Created 6/24/99
  1701. //
  1702. //+----------------------------------------------------------------------------
  1703. int WINAPI LoadStringAU(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax)
  1704. {
  1705. int iReturn = 0;
  1706. if (uID && hInstance) // lpBuffer and nBufferMax could be Zero
  1707. {
  1708. LPSTR pszAnsiBuffer = nBufferMax ? (LPSTR)CmMalloc(nBufferMax*sizeof(CHAR)) : NULL;
  1709. if (pszAnsiBuffer || (0 == nBufferMax))
  1710. {
  1711. iReturn = LoadStringA(hInstance, uID, pszAnsiBuffer, nBufferMax);
  1712. if (lpBuffer && iReturn && (iReturn <= nBufferMax))
  1713. {
  1714. if (!SzToWz(pszAnsiBuffer, lpBuffer, nBufferMax))
  1715. {
  1716. iReturn = 0;
  1717. }
  1718. }
  1719. }
  1720. CmFree(pszAnsiBuffer);
  1721. }
  1722. CMASSERTMSG(iReturn, TEXT("LoadStringAU Failed."));
  1723. return iReturn;
  1724. }
  1725. //+----------------------------------------------------------------------------
  1726. //
  1727. // Function: lstrcatAU
  1728. //
  1729. // Synopsis: Unicode to Ansi wrapper for the win32 lstrcat API. Note that we
  1730. // use wcscat instead of doing a conversion from Unicode to ANSI,
  1731. // then using lstrcatA, and then converting back to Unicode again.
  1732. // That seemed like a lot of effort when wcscat should work just fine.
  1733. //
  1734. // Arguments: See the win32 API definition
  1735. //
  1736. // Returns: See the win32 API definition
  1737. //
  1738. // History: quintinb Created 6/24/99
  1739. //
  1740. //+----------------------------------------------------------------------------
  1741. LPWSTR WINAPI lstrcatAU(IN OUT LPWSTR lpString1, IN LPCWSTR lpString2)
  1742. {
  1743. if (lpString2 && lpString2)
  1744. {
  1745. return wcscat(lpString1, lpString2);
  1746. }
  1747. else
  1748. {
  1749. CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcatAU"));
  1750. return lpString1;
  1751. }
  1752. }
  1753. //+----------------------------------------------------------------------------
  1754. //
  1755. // Function: lstrcmpAU
  1756. //
  1757. // Synopsis: Unicode to Ansi wrapper for the win32 lstrcmp API. Note that we
  1758. // use wcscmp instead of doing a conversion from Unicode to ANSI,
  1759. // then using lstrcmpA, and then converting back to Unicode again.
  1760. // That seemed like a lot of effort when wcscmp should work just fine.
  1761. //
  1762. // Arguments: See the win32 API definition
  1763. //
  1764. // Returns: See the win32 API definition
  1765. //
  1766. // History: quintinb Created 6/24/99
  1767. //
  1768. //+----------------------------------------------------------------------------
  1769. int WINAPI lstrcmpAU(IN LPCWSTR lpString1, IN LPCWSTR lpString2)
  1770. {
  1771. if (lpString1 && lpString2)
  1772. {
  1773. return wcscmp(lpString1, lpString2);
  1774. }
  1775. else
  1776. {
  1777. CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcmpAU"));
  1778. //
  1779. // Wasn't exactly sure what to do on failure since their isn't a failure
  1780. // return value from lstrcmp. I looked at the current implementation
  1781. // and they do something like the following.
  1782. //
  1783. if (lpString1)
  1784. {
  1785. return 1;
  1786. }
  1787. else if (lpString2)
  1788. {
  1789. return -1;
  1790. }
  1791. else
  1792. {
  1793. return 0;
  1794. }
  1795. }
  1796. }
  1797. //+----------------------------------------------------------------------------
  1798. //
  1799. // Function: lstrcmpiAU
  1800. //
  1801. // Synopsis: Unicode to Ansi wrapper for the win32 lstrcmpi API. Note that we
  1802. // use _wcsicmp instead of doing a conversion from Unicode to ANSI,
  1803. // then using lstrcmpiA, and then converting back to Unicode again.
  1804. // That seemed like a lot of effort when _wcsicmp should work just fine.
  1805. //
  1806. // Arguments: See the win32 API definition
  1807. //
  1808. // Returns: See the win32 API definition
  1809. //
  1810. // History: quintinb Created 6/24/99
  1811. //
  1812. //+----------------------------------------------------------------------------
  1813. int WINAPI lstrcmpiAU(IN LPCWSTR lpString1, IN LPCWSTR lpString2)
  1814. {
  1815. if (lpString1 && lpString2)
  1816. {
  1817. return _wcsicmp(lpString1, lpString2);
  1818. }
  1819. else
  1820. {
  1821. CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcmpiAU"));
  1822. //
  1823. // Wasn't exactly sure what to do on failure since their isn't a failure
  1824. // return value from lstrcmp. I looked at the current implementation
  1825. // and they do something like the following.
  1826. //
  1827. if (lpString1)
  1828. {
  1829. return 1;
  1830. }
  1831. else if (lpString2)
  1832. {
  1833. return -1;
  1834. }
  1835. else
  1836. {
  1837. return 0;
  1838. }
  1839. }
  1840. }
  1841. //+----------------------------------------------------------------------------
  1842. //
  1843. // Function: lstrcpyAU
  1844. //
  1845. // Synopsis: Unicode to Ansi wrapper for the win32 lstrcpy API. Note that we
  1846. // use wcscpy instead of doing a conversion from Unicode to ANSI,
  1847. // then using lstrcpyA, and then converting back to Unicode again.
  1848. // That seemed like a lot of effort when wcscpy should work just fine.
  1849. //
  1850. // Arguments: See the win32 API definition
  1851. //
  1852. // Returns: See the win32 API definition
  1853. //
  1854. // History: quintinb Created 6/24/99
  1855. //
  1856. //+----------------------------------------------------------------------------
  1857. LPWSTR WINAPI lstrcpyAU(OUT LPWSTR pszDest, IN LPCWSTR pszSource)
  1858. {
  1859. if (pszDest && pszSource)
  1860. {
  1861. return wcscpy(pszDest, pszSource);
  1862. }
  1863. else
  1864. {
  1865. CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcpyAU"));
  1866. return pszDest;
  1867. }
  1868. }
  1869. //+----------------------------------------------------------------------------
  1870. //
  1871. // Function: lstrcpynAU
  1872. //
  1873. // Synopsis: Unicode to Ansi wrapper for the win32 lstrcpyn API. Note that we
  1874. // use wcsncpy instead of doing a conversion from Unicode to ANSI,
  1875. // then using lstrcpynA, and then converting back to Unicode again.
  1876. // That seemed like a lot of effort when wcsncpy should work just fine.
  1877. //
  1878. // Arguments: See the win32 API definition
  1879. //
  1880. // Returns: See the win32 API definition
  1881. //
  1882. // History: quintinb Created 6/24/99
  1883. //
  1884. //+----------------------------------------------------------------------------
  1885. LPWSTR WINAPI lstrcpynAU(OUT LPWSTR pszDest, IN LPCWSTR pszSource, IN int iMaxLength)
  1886. {
  1887. if (pszDest && pszSource && iMaxLength)
  1888. {
  1889. LPWSTR pszReturn = wcsncpy(pszDest, pszSource, iMaxLength);
  1890. //
  1891. // wcsncpy and lstrcpy behave differently about terminating NULL
  1892. // characters. The last char in the lstrcpyn buffer always gets
  1893. // a TEXT('\0'), whereas wcsncpy doesn't do this. Thus we must
  1894. // NULL the last char before returning.
  1895. //
  1896. pszDest[iMaxLength-1] = TEXT('\0');
  1897. return pszReturn;
  1898. }
  1899. else
  1900. {
  1901. CMASSERTMSG(FALSE, TEXT("Invalid parameter passed to lstrcpynAU"));
  1902. return pszDest;
  1903. }
  1904. }
  1905. //+----------------------------------------------------------------------------
  1906. //
  1907. // Function: lstrlenAU
  1908. //
  1909. // Synopsis: Unicode to Ansi wrapper for the win32 lstrlen API. Note that we
  1910. // use wcslen instead of doing a conversion from Unicode to ANSI,
  1911. // then using lstrlenA, and then converting back to Unicode again.
  1912. // That seemed like a lot of effort when wcslen should work just fine.
  1913. //
  1914. // Arguments: See the win32 API definition
  1915. //
  1916. // Returns: See the win32 API definition
  1917. //
  1918. // History: quintinb Created 6/24/99
  1919. //
  1920. //+----------------------------------------------------------------------------
  1921. int WINAPI lstrlenAU(IN LPCWSTR lpString)
  1922. {
  1923. if (lpString)
  1924. {
  1925. return wcslen(lpString);
  1926. }
  1927. else
  1928. {
  1929. // CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrlenAU"));
  1930. return 0;
  1931. }
  1932. }
  1933. //+----------------------------------------------------------------------------
  1934. //
  1935. // Function: OpenEventAU
  1936. //
  1937. // Synopsis: Unicode to Ansi wrapper for the win32 OpenEvent API.
  1938. //
  1939. // Arguments: See the win32 API definition
  1940. //
  1941. // Returns: See the win32 API definition
  1942. //
  1943. // History: quintinb Created 6/24/99
  1944. //
  1945. //+----------------------------------------------------------------------------
  1946. HANDLE WINAPI OpenEventAU(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
  1947. {
  1948. HANDLE hReturn = NULL;
  1949. if (lpName)
  1950. {
  1951. LPSTR pszAnsiName = WzToSzWithAlloc(lpName);
  1952. if (pszAnsiName)
  1953. {
  1954. hReturn = OpenEventA(dwDesiredAccess, bInheritHandle, pszAnsiName);
  1955. }
  1956. CmFree(pszAnsiName);
  1957. }
  1958. return hReturn;
  1959. }
  1960. //+----------------------------------------------------------------------------
  1961. //
  1962. // Function: OpenFileMappingAU
  1963. //
  1964. // Synopsis: Unicode to Ansi wrapper for the win32 OpenFileMapping API.
  1965. //
  1966. // Arguments: See the win32 API definition
  1967. //
  1968. // Returns: See the win32 API definition
  1969. //
  1970. // History: quintinb Created 6/24/99
  1971. //
  1972. //+----------------------------------------------------------------------------
  1973. HANDLE WINAPI OpenFileMappingAU(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
  1974. {
  1975. HANDLE hReturn = NULL;
  1976. if (lpName)
  1977. {
  1978. LPSTR pszAnsiName = WzToSzWithAlloc(lpName);
  1979. if (pszAnsiName)
  1980. {
  1981. hReturn = OpenFileMappingA(dwDesiredAccess, bInheritHandle, pszAnsiName);
  1982. }
  1983. CmFree(pszAnsiName);
  1984. }
  1985. return hReturn;
  1986. }
  1987. //+----------------------------------------------------------------------------
  1988. //
  1989. // Function: RegCreateKeyExAU
  1990. //
  1991. // Synopsis: Unicode to Ansi wrapper for the win32 RegCreateKeyEx API.
  1992. //
  1993. // Arguments: See the win32 API definition
  1994. //
  1995. // Returns: See the win32 API definition
  1996. //
  1997. // History: quintinb Created 6/24/99
  1998. //
  1999. //+----------------------------------------------------------------------------
  2000. LONG APIENTRY RegCreateKeyExAU(IN HKEY hKey, IN LPCWSTR lpSubKey, IN DWORD Reserved, IN LPWSTR lpClass,
  2001. IN DWORD dwOptions, IN REGSAM samDesired, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  2002. OUT PHKEY phkResult, OUT LPDWORD lpdwDisposition)
  2003. {
  2004. LONG lReturn = ERROR_INVALID_PARAMETER;
  2005. if (lpSubKey)
  2006. {
  2007. LPSTR pszAnsiSubKey = WzToSzWithAlloc(lpSubKey);
  2008. LPSTR pszAnsiClass = lpClass ? WzToSzWithAlloc(lpClass) : NULL;
  2009. if (pszAnsiSubKey && (pszAnsiClass || !lpClass))
  2010. {
  2011. lReturn = RegCreateKeyExA(hKey, pszAnsiSubKey, Reserved, pszAnsiClass,
  2012. dwOptions, samDesired, lpSecurityAttributes,
  2013. phkResult, lpdwDisposition);
  2014. }
  2015. else
  2016. {
  2017. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2018. }
  2019. CmFree(pszAnsiSubKey);
  2020. CmFree(pszAnsiClass);
  2021. }
  2022. CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegCreateKeyExAU Failed."));
  2023. return lReturn;
  2024. }
  2025. //+----------------------------------------------------------------------------
  2026. //
  2027. // Function: RegDeleteKeyAU
  2028. //
  2029. // Synopsis: Unicode to Ansi wrapper for the win32 RegDeleteKey API.
  2030. //
  2031. // Arguments: See the win32 API definition
  2032. //
  2033. // Returns: See the win32 API definition
  2034. //
  2035. // History: quintinb Created 6/24/99
  2036. //
  2037. //+----------------------------------------------------------------------------
  2038. LONG APIENTRY RegDeleteKeyAU(IN HKEY hKey, IN LPCWSTR lpSubKey)
  2039. {
  2040. LONG lReturn = ERROR_INVALID_PARAMETER;
  2041. if (lpSubKey)
  2042. {
  2043. LPSTR pszAnsiSubKey = WzToSzWithAlloc(lpSubKey);
  2044. if (pszAnsiSubKey)
  2045. {
  2046. lReturn = RegDeleteKeyA(hKey, pszAnsiSubKey);
  2047. }
  2048. else
  2049. {
  2050. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2051. }
  2052. CmFree(pszAnsiSubKey);
  2053. }
  2054. CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegDeleteKeyAU Failed."));
  2055. return lReturn;
  2056. }
  2057. //+----------------------------------------------------------------------------
  2058. //
  2059. // Function: RegDeleteValueAU
  2060. //
  2061. // Synopsis: Unicode to Ansi wrapper for the win32 RegDeleteValue API.
  2062. //
  2063. // Arguments: See the win32 API definition
  2064. //
  2065. // Returns: See the win32 API definition
  2066. //
  2067. // History: quintinb Created 6/24/99
  2068. //
  2069. //+----------------------------------------------------------------------------
  2070. LONG APIENTRY RegDeleteValueAU(IN HKEY hKey, IN LPCWSTR lpValueName)
  2071. {
  2072. LONG lReturn = ERROR_INVALID_PARAMETER;
  2073. if (lpValueName)
  2074. {
  2075. LPSTR pszAnsiValueName = WzToSzWithAlloc(lpValueName);
  2076. if (pszAnsiValueName)
  2077. {
  2078. lReturn = RegDeleteValueA(hKey, pszAnsiValueName);
  2079. CmFree(pszAnsiValueName);
  2080. }
  2081. else
  2082. {
  2083. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2084. }
  2085. }
  2086. return lReturn;
  2087. }
  2088. //+----------------------------------------------------------------------------
  2089. //
  2090. // Function: RegEnumKeyExAU
  2091. //
  2092. // Synopsis: Unicode to Ansi wrapper for the win32 RegEnumKeyEx API.
  2093. //
  2094. // Arguments: See the win32 API definition
  2095. //
  2096. // Returns: See the win32 API definition
  2097. //
  2098. // History: quintinb Created 6/24/99
  2099. //
  2100. //+----------------------------------------------------------------------------
  2101. LONG RegEnumKeyExAU(IN HKEY hKey, IN DWORD dwIndex, OUT LPWSTR lpName, IN OUT LPDWORD lpcbName, IN LPDWORD lpReserved, IN OUT LPWSTR lpClass, IN OUT LPDWORD lpcbClass, OUT PFILETIME lpftLastWriteTime)
  2102. {
  2103. LONG lReturn = ERROR_INVALID_PARAMETER;
  2104. if (lpcbName)
  2105. {
  2106. MYDBGASSERT((lpName && *lpcbName) || ((NULL == lpName) && (0 == *lpcbName)));
  2107. LPSTR pszAnsiClass = lpClass ? WzToSzWithAlloc(lpClass) : NULL;
  2108. LPSTR pszTmpBuffer = lpName ? (LPSTR)CmMalloc(*lpcbName) : NULL;
  2109. DWORD dwSizeTmp = lpName ? *lpcbName : 0;
  2110. if (pszTmpBuffer || (NULL == lpName))
  2111. {
  2112. lReturn = RegEnumKeyExA(hKey, dwIndex, pszTmpBuffer, &dwSizeTmp, lpReserved, pszAnsiClass, lpcbClass, lpftLastWriteTime);
  2113. if ((ERROR_SUCCESS == lReturn) && pszTmpBuffer)
  2114. {
  2115. if (!SzToWz(pszTmpBuffer, lpName, (*lpcbName)))
  2116. {
  2117. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2118. }
  2119. else
  2120. {
  2121. *lpcbName = (lstrlenAU((WCHAR*)lpName) + 1);
  2122. }
  2123. }
  2124. }
  2125. else
  2126. {
  2127. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2128. }
  2129. CmFree(pszTmpBuffer);
  2130. }
  2131. return lReturn;
  2132. }
  2133. //+----------------------------------------------------------------------------
  2134. //
  2135. // Function: RegisterClassExAU
  2136. //
  2137. // Synopsis: Unicode to Ansi wrapper for the win32 RegisterClassEx API. Note
  2138. // that we don't deal with the lpszMenuName parameter. If this is
  2139. // needed then conversion code will have to be written.
  2140. //
  2141. // Arguments: See the win32 API definition
  2142. //
  2143. // Returns: See the win32 API definition
  2144. //
  2145. // History: quintinb Created 6/24/99
  2146. //
  2147. //+----------------------------------------------------------------------------
  2148. ATOM WINAPI RegisterClassExAU(CONST WNDCLASSEXW *lpWcw)
  2149. {
  2150. WNDCLASSEXA wca;
  2151. CHAR szClassName[MAX_PATH];
  2152. ATOM ReturnAtom = 0;
  2153. if (lpWcw->lpszClassName)
  2154. {
  2155. if (WzToSz(lpWcw->lpszClassName, szClassName, MAX_PATH))
  2156. {
  2157. wca.cbSize = sizeof(WNDCLASSEXA);
  2158. wca.lpfnWndProc = lpWcw->lpfnWndProc;
  2159. wca.style = lpWcw->style;
  2160. wca.cbClsExtra = lpWcw->cbClsExtra;
  2161. wca.cbWndExtra = lpWcw->cbWndExtra;
  2162. wca.hInstance = lpWcw->hInstance;
  2163. wca.hIcon = lpWcw->hIcon;
  2164. wca.hCursor = lpWcw->hCursor;
  2165. wca.hbrBackground = lpWcw->hbrBackground;
  2166. wca.hIconSm = lpWcw->hIconSm;
  2167. wca.lpszClassName = szClassName;
  2168. MYDBGASSERT(NULL == lpWcw->lpszMenuName);
  2169. wca.lpszMenuName = NULL;
  2170. //
  2171. // Now register the class.
  2172. //
  2173. ReturnAtom = RegisterClassExA(&wca);
  2174. if (0 == ReturnAtom)
  2175. {
  2176. //
  2177. // We want to assert failure unless we failed because the class
  2178. // was already registered. This can happen if something
  2179. // calls two CM entry points without exiting first. A prime
  2180. // example of this is rasrcise.exe. Unfortunately, GetLastError()
  2181. // returns 0 when we try to register the class twice. Thus I
  2182. // will only assert if the ReturnAtom is 0 and dwError is non-zero.
  2183. //
  2184. DWORD dwError = GetLastError();
  2185. CMASSERTMSG(!dwError, TEXT("RegisterClassExAU Failed."));
  2186. }
  2187. }
  2188. }
  2189. return ReturnAtom;
  2190. }
  2191. //+----------------------------------------------------------------------------
  2192. //
  2193. // Function: RegisterWindowMessageAU
  2194. //
  2195. // Synopsis: Unicode to Ansi wrapper for the win32 RegisterWindowMessage API. Note
  2196. // that we expect the message name to fit within MAX_PATH characters.
  2197. //
  2198. // Arguments: See the win32 API definition
  2199. //
  2200. // Returns: See the win32 API definition
  2201. //
  2202. // History: quintinb Created 6/24/99
  2203. //
  2204. //+----------------------------------------------------------------------------
  2205. UINT WINAPI RegisterWindowMessageAU(IN LPCWSTR lpString)
  2206. {
  2207. UINT uReturn = 0;
  2208. if (lpString)
  2209. {
  2210. MYDBGASSERT(MAX_PATH > lstrlenAU(lpString));
  2211. CHAR szAnsiString [MAX_PATH+1];
  2212. if (WzToSz(lpString, szAnsiString, MAX_PATH))
  2213. {
  2214. uReturn = RegisterWindowMessageA(szAnsiString);
  2215. }
  2216. }
  2217. return uReturn;
  2218. }
  2219. //+----------------------------------------------------------------------------
  2220. //
  2221. // Function: RegOpenKeyExAU
  2222. //
  2223. // Synopsis: Unicode to Ansi wrapper for the win32 RegOpenKeyEx API.
  2224. //
  2225. // Arguments: See the win32 API definition
  2226. //
  2227. // Returns: See the win32 API definition
  2228. //
  2229. // History: quintinb Created 6/24/99
  2230. //
  2231. //+----------------------------------------------------------------------------
  2232. LONG APIENTRY RegOpenKeyExAU(IN HKEY hKey, IN LPCWSTR lpSubKey, IN DWORD ulOptions,
  2233. IN REGSAM samDesired, OUT PHKEY phkResult)
  2234. {
  2235. LONG lReturn = ERROR_INVALID_PARAMETER;
  2236. if (lpSubKey)
  2237. {
  2238. LPSTR pszAnsiSubKey = WzToSzWithAlloc(lpSubKey);
  2239. if (pszAnsiSubKey)
  2240. {
  2241. lReturn = RegOpenKeyExA(hKey, pszAnsiSubKey, ulOptions, samDesired, phkResult);
  2242. }
  2243. else
  2244. {
  2245. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2246. }
  2247. CmFree(pszAnsiSubKey);
  2248. }
  2249. // CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegOpenKeyExAU Failed."));
  2250. return lReturn;
  2251. }
  2252. //+----------------------------------------------------------------------------
  2253. //
  2254. // Function: RegQueryValueExAU
  2255. //
  2256. // Synopsis: Unicode to Ansi wrapper for the win32 RegQueryValueEx API. Note that
  2257. // we don't handle the REG_MULTI_SZ type. We would have to have
  2258. // special code to handle it and we currently don't need it. Be careful
  2259. // modifying this function unless you have read and thoroughly understood
  2260. // all of the comments.
  2261. //
  2262. // Arguments: See the win32 API definition
  2263. //
  2264. // Returns: See the win32 API definition
  2265. //
  2266. // History: quintinb Created 6/24/99
  2267. //
  2268. //+----------------------------------------------------------------------------
  2269. LONG APIENTRY RegQueryValueExAU(IN HKEY hKey, IN LPCWSTR lpValueName, IN LPDWORD lpReserved,
  2270. OUT LPDWORD lpType, IN OUT LPBYTE lpData, IN OUT LPDWORD lpcbData)
  2271. {
  2272. LONG lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2273. //
  2274. // lpValueName could be NULL or it could be "". In either case they are after the default
  2275. // entry so just pass NULL (don't convert "").
  2276. //
  2277. LPSTR pszAnsiValueName = (lpValueName && lpValueName[0]) ? WzToSzWithAlloc(lpValueName) : NULL;
  2278. if (pszAnsiValueName || !lpValueName || (TEXT('\0') == lpValueName[0]))
  2279. {
  2280. //
  2281. // lpData could also be NULL, they may not actually want the value just to see if it exists
  2282. //
  2283. LPSTR pszTmpBuffer = lpData ? (LPSTR)CmMalloc(*lpcbData) : NULL;
  2284. if (pszTmpBuffer || !lpData)
  2285. {
  2286. DWORD dwTemp = *lpcbData; // we don't want the original value overwritten
  2287. lReturn = RegQueryValueExA(hKey, pszAnsiValueName, lpReserved, lpType,
  2288. (LPBYTE)pszTmpBuffer, &dwTemp);
  2289. if ((ERROR_SUCCESS == lReturn) && pszTmpBuffer)
  2290. {
  2291. if ((REG_SZ == *lpType) || (REG_EXPAND_SZ == *lpType))
  2292. {
  2293. if (!SzToWz(pszTmpBuffer, (WCHAR*)lpData, (*lpcbData)/sizeof(WCHAR)))
  2294. {
  2295. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2296. }
  2297. else
  2298. {
  2299. *lpcbData = (lstrlenAU((WCHAR*)lpData) + 1) * sizeof(WCHAR);
  2300. }
  2301. }
  2302. else if (REG_MULTI_SZ == *lpType)
  2303. {
  2304. //
  2305. // We currently don't have the parsing logic to convert a Multi_SZ.
  2306. // Since CM doesn't query any keys that return this type, this shouldn't
  2307. // be a problem. However, someday we may need to fill in this code. For
  2308. // now, just assert.
  2309. //
  2310. CMASSERTMSG(FALSE, TEXT("RegQueryValueExAU -- Converion and Parsing code for REG_MULTI_SZ UNIMPLEMENTED."));
  2311. lReturn = ERROR_CALL_NOT_IMPLEMENTED; // closest I could find to E_NOTIMPL
  2312. }
  2313. else
  2314. {
  2315. //
  2316. // Non - text data, nothing to convert so just copy it over
  2317. //
  2318. *lpcbData = dwTemp;
  2319. memcpy(lpData, pszTmpBuffer, dwTemp);
  2320. }
  2321. }
  2322. else
  2323. {
  2324. *lpcbData = dwTemp;
  2325. }
  2326. CmFree (pszTmpBuffer);
  2327. }
  2328. }
  2329. CmFree(pszAnsiValueName);
  2330. // CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegOpenKeyExAU Failed."));
  2331. return lReturn;
  2332. }
  2333. //+----------------------------------------------------------------------------
  2334. //
  2335. // Function: RegSetValueExAU
  2336. //
  2337. // Synopsis: Unicode to Ansi wrapper for the win32 RegSetValueEx API. Note that
  2338. // this wrapper doesn't support writing REG_MULTI_SZ, this code will
  2339. // have to be implemented if we ever need it.
  2340. //
  2341. // Arguments: See the win32 API definition
  2342. //
  2343. // Returns: See the win32 API definition
  2344. //
  2345. // History: quintinb Created 6/24/99
  2346. //
  2347. //+----------------------------------------------------------------------------
  2348. LONG APIENTRY RegSetValueExAU(IN HKEY hKey, IN LPCWSTR lpValueName, IN DWORD Reserved,
  2349. IN DWORD dwType, IN CONST BYTE* lpData, IN DWORD cbData)
  2350. {
  2351. LONG lReturn = ERROR_INVALID_PARAMETER;
  2352. if (lpData)
  2353. {
  2354. LPSTR pszAnsiValueName = (lpValueName && lpValueName[0]) ? WzToSzWithAlloc(lpValueName) : NULL;
  2355. LPSTR pszTmpData = NULL;
  2356. DWORD dwTmpCbData;
  2357. if (pszAnsiValueName || !lpValueName || (TEXT('\0') == lpValueName[0]))
  2358. {
  2359. if ((REG_EXPAND_SZ == dwType) || (REG_SZ == dwType))
  2360. {
  2361. pszTmpData = WzToSzWithAlloc((WCHAR*)lpData);
  2362. if (pszTmpData)
  2363. {
  2364. dwTmpCbData = lstrlenA(pszTmpData) + 1;
  2365. }
  2366. else
  2367. {
  2368. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2369. }
  2370. }
  2371. else if (REG_MULTI_SZ == dwType)
  2372. {
  2373. // We currently don't have the parsing logic to convert a Multi_SZ.
  2374. // Since CM doesn't set any keys that use this type, this shouldn't
  2375. // be a problem. However, someday we may need to fill in this code. For
  2376. // now, just assert.
  2377. //
  2378. CMASSERTMSG(FALSE, TEXT("RegSetValueExAU -- Converion and Parsing code for REG_MULTI_SZ UNIMPLEMENTED."));
  2379. lReturn = ERROR_CALL_NOT_IMPLEMENTED; // closest I could find to E_NOTIMPL
  2380. }
  2381. else
  2382. {
  2383. //
  2384. // No text data, leave the buffer alone
  2385. //
  2386. pszTmpData = (LPSTR)lpData;
  2387. dwTmpCbData = cbData;
  2388. }
  2389. if (pszTmpData)
  2390. {
  2391. lReturn = RegSetValueExA(hKey, pszAnsiValueName, Reserved, dwType,
  2392. (LPBYTE)pszTmpData, dwTmpCbData);
  2393. if ((REG_EXPAND_SZ == dwType) || (REG_SZ == dwType))
  2394. {
  2395. CmFree(pszTmpData);
  2396. }
  2397. }
  2398. CmFree(pszAnsiValueName);
  2399. }
  2400. else
  2401. {
  2402. lReturn = ERROR_NOT_ENOUGH_MEMORY;
  2403. }
  2404. }
  2405. return lReturn;
  2406. }
  2407. //+----------------------------------------------------------------------------
  2408. //
  2409. // Function: SearchPathAU
  2410. //
  2411. // Synopsis: Unicode to Ansi wrapper for the win32 SearchPath API. Note that
  2412. // this wrapper uses wcsrchr to fix up the lpFilePart parameter in
  2413. // the converted return buffer.
  2414. //
  2415. // Arguments: See the win32 API definition
  2416. //
  2417. // Returns: See the win32 API definition
  2418. //
  2419. // History: quintinb Created 6/24/99
  2420. //
  2421. //+----------------------------------------------------------------------------
  2422. DWORD WINAPI SearchPathAU(IN LPCWSTR lpPath, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension,
  2423. IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
  2424. {
  2425. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  2426. if (lpFileName && (L'\0' != lpFileName[0]))
  2427. {
  2428. CHAR szAnsiPath[MAX_PATH+1];
  2429. CHAR szAnsiFileName[MAX_PATH+1];
  2430. CHAR szAnsiExt[MAX_PATH+1];
  2431. LPSTR pszAnsiPath;
  2432. LPSTR pszAnsiExt;
  2433. int iChars;
  2434. //
  2435. // Convert the path if it exists
  2436. //
  2437. if (lpPath && (L'\0' != lpPath[0]))
  2438. {
  2439. pszAnsiPath = szAnsiPath;
  2440. MYVERIFY(0 != WzToSz(lpPath, pszAnsiPath, MAX_PATH));
  2441. }
  2442. else
  2443. {
  2444. pszAnsiPath = NULL;
  2445. }
  2446. //
  2447. // Convert the extension if it exists
  2448. //
  2449. if (lpExtension && (L'\0' != lpExtension[0]))
  2450. {
  2451. pszAnsiExt = szAnsiExt;
  2452. MYVERIFY(0 != WzToSz(lpExtension, pszAnsiExt, MAX_PATH));
  2453. }
  2454. else
  2455. {
  2456. pszAnsiExt = NULL;
  2457. }
  2458. //
  2459. // Convert the file name, which must exist
  2460. //
  2461. iChars = WzToSz(lpFileName, szAnsiFileName, MAX_PATH);
  2462. if (iChars && (MAX_PATH >= iChars))
  2463. {
  2464. LPSTR pszAnsiBuffer = (LPSTR)CmMalloc(nBufferLength);
  2465. if (pszAnsiBuffer)
  2466. {
  2467. dwReturn = SearchPathA(pszAnsiPath, szAnsiFileName, pszAnsiExt, nBufferLength,
  2468. pszAnsiBuffer, NULL);
  2469. if (dwReturn && lpBuffer)
  2470. {
  2471. //
  2472. // We have a successful search. Now convert the output buffer
  2473. //
  2474. iChars = SzToWz(pszAnsiBuffer, lpBuffer, nBufferLength);
  2475. if (!iChars || (nBufferLength < (DWORD)iChars))
  2476. {
  2477. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  2478. }
  2479. else
  2480. {
  2481. //
  2482. // Fix up lpFilePart
  2483. //
  2484. if (lpFilePart)
  2485. {
  2486. //
  2487. // Find the last slash
  2488. //
  2489. *lpFilePart = wcsrchr(lpBuffer, L'\\');
  2490. if (*lpFilePart)
  2491. {
  2492. //
  2493. // Increment
  2494. //
  2495. (*lpFilePart)++;
  2496. }
  2497. }
  2498. }
  2499. }
  2500. CmFree(pszAnsiBuffer);
  2501. }
  2502. }
  2503. }
  2504. return dwReturn;
  2505. }
  2506. //+----------------------------------------------------------------------------
  2507. //
  2508. // Function: SendDlgItemMessageAU
  2509. //
  2510. // Synopsis: Unicode to Ansi wrapper for the win32 SendDlgItemMessage API. Note that
  2511. // this wrapper uses GetDlgItem and SendMessage just as the Win32
  2512. // implementation of the API does.
  2513. //
  2514. // Arguments: See the win32 API definition
  2515. //
  2516. // Returns: See the win32 API definition
  2517. //
  2518. // History: quintinb Created 6/24/99
  2519. //
  2520. //+----------------------------------------------------------------------------
  2521. LONG_PTR WINAPI SendDlgItemMessageAU(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)
  2522. {
  2523. LONG lReturn = 0;
  2524. HWND hWnd = GetDlgItem(hDlg, nIDDlgItem);
  2525. if (hWnd)
  2526. {
  2527. //
  2528. // Rather than going through SendDlgItemMessageA, we just
  2529. // do what the system does, i.e., go through
  2530. // SendMessage
  2531. //
  2532. lReturn = SendMessageAU(hWnd, Msg, wParam, lParam);
  2533. }
  2534. return lReturn;
  2535. }
  2536. //+----------------------------------------------------------------------------
  2537. //
  2538. // Function: SendMessageAU
  2539. //
  2540. // Synopsis: Unicode to Ansi wrapper for the win32 SendMessage API. This
  2541. // wrapper attempts to handle all of the Windows Messages that
  2542. // need conversion, either before the message is sent or after it
  2543. // returns. Obviously this is an inexact science. I have checked
  2544. // and tested all of the message types currently in CM but new ones
  2545. // may be added at some point. I owe much of this function to
  2546. // F. Avery Bishop and his sample code.
  2547. //
  2548. // Arguments: See the win32 API definition
  2549. //
  2550. // Returns: See the win32 API definition
  2551. //
  2552. // History: quintinb Created 6/24/99
  2553. //
  2554. //+----------------------------------------------------------------------------
  2555. LRESULT WINAPI SendMessageAU(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  2556. {
  2557. LRESULT lResult = 0;
  2558. LPVOID lpTempBuffer = NULL;
  2559. int nLength = 0;
  2560. CHAR cCharA[3] ;
  2561. WCHAR cCharW[3] ;
  2562. //
  2563. // Preprocess messages that pass chars and strings via wParam and lParam
  2564. //
  2565. switch (Msg)
  2566. {
  2567. //
  2568. // Single Unicode Character in wParam. Convert Unicode character
  2569. // to ANSI and pass lParam as is.
  2570. //
  2571. case EM_SETPASSWORDCHAR: // wParam is char, lParam = 0
  2572. case WM_CHAR: //*wParam is char, lParam = key data
  2573. case WM_SYSCHAR: // wParam is char, lParam = key data
  2574. // Note that we don't handle LeadByte and TrailBytes for
  2575. // these two cases. An application should send WM_IME_CHAR
  2576. // in these cases anyway
  2577. case WM_DEADCHAR: // wParam is char, lParam = key data
  2578. case WM_SYSDEADCHAR: // wParam is char, lParam = key data
  2579. case WM_IME_CHAR: //*
  2580. cCharW[0] = (WCHAR) wParam ;
  2581. cCharW[1] = L'\0' ;
  2582. if (!WzToSz(cCharW, cCharA, 3))
  2583. {
  2584. return FALSE;
  2585. }
  2586. if(Msg == WM_IME_CHAR)
  2587. {
  2588. wParam = (cCharA[1] & 0x00FF) | (cCharA[0] << 8);
  2589. }
  2590. else
  2591. {
  2592. wParam = cCharA[0];
  2593. }
  2594. wParam &= 0x0000FFFF;
  2595. break;
  2596. //
  2597. // In the following cases, lParam is pointer to an IN buffer containing
  2598. // text to send to window.
  2599. // Preprocess by converting from Unicode to ANSI
  2600. //
  2601. case CB_ADDSTRING: // wParam = 0, lParm = lpStr, buffer to add
  2602. case LB_ADDSTRING: // wParam = 0, lParm = lpStr, buffer to add
  2603. case CB_DIR: // wParam = file attributes, lParam = lpszFileSpec buffer
  2604. case LB_DIR: // wParam = file attributes, lParam = lpszFileSpec buffer
  2605. case CB_FINDSTRING: // wParam = start index, lParam = lpszFind
  2606. case LB_FINDSTRING: // wParam = start index, lParam = lpszFind
  2607. case CB_FINDSTRINGEXACT: // wParam = start index, lParam = lpszFind
  2608. case LB_FINDSTRINGEXACT: // wParam = start index, lParam = lpszFind
  2609. case CB_INSERTSTRING: //*wParam = index, lParam = lpszString to insert
  2610. case LB_INSERTSTRING: //*wParam = index, lParam = lpszString to insert
  2611. case CB_SELECTSTRING: // wParam = start index, lParam = lpszFind
  2612. case LB_SELECTSTRING: // wParam = start index, lParam = lpszFind
  2613. case WM_SETTEXT: //*wParam = 0, lParm = lpStr, buffer to set
  2614. {
  2615. if (NULL != (LPWSTR) lParam)
  2616. {
  2617. nLength = 2*lstrlenAU((LPWSTR)lParam) + 1; // Need double length for DBCS characters
  2618. lpTempBuffer = (LPVOID)CmMalloc(nLength);
  2619. }
  2620. if (!lpTempBuffer || (!WzToSz((LPWSTR)lParam, (LPSTR)lpTempBuffer, nLength)))
  2621. {
  2622. CmFree(lpTempBuffer);
  2623. return FALSE;
  2624. }
  2625. lParam = (LPARAM) lpTempBuffer;
  2626. break ;
  2627. }
  2628. }
  2629. // This is where the actual SendMessage takes place
  2630. lResult = SendMessageA(hWnd, Msg, wParam, lParam) ;
  2631. nLength = 0;
  2632. if(lResult > 0)
  2633. {
  2634. switch (Msg)
  2635. {
  2636. //
  2637. // For these cases, lParam is a pointer to an OUT buffer that received text from
  2638. // SendMessageA in ANSI. Convert to Unicode and send back.
  2639. //
  2640. case WM_GETTEXT: // wParam = numCharacters, lParam = lpBuff to RECEIVE string
  2641. case WM_ASKCBFORMATNAME: // wParam = nBufferSize, lParam = lpBuff to RECEIVE string
  2642. nLength = (int) wParam;
  2643. if(!nLength)
  2644. {
  2645. break;
  2646. }
  2647. case CB_GETLBTEXT: // wParam = index, lParam = lpBuff to RECEIVE string
  2648. case EM_GETLINE: // wParam = Line no, lParam = lpBuff to RECEIVE string
  2649. if(!nLength)
  2650. {
  2651. nLength = lstrlenA((LPSTR) lParam) + 1 ;
  2652. }
  2653. lpTempBuffer = (LPVOID) CmMalloc(nLength*sizeof(WCHAR));
  2654. if(!lpTempBuffer || (!SzToWz((LPCSTR) lParam, (LPWSTR) lpTempBuffer, nLength)))
  2655. {
  2656. *((LPWSTR) lParam) = L'\0';
  2657. CmFree(lpTempBuffer);
  2658. return FALSE;
  2659. }
  2660. lstrcpyAU((LPWSTR) lParam, (LPWSTR) lpTempBuffer) ;
  2661. }
  2662. }
  2663. if(lpTempBuffer != NULL)
  2664. {
  2665. CmFree(lpTempBuffer);
  2666. }
  2667. return lResult;
  2668. }
  2669. //+----------------------------------------------------------------------------
  2670. //
  2671. // Function: SetCurrentDirectoryAU
  2672. //
  2673. // Synopsis: Unicode to Ansi wrapper for the win32 SetCurrentDirectory API.
  2674. // Note that we expect the directory path to fit in MAX_PATH chars.
  2675. //
  2676. // Arguments: See the win32 API definition
  2677. //
  2678. // Returns: See the win32 API definition
  2679. //
  2680. // History: quintinb Created 6/24/99
  2681. //
  2682. //+----------------------------------------------------------------------------
  2683. BOOL SetCurrentDirectoryAU(LPCWSTR pszwPathName)
  2684. {
  2685. BOOL bReturn = FALSE;
  2686. if (pszwPathName && (L'\0' != pszwPathName[0]))
  2687. {
  2688. CHAR szAnsiPath[MAX_PATH+1];
  2689. int iChars = WzToSz(pszwPathName, szAnsiPath, MAX_PATH);
  2690. if (iChars && (MAX_PATH >= iChars))
  2691. {
  2692. bReturn = SetCurrentDirectoryA(szAnsiPath);
  2693. }
  2694. }
  2695. return bReturn;
  2696. }
  2697. //+----------------------------------------------------------------------------
  2698. //
  2699. // Function: SetDlgItemTextAU
  2700. //
  2701. // Synopsis: Unicode to Ansi wrapper for the win32 SetDlgItemText API.
  2702. // This function calls SendMessageAU with a WM_SETTEXT and the
  2703. // appropriate Dialog Item from GetDlgItem.
  2704. //
  2705. // Arguments: See the win32 API definition
  2706. //
  2707. // Returns: See the win32 API definition
  2708. //
  2709. // History: quintinb Created 6/24/99
  2710. //
  2711. //+----------------------------------------------------------------------------
  2712. BOOL WINAPI SetDlgItemTextAU(IN HWND hDlg, IN int nIDDlgItem, IN LPCWSTR pszwString)
  2713. {
  2714. return (BOOL) (0 < SendMessageAU(GetDlgItem(hDlg, nIDDlgItem), WM_SETTEXT, (WPARAM) 0, (LPARAM) pszwString));
  2715. }
  2716. //+----------------------------------------------------------------------------
  2717. //
  2718. // Function: SetWindowTextAU
  2719. //
  2720. // Synopsis: Unicode to Ansi wrapper for the win32 SetWindowText API.
  2721. // This function calls SendMessageAU with a WM_SETTEXT.
  2722. //
  2723. // Arguments: See the win32 API definition
  2724. //
  2725. // Returns: See the win32 API definition
  2726. //
  2727. // History: quintinb Created 6/24/99
  2728. //
  2729. //+----------------------------------------------------------------------------
  2730. BOOL WINAPI SetWindowTextAU(HWND hWnd, LPCWSTR pszwString)
  2731. {
  2732. return (BOOL) (0 < SendMessageAU(hWnd, WM_SETTEXT, 0, (LPARAM) pszwString));
  2733. }
  2734. //+----------------------------------------------------------------------------
  2735. //
  2736. // Function: UnregisterClassAU
  2737. //
  2738. // Synopsis: Unicode to Ansi wrapper for the win32 UnregisterClass API.
  2739. //
  2740. // Arguments: See the win32 API definition
  2741. //
  2742. // Returns: See the win32 API definition
  2743. //
  2744. // History: quintinb Created 6/24/99
  2745. //
  2746. //+----------------------------------------------------------------------------
  2747. BOOL WINAPI UnregisterClassAU(IN LPCWSTR lpClassName, IN HINSTANCE hInstance)
  2748. {
  2749. BOOL bReturn = FALSE;
  2750. if (lpClassName)
  2751. {
  2752. LPSTR pszAnsiClassName = WzToSzWithAlloc(lpClassName);
  2753. if (pszAnsiClassName)
  2754. {
  2755. bReturn = UnregisterClassA(pszAnsiClassName, hInstance);
  2756. }
  2757. CmFree(pszAnsiClassName);
  2758. }
  2759. return bReturn;
  2760. }
  2761. //+----------------------------------------------------------------------------
  2762. //
  2763. // Function: WinHelpAU
  2764. //
  2765. // Synopsis: Unicode to Ansi wrapper for the win32 WinHelp API.
  2766. //
  2767. // Arguments: See the win32 API definition
  2768. //
  2769. // Returns: See the win32 API definition
  2770. //
  2771. // History: quintinb Created 6/24/99
  2772. //
  2773. //+----------------------------------------------------------------------------
  2774. BOOL WINAPI WinHelpAU(IN HWND hWndMain, IN LPCWSTR lpszHelp, IN UINT uCommand, IN ULONG_PTR dwData)
  2775. {
  2776. BOOL bReturn = FALSE;
  2777. if (lpszHelp)
  2778. {
  2779. LPSTR pszAnsiHelp = WzToSzWithAlloc(lpszHelp);
  2780. if (pszAnsiHelp)
  2781. {
  2782. bReturn = WinHelpA(hWndMain, pszAnsiHelp, uCommand, dwData);
  2783. }
  2784. CmFree(pszAnsiHelp);
  2785. }
  2786. return bReturn;
  2787. }
  2788. //+----------------------------------------------------------------------------
  2789. //
  2790. // Function: WritePrivateProfileStringAU
  2791. //
  2792. // Synopsis: Unicode to Ansi wrapper for the win32 WritePrivateProfileString API.
  2793. // Note that we expect lpAppName, lpKeyName, and lpFileName to all
  2794. // fit in MAX_PATH chars.
  2795. //
  2796. // Arguments: See the win32 API definition
  2797. //
  2798. // Returns: See the win32 API definition
  2799. //
  2800. // History: quintinb Created 6/24/99
  2801. //
  2802. //+----------------------------------------------------------------------------
  2803. BOOL WINAPI WritePrivateProfileStringAU(IN LPCWSTR lpAppName, IN LPCWSTR lpKeyName,
  2804. IN LPCWSTR lpString, IN LPCWSTR lpFileName)
  2805. {
  2806. BOOL bReturn = FALSE;
  2807. //
  2808. // Check inputs, but note that either lpKeyName or lpString could be NULL
  2809. //
  2810. if (lpAppName && lpFileName)
  2811. {
  2812. CHAR szAnsiAppName[MAX_PATH+1];
  2813. CHAR szAnsiFileName[MAX_PATH+1];
  2814. CHAR szAnsiKeyName[MAX_PATH+1];
  2815. LPSTR pszAnsiKeyName = NULL;
  2816. LPSTR pszAnsiString;
  2817. if (WzToSz(lpAppName, szAnsiAppName, MAX_PATH))
  2818. {
  2819. if (WzToSz(lpFileName, szAnsiFileName, MAX_PATH))
  2820. {
  2821. if (lpKeyName)
  2822. {
  2823. pszAnsiKeyName = szAnsiKeyName;
  2824. WzToSz(lpKeyName, pszAnsiKeyName, MAX_PATH);
  2825. }
  2826. // else pszAnsiKeyName was already init-ed to NULL
  2827. if (pszAnsiKeyName || !lpKeyName)
  2828. {
  2829. pszAnsiString = lpString ? WzToSzWithAlloc(lpString) : NULL;
  2830. if (pszAnsiString || (!lpString))
  2831. {
  2832. bReturn = WritePrivateProfileStringA(szAnsiAppName, pszAnsiKeyName,
  2833. pszAnsiString, szAnsiFileName);
  2834. CmFree(pszAnsiString);
  2835. }
  2836. }
  2837. }
  2838. }
  2839. }
  2840. else
  2841. {
  2842. SetLastError(ERROR_INVALID_PARAMETER);
  2843. }
  2844. CMASSERTMSG(bReturn, TEXT("WritePrivateProfileStringAU Failed."));
  2845. return bReturn;
  2846. }
  2847. //+----------------------------------------------------------------------------
  2848. //
  2849. // Function: wsprintfAU
  2850. //
  2851. // Synopsis: Unicode to Ansi wrapper for the win32 wsprintf API.
  2852. // Note that it uses a va_list and calls wvsprintfAU.
  2853. //
  2854. // Arguments: See the win32 API definition
  2855. //
  2856. // Returns: See the win32 API definition
  2857. //
  2858. // History: quintinb Created 6/24/99
  2859. //
  2860. //+----------------------------------------------------------------------------
  2861. int WINAPIV wsprintfAU(OUT LPWSTR pszwDest, IN LPCWSTR pszwFmt, ...)
  2862. {
  2863. va_list arglist;
  2864. int ret;
  2865. va_start(arglist, pszwFmt);
  2866. ret = wvsprintfAU(pszwDest, pszwFmt, arglist);
  2867. va_end(arglist);
  2868. return ret;
  2869. }
  2870. //+----------------------------------------------------------------------------
  2871. //
  2872. // Function: wvsprintfAU
  2873. //
  2874. // Synopsis: Unicode to Ansi wrapper for the win32 wvsprintf API. In order to
  2875. // avoid parsing the format string to convert the %s to %S and the
  2876. // %c to %C and then calling wvsprintfA, which is originally how this
  2877. // function was written but which isn't really very safe because
  2878. // we don't know the size of the Dest buffer, we will call the
  2879. // C runtime function vswprintf to directly handle a Unicode string.
  2880. //
  2881. // Arguments: See the win32 API definition
  2882. //
  2883. // Returns: See the win32 API definition
  2884. //
  2885. // History: quintinb Created 6/24/99
  2886. // quintinb Changed algorithm to use
  2887. // the C runtime vswprintf 02/05/00
  2888. //
  2889. //+----------------------------------------------------------------------------
  2890. int WINAPI wvsprintfAU(OUT LPWSTR pszwDest, IN LPCWSTR pszwFmt, IN va_list arglist)
  2891. {
  2892. int iReturn = 0;
  2893. if (pszwDest && pszwFmt)
  2894. {
  2895. //
  2896. // Use the C runtime version of the function
  2897. //
  2898. iReturn = vswprintf(pszwDest, pszwFmt, arglist);
  2899. }
  2900. return iReturn;
  2901. }
  2902. //+----------------------------------------------------------------------------
  2903. //
  2904. // Function: InitCmUToA
  2905. //
  2906. // Synopsis: This function is called once cmutoa.dll is loaded. It will init
  2907. // the passed in UAPIINIT struct with the appropriate function pointers.
  2908. //
  2909. // Arguments: PUAPIINIT pUAInit -- pointer to a UAInit struct which contains memory
  2910. // for all the requested function pointers.
  2911. //
  2912. // Returns: BOOL -- always returns TRUE
  2913. //
  2914. // History: quintinb Created 6/24/99
  2915. //
  2916. //+----------------------------------------------------------------------------
  2917. BOOL InitCmUToA(PUAPIINIT pUAInit)
  2918. {
  2919. //
  2920. // Note that we don't need any translation here, the prototype is the same for A or W
  2921. //
  2922. *(pUAInit->pCallWindowProcU) = CallWindowProcA;
  2923. *(pUAInit->pDefWindowProcU) = DefWindowProcA;
  2924. *(pUAInit->pDispatchMessageU) = DispatchMessageA;
  2925. *(pUAInit->pGetClassLongU) = GetClassLongA;
  2926. *(pUAInit->pGetMessageU) = GetMessageA;
  2927. *(pUAInit->pGetWindowLongU) = GetWindowLongA;
  2928. *(pUAInit->pGetWindowTextLengthU) = GetWindowTextLengthA;
  2929. *(pUAInit->pIsDialogMessageU) = IsDialogMessageA;
  2930. *(pUAInit->pPeekMessageU) = PeekMessageA;
  2931. *(pUAInit->pPostMessageU) = PostMessageA;
  2932. *(pUAInit->pPostThreadMessageU) = PostThreadMessageA;
  2933. *(pUAInit->pSetWindowLongU) = SetWindowLongA;
  2934. //
  2935. // Whereas we need wrappers here to do parameter conversion here
  2936. //
  2937. *(pUAInit->pCharLowerU) = CharLowerAU;
  2938. *(pUAInit->pCharNextU) = CharNextAU;
  2939. *(pUAInit->pCharPrevU) = CharPrevAU;
  2940. *(pUAInit->pCharUpperU) = CharUpperAU;
  2941. *(pUAInit->pCreateDialogParamU) = CreateDialogParamAU;
  2942. *(pUAInit->pCreateDirectoryU) = CreateDirectoryAU;
  2943. *(pUAInit->pCreateEventU) = CreateEventAU;
  2944. *(pUAInit->pCreateFileU) = CreateFileAU;
  2945. *(pUAInit->pCreateFileMappingU) = CreateFileMappingAU;
  2946. *(pUAInit->pCreateMutexU) = CreateMutexAU;
  2947. *(pUAInit->pCreateProcessU) = CreateProcessAU;
  2948. *(pUAInit->pCreateWindowExU) = CreateWindowExAU;
  2949. *(pUAInit->pDeleteFileU) = DeleteFileAU;
  2950. *(pUAInit->pDialogBoxParamU) = DialogBoxParamAU;
  2951. *(pUAInit->pExpandEnvironmentStringsU) = ExpandEnvironmentStringsAU;
  2952. *(pUAInit->pFindResourceExU) = FindResourceExAU;
  2953. *(pUAInit->pFindWindowExU) = FindWindowExAU;
  2954. *(pUAInit->pGetDateFormatU) = GetDateFormatAU;
  2955. *(pUAInit->pGetDlgItemTextU) = GetDlgItemTextAU;
  2956. *(pUAInit->pGetFileAttributesU) = GetFileAttributesAU;
  2957. *(pUAInit->pGetModuleFileNameU) = GetModuleFileNameAU;
  2958. *(pUAInit->pGetModuleHandleU) = GetModuleHandleAU;
  2959. *(pUAInit->pGetPrivateProfileIntU) = GetPrivateProfileIntAU;
  2960. *(pUAInit->pGetPrivateProfileStringU) = GetPrivateProfileStringAU;
  2961. *(pUAInit->pGetStringTypeExU) = GetStringTypeExAU;
  2962. *(pUAInit->pGetSystemDirectoryU) = GetSystemDirectoryAU;
  2963. *(pUAInit->pGetTempFileNameU) = GetTempFileNameAU;
  2964. *(pUAInit->pGetTempPathU) = GetTempPathAU;
  2965. *(pUAInit->pGetTimeFormatU) = GetTimeFormatAU;
  2966. *(pUAInit->pGetUserNameU) = GetUserNameAU;
  2967. *(pUAInit->pGetVersionExU) = GetVersionExAU;
  2968. *(pUAInit->pGetWindowTextU) = GetWindowTextAU;
  2969. *(pUAInit->pInsertMenuU) = InsertMenuAU;
  2970. *(pUAInit->pLoadCursorU) = LoadCursorAU;
  2971. *(pUAInit->pLoadIconU) = LoadIconAU;
  2972. *(pUAInit->pLoadImageU) = LoadImageAU;
  2973. *(pUAInit->pLoadLibraryExU) = LoadLibraryExAU;
  2974. *(pUAInit->pLoadMenuU) = LoadMenuAU;
  2975. *(pUAInit->pLoadStringU) = LoadStringAU;
  2976. *(pUAInit->plstrcatU) = lstrcatAU;
  2977. *(pUAInit->plstrcmpU) = lstrcmpAU;
  2978. *(pUAInit->plstrcmpiU) = lstrcmpiAU;
  2979. *(pUAInit->plstrcpyU) = lstrcpyAU;
  2980. *(pUAInit->plstrcpynU) = lstrcpynAU;
  2981. *(pUAInit->plstrlenU) = lstrlenAU;
  2982. *(pUAInit->pOpenEventU) = OpenEventAU;
  2983. *(pUAInit->pOpenFileMappingU) = OpenFileMappingAU;
  2984. *(pUAInit->pRegCreateKeyExU) = RegCreateKeyExAU;
  2985. *(pUAInit->pRegDeleteKeyU) = RegDeleteKeyAU;
  2986. *(pUAInit->pRegDeleteValueU) = RegDeleteValueAU;
  2987. *(pUAInit->pRegEnumKeyExU) = RegEnumKeyExAU;
  2988. *(pUAInit->pRegisterClassExU) = RegisterClassExAU;
  2989. *(pUAInit->pRegisterWindowMessageU) = RegisterWindowMessageAU;
  2990. *(pUAInit->pRegOpenKeyExU) = RegOpenKeyExAU;
  2991. *(pUAInit->pRegQueryValueExU) = RegQueryValueExAU;
  2992. *(pUAInit->pRegSetValueExU) = RegSetValueExAU;
  2993. *(pUAInit->pSearchPathU) = SearchPathAU;
  2994. *(pUAInit->pSendDlgItemMessageU) = SendDlgItemMessageAU;
  2995. *(pUAInit->pSendMessageU) = SendMessageAU;
  2996. *(pUAInit->pSetCurrentDirectoryU) = SetCurrentDirectoryAU;
  2997. *(pUAInit->pSetDlgItemTextU) = SetDlgItemTextAU;
  2998. *(pUAInit->pSetWindowTextU) = SetWindowTextAU;
  2999. *(pUAInit->pUnregisterClassU) = UnregisterClassAU;
  3000. *(pUAInit->pWinHelpU) = WinHelpAU;
  3001. *(pUAInit->pWritePrivateProfileStringU) = WritePrivateProfileStringAU;
  3002. *(pUAInit->pwsprintfU) = wsprintfAU;
  3003. *(pUAInit->pwvsprintfU) = wvsprintfAU;
  3004. //
  3005. // Currently this always returns TRUE because none of the above can really
  3006. // fail. However, in the future we may need more of a meaningful return
  3007. // value here.
  3008. //
  3009. return TRUE;
  3010. }
  3011. //+----------------------------------------------------------------------------
  3012. //
  3013. // Function: RasDeleteEntryUA
  3014. //
  3015. // Synopsis: Unicode to Ansi wrapper for the win32 RasDeleteEntry API.
  3016. //
  3017. // Arguments: See the win32 API definition
  3018. //
  3019. // Returns: See the win32 API definition
  3020. //
  3021. // History: quintinb Created 7/15/99
  3022. //
  3023. //+----------------------------------------------------------------------------
  3024. DWORD APIENTRY RasDeleteEntryUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry)
  3025. {
  3026. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3027. //
  3028. // The phonebook should always be NULL on win9x
  3029. //
  3030. MYDBGASSERT(NULL == pszwPhoneBook);
  3031. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3032. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3033. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnDeleteEntry);
  3034. if (pszwEntry && pAnsiRasLinkage && pAnsiRasLinkage->pfnDeleteEntry)
  3035. {
  3036. CHAR szAnsiEntry [RAS_MaxEntryName + 1];
  3037. int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName);
  3038. if (iChars && (RAS_MaxEntryName >= iChars))
  3039. {
  3040. dwReturn = pAnsiRasLinkage->pfnDeleteEntry(NULL, szAnsiEntry);
  3041. }
  3042. }
  3043. return dwReturn;
  3044. }
  3045. //+----------------------------------------------------------------------------
  3046. //
  3047. // Function: RasGetEntryPropertiesUA
  3048. //
  3049. // Synopsis: Unicode to Ansi wrapper for the win32 RasGetEntryProperties API.
  3050. //
  3051. // Arguments: See the win32 API definition
  3052. //
  3053. // Returns: See the win32 API definition
  3054. //
  3055. // History: quintinb Created 7/15/99
  3056. //
  3057. //+----------------------------------------------------------------------------
  3058. DWORD APIENTRY RasGetEntryPropertiesUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry,
  3059. LPRASENTRYW pRasEntryW, LPDWORD pdwEntryInfoSize,
  3060. LPBYTE pbDeviceInfo, LPDWORD pdwDeviceInfoSize)
  3061. {
  3062. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3063. //
  3064. // The phonebook should always be NULL on win9x
  3065. //
  3066. MYDBGASSERT(NULL == pszwPhoneBook);
  3067. MYDBGASSERT(NULL == pbDeviceInfo); // We don't use or handle this TAPI param. If we need it,
  3068. // conversion must be implemented.
  3069. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3070. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3071. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetEntryProperties);
  3072. if (pszwEntry && pdwEntryInfoSize && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetEntryProperties)
  3073. {
  3074. CHAR szAnsiEntry [RAS_MaxEntryName + 1];
  3075. RASENTRYA RasEntryA;
  3076. DWORD dwTmpEntrySize = sizeof(RASENTRYA);
  3077. ZeroMemory(&RasEntryA, sizeof(RASENTRYA));
  3078. int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName);
  3079. if (iChars && (RAS_MaxEntryName >= iChars))
  3080. {
  3081. dwReturn = pAnsiRasLinkage->pfnGetEntryProperties(NULL, szAnsiEntry, &RasEntryA,
  3082. &dwTmpEntrySize, NULL, NULL);
  3083. if ((ERROR_SUCCESS == dwReturn) && pRasEntryW)
  3084. {
  3085. //
  3086. // Do conversion of RASENTRYA to RASENTRYW
  3087. //
  3088. // pRasEntryW->dwSize -- this param should already be set
  3089. pRasEntryW->dwfOptions = RasEntryA.dwfOptions;
  3090. //
  3091. // Location/phone number.
  3092. //
  3093. pRasEntryW->dwCountryID = RasEntryA.dwCountryID;
  3094. pRasEntryW->dwCountryCode = RasEntryA.dwCountryCode;
  3095. MYVERIFY(0 != SzToWz(RasEntryA.szAreaCode, pRasEntryW->szAreaCode, RAS_MaxAreaCode));
  3096. MYVERIFY(0 != SzToWz(RasEntryA.szLocalPhoneNumber, pRasEntryW->szLocalPhoneNumber, RAS_MaxPhoneNumber));
  3097. pRasEntryW->dwAlternateOffset = RasEntryA.dwAlternateOffset;
  3098. //
  3099. // PPP/Ip
  3100. //
  3101. memcpy(&(pRasEntryW->ipaddr), &(RasEntryA.ipaddr), sizeof(RASIPADDR));
  3102. memcpy(&(pRasEntryW->ipaddrDns), &(RasEntryA.ipaddrDns), sizeof(RASIPADDR));
  3103. memcpy(&(pRasEntryW->ipaddrDnsAlt), &(RasEntryA.ipaddrDnsAlt), sizeof(RASIPADDR));
  3104. memcpy(&(pRasEntryW->ipaddrWins), &(RasEntryA.ipaddrWins), sizeof(RASIPADDR));
  3105. memcpy(&(pRasEntryW->ipaddrWinsAlt), &(RasEntryA.ipaddrWinsAlt), sizeof(RASIPADDR));
  3106. //
  3107. // Framing
  3108. //
  3109. pRasEntryW->dwFrameSize = RasEntryA.dwFrameSize;
  3110. pRasEntryW->dwfNetProtocols = RasEntryA.dwfNetProtocols;
  3111. pRasEntryW->dwFramingProtocol = RasEntryA.dwFramingProtocol;
  3112. //
  3113. // Scripting
  3114. //
  3115. MYVERIFY(0 != SzToWz(RasEntryA.szScript, pRasEntryW->szScript, MAX_PATH));
  3116. //
  3117. // AutoDial
  3118. //
  3119. MYVERIFY(0 != SzToWz(RasEntryA.szAutodialDll, pRasEntryW->szAutodialDll, MAX_PATH));
  3120. MYVERIFY(0 != SzToWz(RasEntryA.szAutodialFunc, pRasEntryW->szAutodialFunc, MAX_PATH));
  3121. //
  3122. // Device
  3123. //
  3124. MYVERIFY(0 != SzToWz(RasEntryA.szDeviceType, pRasEntryW->szDeviceType, RAS_MaxDeviceType));
  3125. MYVERIFY(0 != SzToWz(RasEntryA.szDeviceName, pRasEntryW->szDeviceName, RAS_MaxDeviceName));
  3126. //
  3127. // X.25 -- we don't use x25
  3128. //
  3129. pRasEntryW->szX25PadType[0] = L'\0';
  3130. pRasEntryW->szX25Address[0] = L'\0';
  3131. pRasEntryW->szX25Facilities[0] = L'\0';
  3132. pRasEntryW->szX25UserData[0] = L'\0';
  3133. pRasEntryW->dwChannels = 0;
  3134. //
  3135. // Reserved
  3136. //
  3137. pRasEntryW->dwReserved1 = RasEntryA.dwReserved1;
  3138. pRasEntryW->dwReserved2 = RasEntryA.dwReserved2;
  3139. }
  3140. else if ((ERROR_BUFFER_TOO_SMALL == dwReturn) || !pRasEntryW)
  3141. {
  3142. //
  3143. // We don't know the actual size since we are passing a RASENTRYA, but
  3144. // the user only knows about RASENTRYW. Thus double the returned size.
  3145. //
  3146. *pdwEntryInfoSize = 2*dwTmpEntrySize;
  3147. }
  3148. }
  3149. }
  3150. return dwReturn;
  3151. }
  3152. //+----------------------------------------------------------------------------
  3153. //
  3154. // Function: RasSetEntryPropertiesUA
  3155. //
  3156. // Synopsis: Unicode to Ansi wrapper for the win32 RasSetEntryProperties API.
  3157. // Note that we do not support the pbDeviceInfo
  3158. // parameter, if you need it you will have to implement it.
  3159. //
  3160. // Arguments: See the win32 API definition
  3161. //
  3162. // Returns: See the win32 API definition
  3163. //
  3164. // History: quintinb Created 7/15/99
  3165. //
  3166. //+----------------------------------------------------------------------------
  3167. DWORD APIENTRY RasSetEntryPropertiesUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry, LPRASENTRYW pRasEntryW,
  3168. DWORD dwEntryInfoSize, LPBYTE pbDeviceInfo, DWORD dwDeviceInfoSize)
  3169. {
  3170. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3171. //
  3172. // We don't use or handle this TAPI param. If we need it, conversion must be implemented.
  3173. // Note that 1 is a special value for Windows Millennium (see Millennium bug 127371)
  3174. //
  3175. MYDBGASSERT((NULL == pbDeviceInfo) || ((LPBYTE)1 == pbDeviceInfo));
  3176. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3177. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3178. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnSetEntryProperties);
  3179. if (pszwEntry && dwEntryInfoSize && pRasEntryW && pAnsiRasLinkage && pAnsiRasLinkage->pfnSetEntryProperties)
  3180. {
  3181. //
  3182. // The phonebook should always be NULL on Win9x.
  3183. //
  3184. MYDBGASSERT(NULL == pszwPhoneBook);
  3185. CHAR szAnsiEntry [RAS_MaxEntryName + 1];
  3186. int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName);
  3187. if (iChars && (RAS_MaxEntryName >= iChars))
  3188. {
  3189. //
  3190. // Figure out the correct size to use
  3191. //
  3192. MYDBGASSERT((sizeof(RASENTRYW) == pRasEntryW->dwSize) ||(sizeof(RASENTRYW_V401) == pRasEntryW->dwSize));
  3193. DWORD dwSize;
  3194. if ((sizeof (RASENTRYW_V401) == pRasEntryW->dwSize) && OS_MIL)
  3195. {
  3196. //
  3197. // Millennium uses the NT4 structure size
  3198. //
  3199. dwSize = sizeof(RASENTRYA_V401);
  3200. }
  3201. else
  3202. {
  3203. dwSize = sizeof(RASENTRYA);
  3204. }
  3205. //
  3206. // Allocate the RasEntryStructure
  3207. //
  3208. LPRASENTRYA pAnsiRasEntry = (LPRASENTRYA)CmMalloc(dwSize);
  3209. if (pAnsiRasEntry)
  3210. {
  3211. //
  3212. // Do conversion of RASENTRYA to RASENTRYW
  3213. //
  3214. pAnsiRasEntry->dwSize = dwSize;
  3215. pAnsiRasEntry->dwfOptions = pRasEntryW->dwfOptions;
  3216. //
  3217. // Location/phone number.
  3218. //
  3219. pAnsiRasEntry->dwCountryID = pRasEntryW->dwCountryID;
  3220. pAnsiRasEntry->dwCountryCode = pRasEntryW->dwCountryCode;
  3221. MYVERIFY(0 != WzToSz(pRasEntryW->szAreaCode, pAnsiRasEntry->szAreaCode, RAS_MaxAreaCode));
  3222. MYVERIFY(0 != WzToSz(pRasEntryW->szLocalPhoneNumber, pAnsiRasEntry->szLocalPhoneNumber, RAS_MaxPhoneNumber));
  3223. CMASSERTMSG(0 == pRasEntryW->dwAlternateOffset, TEXT("RasSetEntryPropertiesUA -- dwAlternateOffset != 0 is not supported. This will need to be implemented if used."));
  3224. pAnsiRasEntry->dwAlternateOffset = 0;
  3225. //
  3226. // PPP/Ip
  3227. //
  3228. memcpy(&(pAnsiRasEntry->ipaddr), &(pRasEntryW->ipaddr), sizeof(RASIPADDR));
  3229. memcpy(&(pAnsiRasEntry->ipaddrDns), &(pRasEntryW->ipaddrDns), sizeof(RASIPADDR));
  3230. memcpy(&(pAnsiRasEntry->ipaddrDnsAlt), &(pRasEntryW->ipaddrDnsAlt), sizeof(RASIPADDR));
  3231. memcpy(&(pAnsiRasEntry->ipaddrWins), &(pRasEntryW->ipaddrWins), sizeof(RASIPADDR));
  3232. memcpy(&(pAnsiRasEntry->ipaddrWinsAlt), &(pRasEntryW->ipaddrWinsAlt), sizeof(RASIPADDR));
  3233. //
  3234. // Framing
  3235. //
  3236. pAnsiRasEntry->dwFrameSize = pRasEntryW->dwFrameSize;
  3237. pAnsiRasEntry->dwfNetProtocols = pRasEntryW->dwfNetProtocols;
  3238. pAnsiRasEntry->dwFramingProtocol = pRasEntryW->dwFramingProtocol;
  3239. //
  3240. // Scripting
  3241. //
  3242. MYVERIFY(0 != WzToSz(pRasEntryW->szScript, pAnsiRasEntry->szScript, MAX_PATH));
  3243. //
  3244. // AutoDial
  3245. //
  3246. MYVERIFY(0 != WzToSz(pRasEntryW->szAutodialDll, pAnsiRasEntry->szAutodialDll, MAX_PATH));
  3247. MYVERIFY(0 != WzToSz(pRasEntryW->szAutodialFunc, pAnsiRasEntry->szAutodialFunc, MAX_PATH));
  3248. //
  3249. // Device
  3250. //
  3251. MYVERIFY(0 != WzToSz(pRasEntryW->szDeviceType, pAnsiRasEntry->szDeviceType, RAS_MaxDeviceType));
  3252. MYVERIFY(0 != WzToSz(pRasEntryW->szDeviceName, pAnsiRasEntry->szDeviceName, RAS_MaxDeviceName));
  3253. //
  3254. // X.25 -- we don't use x25
  3255. //
  3256. pAnsiRasEntry->szX25PadType[0] = '\0';
  3257. pAnsiRasEntry->szX25Address[0] = '\0';
  3258. pAnsiRasEntry->szX25Facilities[0] = '\0';
  3259. pAnsiRasEntry->szX25UserData[0] = '\0';
  3260. pAnsiRasEntry->dwChannels = 0;
  3261. //
  3262. // Reserved
  3263. //
  3264. pAnsiRasEntry->dwReserved1 = pRasEntryW->dwReserved1;
  3265. pAnsiRasEntry->dwReserved2 = pRasEntryW->dwReserved2;
  3266. if (sizeof(RASENTRYA_V401) == dwSize)
  3267. {
  3268. //
  3269. // Copy over the 4.01 data
  3270. //
  3271. LPRASENTRYA_V401 pAnsi401RasEntry = (LPRASENTRYA_V401)pAnsiRasEntry;
  3272. LPRASENTRYW_V401 pWide401RasEntry = (LPRASENTRYW_V401)pRasEntryW;
  3273. pAnsi401RasEntry->dwSubEntries = pWide401RasEntry->dwSubEntries;
  3274. pAnsi401RasEntry->dwDialMode = pWide401RasEntry->dwDialMode;
  3275. pAnsi401RasEntry->dwDialExtraPercent = pWide401RasEntry->dwDialExtraPercent;
  3276. pAnsi401RasEntry->dwDialExtraSampleSeconds = pWide401RasEntry->dwDialExtraSampleSeconds;
  3277. pAnsi401RasEntry->dwHangUpExtraPercent = pWide401RasEntry->dwHangUpExtraPercent;
  3278. pAnsi401RasEntry->dwHangUpExtraSampleSeconds = pWide401RasEntry->dwHangUpExtraSampleSeconds;
  3279. pAnsi401RasEntry->dwIdleDisconnectSeconds = pWide401RasEntry->dwIdleDisconnectSeconds;
  3280. }
  3281. dwReturn = pAnsiRasLinkage->pfnSetEntryProperties(NULL, szAnsiEntry, pAnsiRasEntry,
  3282. pAnsiRasEntry->dwSize, pbDeviceInfo, 0);
  3283. CmFree(pAnsiRasEntry);
  3284. }
  3285. }
  3286. }
  3287. return dwReturn;
  3288. }
  3289. //+----------------------------------------------------------------------------
  3290. //
  3291. // Function: RasDialParamsWtoRasDialParamsA
  3292. //
  3293. // Synopsis: Wrapper function to handle converting a RasDialParamsW struct to
  3294. // a RasDialParamsA Struct. Used by RasSetEntryDialParamsUA and
  3295. // RasDialUA.
  3296. //
  3297. // Arguments: LPRASDIALPARAMSW pRdpW - pointer to a RasDialParamsW
  3298. // LPRASDIALPARAMSA pRdpA - pointer to a RasDialParamsA
  3299. //
  3300. // Returns: Nothing
  3301. //
  3302. // History: quintinb Created 7/15/99
  3303. //
  3304. //+----------------------------------------------------------------------------
  3305. void RasDialParamsWtoRasDialParamsA (LPRASDIALPARAMSW pRdpW, LPRASDIALPARAMSA pRdpA)
  3306. {
  3307. pRdpA->dwSize = sizeof(RASDIALPARAMSA);
  3308. MYVERIFY(0 != WzToSz(pRdpW->szEntryName, pRdpA->szEntryName, RAS_MaxEntryName));
  3309. MYVERIFY(0 != WzToSz(pRdpW->szPhoneNumber, pRdpA->szPhoneNumber, RAS_MaxPhoneNumber));
  3310. MYVERIFY(0 != WzToSz(pRdpW->szCallbackNumber, pRdpA->szCallbackNumber, RAS_MaxCallbackNumber));
  3311. MYVERIFY(0 != WzToSz(pRdpW->szUserName, pRdpA->szUserName, UNLEN));
  3312. MYVERIFY(0 != WzToSz(pRdpW->szPassword, pRdpA->szPassword, PWLEN));
  3313. MYVERIFY(0 != WzToSz(pRdpW->szDomain, pRdpA->szDomain, DNLEN));
  3314. }
  3315. //+----------------------------------------------------------------------------
  3316. //
  3317. // Function: RasDialParamsAtoRasDialParamsW
  3318. //
  3319. // Synopsis: Wrapper function to handle converting a RasDialParamsA struct to
  3320. // a RasDialParamsW Struct. Used by RasGetEntryDialParamsUA.
  3321. //
  3322. // Arguments: LPRASDIALPARAMSW pRdpA - pointer to a RasDialParamsA
  3323. // LPRASDIALPARAMSA pRdpW - pointer to a RasDialParamsW
  3324. //
  3325. // Returns: Nothing
  3326. //
  3327. // History: quintinb Created 7/15/99
  3328. //
  3329. //+----------------------------------------------------------------------------
  3330. void RasDialParamsAtoRasDialParamsW (LPRASDIALPARAMSA pRdpA, LPRASDIALPARAMSW pRdpW)
  3331. {
  3332. pRdpW->dwSize = sizeof(RASDIALPARAMSW);
  3333. MYVERIFY(0 != SzToWz(pRdpA->szEntryName, pRdpW->szEntryName, RAS_MaxEntryName));
  3334. MYVERIFY(0 != SzToWz(pRdpA->szPhoneNumber, pRdpW->szPhoneNumber, RAS_MaxPhoneNumber));
  3335. MYVERIFY(0 != SzToWz(pRdpA->szCallbackNumber, pRdpW->szCallbackNumber, RAS_MaxCallbackNumber));
  3336. MYVERIFY(0 != SzToWz(pRdpA->szUserName, pRdpW->szUserName, UNLEN));
  3337. MYVERIFY(0 != SzToWz(pRdpA->szPassword, pRdpW->szPassword, PWLEN));
  3338. MYVERIFY(0 != SzToWz(pRdpA->szDomain, pRdpW->szDomain, DNLEN));
  3339. }
  3340. //+----------------------------------------------------------------------------
  3341. //
  3342. // Function: RasGetEntryDialParamsUA
  3343. //
  3344. // Synopsis: Unicode to Ansi wrapper for the win32 RasGetEntryDialParams API.
  3345. //
  3346. // Arguments: See the win32 API definition
  3347. //
  3348. // Returns: See the win32 API definition
  3349. //
  3350. // History: quintinb Created 7/15/99
  3351. //
  3352. //+----------------------------------------------------------------------------
  3353. DWORD APIENTRY RasGetEntryDialParamsUA(LPCWSTR pszwPhoneBook, LPRASDIALPARAMSW pRasDialParamsW, LPBOOL pbPassword)
  3354. {
  3355. DWORD dwReturn = ERROR_BUFFER_INVALID;
  3356. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3357. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3358. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetEntryDialParams);
  3359. if (pRasDialParamsW && pbPassword && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetEntryDialParams)
  3360. {
  3361. //
  3362. // The phonebook should always be NULL on win9x
  3363. //
  3364. MYDBGASSERT(NULL == pszwPhoneBook);
  3365. RASDIALPARAMSA RasDialParamsA;
  3366. ZeroMemory(&RasDialParamsA, sizeof(RASDIALPARAMSA));
  3367. RasDialParamsA.dwSize = sizeof(RASDIALPARAMSA);
  3368. int iChars = WzToSz(pRasDialParamsW->szEntryName, RasDialParamsA.szEntryName, RAS_MaxEntryName);
  3369. if (iChars && (RAS_MaxEntryName >= iChars))
  3370. {
  3371. dwReturn = pAnsiRasLinkage->pfnGetEntryDialParams(NULL, &RasDialParamsA, pbPassword);
  3372. if (ERROR_SUCCESS == dwReturn)
  3373. {
  3374. RasDialParamsAtoRasDialParamsW(&RasDialParamsA, pRasDialParamsW);
  3375. }
  3376. }
  3377. }
  3378. return dwReturn;
  3379. }
  3380. //+----------------------------------------------------------------------------
  3381. //
  3382. // Function: RasSetEntryDialParamsUA
  3383. //
  3384. // Synopsis: Unicode to Ansi wrapper for the win32 RasSetEntryDialParams API.
  3385. //
  3386. // Arguments: See the win32 API definition
  3387. //
  3388. // Returns: See the win32 API definition
  3389. //
  3390. // History: quintinb Created 7/15/99
  3391. //
  3392. //+----------------------------------------------------------------------------
  3393. DWORD APIENTRY RasSetEntryDialParamsUA(LPCWSTR pszwPhoneBook, LPRASDIALPARAMSW pRasDialParamsW,
  3394. BOOL bRemovePassword)
  3395. {
  3396. DWORD dwReturn = ERROR_BUFFER_INVALID;
  3397. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3398. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3399. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnSetEntryDialParams);
  3400. if (pRasDialParamsW && pAnsiRasLinkage && pAnsiRasLinkage->pfnSetEntryDialParams)
  3401. {
  3402. //
  3403. // The phonebook should always be NULL on win9x
  3404. //
  3405. MYDBGASSERT(NULL == pszwPhoneBook);
  3406. RASDIALPARAMSA RasDialParamsA;
  3407. RasDialParamsWtoRasDialParamsA (pRasDialParamsW, &RasDialParamsA);
  3408. dwReturn = pAnsiRasLinkage->pfnSetEntryDialParams(NULL, &RasDialParamsA, bRemovePassword);
  3409. }
  3410. return dwReturn;
  3411. }
  3412. //+----------------------------------------------------------------------------
  3413. //
  3414. // Function: RasEnumDevicesUA
  3415. //
  3416. // Synopsis: Unicode to Ansi wrapper for the win32 RasEnumDevices API.
  3417. //
  3418. // Arguments: See the win32 API definition
  3419. //
  3420. // Returns: See the win32 API definition
  3421. //
  3422. // History: quintinb Created 7/15/99
  3423. //
  3424. //+----------------------------------------------------------------------------
  3425. DWORD RasEnumDevicesUA(LPRASDEVINFOW pRasDevInfo, LPDWORD pdwCb, LPDWORD pdwDevices)
  3426. {
  3427. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3428. DWORD dwSize;
  3429. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3430. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3431. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnEnumDevices);
  3432. if (pdwCb && pdwDevices && pAnsiRasLinkage && pAnsiRasLinkage->pfnEnumDevices)
  3433. {
  3434. LPRASDEVINFOA pAnsiDevInfo;
  3435. if ((NULL == pRasDevInfo) && (0 == *pdwCb))
  3436. {
  3437. //
  3438. // Then the caller is just trying to size the buffer
  3439. //
  3440. dwSize = 0;
  3441. pAnsiDevInfo = NULL;
  3442. }
  3443. else
  3444. {
  3445. dwSize = ((*pdwCb)/sizeof(RASDEVINFOW))*sizeof(RASDEVINFOA);
  3446. pAnsiDevInfo = (LPRASDEVINFOA)CmMalloc(dwSize);
  3447. if (NULL == pAnsiDevInfo)
  3448. {
  3449. return ERROR_NOT_ENOUGH_MEMORY;
  3450. }
  3451. pAnsiDevInfo[0].dwSize = sizeof(RASDEVINFOA);
  3452. }
  3453. dwReturn = pAnsiRasLinkage->pfnEnumDevices(pAnsiDevInfo, &dwSize, pdwDevices);
  3454. //
  3455. // Resize the buffer in terms of RASDEVINFOW structs
  3456. //
  3457. *pdwCb = ((dwSize)/sizeof(RASDEVINFOA))*sizeof(RASDEVINFOW);
  3458. if (ERROR_SUCCESS == dwReturn && pRasDevInfo)
  3459. {
  3460. //
  3461. // Then we need to convert the returned structs
  3462. //
  3463. MYDBGASSERT((*pdwDevices)*sizeof(RASDEVINFOW) <= *pdwCb);
  3464. for (DWORD dwIndex = 0; dwIndex < *pdwDevices; dwIndex++)
  3465. {
  3466. MYVERIFY(0 != SzToWz(pAnsiDevInfo[dwIndex].szDeviceType,
  3467. pRasDevInfo[dwIndex].szDeviceType, RAS_MaxDeviceType));
  3468. MYVERIFY(0 != SzToWz(pAnsiDevInfo[dwIndex].szDeviceName,
  3469. pRasDevInfo[dwIndex].szDeviceName, RAS_MaxDeviceName));
  3470. }
  3471. }
  3472. //
  3473. // Free the Ansi buffer
  3474. //
  3475. CmFree (pAnsiDevInfo);
  3476. }
  3477. return dwReturn;
  3478. }
  3479. //+----------------------------------------------------------------------------
  3480. //
  3481. // Function: RasDialUA
  3482. //
  3483. // Synopsis: Unicode to Ansi wrapper for the win32 RasDial API.
  3484. //
  3485. // Arguments: See the win32 API definition
  3486. //
  3487. // Returns: See the win32 API definition
  3488. //
  3489. // History: quintinb Created 7/15/99
  3490. //
  3491. //+----------------------------------------------------------------------------
  3492. DWORD APIENTRY RasDialUA(LPRASDIALEXTENSIONS pRasDialExt, LPCWSTR pszwPhoneBook,
  3493. LPRASDIALPARAMSW pRasDialParamsW, DWORD dwNotifierType, LPVOID pvNotifier,
  3494. LPHRASCONN phRasConn)
  3495. {
  3496. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3497. MYDBGASSERT(NULL == pszwPhoneBook);
  3498. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3499. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3500. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnDial);
  3501. if (pRasDialParamsW && phRasConn && pAnsiRasLinkage && pAnsiRasLinkage->pfnDial)
  3502. {
  3503. RASDIALPARAMSA RasDialParamsA;
  3504. RasDialParamsWtoRasDialParamsA (pRasDialParamsW, &RasDialParamsA);
  3505. dwReturn = pAnsiRasLinkage->pfnDial(pRasDialExt, NULL, &RasDialParamsA, dwNotifierType,
  3506. pvNotifier, phRasConn);
  3507. }
  3508. return dwReturn;
  3509. }
  3510. //+----------------------------------------------------------------------------
  3511. //
  3512. // Function: RasHangUpUA
  3513. //
  3514. // Synopsis: Unicode to Ansi wrapper for the win32 RasHangUp API. Which for
  3515. // some reason has an ANSI and Unicode form, not sure why.
  3516. //
  3517. // Arguments: See the win32 API definition
  3518. //
  3519. // Returns: See the win32 API definition
  3520. //
  3521. // History: quintinb Created 7/15/99
  3522. //
  3523. //+----------------------------------------------------------------------------
  3524. DWORD APIENTRY RasHangUpUA(HRASCONN hRasConn)
  3525. {
  3526. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3527. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3528. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3529. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnHangUp);
  3530. if (hRasConn && pAnsiRasLinkage && pAnsiRasLinkage->pfnHangUp)
  3531. {
  3532. dwReturn = pAnsiRasLinkage->pfnHangUp(hRasConn);
  3533. }
  3534. return dwReturn;
  3535. }
  3536. //+----------------------------------------------------------------------------
  3537. //
  3538. // Function: RasGetErrorStringUA
  3539. //
  3540. // Synopsis: Unicode to Ansi wrapper for the win32 RasGetErrorString API.
  3541. //
  3542. // Arguments: See the win32 API definition
  3543. //
  3544. // Returns: See the win32 API definition
  3545. //
  3546. // History: quintinb Created 7/15/99
  3547. //
  3548. //+----------------------------------------------------------------------------
  3549. DWORD APIENTRY RasGetErrorStringUA(UINT uErrorValue, LPWSTR pszwOutBuf, DWORD dwBufSize)
  3550. {
  3551. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3552. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3553. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3554. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetErrorString);
  3555. if (pszwOutBuf && dwBufSize && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetErrorString)
  3556. {
  3557. LPSTR pszAnsiBuf = (LPSTR)CmMalloc(dwBufSize);
  3558. if (pszAnsiBuf)
  3559. {
  3560. dwReturn = pAnsiRasLinkage->pfnGetErrorString(uErrorValue, pszAnsiBuf, dwBufSize);
  3561. if (ERROR_SUCCESS == dwReturn)
  3562. {
  3563. int iChars = SzToWz(pszAnsiBuf, pszwOutBuf, dwBufSize);
  3564. if (!iChars || (dwBufSize < (DWORD)iChars))
  3565. {
  3566. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  3567. }
  3568. }
  3569. }
  3570. CmFree(pszAnsiBuf);
  3571. }
  3572. return dwReturn;
  3573. }
  3574. //+----------------------------------------------------------------------------
  3575. //
  3576. // Function: RasGetConnectStatusUA
  3577. //
  3578. // Synopsis: Unicode to Ansi wrapper for the win32 RasGetConnectStatus API.
  3579. //
  3580. // Arguments: See the win32 API definition
  3581. //
  3582. // Returns: See the win32 API definition
  3583. //
  3584. // History: quintinb Created 7/15/99
  3585. //
  3586. //+----------------------------------------------------------------------------
  3587. DWORD RasGetConnectStatusUA(HRASCONN hRasConn, LPRASCONNSTATUSW pRasConnStatusW)
  3588. {
  3589. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3590. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3591. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3592. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetConnectStatus);
  3593. if (pRasConnStatusW && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetConnectStatus)
  3594. {
  3595. RASCONNSTATUSA RasConnStatusA;
  3596. ZeroMemory(&RasConnStatusA, sizeof(RASCONNSTATUSA));
  3597. RasConnStatusA.dwSize = sizeof(RASCONNSTATUSA);
  3598. dwReturn = pAnsiRasLinkage->pfnGetConnectStatus(hRasConn, &RasConnStatusA);
  3599. if (ERROR_SUCCESS == dwReturn)
  3600. {
  3601. pRasConnStatusW->rasconnstate = RasConnStatusA.rasconnstate;
  3602. pRasConnStatusW->dwError = RasConnStatusA.dwError;
  3603. int iChars = SzToWz(RasConnStatusA.szDeviceType, pRasConnStatusW->szDeviceType,
  3604. RAS_MaxDeviceType);
  3605. if (!iChars || (RAS_MaxDeviceType < iChars))
  3606. {
  3607. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  3608. }
  3609. else
  3610. {
  3611. iChars = SzToWz(RasConnStatusA.szDeviceName, pRasConnStatusW->szDeviceName,
  3612. RAS_MaxDeviceName);
  3613. if (!iChars || (RAS_MaxDeviceName < iChars))
  3614. {
  3615. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  3616. }
  3617. }
  3618. }
  3619. }
  3620. return dwReturn;
  3621. }
  3622. //+----------------------------------------------------------------------------
  3623. //
  3624. // Function: RasSetSubEntryPropertiesUA
  3625. //
  3626. // Synopsis: Unicode to Ansi wrapper for the win32 RasSetSubEntryProperties API.
  3627. //
  3628. // Arguments: See the win32 API definition
  3629. //
  3630. // Returns: See the win32 API definition
  3631. //
  3632. // History: SumitC Created 10/26/99
  3633. //
  3634. //-----------------------------------------------------------------------------
  3635. DWORD APIENTRY
  3636. RasSetSubEntryPropertiesUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwSubEntry,
  3637. DWORD dwSubEntry, LPRASSUBENTRYW pRasSubEntryW,
  3638. DWORD dwSubEntryInfoSize, LPBYTE pbDeviceConfig,
  3639. DWORD dwcbDeviceConfig)
  3640. {
  3641. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3642. MYDBGASSERT(NULL == pbDeviceConfig); // must currently be NULL
  3643. MYDBGASSERT(0 == dwcbDeviceConfig); // must currently be 0
  3644. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3645. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3646. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnSetEntryProperties);
  3647. if (pszwSubEntry && dwSubEntryInfoSize && pRasSubEntryW && pAnsiRasLinkage && pAnsiRasLinkage->pfnSetSubEntryProperties)
  3648. {
  3649. //
  3650. // The phonebook should always be NULL on win9x
  3651. //
  3652. MYDBGASSERT(NULL == pszwPhoneBook);
  3653. CHAR szAnsiSubEntry [RAS_MaxEntryName + 1];
  3654. RASSUBENTRYA AnsiRasSubEntry;
  3655. ZeroMemory(&AnsiRasSubEntry, sizeof(RASSUBENTRYA));
  3656. DWORD dwTmpEntrySize = sizeof(RASSUBENTRYA);
  3657. int iChars = WzToSz(pszwSubEntry, szAnsiSubEntry, RAS_MaxEntryName);
  3658. if (iChars && (RAS_MaxEntryName >= iChars))
  3659. {
  3660. //
  3661. // Do conversion of RASSUBENTRYW to RASSUBENTRYA
  3662. //
  3663. AnsiRasSubEntry.dwSize = sizeof(RASSUBENTRYA);
  3664. AnsiRasSubEntry.dwfFlags = pRasSubEntryW->dwfFlags;
  3665. //
  3666. // Device
  3667. //
  3668. MYVERIFY(0 != WzToSz(pRasSubEntryW->szDeviceType, AnsiRasSubEntry.szDeviceType, RAS_MaxDeviceType));
  3669. MYVERIFY(0 != WzToSz(pRasSubEntryW->szDeviceName, AnsiRasSubEntry.szDeviceName, RAS_MaxDeviceName));
  3670. //
  3671. // Location/phone number.
  3672. //
  3673. MYVERIFY(0 != WzToSz(pRasSubEntryW->szLocalPhoneNumber, AnsiRasSubEntry.szLocalPhoneNumber, RAS_MaxPhoneNumber));
  3674. CMASSERTMSG(0 == pRasSubEntryW->dwAlternateOffset, TEXT("RasSetSubEntryPropertiesUA -- dwAlternateOffset != 0 is not supported. This will need to be implemented if used."));
  3675. AnsiRasSubEntry.dwAlternateOffset = 0;
  3676. dwReturn = pAnsiRasLinkage->pfnSetSubEntryProperties(NULL, szAnsiSubEntry, dwSubEntry,
  3677. &AnsiRasSubEntry, dwTmpEntrySize, NULL, 0);
  3678. }
  3679. }
  3680. return dwReturn;
  3681. }
  3682. //+----------------------------------------------------------------------------
  3683. //
  3684. // Function: RasDeleteSubEntryUA
  3685. //
  3686. // Synopsis: Unicode to Ansi wrapper for the win32 RasDeleteSubEntryUA API.
  3687. //
  3688. // Arguments: See the win32 API definition
  3689. //
  3690. // Returns: See the win32 API definition
  3691. //
  3692. // History: SumitC Created 12/14/99
  3693. //
  3694. //-----------------------------------------------------------------------------
  3695. DWORD APIENTRY
  3696. RasDeleteSubEntryUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry, DWORD dwSubEntryId)
  3697. {
  3698. DWORD dwReturn = ERROR_INVALID_PARAMETER;
  3699. //
  3700. // The phonebook should always be NULL on win9x
  3701. //
  3702. MYDBGASSERT(NULL == pszwPhoneBook);
  3703. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3704. MYDBGASSERT(NULL != pAnsiRasLinkage);
  3705. MYDBGASSERT(NULL != pAnsiRasLinkage->pfnDeleteSubEntry);
  3706. if (pszwEntry && pAnsiRasLinkage && pAnsiRasLinkage->pfnDeleteSubEntry)
  3707. {
  3708. CHAR szAnsiEntry [RAS_MaxEntryName + 1];
  3709. int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName);
  3710. if (iChars && (RAS_MaxEntryName >= iChars))
  3711. {
  3712. dwReturn = pAnsiRasLinkage->pfnDeleteSubEntry(NULL, szAnsiEntry, dwSubEntryId);
  3713. }
  3714. }
  3715. return dwReturn;
  3716. }
  3717. //+----------------------------------------------------------------------------
  3718. //
  3719. // Function: FreeCmRasUtoA
  3720. //
  3721. // Synopsis: Unloads the RAS dlls (rasapi32.dll and rnaph.dll) and cleans up
  3722. // the RAS linkage structure. To get more details about the cmutoa
  3723. // RAS linkage see InitCmRasUtoA and cmdial\ras.cpp\LinkToRas.
  3724. //
  3725. // Arguments: Nothing
  3726. //
  3727. // Returns: Nothing
  3728. //
  3729. // History: quintinb Created 7/15/99
  3730. //
  3731. //+----------------------------------------------------------------------------
  3732. void FreeCmRasUtoA()
  3733. {
  3734. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3735. CMASSERTMSG(pAnsiRasLinkage, TEXT("FreeCmRasUtoA -- RasLinkage hasn't been established yet. Why are we calling FreeCmRasUtoA now?"));
  3736. if (pAnsiRasLinkage)
  3737. {
  3738. if (pAnsiRasLinkage->hInstRas)
  3739. {
  3740. FreeLibrary(pAnsiRasLinkage->hInstRas);
  3741. }
  3742. if (pAnsiRasLinkage->hInstRnaph)
  3743. {
  3744. FreeLibrary(pAnsiRasLinkage->hInstRnaph);
  3745. }
  3746. CmFree(pAnsiRasLinkage);
  3747. TlsSetValue(g_dwTlsIndex, (LPVOID)NULL);
  3748. }
  3749. }
  3750. //+----------------------------------------------------------------------------
  3751. //
  3752. // Function: InitCmRasUtoA
  3753. //
  3754. // Synopsis: Function to Initialize the Unicode to ANSI conversion layer for
  3755. // RAS functions. In order to make the LinkToRas stuff work the
  3756. // same on win9x and on NT (all come from one dll) we have Cmdial32.dll
  3757. // link to cmutoa and get all of the RAS Entry points through Cmutoa.dll.
  3758. // In order to make this work, we need to keep function pointers to all of
  3759. // the RAS Dll's in memory. In order to prevent two cmdial's on different
  3760. // threads from calling InitCmRasUtoA and FreeCmRasUtoA at the wrong times
  3761. // (one thread freeing right after another had initialized would leave
  3762. // the first thread in a broken state), we usesthread local storage
  3763. // to hold a pointer to a RasLinkageStructA. This makes us thread safe
  3764. // and allows us to only have to init the RAS pointers once per thread
  3765. // (having multiple Cmdials in the same thread is pretty unlikely anyway).
  3766. // See cmdial\ras.cpp\LinkToRas for more details on the cmdial side of
  3767. // things.
  3768. //
  3769. // Arguments: Nothing
  3770. //
  3771. // Returns: BOOL -- TRUE if all of the requested APIs were loaded properly.
  3772. //
  3773. // History: quintinb Created 7/15/99
  3774. //
  3775. //+----------------------------------------------------------------------------
  3776. BOOL InitCmRasUtoA()
  3777. {
  3778. BOOL bReturn = TRUE;
  3779. BOOL bTryRnaph = FALSE;
  3780. //
  3781. // First Try to get the RasLinkageStruct out of Thread Local Storage, we
  3782. // may already be initialized.
  3783. //
  3784. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
  3785. CMASSERTMSG(NULL == pAnsiRasLinkage, TEXT("InitCmRasUtoA -- RasLinkage Already established. Why are we calling InitCmRasUtoA more than once?"));
  3786. if (NULL == pAnsiRasLinkage)
  3787. {
  3788. //
  3789. // Then we haven't linked to RAS yet, first allocate the struct
  3790. //
  3791. pAnsiRasLinkage = (RasLinkageStructA*)CmMalloc(sizeof(RasLinkageStructA));
  3792. if (!pAnsiRasLinkage)
  3793. {
  3794. return FALSE;
  3795. }
  3796. //
  3797. // Now that we have a structure, lets start filling it in. Try getting all of
  3798. // the entry points out of RasApi32.dll first, then try rnaph.dll if necessary.
  3799. //
  3800. pAnsiRasLinkage->hInstRas = LoadLibraryExA("rasapi32.dll", NULL, 0);
  3801. CMASSERTMSG(NULL != pAnsiRasLinkage->hInstRas, TEXT("InitCmRasUtoA -- Unable to load rasapi32.dll. Failing Ras Link."));
  3802. // before doing this, fix up the array based on whether we are on
  3803. // Millennium or not. The function below exists only on Millennium
  3804. if (!OS_MIL)
  3805. {
  3806. c_ArrayOfRasFuncsA[10] = NULL; //RasSetSubEntryProperties
  3807. c_ArrayOfRasFuncsA[11] = NULL; //RasDeleteSubEntry
  3808. }
  3809. if (pAnsiRasLinkage->hInstRas)
  3810. {
  3811. for (int i = 0 ; c_ArrayOfRasFuncsA[i] ; i++)
  3812. {
  3813. pAnsiRasLinkage->apvPfnRas[i] = GetProcAddress(pAnsiRasLinkage->hInstRas, c_ArrayOfRasFuncsA[i]);
  3814. if (!(pAnsiRasLinkage->apvPfnRas[i]))
  3815. {
  3816. bTryRnaph = TRUE;
  3817. }
  3818. }
  3819. }
  3820. //
  3821. // If we missed a few, then we need to get them from rnaph.dll
  3822. //
  3823. if (bTryRnaph)
  3824. {
  3825. pAnsiRasLinkage->hInstRnaph = LoadLibraryExA("rnaph.dll", NULL, 0);
  3826. CMASSERTMSG(NULL != pAnsiRasLinkage->hInstRnaph, TEXT("InitCmRasUtoA -- Unable to load Rnaph.dll. Failing Ras Link."));
  3827. if (pAnsiRasLinkage->hInstRnaph)
  3828. {
  3829. for (int i = 0 ; c_ArrayOfRasFuncsA[i] ; i++)
  3830. {
  3831. if (NULL == pAnsiRasLinkage->apvPfnRas[i])
  3832. {
  3833. pAnsiRasLinkage->apvPfnRas[i] = GetProcAddress(pAnsiRasLinkage->hInstRnaph, c_ArrayOfRasFuncsA[i]);
  3834. if (!(pAnsiRasLinkage->apvPfnRas[i]))
  3835. {
  3836. bReturn = FALSE;
  3837. }
  3838. }
  3839. }
  3840. }
  3841. }
  3842. //
  3843. // Always save the pAnsiRasLinkage value to thread local storage, if the linkage wasn't successful
  3844. // we will call FreeCmRasUtoA to clean it up. If it was successful we need to maintain it for later
  3845. // use. Note that the first thing FreeCmRasUtoA does is get the Ras Linkage struct pointer out of
  3846. // thread local storage because that is were it would reside under normal operation.
  3847. //
  3848. TlsSetValue(g_dwTlsIndex, (LPVOID)pAnsiRasLinkage);
  3849. if (!bReturn)
  3850. {
  3851. //
  3852. // Ras Linkage failed for some reason. We need to free up any resources we
  3853. // may have partially filled in.
  3854. //
  3855. FreeCmRasUtoA();
  3856. }
  3857. }
  3858. return bReturn;
  3859. }
  3860. //+----------------------------------------------------------------------------
  3861. //
  3862. // Function: SHGetPathFromIDListUA
  3863. //
  3864. // Synopsis: Unicode to Ansi wrapper for the win32 SHGetPathFromIDList API.
  3865. //
  3866. // Arguments: See the win32 API definition
  3867. //
  3868. // Returns: See the win32 API definition
  3869. //
  3870. // History: quintinb Created 7/15/99
  3871. //
  3872. //+----------------------------------------------------------------------------
  3873. BOOL SHGetPathFromIDListUA(LPCITEMIDLIST pidl, LPWSTR pszPath)
  3874. {
  3875. BOOL bReturn = FALSE;
  3876. if (pidl && pszPath)
  3877. {
  3878. CHAR szAnsiPath[MAX_PATH+1];
  3879. bReturn = SHGetPathFromIDListA(pidl, szAnsiPath);
  3880. if (bReturn)
  3881. {
  3882. int iChars = SzToWz(szAnsiPath, pszPath, MAX_PATH); // don't know correct length but
  3883. // the API says the path should be at
  3884. // least MAX_PATH
  3885. if (!iChars || (MAX_PATH < (DWORD)iChars))
  3886. {
  3887. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3888. bReturn = FALSE;
  3889. }
  3890. }
  3891. }
  3892. return bReturn;
  3893. }
  3894. //+----------------------------------------------------------------------------
  3895. //
  3896. // Function: SHGetSpecialFolderLocationUA
  3897. //
  3898. // Synopsis: While the win32 SHGetSpecialFolderLocation API doesn't actually
  3899. // require any conversion between Unicode and ANSI, CM's shell dll
  3900. // class can only take one dll to take entry points from. Thus I
  3901. // was forced to add these here so that the class could get all the
  3902. // shell APIs it needed from cmutoa.dll.
  3903. //
  3904. // Arguments: See the win32 API definition
  3905. //
  3906. // Returns: See the win32 API definition
  3907. //
  3908. // History: quintinb Created 7/15/99
  3909. //
  3910. //+----------------------------------------------------------------------------
  3911. HRESULT SHGetSpecialFolderLocationUA(HWND hwnd, int csidl, LPITEMIDLIST *ppidl)
  3912. {
  3913. return SHGetSpecialFolderLocation(hwnd, csidl, ppidl);
  3914. }
  3915. //+----------------------------------------------------------------------------
  3916. //
  3917. // Function: SHGetMallocUA
  3918. //
  3919. // Synopsis: While the win32 SHGetMalloc API doesn't actually
  3920. // require any conversion between Unicode and ANSI, CM's shell dll
  3921. // class can only take one dll to take entry points from. Thus I
  3922. // was forced to add these here so that the class could get all the
  3923. // shell APIs it needed from cmutoa.dll.
  3924. //
  3925. // Arguments: See the win32 API definition
  3926. //
  3927. // Returns: See the win32 API definition
  3928. //
  3929. // History: quintinb Created 7/15/99
  3930. //
  3931. //+----------------------------------------------------------------------------
  3932. HRESULT SHGetMallocUA(LPMALLOC * ppMalloc)
  3933. {
  3934. return SHGetMalloc(ppMalloc);
  3935. }
  3936. //+----------------------------------------------------------------------------
  3937. //
  3938. // Function: ShellExecuteExUA
  3939. //
  3940. // Synopsis: Unicode to Ansi wrapper for the win32 ShellExecuteEx API.
  3941. // Note that we do note convert the lpIDList param of the
  3942. // SHELLEXECUTEINFOW struct because it is just a binary blob. Thus
  3943. // figuring out how to convert it if we don't know what it is. If
  3944. // we need this in the future we will have to deal with it on a case
  3945. // by case basis.
  3946. //
  3947. // Arguments: See the win32 API definition
  3948. //
  3949. // Returns: See the win32 API definition
  3950. //
  3951. // History: quintinb Created 7/15/99
  3952. //
  3953. //+----------------------------------------------------------------------------
  3954. BOOL ShellExecuteExUA(LPSHELLEXECUTEINFOW pShellInfoW)
  3955. {
  3956. BOOL bReturn = FALSE;
  3957. SHELLEXECUTEINFOA ShellInfoA;
  3958. ZeroMemory(&ShellInfoA, sizeof(ShellInfoA));
  3959. if (pShellInfoW)
  3960. {
  3961. ShellInfoA.cbSize = sizeof(ShellInfoA);
  3962. ShellInfoA.fMask = pShellInfoW->fMask;
  3963. ShellInfoA.hwnd = pShellInfoW->hwnd;
  3964. if (pShellInfoW->lpVerb)
  3965. {
  3966. ShellInfoA.lpVerb = WzToSzWithAlloc(pShellInfoW->lpVerb);
  3967. if (NULL == ShellInfoA.lpVerb)
  3968. {
  3969. goto exit;
  3970. }
  3971. }
  3972. if (pShellInfoW->lpFile)
  3973. {
  3974. ShellInfoA.lpFile = WzToSzWithAlloc(pShellInfoW->lpFile);
  3975. if (NULL == ShellInfoA.lpFile)
  3976. {
  3977. goto exit;
  3978. }
  3979. }
  3980. if (pShellInfoW->lpParameters)
  3981. {
  3982. ShellInfoA.lpParameters = WzToSzWithAlloc(pShellInfoW->lpParameters);
  3983. if (NULL == ShellInfoA.lpParameters)
  3984. {
  3985. goto exit;
  3986. }
  3987. }
  3988. if (pShellInfoW->lpDirectory)
  3989. {
  3990. ShellInfoA.lpDirectory = WzToSzWithAlloc(pShellInfoW->lpDirectory);
  3991. if (NULL == ShellInfoA.lpDirectory)
  3992. {
  3993. goto exit;
  3994. }
  3995. }
  3996. ShellInfoA.nShow = pShellInfoW->nShow;
  3997. ShellInfoA.hInstApp = pShellInfoW->hInstApp;
  3998. //
  3999. // Since this is a binary blob conversion could be difficult.
  4000. // We also don't currently use it, so I won't spend the cycles implementing it now.
  4001. //
  4002. MYDBGASSERT(NULL == pShellInfoW->lpIDList);
  4003. ShellInfoA.lpIDList = NULL;
  4004. if (pShellInfoW->lpClass)
  4005. {
  4006. ShellInfoA.lpClass = WzToSzWithAlloc(pShellInfoW->lpClass);
  4007. if (NULL == ShellInfoA.lpClass)
  4008. {
  4009. goto exit;
  4010. }
  4011. }
  4012. ShellInfoA.hkeyClass = pShellInfoW->hkeyClass;
  4013. ShellInfoA.hIcon = pShellInfoW->hIcon; // hIcon/hMonitor is a union so we only need one of them to get the mem
  4014. // HANDLE hProcess this is a return param dealt with below.
  4015. //
  4016. // Finally call ShellExecuteExA
  4017. //
  4018. bReturn = ShellExecuteExA(&ShellInfoA);
  4019. if (ShellInfoA.hProcess)
  4020. {
  4021. //
  4022. // The Caller asked for the process handle so send it back.
  4023. //
  4024. pShellInfoW->hProcess = ShellInfoA.hProcess;
  4025. }
  4026. }
  4027. exit:
  4028. CmFree((void*)ShellInfoA.lpVerb);
  4029. CmFree((void*)ShellInfoA.lpFile);
  4030. CmFree((void*)ShellInfoA.lpParameters);
  4031. CmFree((void*)ShellInfoA.lpDirectory);
  4032. CmFree((void*)ShellInfoA.lpClass);
  4033. return bReturn;
  4034. }
  4035. //+----------------------------------------------------------------------------
  4036. //
  4037. // Function: Shell_NotifyIconUA
  4038. //
  4039. // Synopsis: Unicode to Ansi wrapper for the win32 Shell_NotifyIcon API.
  4040. //
  4041. // Arguments: See the win32 API definition
  4042. //
  4043. // Returns: See the win32 API definition
  4044. //
  4045. // History: quintinb Created 7/15/99
  4046. //
  4047. //+----------------------------------------------------------------------------
  4048. BOOL Shell_NotifyIconUA (DWORD dwMessage, PNOTIFYICONDATAW pnidW)
  4049. {
  4050. BOOL bReturn = FALSE;
  4051. if (pnidW)
  4052. {
  4053. NOTIFYICONDATAA nidA;
  4054. ZeroMemory (&nidA, sizeof(NOTIFYICONDATAA));
  4055. nidA.cbSize = sizeof(NOTIFYICONDATAA);
  4056. nidA.hWnd = pnidW->hWnd;
  4057. nidA.uID = pnidW->uID;
  4058. nidA.uFlags = pnidW->uFlags;
  4059. nidA.uCallbackMessage = pnidW->uCallbackMessage;
  4060. nidA.hIcon = pnidW->hIcon;
  4061. int iChars = WzToSz(pnidW->szTip, nidA.szTip, 64); // 64 is the length of the szTip in the 4.0 struct
  4062. if (!iChars || (64 < iChars))
  4063. {
  4064. nidA.szTip[0] = '\0';
  4065. }
  4066. bReturn = Shell_NotifyIconA(dwMessage, &nidA);
  4067. }
  4068. return bReturn;
  4069. }