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.

209 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. Utmb2u.c
  5. Abstract:
  6. Module that contains code to convert a unicode file
  7. to multibyte.
  8. Author:
  9. Ted Miller (tedm) 17-June-1993
  10. Revision History:
  11. --*/
  12. #include "unitext.h"
  13. VOID
  14. UnicodeTextFileToMultibyte(
  15. IN LPWSTR SourceFileName,
  16. IN LPWSTR TargetFileName,
  17. IN HANDLE SourceFileHandle,
  18. IN HANDLE TargetFileHandle,
  19. IN DWORD SourceFileSize,
  20. IN UINT TargetCodePage
  21. )
  22. /*++
  23. Routine Description:
  24. Convert an open unicode text file to a multibyte text file,
  25. whose characters are in a given codepage.
  26. Arguments:
  27. SourceFileName - name of source (unicode) text file.
  28. TargetFileName - name of target (multibyte) text file.
  29. SourceFileHandle - win32 handle to the open source file.
  30. The file pointer should be fully rewound.
  31. TargetFileHandle - win32 handle to the open target file.
  32. The file pointer should be fully rewound.
  33. SourceFileSize - size in bytes of the source file.
  34. SourceCodePage - codepage for the target file.
  35. Return Value:
  36. None. Does not return if error.
  37. --*/
  38. {
  39. HANDLE SourceMapping,TargetMapping;
  40. LPWSTR SourceView;
  41. LPSTR TargetView;
  42. int BytesWritten;
  43. DWORD MaxTargetSize;
  44. BOOL UsedDefaultChar;
  45. //
  46. // Tell the user what we're doing.
  47. //
  48. MsgPrintfW(MSG_CONV_UNICODE_TO_MB,SourceFileName,TargetFileName,TargetCodePage);
  49. //
  50. // Create a file mapping object that maps the entire source file.
  51. //
  52. SourceMapping = CreateFileMapping(
  53. SourceFileHandle,
  54. NULL,
  55. PAGE_READONLY,
  56. 0,
  57. SourceFileSize,
  58. NULL
  59. );
  60. if(SourceMapping == NULL) {
  61. ErrorAbort(MSG_CANT_MAP_FILE,SourceFileName,GetLastError());
  62. }
  63. //
  64. // Calculate the maximum target file size. This is the same as
  65. // source file size (instead of half its size) because there
  66. // could be double-byte characters in the target file.
  67. //
  68. MaxTargetSize = SourceFileSize;
  69. //
  70. // Create a file mapping object that maps the maximum size of
  71. // the target file.
  72. //
  73. TargetMapping = CreateFileMapping(
  74. TargetFileHandle,
  75. NULL,
  76. PAGE_READWRITE,
  77. 0,
  78. MaxTargetSize,
  79. NULL
  80. );
  81. if(TargetMapping == NULL) {
  82. CloseHandle(SourceMapping);
  83. ErrorAbort(MSG_CANT_MAP_FILE,TargetFileName,GetLastError());
  84. }
  85. //
  86. // Map views of the two files.
  87. //
  88. SourceView = MapViewOfFile(
  89. SourceMapping,
  90. FILE_MAP_READ,
  91. 0,0,
  92. SourceFileSize
  93. );
  94. if(SourceView == NULL) {
  95. CloseHandle(SourceMapping);
  96. CloseHandle(TargetMapping);
  97. ErrorAbort(MSG_CANT_MAP_FILE,SourceFileName,GetLastError());
  98. }
  99. TargetView = MapViewOfFile(
  100. TargetMapping,
  101. FILE_MAP_WRITE,
  102. 0,0,
  103. MaxTargetSize
  104. );
  105. if(TargetView == NULL) {
  106. UnmapViewOfFile(SourceView);
  107. CloseHandle(SourceMapping);
  108. CloseHandle(TargetMapping);
  109. ErrorAbort(MSG_CANT_MAP_FILE,TargetFileName,GetLastError());
  110. }
  111. //
  112. // If the first character in the source file is the byte-order mark,
  113. // skip over it.
  114. //
  115. if(*SourceView == BYTE_ORDER_MARK) {
  116. SourceView++;
  117. SourceFileSize -= sizeof(WCHAR);
  118. }
  119. //
  120. // If the first character is reversed byte-order mark, bail.
  121. //
  122. if(*SourceView == SWAPPED_BYTE_ORDER_MARK) {
  123. ErrorAbort(MSG_ERROR_BYTES_SWAPPED);
  124. }
  125. //
  126. // Do the conversion in one fell swoop.
  127. //
  128. BytesWritten = WideCharToMultiByte(
  129. TargetCodePage,
  130. 0,
  131. SourceView,
  132. SourceFileSize / sizeof(WCHAR),
  133. TargetView,
  134. MaxTargetSize,
  135. NULL,
  136. &UsedDefaultChar
  137. );
  138. //
  139. // Do some cleanup.
  140. //
  141. UnmapViewOfFile(SourceView);
  142. UnmapViewOfFile(TargetView);
  143. CloseHandle(SourceMapping);
  144. CloseHandle(TargetMapping);
  145. //
  146. // Check for error in conversion.
  147. //
  148. if(!BytesWritten) {
  149. ErrorAbort(MSG_CONVERT_FAILED,GetLastError());
  150. }
  151. //
  152. // We know how many bytes there are in the target file now,
  153. // so set the target file size accordingly.
  154. //
  155. if(SetFilePointer(TargetFileHandle,BytesWritten,NULL,FILE_BEGIN) != (DWORD)BytesWritten) {
  156. ErrorAbort(MSG_SEEK_ERROR,TargetFileName,GetLastError());
  157. }
  158. if(!SetEndOfFile(TargetFileHandle)) {
  159. ErrorAbort(MSG_ERROR_SET_EOF,TargetFileName,GetLastError());
  160. }
  161. MsgPrintfW(UsedDefaultChar ? MSG_USED_DEFAULT_CHAR : MSG_CONVERT_OK);
  162. }