From a4cd19ec4224b29dc33361249af11feb989e9f92 Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Wed, 14 Sep 2016 00:31:30 +0000 Subject: [PATCH] [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) svn path=/trunk/; revision=72668 --- reactos/sdk/lib/rtl/dos8dot3.c | 314 +++++++++++++-------------------- 1 file changed, 120 insertions(+), 194 deletions(-) diff --git a/reactos/sdk/lib/rtl/dos8dot3.c b/reactos/sdk/lib/rtl/dos8dot3.c index b63d5c4fda2..48c96aea203 100644 --- a/reactos/sdk/lib/rtl/dos8dot3.c +++ b/reactos/sdk/lib/rtl/dos8dot3.c @@ -13,81 +13,66 @@ #define NDEBUG #include +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; + PWCHAR CurrentChar; + USHORT Hash; + USHORT Saved; + USHORT Length; - if (Name->Length == 0) - { + 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)) + if (Length + 1 < Name->Length / sizeof(WCHAR)) { - Hash += *(CurChar + 1); + 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 @@ RtlGenerate8dot3Name(IN PUNICODE_STRING Name, 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 DotPos; - ULONG i, j; + ULONG Length = Name->Length / sizeof(WCHAR); ULONG IndexLength; - ULONG CurrentIndex; + ULONG Index; + ULONG DotPos; + 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 (!Context->NameLength) { - if (Name->Buffer[i] == L'.') - { - DotPos = i; - } - } + DotPos = Length; - 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) + /* Find last dot in Name */ + for (Index = 0; Index < Length; Index++) { - c = RtlUpcaseUnicodeChar(Name->Buffer[i]); - Count = 1; - } - else - { - RtlUpcaseUnicodeToOemN((CHAR *)&c, sizeof(CHAR), &Count, &Name->Buffer[i], sizeof(WCHAR)); + if (Name->Buffer[Index] == L'.') + DotPos = Index; } - if (Count != 1 || c == UNICODE_NULL || RtlpIsShortIllegal(c)) + /* Copy name (6 valid characters max) */ + for (Index = 0; Index < DotPos && Context->NameLength < 6; Index++) { - NameBuffer[NameLength++] = L'_'; - } - else if (c != L'.' && c != L' ') - { - if (isgraph(c) || (AllowExtendedCharacters && iswgraph(c))) + 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++) + /* Copy extension (4 valid characters max) */ + Context->ExtensionLength = 0; + if (DotPos < Length) { - c = UNICODE_NULL; + Context->ExtensionBuffer[0] = L'.'; + Context->ExtensionLength = 1; - if (AllowExtendedCharacters) + while (DotPos < Length && Context->ExtensionLength < 4) { - c = RtlUpcaseUnicodeChar(Name->Buffer[i]); - Count = 1; - } - else - { - RtlUpcaseUnicodeToOemN((CHAR *)&c, sizeof(CHAR), &Count, &Name->Buffer[i], sizeof(WCHAR)); - } + Char = Name->Buffer[DotPos]; - if (Count != 1 || c == UNICODE_NULL || RtlpIsShortIllegal(c)) - { - ExtBuffer[ExtLength++] = L'_'; - } - else if (c != L' ') - { - if (isgraph(c) || c == L'.' || (AllowExtendedCharacters && iswgraph(c))) + if ((Char > L' ') && (Char != L'.') && + ((Char < 127) || (AllowExtendedCharacters && RtlIsValidOemCharacter(&Char)))) { - ExtBuffer[ExtLength++] = c; + 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; } + + if (Char != UNICODE_NULL) + Context->ExtensionBuffer[Context->ExtensionLength - 1] = L'~'; } - } - 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) + if (Context->NameLength <= 2) { + Checksum = Context->Checksum = RtlpGetCheckSum(Name); + + for (Index = 0; Index < 4; Index++) + { + Context->NameBuffer[Context->NameLength + Index] = + (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0'; + Checksum >>= 4; + } + Context->CheckSumInserted = TRUE; - Context->LastIndexValue = 1; - Context->Checksum = RtlpGetCheckSum(Name); - } - } - else - { - Context->LastIndexValue = 1; - - if (NameLength == 0) - { - Context->CheckSumInserted = TRUE; - Context->Checksum = RtlpGetCheckSum(Name); - } - else - { - Context->CheckSumInserted = FALSE; + Context->NameLength += 4; } } - IndexLength = RtlpGetIndexLength(Context->LastIndexValue); + ++Context->LastIndexValue; - DPRINT("CurrentIndex: %lu, IndexLength %lu\n", Context->LastIndexValue, IndexLength); - - if (Context->CheckSumInserted) + if (Context->LastIndexValue > 4 && !Context->CheckSumInserted) { - CopyLength = min(NameLength, 8 - 4 - 1 - IndexLength); - } - else - { - CopyLength = min(NameLength, 8 - 1 - IndexLength); - } + Checksum = Context->Checksum = RtlpGetCheckSum(Name); - /* 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++) + for (Index = 2; Index < 6; Index++) { - Name8dot3->Buffer[j++] = (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0'; + Context->NameBuffer[Index] = + (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0'; Checksum >>= 4; } - j = CopyLength + 4; + Context->CheckSumInserted = TRUE; + Context->NameLength = 6; + Context->LastIndexValue = 1; } - Name8dot3->Buffer[j++] = L'~'; - j += IndexLength - 1; - CurrentIndex = Context->LastIndexValue; - - for (i = 0; i < IndexLength; i++) + /* Calculate index length and index buffer */ + Index = Context->LastIndexValue; + for (IndexLength = 1; IndexLength <= 7 && Index > 0; IndexLength++) { - Name8dot3->Buffer[j--] = (CurrentIndex % 10) + L'0'; - CurrentIndex /= 10; + IndexBuffer[8 - IndexLength] = L'0' + (Index % 10); + Index /= 10; } - j += IndexLength + 1; + IndexBuffer[8 - IndexLength] = L'~'; - memcpy(Name8dot3->Buffer + j, ExtBuffer, ExtLength * sizeof(WCHAR)); - Name8dot3->Length = (USHORT)(j + ExtLength) * sizeof(WCHAR); + /* Reset name length */ + Name8dot3->Length = 0; - DPRINT("Name8dot3: '%wZ'\n", Name8dot3); + /* If name present */ + if (Context->NameLength) + { + /* Copy name buffer */ + Length = Context->NameLength * sizeof(WCHAR); + RtlCopyMemory(Name8dot3->Buffer, Context->NameBuffer, Length); + Name8dot3->Length = Length; + } - /* Update context */ - Context->NameLength = (UCHAR)CopyLength; - Context->ExtensionLength = ExtLength; + /* Copy index buffer */ + Length = IndexLength * sizeof(WCHAR); + RtlCopyMemory(Name8dot3->Buffer + (Name8dot3->Length / sizeof(WCHAR)), + IndexBuffer + (8 - IndexLength), + Length); + Name8dot3->Length += Length; - memcpy(Context->NameBuffer, NameBuffer, CopyLength * sizeof(WCHAR)); - memcpy(Context->ExtensionBuffer, ExtBuffer, ExtLength * sizeof(WCHAR)); + /* 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; + } }