[FASTFAT]

- Generate LFNs for files containing non-ASCII characters in their names.
CORE-8617 #resolve

svn path=/trunk/; revision=73191
This commit is contained in:
Thomas Faber 2016-11-10 11:04:29 +00:00
parent ac5bba8ea8
commit d26b1ff847

View file

@ -298,10 +298,13 @@ FATAddEntry(
PVOID Context = NULL; PVOID Context = NULL;
PFAT_DIR_ENTRY pFatEntry; PFAT_DIR_ENTRY pFatEntry;
slot *pSlots; slot *pSlots;
USHORT nbSlots = 0, j, posCar; USHORT nbSlots = 0, j;
PUCHAR Buffer; PUCHAR Buffer;
BOOLEAN needTilde = FALSE, needLong = FALSE; BOOLEAN needTilde = FALSE, needLong = FALSE;
BOOLEAN lCaseBase = FALSE, uCaseBase, lCaseExt = FALSE, uCaseExt; BOOLEAN BaseAllLower, BaseAllUpper;
BOOLEAN ExtensionAllLower, ExtensionAllUpper;
BOOLEAN InExtension;
WCHAR c;
ULONG CurrentCluster; ULONG CurrentCluster;
LARGE_INTEGER SystemTime, FileOffset; LARGE_INTEGER SystemTime, FileOffset;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
@ -386,53 +389,51 @@ FATAddEntry(
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.ShortNameU, &NameA, &SpacesFound); IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.ShortNameU, &NameA, &SpacesFound);
aName[NameA.Length]=0;
} }
else else
{ {
aName[NameA.Length] = 0; BaseAllLower = BaseAllUpper = TRUE;
for (posCar = 0; posCar < DirContext.LongNameU.Length / sizeof(WCHAR); posCar++) ExtensionAllLower = ExtensionAllUpper = TRUE;
InExtension = FALSE;
for (i = 0; i < DirContext.LongNameU.Length / sizeof(WCHAR); i++)
{ {
if (DirContext.LongNameU.Buffer[posCar] == L'.') c = DirContext.LongNameU.Buffer[i];
if (c >= L'A' && c <= L'Z')
{ {
if (InExtension)
ExtensionAllLower = FALSE;
else
BaseAllLower = FALSE;
}
else if (c >= L'a' && c <= L'z')
{
if (InExtension)
ExtensionAllUpper = FALSE;
else
BaseAllUpper = FALSE;
}
else if (c > 0x7f)
{
needLong = TRUE;
break; break;
} }
}
/* check if the name and the extension contains upper case characters */ if (c == L'.')
RtlDowncaseUnicodeString(&DirContext.ShortNameU, &DirContext.LongNameU, FALSE);
DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
uCaseBase = wcsncmp(DirContext.LongNameU.Buffer,
DirContext.ShortNameU.Buffer, posCar) ? TRUE : FALSE;
if (posCar < DirContext.LongNameU.Length/sizeof(WCHAR))
{ {
i = DirContext.LongNameU.Length / sizeof(WCHAR) - posCar; InExtension = TRUE;
uCaseExt = wcsncmp(DirContext.LongNameU.Buffer + posCar,
DirContext.ShortNameU.Buffer + posCar, i) ? TRUE : FALSE;
} }
else
{
uCaseExt = FALSE;
} }
/* check if the name and the extension contains lower case characters */
RtlUpcaseUnicodeString(&DirContext.ShortNameU, &DirContext.LongNameU, FALSE); if ((!BaseAllLower && !BaseAllUpper) ||
DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0; (!ExtensionAllLower && !ExtensionAllUpper))
lCaseBase = wcsncmp(DirContext.LongNameU.Buffer,
DirContext.ShortNameU.Buffer, posCar) ? TRUE : FALSE;
if (posCar < DirContext.LongNameU.Length / sizeof(WCHAR))
{
i = DirContext.LongNameU.Length / sizeof(WCHAR) - posCar;
lCaseExt = wcsncmp(DirContext.LongNameU.Buffer + posCar,
DirContext.ShortNameU.Buffer + posCar, i) ? TRUE : FALSE;
}
else
{
lCaseExt = FALSE;
}
if ((lCaseBase && uCaseBase) || (lCaseExt && uCaseExt))
{ {
needLong = TRUE; needLong = TRUE;
} }
RtlUpcaseUnicodeString(&DirContext.ShortNameU, &DirContext.LongNameU, FALSE);
DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
} }
aName[NameA.Length] = 0;
DPRINT("'%s', '%wZ', needTilde=%u, needLong=%u\n", DPRINT("'%s', '%wZ', needTilde=%u, needLong=%u\n",
aName, &DirContext.LongNameU, needTilde, needLong); aName, &DirContext.LongNameU, needTilde, needLong);
memset(DirContext.DirEntry.Fat.ShortName, ' ', 11); memset(DirContext.DirEntry.Fat.ShortName, ' ', 11);
@ -465,11 +466,11 @@ FATAddEntry(
else else
{ {
nbSlots = 1; nbSlots = 1;
if (lCaseBase) if (BaseAllLower && !BaseAllUpper)
{ {
DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_BASE; DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_BASE;
} }
if (lCaseExt) if (ExtensionAllLower && !ExtensionAllUpper)
{ {
DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_EXT; DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_EXT;
} }