Added support for the lower case flags of 8.3 names.

Fixed a bug that will corrupt directories if ros creates 8.3 names without a long name.

svn path=/trunk/; revision=3818
This commit is contained in:
Hartmut Birr 2002-12-03 01:14:49 +00:00
parent c00bebf1f2
commit e3a1b88d60
4 changed files with 119 additions and 57 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: create.c,v 1.48 2002/11/11 21:49:17 hbirr Exp $
/* $Id: create.c,v 1.49 2002/12/03 01:14:49 hbirr Exp $
*
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/create.c
@ -42,42 +42,70 @@
/* FUNCTIONS *****************************************************************/
void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName)
void vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PWSTR pName)
{
int fromIndex, toIndex;
fromIndex = toIndex = 0;
while (fromIndex < 8 && pBasename [fromIndex] != ' ')
while (fromIndex < 8 && pEntry->Filename [fromIndex] != ' ')
{
pName [toIndex++] = pBasename [fromIndex++];
if (pEntry->lCase & VFAT_CASE_LOWER_BASE)
{
pName [toIndex++] = tolower(pEntry->Filename [fromIndex++]);
}
else
{
pName [toIndex++] = pEntry->Filename [fromIndex++];
}
}
if (pExtension [0] != ' ')
if (pEntry->Ext [0] != ' ')
{
pName [toIndex++] = L'.';
fromIndex = 0;
while (fromIndex < 3 && pExtension [fromIndex] != ' ')
while (fromIndex < 3 && pEntry->Ext [fromIndex] != ' ')
{
pName [toIndex++] = pExtension [fromIndex++];
if (pEntry->lCase & VFAT_CASE_LOWER_EXT)
{
pName [toIndex++] = tolower(pEntry->Ext [fromIndex++]);
}
else
{
pName [toIndex++] = pEntry->Ext [fromIndex++];
}
}
}
pName [toIndex] = L'\0';
}
static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pName)
static void vfat8Dot3ToVolumeLabel (PFAT_DIR_ENTRY pEntry, PWSTR pName)
{
int fromIndex, toIndex;
fromIndex = toIndex = 0;
while (fromIndex < 8 && pBasename [fromIndex] != ' ')
while (fromIndex < 8 && pEntry->Filename [fromIndex] != ' ')
{
pName [toIndex++] = pBasename [fromIndex++];
if (pEntry->lCase & VFAT_CASE_LOWER_BASE)
{
pName [toIndex++] = tolower(pEntry->Filename [fromIndex++]);
}
else
{
pName [toIndex++] = pEntry->Filename [fromIndex++];
}
}
if (pExtension [0] != ' ')
if (pEntry->Ext [0] != ' ')
{
fromIndex = 0;
while (fromIndex < 3 && pBasename [fromIndex] != ' ')
while (fromIndex < 3 && pEntry->Ext [fromIndex] != ' ')
{
pName [toIndex++] = pExtension [fromIndex++];
if (pEntry->lCase & VFAT_CASE_LOWER_EXT)
{
pName [toIndex++] = tolower(pEntry->Ext [fromIndex++]);
}
else
{
pName [toIndex++] = pEntry->Ext [fromIndex++];
}
}
}
pName [toIndex] = L'\0';
@ -108,7 +136,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
if (vfatIsDirEntryVolume(Entry))
{
/* copy volume label */
vfat8Dot3ToVolumeLabel (Entry->Filename, Entry->Ext, Vpb->VolumeLabel);
vfat8Dot3ToVolumeLabel (Entry, Vpb->VolumeLabel);
Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR);
break;
}
@ -286,7 +314,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
DirIndex++;
continue;
}
vfat8Dot3ToString(fatDirEntry.Filename, fatDirEntry.Ext, name2);
vfat8Dot3ToString(&fatDirEntry, name2);
if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
{
if (Parent && Parent->PathName)

View file

@ -1,4 +1,4 @@
/* $Id: direntry.c,v 1.10 2002/11/11 21:49:18 hbirr Exp $
/* $Id: direntry.c,v 1.11 2002/12/03 01:14:49 hbirr Exp $
*
*
* FILE: DirEntry.c
@ -68,7 +68,7 @@ vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry)
void
vfatGetDirEntryName (PFAT_DIR_ENTRY dirEntry, PWSTR entryName)
{
vfat8Dot3ToString (dirEntry->Filename, dirEntry->Ext, entryName);
vfat8Dot3ToString (dirEntry, entryName);
}
@ -87,13 +87,6 @@ NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
slot * longNameEntry;
ULONG index;
DPRINT ("vfatGetNextDirEntry (%x,%x,%d,%x,%x)\n",
DeviceExt,
pDirFcb,
*pDirIndex,
pFileName,
pDirEntry);
*pFileName = 0;
FileOffset.u.HighPart = 0;

View file

@ -1,4 +1,4 @@
/* $Id: dirwr.c,v 1.32 2002/11/11 21:49:18 hbirr Exp $
/* $Id: dirwr.c,v 1.33 2002/12/03 01:14:49 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -192,6 +192,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
short nbSlots = 0, nbFree = 0, j, posCar, NameLen;
PUCHAR Buffer;
BOOLEAN needTilde = FALSE, needLong = FALSE;
BOOLEAN lCaseBase, uCaseBase, lCaseExt, uCaseExt;
PVFATFCB newFCB;
ULONG CurrentCluster;
LARGE_INTEGER SystemTime, LocalTime, FileOffset;
@ -334,7 +335,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
}
pEntry->Filename[posCar - 2] = '~';
pEntry->Filename[posCar - 1] = '1';
vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName);
vfat8Dot3ToString (pEntry, DirName);
//try first with xxxxxx~y.zzz
for (i = 1; i < 10; i++)
{
@ -356,7 +357,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
pEntry->Filename[posCar - 3] = '~';
pEntry->Filename[posCar - 2] = '1';
pEntry->Filename[posCar - 1] = '0';
vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName);
vfat8Dot3ToString (pEntry, DirName);
//try second with xxxxx~yy.zzz
for (i = 10; i < 100; i++)
{
@ -381,9 +382,20 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
else
{
DPRINT ("check if long name entry needed, needlong=%d\n", needLong);
lCaseBase = uCaseBase = lCaseExt = uCaseExt = FALSE;
for (i = 0; i < posCar; i++)
{
if ((USHORT) pEntry->Filename[i] != FileName[i])
if ((USHORT) tolower(pEntry->Filename[i]) == FileName[i])
{
DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
lCaseBase = TRUE;
}
else if ((USHORT) pEntry->Filename[i] == FileName[i])
{
DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
uCaseBase = TRUE;
}
else
{
DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
needLong = TRUE;
@ -392,16 +404,30 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
if (FileName[i])
{
i++; //jump on point char
for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++, j++)
{
if ((USHORT) pEntry->Ext[j++] != FileName[i])
if ((USHORT) tolower(pEntry->Ext[j]) == FileName[i])
{
DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]);
lCaseExt = TRUE;
}
else if ((USHORT) pEntry->Ext[j] == FileName[i])
{
DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]);
uCaseExt = TRUE;
}
else
{
DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i],
FileName[i]);
DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Ext[j], FileName[i]);
needLong = TRUE;
}
}
}
if ((lCaseBase && uCaseBase) || (lCaseExt && uCaseExt))
{
CHECKPOINT;
needLong = TRUE;
}
}
if (needLong == FALSE)
{
@ -409,6 +435,14 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
memcpy (Buffer, pEntry, sizeof (FATDirEntry));
memset (pEntry, 0, sizeof (FATDirEntry));
pEntry = (FATDirEntry *) Buffer;
if (lCaseBase)
{
pEntry->lCase |= VFAT_CASE_LOWER_BASE;
}
if (lCaseExt)
{
pEntry->lCase |= VFAT_CASE_LOWER_EXT;
}
}
else
{
@ -443,33 +477,35 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
pEntry->UpdateTime = pEntry->CreationTime;
pEntry->AccessDate = pEntry->CreationDate;
// calculate checksum for 8.3 name
for (pSlots[0].alias_checksum = i = 0; i < 11; i++)
if (needLong)
{
pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
| ((pSlots[0].alias_checksum & 0xfe) >> 1))
+ pEntry->Filename[i]);
}
//construct slots and entry
for (i = nbSlots - 2; i >= 0; i--)
{
DPRINT ("construct slot %d\n", i);
pSlots[i].attr = 0xf;
if (i)
// calculate checksum for 8.3 name
for (pSlots[0].alias_checksum = i = 0; i < 11; i++)
{
pSlots[i].id = nbSlots - i - 1;
pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
| ((pSlots[0].alias_checksum & 0xfe) >> 1))
+ pEntry->Filename[i]);
}
else
//construct slots and entry
for (i = nbSlots - 2; i >= 0; i--)
{
pSlots[i].id = nbSlots - i - 1 + 0x40;
}
pSlots[i].alias_checksum = pSlots[0].alias_checksum;
DPRINT ("construct slot %d\n", i);
pSlots[i].attr = 0xf;
if (i)
{
pSlots[i].id = nbSlots - i - 1;
}
else
{
pSlots[i].id = nbSlots - i - 1 + 0x40;
}
pSlots[i].alias_checksum = pSlots[0].alias_checksum;
//FIXME pSlots[i].start=;
memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10);
memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12);
memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4);
memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10);
memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12);
memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4);
}
}
//try to find nbSlots contiguous entries frees in directory
if (!findDirSpace(DeviceExt, pDirFcb, nbSlots, &start))
{

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.48 2002/11/11 21:49:18 hbirr Exp $ */
/* $Id: vfat.h,v 1.49 2002/12/03 01:14:49 hbirr Exp $ */
#include <ddk/ntifs.h>
@ -65,9 +65,15 @@ struct _BootBackupSector
typedef struct _BootSector BootSector;
#define VFAT_CASE_LOWER_BASE 8 // base is lower case
#define VFAT_CASE_LOWER_EXT 16 // extension is lower case
struct _FATDirEntry
{
unsigned char Filename[8], Ext[3], Attrib, Res[2];
unsigned char Filename[8], Ext[3];
unsigned char Attrib;
unsigned char lCase;
unsigned char CreationTimeMs;
unsigned short CreationTime,CreationDate,AccessDate;
unsigned short FirstClusterHigh; // higher
unsigned short UpdateTime; //time create/update
@ -313,8 +319,7 @@ NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
PULONG pDirIndex,
PULONG pDirIndex2);
VOID vfat8Dot3ToString (PCHAR pBasename,
PCHAR pExtension,
VOID vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry,
PWSTR pName);
NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,