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.

328 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1991-1992 Microsoft Corporation
  3. Module Name:
  4. CopyStr.c
  5. Abstract:
  6. This module contains the main two functions for copying and converting
  7. strings between the default codepage for the LAN and wide characters
  8. (i.e. UNICODE).
  9. Author:
  10. John Rogers (JohnRo) 24-Sep-1991
  11. Environment:
  12. Only runs under NT, although the interface is portable (Win/32).
  13. Requires ANSI C extensions: slash-slash comments, long external names.
  14. Note:
  15. These functions assume that the machine's default codepage is the same
  16. as the LAN's default codepage.
  17. Revision History:
  18. 24-Sep-1991 JohnRo
  19. Created.
  20. 04-Oct-1991 JohnRo
  21. Fixed buffer length bug in CopyStrToWStr().
  22. 24-Oct-1991 JohnRo
  23. Corrected Environment comments above.
  24. 21-Nov-1991 JohnRo
  25. Added some alignment assertions.
  26. 26-Nov-1991 JohnRo
  27. Added NetpNCopy routines (used by new net config helpers).
  28. 03-Jan-1992 JohnRo
  29. Added NetpCopyStringToTStr() for FAKE_PER_PROCESS_RW_CONFIG handling.
  30. 29-Apr-1992 JohnRo
  31. Fixed NetpNCopyStrToWStr() under UNICODE. Ditto NetpNCopyWStrToStr.
  32. Made a few changes suggested by PC-LINT.
  33. 21-May-1992 JohnRo
  34. Removed bogus assert in NetpNCopyStrToWStr().
  35. --*/
  36. // These must be included first:
  37. #include <nt.h> // Must be first. IN, VOID, etc.
  38. #include <windef.h> // LPWSTR.
  39. #include <lmcons.h> // (Needed by NetLibNt.h)
  40. // These can be in any order:
  41. #include <align.h> // ROUND_UP_POINTER(), ALIGN_WCHAR.
  42. #include <lmapibuf.h> // NetApiBufferFree().
  43. #include <netdebug.h> // NetpAssert(), etc.
  44. #include <ntrtl.h> // RtlUnicodeStringToOemString(), etc.
  45. #include <string.h> // strlen().
  46. #include <tstring.h> // Most of my prototypes.
  47. #include <stdlib.h> // wcslen(), wcsncpy().
  48. #include <winerror.h> // NO_ERROR, ERROR_NOT_ENOUGH_MEMORY.
  49. VOID
  50. NetpCopyWStrToStr(
  51. OUT LPSTR Dest,
  52. IN LPWSTR Src
  53. )
  54. /*++
  55. Routine Description:
  56. NetpCopyWStrToStr copies characters from a source string
  57. to a destination, converting as it copies them.
  58. Arguments:
  59. Dest - is an LPSTR indicating where the converted characters are to go.
  60. This string will be in the default codepage for the LAN.
  61. Src - is in LPWSTR indicating the source string.
  62. Return Value:
  63. None.
  64. --*/
  65. {
  66. OEM_STRING DestAnsi;
  67. NTSTATUS NtStatus;
  68. UNICODE_STRING SrcUnicode;
  69. NetpAssert( Dest != NULL );
  70. NetpAssert( Src != NULL );
  71. NetpAssert( ((LPVOID)Dest) != ((LPVOID)Src) );
  72. NetpAssert( ROUND_UP_POINTER( Src, ALIGN_WCHAR ) == Src );
  73. *Dest = '\0';
  74. NetpInitOemString(
  75. & DestAnsi, // output: struct
  76. Dest); // input: null terminated
  77. //
  78. // Tell RTL routines there's enough memory out there.
  79. // Note that using a max length in characters is by
  80. // design as this is what this routine's callers
  81. // expect (the max length should normally be in bytes).
  82. //
  83. DestAnsi.MaximumLength = (USHORT) (wcslen(Src)+1);
  84. RtlInitUnicodeString(
  85. & SrcUnicode, // output: struct
  86. Src); // input: null terminated
  87. NtStatus = RtlUnicodeStringToOemString(
  88. & DestAnsi, // output: struct
  89. & SrcUnicode, // input: struct
  90. (BOOLEAN) FALSE); // don't allocate string.
  91. NetpAssert( NT_SUCCESS(NtStatus) );
  92. } // NetpCopyWStrToStr
  93. VOID
  94. NetpCopyStrToWStr(
  95. OUT LPWSTR Dest,
  96. IN LPSTR Src
  97. )
  98. /*++
  99. Routine Description:
  100. NetpCopyStrToWStr copies characters from a source string
  101. to a destination, converting as it copies them.
  102. Arguments:
  103. Dest - is an LPWSTR indicating where the converted characters are to go.
  104. Src - is in LPSTR indicating the source string. This must be a string in
  105. the default codepage of the LAN.
  106. Return Value:
  107. None.
  108. --*/
  109. {
  110. UNICODE_STRING DestUnicode;
  111. NTSTATUS NtStatus;
  112. OEM_STRING SrcAnsi;
  113. NetpAssert( Dest != NULL );
  114. NetpAssert( Src != NULL );
  115. NetpAssert( ((LPVOID)Dest) != ((LPVOID)Src) );
  116. NetpAssert( ROUND_UP_POINTER( Dest, ALIGN_WCHAR ) == Dest );
  117. *Dest = L'\0';
  118. NetpInitOemString(
  119. & SrcAnsi, // output: struct
  120. Src); // input: null terminated
  121. RtlInitUnicodeString(
  122. & DestUnicode, // output: struct
  123. Dest); // input: null terminated
  124. // Tell RTL routines there's enough memory out there.
  125. DestUnicode.MaximumLength = (USHORT)
  126. ((USHORT) (strlen(Src)+1)) * (USHORT) sizeof(wchar_t);
  127. NtStatus = RtlOemStringToUnicodeString(
  128. & DestUnicode, // output: struct
  129. & SrcAnsi, // input: struct
  130. (BOOLEAN) FALSE); // don't allocate string.
  131. NetpAssert( NT_SUCCESS(NtStatus) );
  132. } // NetpCopyStrToWStr
  133. NET_API_STATUS
  134. NetpNCopyStrToWStr(
  135. OUT LPWSTR Dest,
  136. IN LPSTR Src, // string in default LAN codepage
  137. IN DWORD CharCount
  138. )
  139. {
  140. LPWSTR TempW;
  141. NetpAssert( Dest != NULL );
  142. NetpAssert( Src != NULL );
  143. NetpAssert( ((LPVOID)Dest) != ((LPVOID)Src) );
  144. NetpAssert( ROUND_UP_POINTER( Dest, ALIGN_WCHAR ) == Dest );
  145. // Allocate a copy of the full string, and convert to UNICODE.
  146. TempW = NetpAllocWStrFromStr( Src );
  147. if (TempW == NULL) {
  148. // Out of memory!
  149. return (ERROR_NOT_ENOUGH_MEMORY);
  150. }
  151. // Copy portion of array. Append with nulls if necessary.
  152. // (Thank god for the C runtime library! --JR)
  153. (VOID) wcsncpy( Dest, TempW, CharCount );
  154. // Free our temporary string.
  155. (VOID) NetApiBufferFree( TempW );
  156. return (NO_ERROR);
  157. } // NetpNCopyStrToWStr
  158. NET_API_STATUS
  159. NetpNCopyWStrToStr(
  160. OUT LPSTR Dest, // string in default LAN codepage
  161. IN LPWSTR Src,
  162. IN DWORD CharCount
  163. )
  164. {
  165. LPSTR TempStr;
  166. NetpAssert( Dest != NULL );
  167. NetpAssert( Src != NULL );
  168. NetpAssert( ((LPVOID)Dest) != ((LPVOID)Src) );
  169. NetpAssert( ROUND_UP_POINTER( Src, ALIGN_WCHAR ) == Src );
  170. // Allocate a copy of the full string, and convert to UNICODE.
  171. TempStr = NetpAllocStrFromWStr( Src );
  172. if (TempStr == NULL) {
  173. return (ERROR_NOT_ENOUGH_MEMORY);
  174. }
  175. // Copy N chars, pad with nulls, etc.
  176. (VOID) strncpy( Dest, TempStr, CharCount );
  177. // Free our temporary data.
  178. (VOID) NetApiBufferFree( TempStr );
  179. return (NO_ERROR);
  180. } // NetpNCopyWStrToStr
  181. // NetpCopyStrToStr that assumes Dest <= wcslen(SRC)+1 * sizeof(WCHAR)
  182. // This will be called whereever we have made sure that the proper
  183. // buffer size has been allocated. Eventually we can replace
  184. // NetpCopStrToStr with this entirely once all calling functions
  185. // have been fixed up.
  186. VOID NetpCopyWStrToStrDBCS(
  187. OUT LPSTR Dest,
  188. IN LPWSTR Src
  189. )
  190. /*++
  191. Routine Description:
  192. NetpCopyWStrToStr copies characters from a source string
  193. to a destination, converting as it copies them.
  194. Arguments:
  195. Dest - is an LPSTR indicating where the converted characters are to go.
  196. This string will be in the default codepage for the LAN.
  197. Src - is in LPWSTR indicating the source string.
  198. Return Value:
  199. None.
  200. --*/
  201. {
  202. NTSTATUS NtStatus;
  203. LONG Index;
  204. ULONG DestLen = NetpUnicodeToDBCSLen( Src )+1;
  205. NetpAssert( Dest != NULL );
  206. NetpAssert( Src != NULL );
  207. NetpAssert( ((LPVOID)Dest) != ((LPVOID)Src) );
  208. NetpAssert( ROUND_UP_POINTER( Src, ALIGN_WCHAR ) == Src );
  209. NtStatus = RtlUnicodeToOemN(
  210. Dest, // Destination string
  211. DestLen, // Destination string length
  212. &Index, // Last char in translated string
  213. Src, // Source string
  214. wcslen(Src)*sizeof(WCHAR) // Length of source string
  215. );
  216. Dest[Index] = '\0';
  217. NetpAssert( NT_SUCCESS(NtStatus) );
  218. } // NetpCopyWStrToStr
  219. ULONG
  220. NetpUnicodeToDBCSLen(
  221. IN LPWSTR Src
  222. )
  223. {
  224. UNICODE_STRING SrcUnicode;
  225. RtlInitUnicodeString(
  226. & SrcUnicode, // output: struct
  227. Src); // input: null terminated
  228. return( RtlUnicodeStringToOemSize( &SrcUnicode ) -1 );
  229. }