1 /* 2 * PROJECT: .inf file parser 3 * LICENSE: GPL - See COPYING in the top level directory 4 * PROGRAMMER: Royce Mitchell III 5 * Eric Kohl 6 * Ge van Geldorp <gvg@reactos.org> 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include "inflib.h" 12 #include "infhost.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 NTSTATUS NTAPI 18 RtlMultiByteToUnicodeN( 19 IN PWCHAR UnicodeString, 20 IN ULONG UnicodeSize, 21 IN PULONG ResultSize, 22 IN PCSTR MbString, 23 IN ULONG MbSize) 24 { 25 ULONG Size = 0; 26 ULONG i; 27 PUCHAR WideString; 28 29 /* single-byte code page */ 30 if (MbSize > (UnicodeSize / sizeof(WCHAR))) 31 Size = UnicodeSize / sizeof(WCHAR); 32 else 33 Size = MbSize; 34 35 if (ResultSize != NULL) 36 *ResultSize = Size * sizeof(WCHAR); 37 38 WideString = (PUCHAR)UnicodeString; 39 for (i = 0; i < Size; i++) 40 { 41 WideString[2 * i + 0] = (UCHAR)MbString[i]; 42 WideString[2 * i + 1] = 0; 43 } 44 45 return STATUS_SUCCESS; 46 } 47 48 49 BOOLEAN 50 NTAPI 51 RtlIsTextUnicode( PVOID buf, INT len, INT *pf ) 52 { 53 static const WCHAR std_control_chars[] = {'\r','\n','\t',' ',0x3000,0}; 54 static const WCHAR byterev_control_chars[] = {0x0d00,0x0a00,0x0900,0x2000,0}; 55 const WCHAR *s = buf; 56 int i; 57 unsigned int flags = MAXULONG, out_flags = 0; 58 59 if (len < sizeof(WCHAR)) 60 { 61 /* FIXME: MSDN documents IS_TEXT_UNICODE_BUFFER_TOO_SMALL but there is no such thing... */ 62 if (pf) *pf = 0; 63 return FALSE; 64 } 65 if (pf) 66 flags = (unsigned int)*pf; 67 /* 68 * Apply various tests to the text string. According to the 69 * docs, each test "passed" sets the corresponding flag in 70 * the output flags. But some of the tests are mutually 71 * exclusive, so I don't see how you could pass all tests ... 72 */ 73 74 /* Check for an odd length ... pass if even. */ 75 if (len & 1) out_flags |= IS_TEXT_UNICODE_ODD_LENGTH; 76 77 if (((char *)buf)[len - 1] == 0) 78 len--; /* Windows seems to do something like that to avoid e.g. false IS_TEXT_UNICODE_NULL_BYTES */ 79 80 len /= (INT)sizeof(WCHAR); 81 /* Windows only checks the first 256 characters */ 82 if (len > 256) len = 256; 83 84 /* Check for the special byte order unicode marks. */ 85 if (*s == 0xFEFF) out_flags |= IS_TEXT_UNICODE_SIGNATURE; 86 if (*s == 0xFFFE) out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE; 87 88 /* apply some statistical analysis */ 89 if (flags & IS_TEXT_UNICODE_STATISTICS) 90 { 91 int stats = 0; 92 /* FIXME: checks only for ASCII characters in the unicode stream */ 93 for (i = 0; i < len; i++) 94 { 95 if (s[i] <= 255) stats++; 96 } 97 if (stats > len / 2) 98 out_flags |= IS_TEXT_UNICODE_STATISTICS; 99 } 100 101 /* Check for unicode NULL chars */ 102 if (flags & IS_TEXT_UNICODE_NULL_BYTES) 103 { 104 for (i = 0; i < len; i++) 105 { 106 if (!(s[i] & 0xff) || !(s[i] >> 8)) 107 { 108 out_flags |= IS_TEXT_UNICODE_NULL_BYTES; 109 break; 110 } 111 } 112 } 113 114 if (flags & IS_TEXT_UNICODE_CONTROLS) 115 { 116 for (i = 0; i < len; i++) 117 { 118 if (strchrW(std_control_chars, s[i])) 119 { 120 out_flags |= IS_TEXT_UNICODE_CONTROLS; 121 break; 122 } 123 } 124 } 125 126 if (flags & IS_TEXT_UNICODE_REVERSE_CONTROLS) 127 { 128 for (i = 0; i < len; i++) 129 { 130 if (strchrW(byterev_control_chars, s[i])) 131 { 132 out_flags |= IS_TEXT_UNICODE_REVERSE_CONTROLS; 133 break; 134 } 135 } 136 } 137 138 if (pf) 139 { 140 out_flags &= (unsigned int)*pf; 141 *pf = (INT)out_flags; 142 } 143 /* check for flags that indicate it's definitely not valid Unicode */ 144 if (out_flags & (IS_TEXT_UNICODE_REVERSE_MASK | IS_TEXT_UNICODE_NOT_UNICODE_MASK)) return FALSE; 145 /* now check for invalid ASCII, and assume Unicode if so */ 146 if (out_flags & IS_TEXT_UNICODE_NOT_ASCII_MASK) return TRUE; 147 /* now check for Unicode flags */ 148 if (out_flags & IS_TEXT_UNICODE_UNICODE_MASK) return TRUE; 149 /* no flags set */ 150 return FALSE; 151 } 152