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

328 lines
8.2 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: StrUtils.cpp
  6. * Content: Implements the string utils
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 02/12/2000 rmt Created
  12. * 08/28/2000 masonb Voice Merge: Added check of return code of MultiByteToWideChar in STR_jkAnsiToWide
  13. * 09/16/2000 aarono fix STR_AllocAndConvertToANSI, ANSI doesn't mean 1 byte per DBCS character so we
  14. * must allow up to 2 bytes per char when allocating buffer (B#43286)
  15. *@@END_MSINTERNAL
  16. *
  17. ***************************************************************************/
  18. #include "dncmni.h"
  19. /*
  20. ** WideToAnsi
  21. *
  22. * CALLED BY: everywhere
  23. *
  24. * PARAMETERS: lpStr - destination string
  25. * lpWStr - string to convert
  26. * cchStr - size of dest buffer
  27. *
  28. * DESCRIPTION:
  29. * converts unicode lpWStr to ansi lpStr.
  30. * fills in unconvertable chars w/ DPLAY_DEFAULT_CHAR "-"
  31. *
  32. *
  33. * RETURNS: if cchStr is 0, returns the size required to hold the string
  34. * otherwise, returns the number of chars converted
  35. *
  36. */
  37. #undef DPF_MODNAME
  38. #define DPF_MODNAME "STR_jkWideToAnsi"
  39. HRESULT STR_jkWideToAnsi(LPSTR lpStr,LPCWSTR lpWStr,int cchStr)
  40. {
  41. int rval;
  42. BOOL fDefault = FALSE;
  43. // can't call us w/ null pointer & non-zero cch
  44. DNASSERT(lpWStr || !cchStr);
  45. // use the default code page (CP_ACP)
  46. // -1 indicates WStr must be null terminated
  47. rval = WideCharToMultiByte(CP_ACP,0,lpWStr,-1,lpStr,cchStr,NULL,&fDefault);
  48. DNASSERT(!fDefault);
  49. if(rval == 0)
  50. {
  51. return E_FAIL;
  52. }
  53. else
  54. {
  55. return S_OK;
  56. }
  57. } // WideToAnsi
  58. #undef DPF_MODNAME
  59. #define DPF_MODNAME "STR_jkAnsiToWide"
  60. /*
  61. ** AnsiToWide
  62. *
  63. * CALLED BY: everywhere
  64. *
  65. * PARAMETERS: lpWStr - dest string
  66. * lpStr - string to convert
  67. * cchWstr - size of dest buffer
  68. *
  69. * DESCRIPTION: converts Ansi lpStr to Unicode lpWstr
  70. *
  71. */
  72. HRESULT STR_jkAnsiToWide(LPWSTR lpWStr,LPCSTR lpStr,int cchWStr)
  73. {
  74. int rval;
  75. DNASSERT(lpStr);
  76. DNASSERT(lpWStr);
  77. rval = MultiByteToWideChar(CP_ACP,0,lpStr,-1,lpWStr,cchWStr);
  78. if (!rval)
  79. {
  80. DPFX(DPFPREP,0,"MultiByteToWideChar failed in STR_jkAnsiToWide");
  81. return E_FAIL;
  82. }
  83. else
  84. {
  85. return S_OK;
  86. }
  87. } // AnsiToWide
  88. #ifndef WINCE
  89. #undef DPF_MODNAME
  90. #define DPF_MODNAME "STR_WideToAnsi"
  91. //**********************************************************************
  92. // ------------------------------
  93. // WideToANSI - convert a wide string to an ANSI string
  94. //
  95. // Entry: Pointer to source wide string
  96. // Size of source string (in WCHAR units, -1 implies NULL-terminated)
  97. // Pointer to ANSI string destination
  98. // Pointer to size of ANSI destination
  99. //
  100. // Exit: Error code:
  101. // E_FAIL = operation failed
  102. // S_OK = operation succeded
  103. // E_OUTOFMEMORY = destination buffer too small
  104. // ------------------------------
  105. HRESULT STR_WideToAnsi( const WCHAR *const pWCHARString,
  106. const DWORD dwWCHARStringLength,
  107. char *const pString,
  108. DWORD *const pdwStringLength )
  109. {
  110. HRESULT hr;
  111. int iReturn;
  112. BOOL fDefault;
  113. char cMilleniumHackBuffer;
  114. char *pMilleniumHackBuffer;
  115. DNASSERT( pWCHARString != NULL );
  116. DNASSERT( pdwStringLength != NULL );
  117. DNASSERT( ( pString != NULL ) || ( *pdwStringLength == 0 ) );
  118. //
  119. // Initialize. A hack needs to be implemented for WinME parameter
  120. // validation, because when you pass zero for a destination size, you
  121. // MUST have a valid pointer. Works on Win95, 98, NT4, Win2K, etc.....
  122. //
  123. hr = S_OK;
  124. if ( *pdwStringLength == 0 )
  125. {
  126. pMilleniumHackBuffer = &cMilleniumHackBuffer;
  127. }
  128. else
  129. {
  130. pMilleniumHackBuffer = pString;
  131. }
  132. fDefault = FALSE;
  133. iReturn = WideCharToMultiByte( CP_ACP, // code page (default ANSI)
  134. 0, // flags (none)
  135. pWCHARString, // pointer to WCHAR string
  136. dwWCHARStringLength, // size of WCHAR string
  137. pMilleniumHackBuffer, // pointer to destination ANSI string
  138. *pdwStringLength, // size of destination string
  139. NULL, // pointer to default for unmappable characters (none)
  140. &fDefault // pointer to flag indicating that default was used
  141. );
  142. if ( iReturn == 0 )
  143. {
  144. DWORD dwError;
  145. dwError = GetLastError();
  146. DPFX( DPFPREP, 0, "Failed to convert WCHAR to multi-byte! %d", dwError );
  147. hr = E_FAIL;
  148. }
  149. else
  150. {
  151. if ( *pdwStringLength == 0 )
  152. {
  153. hr = E_OUTOFMEMORY;
  154. }
  155. else
  156. {
  157. DNASSERT( hr == S_OK );
  158. }
  159. *pdwStringLength = iReturn;
  160. }
  161. //
  162. // if you hit this ASSERT it's because you've probably got ASCII text as your
  163. // input WCHAR string. Double-check your input!!
  164. //
  165. DNASSERT( fDefault == FALSE );
  166. return hr;
  167. }
  168. //**********************************************************************
  169. //**********************************************************************
  170. // ------------------------------
  171. // ANSIToWide - convert an ANSI string to a wide string
  172. //
  173. // Entry: Pointer to source multi-byte (ANSI) string
  174. // Size of source string (-1 imples NULL-terminated)
  175. // Pointer to multi-byte string destination
  176. // Pointer to size of multi-byte destination (in WCHAR units)
  177. //
  178. // Exit: Error code:
  179. // E_FAIL = operation failed
  180. // S_OK = operation succeded
  181. // E_OUTOFMEMORY = destination buffer too small
  182. // ------------------------------
  183. #undef DPF_MODNAME
  184. #define DPF_MODNAME "STR_AnsiToWide"
  185. HRESULT STR_AnsiToWide( const char *const pString,
  186. const DWORD dwStringLength,
  187. WCHAR *const pWCHARString,
  188. DWORD *const pdwWCHARStringLength )
  189. {
  190. HRESULT hr;
  191. int iReturn;
  192. WCHAR MilleniumHackBuffer;
  193. WCHAR *pMilleniumHackBuffer;
  194. DNASSERT( pString != NULL );
  195. DNASSERT( pdwWCHARStringLength != NULL );
  196. DNASSERT( ( pWCHARString != NULL ) || ( *pdwWCHARStringLength == 0 ) );
  197. //
  198. // Initialize. A hack needs to be implemented for WinME parameter
  199. // validation, because when you pass zero for a destination size, you
  200. // MUST have a valid pointer. Works on Win95, 98, NT4, Win2K, etc.....
  201. //
  202. hr = S_OK;
  203. if ( *pdwWCHARStringLength == 0 )
  204. {
  205. pMilleniumHackBuffer = &MilleniumHackBuffer;
  206. }
  207. else
  208. {
  209. pMilleniumHackBuffer = pWCHARString;
  210. }
  211. iReturn = MultiByteToWideChar( CP_ACP, // code page (default ANSI)
  212. 0, // flags (none)
  213. pString, // pointer to multi-byte string
  214. dwStringLength, // size of string (assume null-terminated)
  215. pMilleniumHackBuffer, // pointer to destination wide-char string
  216. *pdwWCHARStringLength // size of destination in WCHARs
  217. );
  218. if ( iReturn == 0 )
  219. {
  220. DWORD dwError;
  221. dwError = GetLastError();
  222. DPFX(DPFPREP, 0, "Failed to convert multi-byte to WCHAR! %d", dwError );
  223. hr = E_FAIL;
  224. }
  225. else
  226. {
  227. if ( *pdwWCHARStringLength == 0 )
  228. {
  229. hr = E_OUTOFMEMORY;
  230. }
  231. else
  232. {
  233. DNASSERT( hr == S_OK );
  234. }
  235. *pdwWCHARStringLength = iReturn;
  236. }
  237. return hr;
  238. }
  239. //**********************************************************************
  240. // WideToAnsi
  241. //
  242. // Convert a WCHAR (Wide) string to a CHAR (ANSI) string
  243. //
  244. // CHAR *pStr CHAR string
  245. // WCHAR *pWStr WCHAR string
  246. // int iStrSize size (in bytes) of buffer pointed to by lpStr
  247. #undef DPF_MODNAME
  248. #define DPF_MODNAME "STR_AllocAndConvertToANSI"
  249. /*
  250. ** GetAnsiString
  251. *
  252. * CALLED BY: Everywhere
  253. *
  254. * PARAMETERS: *ppszAnsi - pointer to string
  255. * lpszWide - string to copy
  256. *
  257. * DESCRIPTION: handy utility function
  258. * allocs space for and converts lpszWide to ansi
  259. *
  260. * RETURNS: string length
  261. *
  262. */
  263. HRESULT STR_AllocAndConvertToANSI(LPSTR * ppszAnsi,LPCWSTR lpszWide)
  264. {
  265. int iStrLen;
  266. BOOL bDefault;
  267. DNASSERT(ppszAnsi);
  268. if (!lpszWide)
  269. {
  270. *ppszAnsi = NULL;
  271. return S_OK;
  272. }
  273. *ppszAnsi = (char*) DNMalloc((wcslen(lpszWide)*2+1)*sizeof(char));
  274. if (!*ppszAnsi)
  275. {
  276. DPFX(DPFPREP,0, "could not get ansi string -- out of memory");
  277. return E_OUTOFMEMORY;
  278. }
  279. iStrLen = WideCharToMultiByte(CP_ACP,0,lpszWide,-1,*ppszAnsi,wcslen(lpszWide)*2+1,
  280. NULL,&bDefault);
  281. return S_OK;
  282. } // OSAL_AllocAndConvertToANSI
  283. #endif // !WINCE