1 /* 2 * PROJECT: ReactOS NLS to TXT Converter 3 * LICENSE: GNU General Public License Version 2.0 or any later version 4 * FILE: devutils/nlsedit/nls.c 5 * COPYRIGHT: Copyright 2016 Dmitry Chapyshev <dmitry@reactos.org> 6 */ 7 8 #include "precomp.h" 9 10 static VOID 11 NLS_InitCodePageTable(PUSHORT TableBase, PCPTABLEINFO CodePageTable) 12 { 13 PNLS_FILE_HEADER NlsFileHeader; 14 15 NlsFileHeader = (PNLS_FILE_HEADER)TableBase; 16 17 /* Copy header fields first */ 18 CodePageTable->CodePage = NlsFileHeader->CodePage; 19 CodePageTable->MaximumCharacterSize = NlsFileHeader->MaximumCharacterSize; 20 CodePageTable->DefaultChar = NlsFileHeader->DefaultChar; 21 CodePageTable->UniDefaultChar = NlsFileHeader->UniDefaultChar; 22 CodePageTable->TransDefaultChar = NlsFileHeader->TransDefaultChar; 23 CodePageTable->TransUniDefaultChar = NlsFileHeader->TransUniDefaultChar; 24 25 CopyMemory(&CodePageTable->LeadByte, &NlsFileHeader->LeadByte, MAXIMUM_LEADBYTES); 26 27 /* Offset to wide char table is after the header */ 28 CodePageTable->WideCharTable = TableBase + NlsFileHeader->HeaderSize + 1 + 29 TableBase[NlsFileHeader->HeaderSize]; 30 31 /* Then multibyte table (256 wchars) follows */ 32 CodePageTable->MultiByteTable = TableBase + NlsFileHeader->HeaderSize + 1; 33 34 /* Check the presence of glyph table (256 wchars) */ 35 if (!CodePageTable->MultiByteTable[256]) 36 { 37 CodePageTable->DBCSRanges = CodePageTable->MultiByteTable + 256 + 1; 38 } 39 else 40 { 41 CodePageTable->DBCSRanges = CodePageTable->MultiByteTable + 256 + 1 + 256; 42 } 43 44 /* Is this double-byte code page? */ 45 if (*CodePageTable->DBCSRanges) 46 { 47 CodePageTable->DBCSCodePage = 1; 48 CodePageTable->DBCSOffsets = CodePageTable->DBCSRanges + 1; 49 } 50 else 51 { 52 CodePageTable->DBCSCodePage = 0; 53 CodePageTable->DBCSOffsets = NULL; 54 } 55 } 56 57 PUSHORT 58 NLS_ReadFile(const WCHAR *pszFile, PCPTABLEINFO CodePageTable) 59 { 60 HANDLE hFile; 61 62 hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 63 if (hFile != INVALID_HANDLE_VALUE) 64 { 65 PUSHORT pData; 66 DWORD dwRead; 67 DWORD dwFileSize; 68 69 dwFileSize = GetFileSize(hFile, NULL); 70 pData = malloc(dwFileSize); 71 if (pData != NULL) 72 { 73 if (ReadFile(hFile, pData, dwFileSize, &dwRead, NULL) != FALSE) 74 { 75 NLS_InitCodePageTable(pData, CodePageTable); 76 CloseHandle(hFile); 77 78 return pData; 79 } 80 81 free(pData); 82 } 83 84 CloseHandle(hFile); 85 } 86 87 return NULL; 88 } 89 90 BOOL 91 NLS_IsDBCSCodePage(PCPTABLEINFO CodePageTable) 92 { 93 return (BOOL)CodePageTable->DBCSCodePage; 94 } 95 96 BOOL 97 NLS_IsGlyphTablePresent(PCPTABLEINFO CodePageTable) 98 { 99 return (CodePageTable->MultiByteTable[256]) ? TRUE : FALSE; 100 } 101 102 BOOL 103 NLS_IsDefaultCharForMB(PCPTABLEINFO CodePageTable, UCHAR Char) 104 { 105 if (CodePageTable->MultiByteTable[Char] != CodePageTable->UniDefaultChar) 106 return FALSE; 107 108 return TRUE; 109 } 110 111 BOOL 112 NLS_IsDefaultCharForUnicode(PCPTABLEINFO CodePageTable, USHORT Char) 113 { 114 USHORT CodePageChar; 115 116 if (NLS_IsDBCSCodePage(CodePageTable)) 117 { 118 PUSHORT MultiByteTable = (PUSHORT)CodePageTable->WideCharTable; 119 CodePageChar = MultiByteTable[Char]; 120 } 121 else 122 { 123 PUCHAR SingleByteTable = (PUCHAR)CodePageTable->WideCharTable; 124 CodePageChar = SingleByteTable[Char]; 125 } 126 127 if (CodePageChar != CodePageTable->DefaultChar) 128 return FALSE; 129 130 return TRUE; 131 } 132 133 USHORT 134 NLS_RecordsCountForMBTable(PCPTABLEINFO CodePageTable) 135 { 136 USHORT CodePageChar; 137 USHORT Count = 0; 138 139 for (CodePageChar = 0; CodePageChar <= 0xFF; CodePageChar++) 140 { 141 if (!NLS_IsDefaultCharForMB(CodePageTable, CodePageChar)) 142 Count++; 143 } 144 145 return Count; 146 } 147 148 USHORT 149 NLS_RecordsCountForUnicodeTable(PCPTABLEINFO CodePageTable) 150 { 151 ULONG UnicodeChar; 152 USHORT Count = 0; 153 154 for (UnicodeChar = 0; UnicodeChar <= 0xFFFF; UnicodeChar++) 155 { 156 if (!NLS_IsDefaultCharForUnicode(CodePageTable, UnicodeChar)) 157 Count++; 158 } 159 160 return Count; 161 } 162 163 USHORT 164 NLS_RecordsCountForGlyphTable(PCPTABLEINFO CodePageTable) 165 { 166 USHORT Count = 0; 167 168 if (NLS_IsGlyphTablePresent(CodePageTable)) 169 { 170 PUSHORT GlyphTable = CodePageTable->MultiByteTable + 256 + 1; 171 USHORT CodePageChar; 172 173 for (CodePageChar = 0; CodePageChar <= 0xFF; CodePageChar++) 174 { 175 USHORT Char = GlyphTable[CodePageChar]; 176 177 if (Char != CodePageTable->UniDefaultChar) 178 Count++; 179 } 180 } 181 182 return Count; 183 } 184 185 USHORT 186 NLS_RecordsCountForDBCSTable(PCPTABLEINFO CodePageTable, UCHAR LeadByte) 187 { 188 PUSHORT LeadByteInfo = CodePageTable->DBCSOffsets; 189 USHORT CodePageChar; 190 USHORT Count = 0; 191 192 for (CodePageChar = 0; CodePageChar <= 0xFF; CodePageChar++) 193 { 194 USHORT Info = LeadByteInfo[LeadByte]; 195 196 if (Info && LeadByteInfo[Info + CodePageChar] != CodePageTable->UniDefaultChar) 197 { 198 Count++; 199 } 200 } 201 202 return Count; 203 } 204