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.

382 lines
6.9 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. unicodes
  5. Abstract:
  6. This module implements the CUnicodeString class. This class allows a string
  7. to automatically convert between PUNICODE_STRING, LPCSTR, and LPCWSTR.
  8. Author:
  9. Doug Barlow (dbarlow) 11/6/1997
  10. Environment:
  11. Win32, C++
  12. Notes:
  13. ?Notes?
  14. --*/
  15. #ifndef _WIN32_WINNT
  16. #define _WIN32_WINNT 0x0400
  17. #endif
  18. #ifndef WIN32_LEAN_AND_MEAN
  19. #define WIN32_LEAN_AND_MEAN 1
  20. #endif
  21. #include <windows.h>
  22. #include <wincrypt.h>
  23. #include <crtdbg.h>
  24. #include "scLogon.h"
  25. #include "unicodes.h"
  26. //
  27. // Piddly routines.
  28. //
  29. CUnicodeString::CUnicodeString(
  30. void)
  31. {
  32. m_szAnsi = NULL;
  33. m_wszUnicode = NULL;
  34. m_fFlags = fBothGood;
  35. }
  36. CUnicodeString::CUnicodeString(
  37. LPCSTR sz)
  38. {
  39. m_szAnsi = NULL;
  40. m_wszUnicode = NULL;
  41. m_fFlags = fBothGood;
  42. Set(sz);
  43. }
  44. CUnicodeString::CUnicodeString(
  45. LPCWSTR wsz)
  46. {
  47. m_szAnsi = NULL;
  48. m_wszUnicode = NULL;
  49. m_fFlags = fBothGood;
  50. Set(wsz);
  51. }
  52. CUnicodeString::CUnicodeString(
  53. PUNICODE_STRING pus)
  54. {
  55. m_szAnsi = NULL;
  56. m_wszUnicode = NULL;
  57. m_fFlags = fBothGood;
  58. Set(pus);
  59. }
  60. CUnicodeString::~CUnicodeString()
  61. {
  62. if (NULL != m_szAnsi)
  63. {
  64. memset(m_szAnsi, 0, lstrlenA(m_szAnsi));
  65. LocalFree(m_szAnsi);
  66. }
  67. if (NULL != m_wszUnicode)
  68. {
  69. memset(m_wszUnicode, 0, lstrlenW(m_wszUnicode)*sizeof(WCHAR));
  70. LocalFree(m_wszUnicode);
  71. }
  72. }
  73. PUNICODE_STRING
  74. CUnicodeString::Set(
  75. PUNICODE_STRING pus)
  76. {
  77. if (NULL != m_szAnsi)
  78. {
  79. LocalFree(m_szAnsi);
  80. m_szAnsi = NULL;
  81. }
  82. if (NULL != m_wszUnicode)
  83. {
  84. LocalFree(m_wszUnicode);
  85. m_wszUnicode = NULL;
  86. }
  87. m_fFlags = fNoneGood;
  88. if (pus != NULL)
  89. {
  90. m_wszUnicode = (LPWSTR)LocalAlloc(LPTR, pus->Length + sizeof(WCHAR));
  91. if (m_wszUnicode != NULL)
  92. {
  93. CopyMemory(
  94. m_wszUnicode,
  95. pus->Buffer,
  96. pus->Length
  97. );
  98. m_wszUnicode[pus->Length/sizeof(WCHAR)] = L'\0';
  99. m_fFlags = fUnicodeGood;
  100. }
  101. }
  102. return pus;
  103. }
  104. /*++
  105. Set:
  106. These methods initialize the object to a given string.
  107. Arguments:
  108. sz - Supplies an ANSI string with which to initialize the object.
  109. wsz - Supplies a UNICODE string with which to initialize the object.
  110. pus - Supplies a pointer to a UNICODE_STRING structure from which to
  111. initialize the object.
  112. Return Value:
  113. The same value as was provided.
  114. Author:
  115. Doug Barlow (dbarlow) 11/6/1997
  116. --*/
  117. LPCSTR
  118. CUnicodeString::Set(
  119. LPCSTR sz)
  120. {
  121. if (NULL != m_wszUnicode)
  122. {
  123. LocalFree(m_wszUnicode);
  124. m_wszUnicode = NULL;
  125. }
  126. if (NULL != m_szAnsi)
  127. LocalFree(m_szAnsi);
  128. m_fFlags = fNoneGood;
  129. m_szAnsi = (LPSTR)LocalAlloc(LPTR, (lstrlenA(sz) + 1) * sizeof(CHAR));
  130. if (NULL != m_szAnsi)
  131. {
  132. lstrcpyA(m_szAnsi, sz);
  133. m_fFlags = fAnsiGood;
  134. }
  135. return m_szAnsi;
  136. }
  137. LPCWSTR
  138. CUnicodeString::Set(
  139. LPCWSTR wsz)
  140. {
  141. if (NULL != m_szAnsi)
  142. {
  143. LocalFree(m_szAnsi);
  144. m_szAnsi = NULL;
  145. }
  146. if (NULL != m_wszUnicode)
  147. LocalFree(m_wszUnicode);
  148. m_fFlags = fNoneGood;
  149. m_wszUnicode = (LPWSTR)LocalAlloc(LPTR, (lstrlenW(wsz) + 1) * sizeof(WCHAR));
  150. if (m_wszUnicode != NULL)
  151. {
  152. lstrcpyW(m_wszUnicode, wsz);
  153. m_fFlags = fUnicodeGood;
  154. }
  155. return m_wszUnicode;
  156. }
  157. CUnicodeString::operator PUNICODE_STRING(
  158. void)
  159. {
  160. m_us.Buffer = (LPWSTR)Unicode();
  161. m_us.Length = m_us.MaximumLength = (USHORT)(lstrlenW(m_us.Buffer) * sizeof(WCHAR));
  162. return &m_us;
  163. }
  164. /*++
  165. Unicode:
  166. This method ensures that the object has a valaid internal UNICODE
  167. representation.
  168. Arguments:
  169. None
  170. Return Value:
  171. The represented string, in UNICODE format.
  172. Author:
  173. Doug Barlow (dbarlow) 11/6/1997
  174. --*/
  175. LPCWSTR
  176. CUnicodeString::Unicode(
  177. void)
  178. {
  179. int length;
  180. //
  181. // See what data we've got, and if any conversion is necessary.
  182. //
  183. switch (m_fFlags)
  184. {
  185. case fAnsiGood:
  186. // The ANSI value is good. Convert it to Unicode.
  187. _ASSERTE(NULL != m_szAnsi);
  188. length =
  189. MultiByteToWideChar(
  190. GetACP(),
  191. MB_PRECOMPOSED,
  192. m_szAnsi,
  193. -1,
  194. NULL,
  195. 0);
  196. if (NULL != m_wszUnicode)
  197. {
  198. LocalFree(m_wszUnicode);
  199. }
  200. if (0 != length)
  201. {
  202. m_wszUnicode = (LPWSTR)LocalAlloc(LPTR, (length + 1) * sizeof(WCHAR));
  203. if (m_wszUnicode == NULL)
  204. {
  205. break;
  206. }
  207. length =
  208. MultiByteToWideChar(
  209. GetACP(),
  210. MB_PRECOMPOSED,
  211. m_szAnsi,
  212. -1,
  213. m_wszUnicode,
  214. length);
  215. m_wszUnicode[length] = 0;
  216. }
  217. else
  218. {
  219. m_wszUnicode = NULL;
  220. }
  221. m_fFlags = fBothGood;
  222. break;
  223. case fUnicodeGood:
  224. case fBothGood:
  225. // The Unicode value is good. Just return that.
  226. break;
  227. case fNoneGood:
  228. default:
  229. // Internal error.
  230. _ASSERT(FALSE);
  231. break;
  232. }
  233. return m_wszUnicode;
  234. }
  235. /*++
  236. Ansi:
  237. This method ensures that the object has a valaid internal ANSI
  238. representation.
  239. Arguments:
  240. None
  241. Return Value:
  242. The represented string, in ANSI format.
  243. Author:
  244. Doug Barlow (dbarlow) 11/6/1997
  245. --*/
  246. LPCSTR
  247. CUnicodeString::Ansi(
  248. void)
  249. {
  250. int length;
  251. //
  252. // See what data we've got, and if any conversion is necessary.
  253. //
  254. switch (m_fFlags)
  255. {
  256. case fUnicodeGood:
  257. // The Unicode buffer is good. Convert it to ANSI.
  258. length =
  259. WideCharToMultiByte(
  260. GetACP(),
  261. 0,
  262. m_wszUnicode,
  263. -1,
  264. NULL,
  265. 0,
  266. NULL,
  267. NULL);
  268. if (NULL != m_szAnsi)
  269. {
  270. LocalFree(m_szAnsi);
  271. }
  272. if (0 != length)
  273. {
  274. m_szAnsi = (LPSTR)LocalAlloc(LPTR, (length + 1) * sizeof(CHAR));
  275. if (m_szAnsi == NULL)
  276. {
  277. break;
  278. }
  279. length =
  280. WideCharToMultiByte(
  281. GetACP(),
  282. 0,
  283. m_wszUnicode,
  284. -1,
  285. m_szAnsi,
  286. length,
  287. NULL,
  288. NULL);
  289. m_szAnsi[length] = 0;
  290. }
  291. else
  292. {
  293. m_szAnsi = NULL;
  294. }
  295. m_fFlags = fBothGood;
  296. break;
  297. case fAnsiGood:
  298. case fBothGood:
  299. // The ANSI buffer is good. We'll return that.
  300. break;
  301. case fNoneGood:
  302. default:
  303. // An internal error.
  304. _ASSERT(FALSE);
  305. break;
  306. }
  307. return m_szAnsi;
  308. }