Author: dchapyshev Date: Wed Sep 14 00:31:30 2016 New Revision: 72668
URL: http://svn.reactos.org/svn/reactos?rev=72668&view=rev Log: [RTL] - Use correct checks for illegal chars - Build context and 8.3 name on the basis of it (context can be already presented)
* Fixes 34 tests for ntdll:RtlGenerate8dot3Name (remained 16 tests will be fixed after correction of a problem with NLS files)
Modified: trunk/reactos/sdk/lib/rtl/dos8dot3.c
Modified: trunk/reactos/sdk/lib/rtl/dos8dot3.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/rtl/dos8dot3.c?rev=... ============================================================================== --- trunk/reactos/sdk/lib/rtl/dos8dot3.c [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/rtl/dos8dot3.c [iso-8859-1] Wed Sep 14 00:31:30 2016 @@ -13,80 +13,65 @@ #define NDEBUG #include <debug.h>
+extern PUSHORT NlsUnicodeToMbOemTable;
/* CONSTANTS *****************************************************************/
-const PCHAR RtlpShortIllegals = ";+=[],"*\<>/?:|"; - +const ULONG RtlpShortIllegals[] = { 0xFFFFFFFF, 0xFC009C04, 0x38000000, 0x10000000 };
/* FUNCTIONS *****************************************************************/
+BOOLEAN +NTAPI +RtlIsValidOemCharacter(IN PWCHAR Char); + static BOOLEAN -RtlpIsShortIllegal(CHAR Char) +RtlpIsShortIllegal(const WCHAR Char) { - return strchr(RtlpShortIllegals, Char) ? TRUE : FALSE; + return (Char < 128 && (RtlpShortIllegals[Char / 32] & (1 << (Char % 32)))); }
static USHORT RtlpGetCheckSum(PUNICODE_STRING Name) { - USHORT Hash, Saved; - WCHAR* CurChar; - USHORT Len; - - if (Name->Length == 0) - { + PWCHAR CurrentChar; + USHORT Hash; + USHORT Saved; + USHORT Length; + + if (!Name->Length) return 0; - }
if (Name->Length == sizeof(WCHAR)) - { return Name->Buffer[0]; - } - - CurChar = Name->Buffer; - Hash = (*CurChar << 8) + *(CurChar + 1); + + CurrentChar = Name->Buffer; + Hash = (*CurrentChar << 8) + *(CurrentChar + 1);
if (Name->Length == 2 * sizeof(WCHAR)) - { return Hash; - }
Saved = Hash; - Len = 2; + Length = 2;
do { - CurChar = CurChar + 2; - Hash = (Hash << 7) + *CurChar; + CurrentChar += 2; + Hash = (Hash << 7) + *CurrentChar; Hash = (Saved >> 1) + (Hash << 8);
- if (Len + 1 < Name->Length / sizeof(WCHAR)) - { - Hash += *(CurChar + 1); + if (Length + 1 < Name->Length / sizeof(WCHAR)) + { + Hash += *(CurrentChar + 1); }
Saved = Hash; - Len += 2; - } while (Len < Name->Length / sizeof(WCHAR)); + Length += 2; + } + while (Length < Name->Length / sizeof(WCHAR));
return Hash; } - -static ULONG -RtlpGetIndexLength(ULONG Index) -{ - ULONG Length = 0; - - while (Index) - { - Index /= 10; - Length++; - } - - return Length ? Length : 1; -} -
/* * @implemented @@ -98,205 +83,146 @@ IN OUT PGENERATE_NAME_CONTEXT Context, OUT PUNICODE_STRING Name8dot3) { - ULONG Count; - WCHAR NameBuffer[8]; - WCHAR ExtBuffer[4]; - ULONG StrLength; - ULONG NameLength; - ULONG ExtLength; - ULONG CopyLength; + ULONG Length = Name->Length / sizeof(WCHAR); + ULONG IndexLength; + ULONG Index; ULONG DotPos; - ULONG i, j; - ULONG IndexLength; - ULONG CurrentIndex; + WCHAR IndexBuffer[8]; + WCHAR Char; USHORT Checksum; - WCHAR c; - - StrLength = Name->Length / sizeof(WCHAR); - - DPRINT("StrLength: %lu\n", StrLength); - - /* Find last dot in Name */ - DotPos = StrLength; - for (i = 0; i < StrLength; i++) - { - if (Name->Buffer[i] == L'.') - { - DotPos = i; - } - } - - DPRINT("DotPos: %lu\n", DotPos); - - /* Copy name (6 valid characters max) */ - for (i = 0, NameLength = 0; NameLength < 6 && i < DotPos; i++) - { - c = UNICODE_NULL; - if (AllowExtendedCharacters) - { - c = RtlUpcaseUnicodeChar(Name->Buffer[i]); - Count = 1; - } - else - { - RtlUpcaseUnicodeToOemN((CHAR *)&c, sizeof(CHAR), &Count, &Name->Buffer[i], sizeof(WCHAR)); - } - - if (Count != 1 || c == UNICODE_NULL || RtlpIsShortIllegal(c)) - { - NameBuffer[NameLength++] = L'_'; - } - else if (c != L'.' && c != L' ') - { - if (isgraph(c) || (AllowExtendedCharacters && iswgraph(c))) + + if (!Context->NameLength) + { + DotPos = Length; + + /* Find last dot in Name */ + for (Index = 0; Index < Length; Index++) + { + if (Name->Buffer[Index] == L'.') + DotPos = Index; + } + + /* Copy name (6 valid characters max) */ + for (Index = 0; Index < DotPos && Context->NameLength < 6; Index++) + { + Char = Name->Buffer[Index]; + + if ((Char > L' ') && (Char != L'.') && + ((Char < 127) || (AllowExtendedCharacters && RtlIsValidOemCharacter(&Char)))) { - NameBuffer[NameLength++] = c; + if (RtlpIsShortIllegal(Char)) + Char = L'_'; + else if (Char >= L'a' && Char <= L'z') + Char = RtlUpcaseUnicodeChar(Char); + + Context->NameBuffer[Context->NameLength] = Char; + ++Context->NameLength; } } - } - - DPRINT("NameBuffer: '%.08S'\n", NameBuffer); - DPRINT("NameLength: %lu\n", NameLength); - - /* Copy extension (4 valid characters max) */ - if (DotPos < StrLength) - { - for (i = DotPos, ExtLength = 0; ExtLength < 4 && i < StrLength; i++) - { - c = UNICODE_NULL; - - if (AllowExtendedCharacters) + + /* Copy extension (4 valid characters max) */ + Context->ExtensionLength = 0; + if (DotPos < Length) + { + Context->ExtensionBuffer[0] = L'.'; + Context->ExtensionLength = 1; + + while (DotPos < Length && Context->ExtensionLength < 4) { - c = RtlUpcaseUnicodeChar(Name->Buffer[i]); - Count = 1; + Char = Name->Buffer[DotPos]; + + if ((Char > L' ') && (Char != L'.') && + ((Char < 127) || (AllowExtendedCharacters && RtlIsValidOemCharacter(&Char)))) + { + if (RtlpIsShortIllegal(Char)) + Char = L'_'; + else if (Char >= L'a' && Char <= L'z') + Char = RtlUpcaseUnicodeChar(Char); + + Context->ExtensionBuffer[Context->ExtensionLength++] = Char; + } + + Char = UNICODE_NULL; + ++DotPos; } - else + + if (Char != UNICODE_NULL) + Context->ExtensionBuffer[Context->ExtensionLength - 1] = L'~'; + } + + if (Context->NameLength <= 2) + { + Checksum = Context->Checksum = RtlpGetCheckSum(Name); + + for (Index = 0; Index < 4; Index++) { - RtlUpcaseUnicodeToOemN((CHAR *)&c, sizeof(CHAR), &Count, &Name->Buffer[i], sizeof(WCHAR)); + Context->NameBuffer[Context->NameLength + Index] = + (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0'; + Checksum >>= 4; }
- if (Count != 1 || c == UNICODE_NULL || RtlpIsShortIllegal(c)) - { - ExtBuffer[ExtLength++] = L'_'; - } - else if (c != L' ') - { - if (isgraph(c) || c == L'.' || (AllowExtendedCharacters && iswgraph(c))) - { - ExtBuffer[ExtLength++] = c; - } - } - } - } - else - { - ExtLength = 0; - } - - DPRINT("ExtBuffer: '%.04S'\n", ExtBuffer); - DPRINT("ExtLength: %lu\n", ExtLength); - - /* Determine next index */ - IndexLength = RtlpGetIndexLength(Context->LastIndexValue); - if (Context->CheckSumInserted) - { - CopyLength = min(NameLength, 8 - 4 - 1 - IndexLength); - Checksum = RtlpGetCheckSum(Name); - } - else - { - CopyLength = min(NameLength, 8 - 1 - IndexLength); - Checksum = 0; - } - - DPRINT("CopyLength: %lu\n", CopyLength); - - if ((Context->NameLength == CopyLength) && - (wcsncmp(Context->NameBuffer, NameBuffer, CopyLength) == 0) && - (Context->ExtensionLength == ExtLength) && - (wcsncmp(Context->ExtensionBuffer, ExtBuffer, ExtLength) == 0) && - (Checksum == Context->Checksum) && - (Context->LastIndexValue < 999)) - { - Context->LastIndexValue++; - - if (Context->CheckSumInserted == FALSE && - Context->LastIndexValue > 9) - { Context->CheckSumInserted = TRUE; - Context->LastIndexValue = 1; - Context->Checksum = RtlpGetCheckSum(Name); - } - } - else - { + Context->NameLength += 4; + } + } + + ++Context->LastIndexValue; + + if (Context->LastIndexValue > 4 && !Context->CheckSumInserted) + { + Checksum = Context->Checksum = RtlpGetCheckSum(Name); + + for (Index = 2; Index < 6; Index++) + { + Context->NameBuffer[Index] = + (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0'; + Checksum >>= 4; + } + + Context->CheckSumInserted = TRUE; + Context->NameLength = 6; Context->LastIndexValue = 1; - - if (NameLength == 0) - { - Context->CheckSumInserted = TRUE; - Context->Checksum = RtlpGetCheckSum(Name); - } - else - { - Context->CheckSumInserted = FALSE; - } - } - - IndexLength = RtlpGetIndexLength(Context->LastIndexValue); - - DPRINT("CurrentIndex: %lu, IndexLength %lu\n", Context->LastIndexValue, IndexLength); - - if (Context->CheckSumInserted) - { - CopyLength = min(NameLength, 8 - 4 - 1 - IndexLength); - } - else - { - CopyLength = min(NameLength, 8 - 1 - IndexLength); - } - - /* Build the short name */ - memcpy(Name8dot3->Buffer, NameBuffer, CopyLength * sizeof(WCHAR)); - - j = CopyLength; - - if (Context->CheckSumInserted) - { - Checksum = Context->Checksum; - - for (i = 0; i < 4; i++) - { - Name8dot3->Buffer[j++] = (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0'; - Checksum >>= 4; - } - - j = CopyLength + 4; - } - - Name8dot3->Buffer[j++] = L'~'; - j += IndexLength - 1; - CurrentIndex = Context->LastIndexValue; - - for (i = 0; i < IndexLength; i++) - { - Name8dot3->Buffer[j--] = (CurrentIndex % 10) + L'0'; - CurrentIndex /= 10; - } - - j += IndexLength + 1; - - memcpy(Name8dot3->Buffer + j, ExtBuffer, ExtLength * sizeof(WCHAR)); - Name8dot3->Length = (USHORT)(j + ExtLength) * sizeof(WCHAR); - - DPRINT("Name8dot3: '%wZ'\n", Name8dot3); - - /* Update context */ - Context->NameLength = (UCHAR)CopyLength; - Context->ExtensionLength = ExtLength; - - memcpy(Context->NameBuffer, NameBuffer, CopyLength * sizeof(WCHAR)); - memcpy(Context->ExtensionBuffer, ExtBuffer, ExtLength * sizeof(WCHAR)); + } + + /* Calculate index length and index buffer */ + Index = Context->LastIndexValue; + for (IndexLength = 1; IndexLength <= 7 && Index > 0; IndexLength++) + { + IndexBuffer[8 - IndexLength] = L'0' + (Index % 10); + Index /= 10; + } + + IndexBuffer[8 - IndexLength] = L'~'; + + /* Reset name length */ + Name8dot3->Length = 0; + + /* If name present */ + if (Context->NameLength) + { + /* Copy name buffer */ + Length = Context->NameLength * sizeof(WCHAR); + RtlCopyMemory(Name8dot3->Buffer, Context->NameBuffer, Length); + Name8dot3->Length = Length; + } + + /* Copy index buffer */ + Length = IndexLength * sizeof(WCHAR); + RtlCopyMemory(Name8dot3->Buffer + (Name8dot3->Length / sizeof(WCHAR)), + IndexBuffer + (8 - IndexLength), + Length); + Name8dot3->Length += Length; + + /* If extension present */ + if (Context->ExtensionLength) + { + /* Copy extension buffer */ + Length = Context->ExtensionLength * sizeof(WCHAR); + RtlCopyMemory(Name8dot3->Buffer + (Name8dot3->Length / sizeof(WCHAR)), + Context->ExtensionBuffer, + Length); + Name8dot3->Length += Length; + } }