14 modified files
reactos/drivers/fs/vfat
diff -u -r1.15 -r1.16
--- cleanup.c 28 Aug 2004 22:19:12 -0000 1.15
+++ cleanup.c 5 Dec 2004 16:31:50 -0000 1.16
@@ -1,4 +1,4 @@
-/* $Id: cleanup.c,v 1.15 2004/08/28 22:19:12 navaraf Exp $
+/* $Id: cleanup.c,v 1.16 2004/12/05 16:31:50 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -35,7 +35,7 @@
pFcb = (PVFATFCB) FileObject->FsContext;
if (pFcb)
{
- if (!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) &&
+ if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
{
/* remove all locks this process have on this file */
reactos/drivers/fs/vfat
diff -u -r1.75 -r1.76
--- create.c 6 Nov 2004 13:44:56 -0000 1.75
+++ create.c 5 Dec 2004 16:31:50 -0000 1.76
@@ -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.75 2004/11/06 13:44:56 ekohl Exp $
+/* $Id: create.c,v 1.76 2004/12/05 16:31:50 gvg Exp $
*
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/create.c
@@ -36,10 +36,6 @@
#include "vfat.h"
-/* GLOBALS *******************************************************************/
-
-#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
-
/* FUNCTIONS *****************************************************************/
void vfat8Dot3ToString (PFAT_DIR_ENTRY pEntry, PUNICODE_STRING NameU)
@@ -48,7 +44,7 @@
ULONG Length;
CHAR cString[12];
- memcpy(cString, pEntry->Filename, 11);
+ RtlCopyMemory(cString, pEntry->Filename, 11);
cString[11] = 0;
if (cString[0] == 0x05)
{
@@ -71,7 +67,7 @@
{
Length = NameU->Length;
NameU->Buffer += Length / sizeof(WCHAR);
- if (!ENTRY_VOLUME(pEntry))
+ if (!FAT_ENTRY_VOLUME(pEntry))
{
Length += sizeof(WCHAR);
NameU->Buffer[0] = L'.';
@@ -106,16 +102,30 @@
{
PVOID Context = NULL;
ULONG DirIndex = 0;
- FATDirEntry* Entry;
+ PDIR_ENTRY Entry;
PVFATFCB pFcb;
LARGE_INTEGER FileOffset;
UNICODE_STRING NameU;
+ ULONG SizeDirEntry;
+ ULONG EntriesPerPage;
+ OEM_STRING StringO;
NameU.Buffer = Vpb->VolumeLabel;
NameU.Length = 0;
NameU.MaximumLength = sizeof(Vpb->VolumeLabel);
*(Vpb->VolumeLabel) = 0;
Vpb->VolumeLabelLength = 0;
+
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ SizeDirEntry = sizeof(FATX_DIR_ENTRY);
+ EntriesPerPage = FATX_ENTRIES_PER_PAGE;
+ }
+ else
+ {
+ SizeDirEntry = sizeof(FAT_DIR_ENTRY);
+ EntriesPerPage = FAT_ENTRIES_PER_PAGE;
+ }
ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE);
pFcb = vfatOpenRootFCB (DeviceExt);
@@ -126,20 +136,29 @@
{
while (TRUE)
{
- if (ENTRY_VOLUME(Entry))
+ if (ENTRY_VOLUME(DeviceExt, Entry))
{
/* copy volume label */
- vfat8Dot3ToString (Entry, &NameU);
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ StringO.Buffer = Entry->FatX.Filename;
+ StringO.MaximumLength = StringO.Length = Entry->FatX.FilenameLength;
+ RtlOemStringToUnicodeString(&NameU, &StringO, FALSE);
+ }
+ else
+ {
+ vfat8Dot3ToString (&Entry->Fat, &NameU);
+ }
Vpb->VolumeLabelLength = NameU.Length;
break;
}
- if (ENTRY_END(Entry))
+ if (ENTRY_END(DeviceExt, Entry))
{
break;
}
DirIndex++;
- Entry++;
- if ((DirIndex % ENTRIES_PER_PAGE) == 0)
+ Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
+ if ((DirIndex % EntriesPerPage) == 0)
{
CcUnpinData(Context);
FileOffset.u.LowPart += PAGE_SIZE;
@@ -212,7 +231,7 @@
{
RtlCopyUnicodeString(&DirContext->LongNameU, &rcFcb->LongNameU);
RtlCopyUnicodeString(&DirContext->ShortNameU, &rcFcb->ShortNameU);
- memcpy(&DirContext->FatDirEntry, &rcFcb->entry, sizeof(FATDirEntry));
+ RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
DirContext->StartIndex = rcFcb->startIndex;
DirContext->DirIndex = rcFcb->dirIndex;
DPRINT("FindFile: new Name %wZ, DirIndex %d (%d)\n",
@@ -231,13 +250,13 @@
while(TRUE)
{
- Status = vfatGetNextDirEntry(&Context, &Page, Parent, DirContext, First);
+ Status = DeviceExt->GetNextDirEntry(&Context, &Page, Parent, DirContext, First);
First = FALSE;
if (Status == STATUS_NO_MORE_ENTRIES)
{
break;
}
- if (ENTRY_VOLUME(&DirContext->FatDirEntry))
+ if (ENTRY_VOLUME(DeviceExt, &DirContext->DirEntry))
{
DirContext->DirIndex++;
continue;
@@ -269,7 +288,7 @@
rcFcb = vfatGrabFCBFromTable(DeviceExt, &PathNameU);
if (rcFcb != NULL)
{
- memcpy(&DirContext->FatDirEntry, &rcFcb->entry, sizeof(FATDirEntry));
+ RtlCopyMemory(&DirContext->DirEntry, &rcFcb->entry, sizeof(DIR_ENTRY));
vfatReleaseFCB(DeviceExt, rcFcb);
}
}
@@ -407,17 +426,26 @@
ULONG Cluster, NextCluster;
NTSTATUS Status;
- Fcb->entry.FileSize = 0;
- if (DeviceExt->FatInfo.FatType == FAT32)
- {
- Cluster = Fcb->entry.FirstCluster + Fcb->entry.FirstClusterHigh * 65536;
- }
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ {
+ Fcb->entry.FatX.FileSize = 0;
+ Cluster = Fcb->entry.FatX.FirstCluster;
+ Fcb->entry.FatX.FirstCluster = 0;
+ }
else
- {
- Cluster = Fcb->entry.FirstCluster;
- }
- Fcb->entry.FirstCluster = 0;
- Fcb->entry.FirstClusterHigh = 0;
+ {
+ Fcb->entry.Fat.FileSize = 0;
+ if (DeviceExt->FatInfo.FatType == FAT32)
+ {
+ Cluster = Fcb->entry.Fat.FirstCluster + Fcb->entry.Fat.FirstClusterHigh * 65536;
+ }
+ else
+ {
+ Cluster = Fcb->entry.Fat.FirstCluster;
+ }
+ Fcb->entry.Fat.FirstCluster = 0;
+ Fcb->entry.Fat.FirstClusterHigh = 0;
+ }
Fcb->LastOffset = Fcb->LastCluster = 0;
VfatUpdateEntry (Fcb);
if (Fcb->RFCB.FileSize.QuadPart > 0)
@@ -496,7 +524,7 @@
{
return (STATUS_INSUFFICIENT_RESOURCES);
}
- memset(pCcb, 0, sizeof(VFATCCB));
+ RtlZeroMemory(pCcb, sizeof(VFATCCB));
FileObject->Flags |= FO_FCB_IS_VALID;
FileObject->SectionObjectPointer = &pFcb->SectionObjectPointers;
FileObject->FsContext = pFcb;
@@ -626,13 +654,13 @@
* Check the file has the requested attributes
*/
if (RequestedOptions & FILE_NON_DIRECTORY_FILE &&
- pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ *pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
VfatCloseFile (DeviceExt, FileObject);
return(STATUS_FILE_IS_A_DIRECTORY);
}
if (RequestedOptions & FILE_DIRECTORY_FILE &&
- !(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
+ !(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
{
VfatCloseFile (DeviceExt, FileObject);
return(STATUS_NOT_A_DIRECTORY);
reactos/drivers/fs/vfat
diff -u -r1.35 -r1.36
--- dir.c 6 Nov 2004 13:44:57 -0000 1.35
+++ dir.c 5 Dec 2004 16:31:50 -0000 1.36
@@ -1,5 +1,5 @@
/*
- * $Id: dir.c,v 1.35 2004/11/06 13:44:57 ekohl Exp $
+ * $Id: dir.c,v 1.36 2004/12/05 16:31:50 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -21,7 +21,7 @@
// function like DosDateTimeToFileTime
BOOL
-FsdDosDateTimeToSystemTime (WORD wDosDate, WORD wDosTime, PLARGE_INTEGER SystemTime)
+FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, WORD wDosDate, WORD wDosTime, PLARGE_INTEGER SystemTime)
{
PDOSTIME pdtime = (PDOSTIME) & wDosTime;
PDOSDATE pddate = (PDOSDATE) & wDosDate;
@@ -38,7 +38,7 @@
TimeFields.Day = pddate->Day;
TimeFields.Month = pddate->Month;
- TimeFields.Year = 1980 + pddate->Year;
+ TimeFields.Year = DeviceExt->BaseDateYear + pddate->Year;
RtlTimeFieldsToTime (&TimeFields, &LocalTime);
ExLocalTimeToSystemTime(&LocalTime, SystemTime);
@@ -46,10 +46,9 @@
return TRUE;
}
-
// function like FileTimeToDosDateTime
BOOL
-FsdSystemTimeToDosDateTime (PLARGE_INTEGER SystemTime, WORD * pwDosDate, WORD * pwDosTime)
+FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, WORD * pwDosDate, WORD * pwDosTime)
{
PDOSTIME pdtime = (PDOSTIME) pwDosTime;
PDOSDATE pddate = (PDOSDATE) pwDosDate;
@@ -73,13 +72,12 @@
{
pddate->Day = TimeFields.Day;
pddate->Month = TimeFields.Month;
- pddate->Year = TimeFields.Year - 1980;
+ pddate->Year = TimeFields.Year - DeviceExt->BaseDateYear;
}
return TRUE;
}
-
#define DWORD_ROUND_UP(x) ROUND_UP((x), (sizeof(DWORD)))
NTSTATUS
@@ -91,7 +89,7 @@
pInfo->FileNameLength = DirContext->LongNameU.Length;
pInfo->NextEntryOffset =
DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
- memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
return STATUS_SUCCESS;
}
@@ -106,31 +104,61 @@
pInfo->FileNameLength = DirContext->LongNameU.Length;
pInfo->NextEntryOffset =
DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
- memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
// pInfo->FileIndex=;
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.CreationDate,
- DirContext->FatDirEntry.CreationTime,
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
&pInfo->CreationTime);
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.AccessDate, 0,
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
&pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.UpdateDate,
- DirContext->FatDirEntry.UpdateTime,
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
&pInfo->LastWriteTime);
- pInfo->ChangeTime = pInfo->LastWriteTime;
- if (DirContext->FatDirEntry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
- {
- pInfo->EndOfFile.QuadPart = 0LL;
- pInfo->AllocationSize.QuadPart = 0LL;
- }
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
+ }
else
- {
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
- }
- pInfo->FileAttributes = DirContext->FatDirEntry.Attrib & 0x3f;
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
return STATUS_SUCCESS;
}
@@ -146,23 +174,45 @@
pInfo->FileNameLength = DirContext->LongNameU.Length;
pInfo->NextEntryOffset =
DWORD_ROUND_UP (sizeof (FILE_FULL_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
- memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
// pInfo->FileIndex=;
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.CreationDate,
- DirContext->FatDirEntry.CreationTime,
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
&pInfo->CreationTime);
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.AccessDate,
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
+ }
+ else
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate,
0, &pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.UpdateDate,
- DirContext->FatDirEntry.UpdateTime,
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
&pInfo->LastWriteTime);
- pInfo->ChangeTime = pInfo->LastWriteTime;
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
- pInfo->FileAttributes = DirContext->FatDirEntry.Attrib & 0x3f;
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
// pInfo->EaSize=;
return STATUS_SUCCESS;
}
@@ -175,36 +225,74 @@
{
if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength = DirContext->LongNameU.Length;
- pInfo->NextEntryOffset =
- DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
- memcpy(pInfo->ShortName, DirContext->ShortNameU.Buffer, DirContext->ShortNameU.Length);
- pInfo->ShortNameLength = DirContext->ShortNameU.Length;
- memcpy (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
-// pInfo->FileIndex=;
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.CreationDate,
- DirContext->FatDirEntry.CreationDate,
+
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ RtlCopyMemory(pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+ pInfo->NextEntryOffset =
+ DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+ pInfo->ShortName[0] = 0;
+ pInfo->ShortNameLength = 0;
+ // pInfo->FileIndex=;
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
&pInfo->CreationTime);
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.AccessDate, 0,
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
&pInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime (DirContext->FatDirEntry.UpdateDate,
- DirContext->FatDirEntry.UpdateTime,
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
&pInfo->LastWriteTime);
- pInfo->ChangeTime = pInfo->LastWriteTime;
- if (DirContext->FatDirEntry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
- {
- pInfo->EndOfFile.QuadPart = 0LL;
- pInfo->AllocationSize.QuadPart = 0LL;
- }
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
+ }
else
- {
- pInfo->EndOfFile.u.HighPart = 0;
- pInfo->EndOfFile.u.LowPart = DirContext->FatDirEntry.FileSize;
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- pInfo->AllocationSize.u.HighPart = 0;
- pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->FatDirEntry.FileSize, DeviceExt->FatInfo.BytesPerCluster);
- }
- pInfo->FileAttributes = DirContext->FatDirEntry.Attrib & 0x3f;
+ {
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ pInfo->NextEntryOffset =
+ DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory(pInfo->ShortName, DirContext->ShortNameU.Buffer, DirContext->ShortNameU.Length);
+ pInfo->ShortNameLength = DirContext->ShortNameU.Length;
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+ // pInfo->FileIndex=;
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
pInfo->EaSize=0;
return STATUS_SUCCESS;
}
reactos/drivers/fs/vfat
diff -u -r1.17 -r1.18
--- direntry.c 1 Aug 2004 21:57:17 -0000 1.17
+++ direntry.c 5 Dec 2004 16:31:50 -0000 1.18
@@ -1,4 +1,4 @@
-/* $Id: direntry.c,v 1.17 2004/08/01 21:57:17 navaraf Exp $
+/* $Id: direntry.c,v 1.18 2004/12/05 16:31:50 gvg Exp $
*
*
* FILE: DirEntry.c
@@ -8,6 +8,7 @@
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
* Rex Jolliff (rex@lvcablemodem.com)
* Hartmut Birr
+ * Herve Poussineau (reactos@poussine.freesurf.fr)
*/
/* ------------------------------------------------------- INCLUDES */
@@ -21,28 +22,30 @@
#include "vfat.h"
-#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATDirEntry))
-
ULONG
vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
- PFAT_DIR_ENTRY pFatDirEntry)
+ PDIR_ENTRY pFatDirEntry)
{
ULONG cluster;
if (pDeviceExt->FatInfo.FatType == FAT32)
{
- cluster = pFatDirEntry->FirstCluster +
- pFatDirEntry->FirstClusterHigh * 65536;
+ cluster = pFatDirEntry->Fat.FirstCluster +
+ pFatDirEntry->Fat.FirstClusterHigh * 65536;
+ }
+ else if (pDeviceExt->Flags & VCB_IS_FATX)
+ {
+ cluster = pFatDirEntry->FatX.FirstCluster;
}
else
{
- cluster = pFatDirEntry->FirstCluster;
+ cluster = pFatDirEntry->Fat.FirstCluster;
}
return cluster;
}
-BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb)
+BOOL FATIsDirectoryEmpty(PVFATFCB Fcb)
{
LARGE_INTEGER FileOffset;
PVOID Context = NULL;
@@ -63,7 +66,7 @@
while (Index < MaxIndex)
{
- if (Context == NULL || (Index % ENTRIES_PER_PAGE) == 0)
+ if (Context == NULL || (Index % FAT_ENTRIES_PER_PAGE) == 0)
{
if (Context != NULL)
{
@@ -73,14 +76,14 @@
{
return TRUE;
}
- FatDirEntry += Index % ENTRIES_PER_PAGE;
+ FatDirEntry += Index % FAT_ENTRIES_PER_PAGE;
}
- if (ENTRY_END(FatDirEntry))
+ if (FAT_ENTRY_END(FatDirEntry))
{
CcUnpinData(Context);
return TRUE;
}
- if (!ENTRY_DELETED(FatDirEntry))
+ if (!FAT_ENTRY_DELETED(FatDirEntry))
{
CcUnpinData(Context);
return FALSE;
@@ -95,7 +98,61 @@
return TRUE;
}
-NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
+BOOL FATXIsDirectoryEmpty(PVFATFCB Fcb)
+{
+ LARGE_INTEGER FileOffset;
+ PVOID Context = NULL;
+ PFATX_DIR_ENTRY FatXDirEntry;
+ ULONG Index, MaxIndex;
+
+ Index = 0;
+
+ FileOffset.QuadPart = 0LL;
+ MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FATX_DIR_ENTRY);
+
+ while (Index < MaxIndex)
+ {
+ if (Context == NULL || (Index % FATX_ENTRIES_PER_PAGE) == 0)
+ {
+ if (Context != NULL)
+ {
+ CcUnpinData(Context);
+ }
+ if (!CcMapData(Fcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&FatXDirEntry))
+ {
+ return TRUE;
+ }
+ FatXDirEntry += Index % FATX_ENTRIES_PER_PAGE;
+ }
+ if (FATX_ENTRY_END(FatXDirEntry))
+ {
+ CcUnpinData(Context);
+ return TRUE;
+ }
+ if (!FATX_ENTRY_DELETED(FatXDirEntry))
+ {
+ CcUnpinData(Context);
+ return FALSE;
+ }
+ Index++;
+ FatXDirEntry++;
+ }
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ return TRUE;
+}
+
+BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb)
+{
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ return FATXIsDirectoryEmpty(Fcb);
+ else
+ return FATIsDirectoryEmpty(Fcb);
+}
+
+NTSTATUS FATGetNextDirEntry(PVOID * pContext,
PVOID * pPage,
IN PVFATFCB pDirFcb,
PVFAT_DIRENTRY_CONTEXT DirContext,
@@ -104,7 +161,7 @@
ULONG dirMap;
PWCHAR pName;
LARGE_INTEGER FileOffset;
- FATDirEntry * fatDirEntry;
+ PFAT_DIR_ENTRY fatDirEntry;
slot * longNameEntry;
ULONG index;
@@ -116,9 +173,9 @@
DirContext->LongNameU.Buffer[0] = 0;
FileOffset.u.HighPart = 0;
- FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FATDirEntry), PAGE_SIZE);
+ FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FAT_DIR_ENTRY), PAGE_SIZE);
- if (*pContext == NULL || (DirContext->DirIndex % ENTRIES_PER_PAGE) == 0)
+ if (*pContext == NULL || (DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
{
if (*pContext != NULL)
{
@@ -132,7 +189,7 @@
}
- fatDirEntry = (FATDirEntry*)(*pPage) + DirContext->DirIndex % ENTRIES_PER_PAGE;
+ fatDirEntry = (PFAT_DIR_ENTRY)(*pPage) + DirContext->DirIndex % FAT_ENTRIES_PER_PAGE;
longNameEntry = (slot*) fatDirEntry;
dirMap = 0;
@@ -142,14 +199,14 @@
* into a long name or points to a short name with an assigned long name.
* We must go back to the real start of the entry */
while (DirContext->DirIndex > 0 &&
- !ENTRY_END(fatDirEntry) &&
- !ENTRY_DELETED(fatDirEntry) &&
- ((!ENTRY_LONG(fatDirEntry) && !Back) ||
- (ENTRY_LONG(fatDirEntry) && !(longNameEntry->id & 0x40))))
+ !FAT_ENTRY_END(fatDirEntry) &&
+ !FAT_ENTRY_DELETED(fatDirEntry) &&
+ ((!FAT_ENTRY_LONG(fatDirEntry) && !Back) ||
+ (FAT_ENTRY_LONG(fatDirEntry) && !(longNameEntry->id & 0x40))))
{
DirContext->DirIndex--;
Back = TRUE;
- if ((DirContext->DirIndex % ENTRIES_PER_PAGE) == ENTRIES_PER_PAGE - 1)
+ if ((DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == FAT_ENTRIES_PER_PAGE - 1)
{
CcUnpinData(*pContext);
FileOffset.u.LowPart -= PAGE_SIZE;
@@ -159,7 +216,7 @@
*pContext = NULL;
return STATUS_NO_MORE_ENTRIES;
}
- fatDirEntry = (FATDirEntry*)(*pPage) + DirContext->DirIndex % ENTRIES_PER_PAGE;
+ fatDirEntry = (PFAT_DIR_ENTRY)(*pPage) + DirContext->DirIndex % FAT_ENTRIES_PER_PAGE;
longNameEntry = (slot*) fatDirEntry;
}
else
@@ -169,11 +226,11 @@
}
}
- if (Back && !ENTRY_END(fatDirEntry) &&
- (ENTRY_DELETED(fatDirEntry) || !ENTRY_LONG(fatDirEntry)))
+ if (Back && !FAT_ENTRY_END(fatDirEntry) &&
+ (FAT_ENTRY_DELETED(fatDirEntry) || !FAT_ENTRY_LONG(fatDirEntry)))
{
DirContext->DirIndex++;
- if ((DirContext->DirIndex % ENTRIES_PER_PAGE) == 0)
+ if ((DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
{
CcUnpinData(*pContext);
FileOffset.u.LowPart += PAGE_SIZE;
@@ -183,7 +240,7 @@
*pContext = NULL;
return STATUS_NO_MORE_ENTRIES;
}
- fatDirEntry = (FATDirEntry*)*pPage;
+ fatDirEntry = (PFAT_DIR_ENTRY)*pPage;
longNameEntry = (slot*) *pPage;
}
else
@@ -199,14 +256,14 @@
while (TRUE)
{
- if (ENTRY_END(fatDirEntry))
+ if (FAT_ENTRY_END(fatDirEntry))
{
CcUnpinData(*pContext);
*pContext = NULL;
return STATUS_NO_MORE_ENTRIES;
}
- if (ENTRY_DELETED(fatDirEntry))
+ if (FAT_ENTRY_DELETED(fatDirEntry))
{
dirMap = 0;
DirContext->LongNameU.Buffer[0] = 0;
@@ -214,12 +271,12 @@
}
else
{
- if (ENTRY_LONG(fatDirEntry))
+ if (FAT_ENTRY_LONG(fatDirEntry))
{
if (dirMap == 0)
{
DPRINT (" long name entry found at %d\n", DirContext->DirIndex);
- memset(DirContext->LongNameU.Buffer, 0, DirContext->LongNameU.MaximumLength);
+ RtlZeroMemory(DirContext->LongNameU.Buffer, DirContext->LongNameU.MaximumLength);
CheckSum = longNameEntry->alias_checksum;
Valid = TRUE;
}
@@ -233,9 +290,9 @@
dirMap |= 1 << index;
pName = DirContext->LongNameU.Buffer + 13 * index;
- memcpy(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR));
- memcpy(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR));
- memcpy(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR));
+ RtlCopyMemory(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR));
+ RtlCopyMemory(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR));
+ RtlCopyMemory(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR));
DPRINT (" longName: [%S]\n", DirContext->LongNameU.Buffer);
if (CheckSum != longNameEntry->alias_checksum)
@@ -265,12 +322,12 @@
DirContext->LongNameU.Buffer[0] = 0;
}
- memcpy (&DirContext->FatDirEntry, fatDirEntry, sizeof (FAT_DIR_ENTRY));
+ RtlCopyMemory (&DirContext->DirEntry.Fat, fatDirEntry, sizeof (FAT_DIR_ENTRY));
break;
}
}
DirContext->DirIndex++;
- if ((DirContext->DirIndex % ENTRIES_PER_PAGE) == 0)
+ if ((DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
{
CcUnpinData(*pContext);
FileOffset.u.LowPart += PAGE_SIZE;
@@ -280,7 +337,7 @@
*pContext = NULL;
return STATUS_NO_MORE_ENTRIES;
}
- fatDirEntry = (FATDirEntry*)*pPage;
+ fatDirEntry = (PFAT_DIR_ENTRY)*pPage;
longNameEntry = (slot*) *pPage;
}
else
@@ -290,10 +347,116 @@
}
}
DirContext->LongNameU.Length = wcslen(DirContext->LongNameU.Buffer) * sizeof(WCHAR);
- vfat8Dot3ToString(&DirContext->FatDirEntry, &DirContext->ShortNameU);
+ vfat8Dot3ToString(&DirContext->DirEntry.Fat, &DirContext->ShortNameU);
if (DirContext->LongNameU.Length == 0)
{
RtlCopyUnicodeString(&DirContext->LongNameU, &DirContext->ShortNameU);
}
return STATUS_SUCCESS;
}
+
+NTSTATUS FATXGetNextDirEntry(PVOID * pContext,
+ PVOID * pPage,
+ IN PVFATFCB pDirFcb,
+ PVFAT_DIRENTRY_CONTEXT DirContext,
+ BOOLEAN First)
+{
+ LARGE_INTEGER FileOffset;
+ PFATX_DIR_ENTRY fatxDirEntry;
+ OEM_STRING StringO;
+ ULONG DirIndex = DirContext->DirIndex;
+
+ FileOffset.u.HighPart = 0;
+ FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FATX_DIR_ENTRY), PAGE_SIZE);
+
+ if (!vfatFCBIsRoot(pDirFcb))
+ {
+ /* need to add . and .. entries */
+ switch (DirContext->DirIndex)
+ {
+ case 0: /* entry . */
+ {
+ DirContext->ShortNameU.Buffer[0] = 0;
+ DirContext->ShortNameU.Length = 0;
+ DirContext->LongNameU.Buffer[0] = L'.';
+ DirContext->LongNameU.Length = sizeof(WCHAR);
+ RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
+ DirContext->DirEntry.FatX.Filename[0] = '.';
+ DirContext->DirEntry.FatX.FilenameLength = 1;
+ DirContext->StartIndex = 0;
+ return STATUS_SUCCESS;
+ }
+ case 1: /* entry .. */
+ {
+ DirContext->ShortNameU.Buffer[0] = 0;
+ DirContext->ShortNameU.Length = 0;
+ DirContext->LongNameU.Buffer[0] = DirContext->LongNameU.Buffer[1] = L'.';
+ DirContext->LongNameU.Length = 2 * sizeof(WCHAR);
+ RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY));
+ DirContext->DirEntry.FatX.Filename[0] = DirContext->DirEntry.FatX.Filename[1] = '.';
+ DirContext->DirEntry.FatX.FilenameLength = 2;
+ DirContext->StartIndex = 1;
+ return STATUS_SUCCESS;
+ }
+ default:
+ DirIndex -= 2;
+ }
+ }
+
+ if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
+ {
+ if (*pContext != NULL)
+ {
+ CcUnpinData(*pContext);
+ }
+ if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
+ {
+ *pContext = NULL;
+ return STATUS_NO_MORE_ENTRIES;
+ }
+ }
+
+ fatxDirEntry = (PFATX_DIR_ENTRY)(*pPage) + DirIndex % FATX_ENTRIES_PER_PAGE;
+
+ DirContext->StartIndex = DirIndex;
+
+ while (TRUE)
+ {
+ if (FATX_ENTRY_END(fatxDirEntry))
+ {
+ CcUnpinData(*pContext);
+ *pContext = NULL;
+ return STATUS_NO_MORE_ENTRIES;
+ }
+
+ if (!FATX_ENTRY_DELETED(fatxDirEntry))
+ {
+ RtlCopyMemory(&DirContext->DirEntry.FatX, fatxDirEntry, sizeof(FATX_DIR_ENTRY));
+ break;
+ }
+ DirContext->DirIndex++;
+ DirContext->StartIndex++;
+ if ((DirContext->DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
+ {
+ CcUnpinData(*pContext);
+ FileOffset.u.LowPart += PAGE_SIZE;
+ if (!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
+ {
+ CHECKPOINT;
+ *pContext = NULL;
+ return STATUS_NO_MORE_ENTRIES;
+ }
+ fatxDirEntry = (PFATX_DIR_ENTRY)*pPage;
+ }
+ else
+ {
+ fatxDirEntry++;
+ }
+ }
+ DirContext->ShortNameU.Buffer[0] = 0;
+ DirContext->ShortNameU.Length = 0;
+ StringO.Buffer = fatxDirEntry->Filename;
+ StringO.Length = StringO.MaximumLength = fatxDirEntry->FilenameLength;
+ RtlOemStringToUnicodeString(&DirContext->LongNameU, &StringO, FALSE);
+ return STATUS_SUCCESS;
+}
reactos/drivers/fs/vfat
diff -u -r1.42 -r1.43
--- dirwr.c 6 Nov 2004 13:44:57 -0000 1.42
+++ dirwr.c 5 Dec 2004 16:31:50 -0000 1.43
@@ -1,4 +1,4 @@
-/* $Id: dirwr.c,v 1.42 2004/11/06 13:44:57 ekohl Exp $
+/* $Id: dirwr.c,v 1.43 2004/12/05 16:31:50 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -26,21 +26,34 @@
*/
{
PVOID Context;
- PFAT_DIR_ENTRY PinEntry;
+ PDIR_ENTRY PinEntry;
LARGE_INTEGER Offset;
+ ULONG SizeDirEntry;
+ ULONG dirIndex;
ASSERT(pFcb);
ASSERT(pFcb->parentFcb);
+
+ if (pFcb->Flags & FCB_IS_FATX_ENTRY)
+ {
+ SizeDirEntry = sizeof(FATX_DIR_ENTRY);
+ dirIndex = pFcb->startIndex;
+ }
+ else
+ {
+ SizeDirEntry = sizeof(FAT_DIR_ENTRY);
+ dirIndex = pFcb->dirIndex;
+ }
- DPRINT ("updEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
+ DPRINT ("updEntry dirIndex %d, PathName \'%wZ\'\n", dirIndex, &pFcb->PathNameU);
Offset.u.HighPart = 0;
- Offset.u.LowPart = pFcb->dirIndex * sizeof(FATDirEntry);
- if (CcMapData (pFcb->parentFcb->FileObject, &Offset, sizeof(FATDirEntry),
+ Offset.u.LowPart = dirIndex * SizeDirEntry;
+ if (CcMapData (pFcb->parentFcb->FileObject, &Offset, SizeDirEntry,
TRUE, &Context, (PVOID*)&PinEntry))
{
pFcb->Flags &= ~FCB_IS_DIRTY;
- *PinEntry = pFcb->entry;
+ RtlCopyMemory(PinEntry, &pFcb->entry, SizeDirEntry);
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
return STATUS_SUCCESS;
@@ -64,13 +77,20 @@
*/
LARGE_INTEGER FileOffset;
ULONG i, count, size, nbFree = 0;
- FATDirEntry* pFatEntry;
+ PDIR_ENTRY pFatEntry;
PVOID Context = NULL;
NTSTATUS Status;
+ ULONG SizeDirEntry;
FileOffset.QuadPart = 0;
- count = pDirFcb->RFCB.FileSize.u.LowPart / sizeof(FATDirEntry);
- size = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
- for (i = 0; i < count; i++, pFatEntry++)
+
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ SizeDirEntry = sizeof(FATX_DIR_ENTRY);
+ else
+ SizeDirEntry = sizeof(FAT_DIR_ENTRY);
+
+ count = pDirFcb->RFCB.FileSize.u.LowPart / SizeDirEntry;
+ size = DeviceExt->FatInfo.BytesPerCluster / SizeDirEntry;
+ for (i = 0; i < count; i++, pFatEntry = (PDIR_ENTRY)((ULONG_PTR)pFatEntry + SizeDirEntry))
{
if (Context == NULL || (i % size) == 0)
{
@@ -83,11 +103,11 @@
TRUE, &Context, (PVOID*)&pFatEntry);
FileOffset.u.LowPart += DeviceExt->FatInfo.BytesPerCluster;
}
- if (ENTRY_END(pFatEntry))
+ if (ENTRY_END(DeviceExt, pFatEntry))
{
break;
}
- if (ENTRY_DELETED(pFatEntry))
+ if (ENTRY_DELETED(DeviceExt, pFatEntry))
{
nbFree++;
}
@@ -120,7 +140,7 @@
// extend the directory
if (vfatFCBIsRoot(pDirFcb) && DeviceExt->FatInfo.FatType != FAT32)
{
- // We can't extend a root directory on a FAT12/FAT16 partition
+ // We can't extend a root directory on a FAT12/FAT16/FATX partition
return FALSE;
}
AllocationSize.QuadPart = pDirFcb->RFCB.FileSize.u.LowPart + DeviceExt->FatInfo.BytesPerCluster;
@@ -135,15 +155,21 @@
DeviceExt->FatInfo.BytesPerCluster);
CcMapData (pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster,
TRUE, &Context, (PVOID*)&pFatEntry);
- RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ memset(pFatEntry, 0xff, DeviceExt->FatInfo.BytesPerCluster);
+ else
+ RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
}
else if (*start + nbSlots < count)
{
// clear the entry after the last new entry
- FileOffset.u.LowPart = (*start + nbSlots) * sizeof(FATDirEntry);
- CcMapData (pDirFcb->FileObject, &FileOffset, sizeof(FATDirEntry),
+ FileOffset.u.LowPart = (*start + nbSlots) * SizeDirEntry;
+ CcMapData (pDirFcb->FileObject, &FileOffset, SizeDirEntry,
TRUE, &Context, (PVOID*)&pFatEntry);
- RtlZeroMemory(pFatEntry, sizeof(FATDirEntry));
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ memset(pFatEntry, 0xff, SizeDirEntry);
+ else
+ RtlZeroMemory(pFatEntry, SizeDirEntry);
}
if (Context)
{
@@ -156,7 +182,7 @@
}
NTSTATUS
-VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
+FATAddEntry (PDEVICE_EXTENSION DeviceExt,
PUNICODE_STRING PathNameU,
PFILE_OBJECT pFileObject,
ULONG RequestedOptions,
@@ -166,7 +192,7 @@
*/
{
PVOID Context = NULL;
- FATDirEntry *pFatEntry;
+ PFAT_DIR_ENTRY pFatEntry;
slot *pSlots;
short nbSlots = 0, j, posCar;
PUCHAR Buffer;
@@ -180,7 +206,7 @@
ULONG size;
long i;
- ANSI_STRING NameA;
+ OEM_STRING NameA;
CHAR aName[13];
BOOLEAN IsNameLegal;
BOOLEAN SpacesFound;
@@ -212,8 +238,8 @@
nbSlots = (DirContext.LongNameU.Length / sizeof(WCHAR) + 12) / 13 + 1; //nb of entry needed for long name+normal entry
DPRINT ("NameLen= %d, nbSlots =%d\n", DirContext.LongNameU.Length / sizeof(WCHAR), nbSlots);
- Buffer = ExAllocatePool (NonPagedPool, (nbSlots - 1) * sizeof (FATDirEntry));
- RtlZeroMemory (Buffer, (nbSlots - 1) * sizeof (FATDirEntry));
+ Buffer = ExAllocatePool (NonPagedPool, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
+ RtlZeroMemory (Buffer, (nbSlots - 1) * sizeof (FAT_DIR_ENTRY));
pSlots = (slot *) Buffer;
NameA.Buffer = aName;
@@ -224,7 +250,7 @@
DirContext.ShortNameU.Length = 0;
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
- memset(&DirContext.FatDirEntry, 0, sizeof(FATDirEntry));
+ RtlZeroMemory(&DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.LongNameU, &NameA, &SpacesFound);
@@ -235,7 +261,7 @@
WCHAR ShortSearchName[13];
needTilde = TRUE;
needLong = TRUE;
- memset(&NameContext, 0, sizeof(GENERATE_NAME_CONTEXT));
+ RtlZeroMemory(&NameContext, sizeof(GENERATE_NAME_CONTEXT));
SearchContext.LongNameU.Buffer = LongNameBuffer;
SearchContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
SearchContext.ShortNameU.Buffer = ShortSearchName;
@@ -257,7 +283,7 @@
ExReleaseResourceLite(&pDirFcb->MainResource);
vfatReleaseFCB(DeviceExt, pDirFcb);
ExFreePool (Buffer);
- CHECKPOINT;
+ CHECKPOINT;
return STATUS_UNSUCCESSFUL;
}
IsNameLegal = RtlIsNameLegalDOS8Dot3(&DirContext.ShortNameU, &NameA, &SpacesFound);
@@ -310,27 +336,27 @@
}
DPRINT ("'%s', '%wZ', needTilde=%d, needLong=%d\n",
aName, &DirContext.LongNameU, needTilde, needLong);
- memset(DirContext.FatDirEntry.Filename, ' ', 11);
+ memset(DirContext.DirEntry.Fat.Filename, ' ', 11);
for (i = 0; i < 8 && aName[i] && aName[i] != '.'; i++)
{
- DirContext.FatDirEntry.Filename[i] = aName[i];
+ DirContext.DirEntry.Fat.Filename[i] = aName[i];
}
if (aName[i] == '.')
{
i++;
for (j = 8; j < 11 && aName[i]; j++, i++)
{
- DirContext.FatDirEntry.Filename[j] = aName[i];
+ DirContext.DirEntry.Fat.Filename[j] = aName[i];
}
}
- if (DirContext.FatDirEntry.Filename[0] == 0xe5)
+ if (DirContext.DirEntry.Fat.Filename[0] == 0xe5)
{
- DirContext.FatDirEntry.Filename[0] = 0x05;
+ DirContext.DirEntry.Fat.Filename[0] = 0x05;
}
if (needLong)
{
- memcpy(LongNameBuffer, DirContext.LongNameU.Buffer, DirContext.LongNameU.Length);
+ RtlCopyMemory(LongNameBuffer, DirContext.LongNameU.Buffer, DirContext.LongNameU.Length);
DirContext.LongNameU.Buffer = LongNameBuffer;
DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
DirContext.LongNameU.Buffer[DirContext.LongNameU.Length / sizeof(WCHAR)] = 0;
@@ -342,39 +368,29 @@
nbSlots = 1;
if (lCaseBase)
{
- DirContext.FatDirEntry.lCase |= VFAT_CASE_LOWER_BASE;
+ DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_BASE;
}
if (lCaseExt)
{
- DirContext.FatDirEntry.lCase |= VFAT_CASE_LOWER_EXT;
+ DirContext.DirEntry.Fat.lCase |= VFAT_CASE_LOWER_EXT;
}
}
- DPRINT ("dos name=%11.11s\n", DirContext.FatDirEntry.Filename);
+ DPRINT ("dos name=%11.11s\n", DirContext.DirEntry.Fat.Filename);
/* set attributes */
- DirContext.FatDirEntry.Attrib = ReqAttr;
+ DirContext.DirEntry.Fat.Attrib = ReqAttr;
if (RequestedOptions & FILE_DIRECTORY_FILE)
{
- DirContext.FatDirEntry.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
+ DirContext.DirEntry.Fat.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
}
/* set dates and times */
KeQuerySystemTime (&SystemTime);
-#if 0
- {
- TIME_FIELDS tf;
- RtlTimeToTimeFields (&SystemTime, &tf);
- DPRINT1("%d.%d.%d %02d:%02d:%02d.%03d '%S'\n",
- tf.Day, tf.Month, tf.Year, tf.Hour,
- tf.Minute, tf.Second, tf.Milliseconds,
- pFileObject->FileName.Buffer);
- }
-#endif
- FsdSystemTimeToDosDateTime (&SystemTime, &DirContext.FatDirEntry.CreationDate,
- &DirContext.FatDirEntry.CreationTime);
- DirContext.FatDirEntry.UpdateDate = DirContext.FatDirEntry.CreationDate;
- DirContext.FatDirEntry.UpdateTime = DirContext.FatDirEntry.CreationTime;
- DirContext.FatDirEntry.AccessDate = DirContext.FatDirEntry.CreationDate;
+ FsdSystemTimeToDosDateTime (DeviceExt, &SystemTime, &DirContext.DirEntry.Fat.CreationDate,
+ &DirContext.DirEntry.Fat.CreationTime);
+ DirContext.DirEntry.Fat.UpdateDate = DirContext.DirEntry.Fat.CreationDate;
+ DirContext.DirEntry.Fat.UpdateTime = DirContext.DirEntry.Fat.CreationTime;
+ DirContext.DirEntry.Fat.AccessDate = DirContext.DirEntry.Fat.CreationDate;
if (needLong)
{
@@ -383,7 +399,7 @@
{
pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
| ((pSlots[0].alias_checksum & 0xfe) >> 1))
- + DirContext.FatDirEntry.Filename[i]);
+ + DirContext.DirEntry.Fat.Filename[i]);
}
/* construct slots and entry */
for (i = nbSlots - 2; i >= 0; i--)
@@ -399,9 +415,9 @@
pSlots[i].id = nbSlots - i - 1 + 0x40;
}
pSlots[i].alias_checksum = pSlots[0].alias_checksum;
- memcpy (pSlots[i].name0_4, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13, 10);
- memcpy (pSlots[i].name5_10, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 5, 12);
- memcpy (pSlots[i].name11_12, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 11, 4);
+ RtlCopyMemory (pSlots[i].name0_4, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13, 10);
+ RtlCopyMemory (pSlots[i].name5_10, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 5, 12);
+ RtlCopyMemory (pSlots[i].name11_12, DirContext.LongNameU.Buffer + (nbSlots - i - 2) * 13 + 11, 4);
}
}
/* try to find nbSlots contiguous entries frees in directory */
@@ -430,47 +446,47 @@
}
if (DeviceExt->FatInfo.FatType == FAT32)
{
- DirContext.FatDirEntry.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
+ DirContext.DirEntry.Fat.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
}
- DirContext.FatDirEntry.FirstCluster = (unsigned short)CurrentCluster;
+ DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
}
- i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
+ i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FAT_DIR_ENTRY);
FileOffset.u.HighPart = 0;
- FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FATDirEntry);
+ FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FAT_DIR_ENTRY);
if (DirContext.StartIndex / i == DirContext.DirIndex / i)
{
/* one cluster */
CHECKPOINT;
- CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FATDirEntry),
+ CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FAT_DIR_ENTRY),
TRUE, &Context, (PVOID*)&pFatEntry);
if (nbSlots > 1)
{
- memcpy(pFatEntry, Buffer, (nbSlots - 1) * sizeof(FATDirEntry));
+ RtlCopyMemory(pFatEntry, Buffer, (nbSlots - 1) * sizeof(FAT_DIR_ENTRY));
}
- memcpy(pFatEntry + (nbSlots - 1), &DirContext.FatDirEntry, sizeof(FATDirEntry));
+ RtlCopyMemory(pFatEntry + (nbSlots - 1), &DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
}
else
{
/* two clusters */
CHECKPOINT;
size = DeviceExt->FatInfo.BytesPerCluster -
- (DirContext.StartIndex * sizeof(FATDirEntry)) % DeviceExt->FatInfo.BytesPerCluster;
- i = size / sizeof(FATDirEntry);
+ (DirContext.StartIndex * sizeof(FAT_DIR_ENTRY)) % DeviceExt->FatInfo.BytesPerCluster;
+ i = size / sizeof(FAT_DIR_ENTRY);
CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
&Context, (PVOID*)&pFatEntry);
- memcpy(pFatEntry, Buffer, size);
+ RtlCopyMemory(pFatEntry, Buffer, size);
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
FileOffset.u.LowPart += size;
CcMapData (pDirFcb->FileObject, &FileOffset,
- nbSlots * sizeof(FATDirEntry) - size,
+ nbSlots * sizeof(FAT_DIR_ENTRY) - size,
TRUE, &Context, (PVOID*)&pFatEntry);
if (nbSlots - 1 > i)
{
- memcpy(pFatEntry, (PVOID)(Buffer + size), (nbSlots - 1 - i) * sizeof(FATDirEntry));
+ RtlCopyMemory(pFatEntry, (PVOID)(Buffer + size), (nbSlots - 1 - i) * sizeof(FAT_DIR_ENTRY));
}
- memcpy(pFatEntry + nbSlots - 1 - i, &DirContext.FatDirEntry, sizeof(FATDirEntry));
+ RtlCopyMemory(pFatEntry + nbSlots - 1 - i, &DirContext.DirEntry.Fat, sizeof(FAT_DIR_ENTRY));
}
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
@@ -479,8 +495,8 @@
vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, &DirContext, &newFCB);
vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
- DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
- DPRINT ("new : entry=%11.11s\n", DirContext.FatDirEntry.Filename);
+ DPRINT ("new : entry=%11.11s\n", newFCB->entry.Fat.Filename);
+ DPRINT ("new : entry=%11.11s\n", DirContext.DirEntry.Fat.Filename);
if (RequestedOptions & FILE_DIRECTORY_FILE)
{
@@ -490,12 +506,12 @@
/* clear the new directory cluster */
RtlZeroMemory (pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
/* create '.' and '..' */
- memcpy (&pFatEntry[0].Attrib, &DirContext.FatDirEntry.Attrib, sizeof(FATDirEntry) - 11);
- memcpy (pFatEntry[0].Filename, ". ", 11);
- memcpy (&pFatEntry[1].Attrib, &DirContext.FatDirEntry.Attrib, sizeof(FATDirEntry) - 11);
- memcpy (pFatEntry[1].Filename, ".. ", 11);
- pFatEntry[1].FirstCluster = pDirFcb->entry.FirstCluster;
- pFatEntry[1].FirstClusterHigh = pDirFcb->entry.FirstClusterHigh;
+ RtlCopyMemory (&pFatEntry[0].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
+ RtlCopyMemory (pFatEntry[0].Filename, ". ", 11);
+ RtlCopyMemory (&pFatEntry[1].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
+ RtlCopyMemory (pFatEntry[1].Filename, ".. ", 11);
+ pFatEntry[1].FirstCluster = pDirFcb->entry.Fat.FirstCluster;
+ pFatEntry[1].FirstClusterHigh = pDirFcb->entry.Fat.FirstClusterHigh;
if (vfatFCBIsRoot(pDirFcb))
{
pFatEntry[1].FirstCluster = 0;
@@ -512,7 +528,129 @@
}
NTSTATUS
-VfatDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
+FATXAddEntry (PDEVICE_EXTENSION DeviceExt,
+ PUNICODE_STRING PathNameU,
+ PFILE_OBJECT pFileObject,
+ ULONG RequestedOptions,
+ UCHAR ReqAttr)
+/*
+ create a new FAT entry
+*/
+{
+ PVOID Context = NULL;
+ PVFATFCB newFCB;
+ LARGE_INTEGER SystemTime, FileOffset;
+ PVFATFCB pDirFcb;
+ OEM_STRING NameA;
+ VFAT_DIRENTRY_CONTEXT DirContext;
+ PFATX_DIR_ENTRY pFatXDirEntry;
+ UNICODE_STRING DirNameU;
+
+ DPRINT ("addEntry: Pathname='%wZ'\n", PathNameU);
+
+ vfatSplitPathName(PathNameU, &DirNameU, &DirContext.LongNameU);
+ if (DirNameU.Length > sizeof(WCHAR))
+ {
+ DirNameU.Length -= sizeof(WCHAR);
+ }
+
+ if (DirContext.LongNameU.Length / sizeof(WCHAR) > 42)
+ {
+ /* name too long */
+ CHECKPOINT;
+ return STATUS_NAME_TOO_LONG;
+ }
+
+ pDirFcb = vfatGrabFCBFromTable(DeviceExt, &DirNameU);
+ if (pDirFcb == NULL)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (!ExAcquireResourceExclusiveLite(&pDirFcb->MainResource, TRUE))
+ {
+ DPRINT("Failed acquiring lock\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* try to find 1 entry free in directory */
+ if (!vfatFindDirSpace(DeviceExt, pDirFcb, 1, &DirContext.StartIndex))
+ {
+ ExReleaseResourceLite(&pDirFcb->MainResource);
+ vfatReleaseFCB(DeviceExt, pDirFcb);
+ return STATUS_DISK_FULL;
+ }
+ DirContext.DirIndex = DirContext.StartIndex;
+ if (!vfatFCBIsRoot(pDirFcb))
+ {
+ DirContext.DirIndex += 2;
+ }
+
+ DirContext.ShortNameU.Buffer = 0;
+ DirContext.ShortNameU.Length = 0;
+ DirContext.ShortNameU.MaximumLength = 0;
+ RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
+ memset(DirContext.DirEntry.FatX.Filename, 0xff, 42);
+ DirContext.DirEntry.FatX.FirstCluster = 0;
+ DirContext.DirEntry.FatX.FileSize = 0;
+
+ /* set file name */
+ NameA.Buffer = DirContext.DirEntry.FatX.Filename;
+ NameA.Length = 0;
+ NameA.MaximumLength = 42;
+ RtlUnicodeStringToOemString(&NameA, &DirContext.LongNameU, FALSE);
+ DirContext.DirEntry.FatX.FilenameLength = NameA.Length;
+
+ /* set attributes */
+ DirContext.DirEntry.FatX.Attrib = ReqAttr;
+ if (RequestedOptions & FILE_DIRECTORY_FILE)
+ {
+ DirContext.DirEntry.FatX.Attrib |= FILE_ATTRIBUTE_DIRECTORY;
+ }
+
+ /* set dates and times */
+ KeQuerySystemTime (&SystemTime);
+ FsdSystemTimeToDosDateTime(DeviceExt, &SystemTime, &DirContext.DirEntry.FatX.CreationDate,
+ &DirContext.DirEntry.FatX.CreationTime);
+ DirContext.DirEntry.FatX.UpdateDate = DirContext.DirEntry.FatX.CreationDate;
+ DirContext.DirEntry.FatX.UpdateTime = DirContext.DirEntry.FatX.CreationTime;
+ DirContext.DirEntry.FatX.AccessDate = DirContext.DirEntry.FatX.CreationDate;
+ DirContext.DirEntry.FatX.AccessTime = DirContext.DirEntry.FatX.CreationTime;
+
+ /* add entry into parent directory */
+ FileOffset.u.HighPart = 0;
+ FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FATX_DIR_ENTRY);
+ CcMapData(pDirFcb->FileObject, &FileOffset, sizeof(FATX_DIR_ENTRY),
+ TRUE, &Context, (PVOID*)&pFatXDirEntry);
+ RtlCopyMemory(pFatXDirEntry, &DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+
+ /* FIXME: check status */
+ vfatMakeFCBFromDirEntry(DeviceExt, pDirFcb, &DirContext, &newFCB);
+ vfatAttachFCBToFileObject(DeviceExt, newFCB, pFileObject);
+
+ ExReleaseResourceLite(&pDirFcb->MainResource);
+ vfatReleaseFCB(DeviceExt, pDirFcb);
+ DPRINT("addentry ok\n");
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
+ PUNICODE_STRING PathNameU,
+ PFILE_OBJECT pFileObject,
+ ULONG RequestedOptions,
+ UCHAR ReqAttr)
+{
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ return FATXAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
+ else
+ return FATAddEntry(DeviceExt, PathNameU, pFileObject, RequestedOptions, ReqAttr);
+}
+
+NTSTATUS
+FATDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
/*
* deleting an existing FAT entry
*/
@@ -520,7 +658,7 @@
ULONG CurrentCluster = 0, NextCluster, i;
PVOID Context = NULL;
LARGE_INTEGER Offset;
- FATDirEntry* pDirEntry;
+ PFAT_DIR_ENTRY pDirEntry;
ASSERT(pFcb);
ASSERT(pFcb->parentFcb);
@@ -530,23 +668,23 @@
Offset.u.HighPart = 0;
for (i = pFcb->startIndex; i <= pFcb->dirIndex; i++)
{
- if (Context == NULL || ((i * sizeof(FATDirEntry)) % PAGE_SIZE) == 0)
+ if (Context == NULL || ((i * sizeof(FAT_DIR_ENTRY)) % PAGE_SIZE) == 0)
{
if (Context)
{
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
}
- Offset.u.LowPart = (i * sizeof(FATDirEntry) / PAGE_SIZE) * PAGE_SIZE;
+ Offset.u.LowPart = (i * sizeof(FAT_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
CcMapData (pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, TRUE,
&Context, (PVOID*)&pDirEntry);
}
- pDirEntry[i % (PAGE_SIZE / sizeof(FATDirEntry))].Filename[0] = 0xe5;
+ pDirEntry[i % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))].Filename[0] = 0xe5;
if (i == pFcb->dirIndex)
{
CurrentCluster =
vfatDirEntryGetFirstCluster (DeviceExt,
- &pDirEntry[i % (PAGE_SIZE / sizeof(FATDirEntry))]);
+ (PDIR_ENTRY)&pDirEntry[i % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))]);
}
}
if (Context)
@@ -565,4 +703,58 @@
return STATUS_SUCCESS;
}
+NTSTATUS
+FATXDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
+/*
+ * deleting an existing FAT entry
+ */
+{
+ ULONG CurrentCluster = 0, NextCluster;
+ PVOID Context = NULL;
+ LARGE_INTEGER Offset;
+ PFATX_DIR_ENTRY pDirEntry;
+ ULONG StartIndex;
+
+ ASSERT(pFcb);
+ ASSERT(pFcb->parentFcb);
+ ASSERT(pFcb->Flags & FCB_IS_FATX_ENTRY);
+
+ StartIndex = pFcb->startIndex;
+
+ DPRINT ("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
+ DPRINT ("delete entry: %d\n", StartIndex);
+ Offset.u.HighPart = 0;
+ Offset.u.LowPart = (StartIndex * sizeof(FATX_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
+ if (!CcMapData (pFcb->parentFcb->FileObject, &Offset, PAGE_SIZE, TRUE,
+ &Context, (PVOID*)&pDirEntry))
+ {
+ DPRINT1("CcMapData(Offset %x:%x, Length %d) failed\n", Offset.u.HighPart, Offset.u.LowPart, PAGE_SIZE);
+ return STATUS_UNSUCCESSFUL;
+ }
+ pDirEntry = &pDirEntry[StartIndex % (PAGE_SIZE / sizeof(FATX_DIR_ENTRY))];
+ pDirEntry->FilenameLength = 0xe5;
+ CurrentCluster = vfatDirEntryGetFirstCluster (DeviceExt,
+ (PDIR_ENTRY)pDirEntry);
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+
+ while (CurrentCluster && CurrentCluster != 0xffffffff)
+ {
+ GetNextCluster (DeviceExt, CurrentCluster, &NextCluster);
+ /* FIXME: check status */
+ WriteCluster(DeviceExt, CurrentCluster, 0);
+ CurrentCluster = NextCluster;
+ }
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+VfatDelEntry (PDEVICE_EXTENSION DeviceExt, PVFATFCB pFcb)
+{
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ return FATXDelEntry(DeviceExt, pFcb);
+ else
+ return FATDelEntry(DeviceExt, pFcb);
+}
+
/* EOF */
reactos/drivers/fs/vfat
diff -u -r1.46 -r1.47
--- fat.c 5 Aug 2004 02:48:18 -0000 1.46
+++ fat.c 5 Dec 2004 16:31:50 -0000 1.47
@@ -1,5 +1,5 @@
/*
- * $Id: fat.c,v 1.46 2004/08/05 02:48:18 navaraf Exp $
+ * $Id: fat.c,v 1.47 2004/12/05 16:31:50 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -459,7 +459,7 @@
{
if (DeviceExt->FatInfo.FatType == FAT12)
Status = FAT12CountAvailableClusters(DeviceExt);
- else if (DeviceExt->FatInfo.FatType == FAT16)
+ else if (DeviceExt->FatInfo.FatType == FAT16 || DeviceExt->FatInfo.FatType == FATX16)
Status = FAT16CountAvailableClusters(DeviceExt);
else
Status = FAT32CountAvailableClusters(DeviceExt);
@@ -641,7 +641,7 @@
DeviceExt, CurrentCluster);
if (CurrentCluster == 0)
- return(STATUS_UNSUCCESSFUL);
+ return(STATUS_INVALID_PARAMETER);
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
Status = DeviceExt->GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
reactos/drivers/fs/vfat
diff -u -r1.42 -r1.43
--- fcb.c 6 Nov 2004 13:44:57 -0000 1.42
+++ fcb.c 5 Dec 2004 16:31:51 -0000 1.43
@@ -1,4 +1,4 @@
-/* $Id: fcb.c,v 1.42 2004/11/06 13:44:57 ekohl Exp $
+/* $Id: fcb.c,v 1.43 2004/12/05 16:31:51 gvg Exp $
*
*
* FILE: drivers/fs/vfat/fcb.c
@@ -8,6 +8,7 @@
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
* Rex Jolliff (rex@lvcablemodem.com)
* Hartmut Birr
+ * Herve Poussineau (reactos@poussine.freesurf.fr)
*/
/* ------------------------------------------------------- INCLUDES */
@@ -38,6 +39,7 @@
PWCHAR curr;
register WCHAR c;
+ ASSERT(NameU->Buffer[0] != L'.');
curr = NameU->Buffer;
last = NameU->Buffer + NameU->Length / sizeof(WCHAR);
@@ -93,7 +95,7 @@
}
PVFATFCB
-vfatNewFCB(PUNICODE_STRING pFileNameU)
+vfatNewFCB(PDEVICE_EXTENSION pVCB, PUNICODE_STRING pFileNameU)
{
PVFATFCB rcFCB;
@@ -104,8 +106,15 @@
{
return NULL;
}
- memset(rcFCB, 0, sizeof(VFATFCB));
+ RtlZeroMemory(rcFCB, sizeof(VFATFCB));
vfatInitFcb(rcFCB, pFileNameU);
+ if (pVCB->Flags & VCB_IS_FATX)
+ {
+ rcFCB->Flags |= FCB_IS_FATX_ENTRY;
+ rcFCB->Attributes = &rcFCB->entry.FatX.Attrib;
+ }
+ else
+ rcFCB->Attributes = &rcFCB->entry.Fat.Attrib;
rcFCB->Hash.Hash = vfatNameHash(0, &rcFCB->PathNameU);
rcFCB->Hash.self = rcFCB;
rcFCB->ShortHash.self = rcFCB;
@@ -138,7 +147,7 @@
BOOL
vfatFCBIsDirectory(PVFATFCB FCB)
{
- return FCB->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY;
+ return *FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY;
}
BOOL
@@ -312,7 +321,7 @@
{
return STATUS_INSUFFICIENT_RESOURCES;
}
- memset (newCCB, 0, sizeof (VFATCCB));
+ RtlZeroMemory(newCCB, sizeof (VFATCCB));
fileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
@@ -347,28 +356,39 @@
RtlRosInitUnicodeStringFromLiteral(&NameU, L"\\");
- FCB = vfatNewFCB(&NameU);
- memset(FCB->entry.Filename, ' ', 11);
- FCB->ShortHash.Hash = FCB->Hash.Hash;
- FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
- FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
- if (pVCB->FatInfo.FatType == FAT32)
- {
- CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
- FCB->entry.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
- FCB->entry.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
-
- while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
- {
- Size += pVCB->FatInfo.BytesPerCluster;
- Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
- }
+ FCB = vfatNewFCB(pVCB, &NameU);
+ if (FCB->Flags & FCB_IS_FATX_ENTRY)
+ {
+ memset(FCB->entry.FatX.Filename, ' ', 42);
+ FCB->entry.FatX.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ FCB->entry.FatX.Attrib = FILE_ATTRIBUTE_DIRECTORY;
+ FCB->entry.FatX.FirstCluster = 1;
+ Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
}
else
{
- FCB->entry.FirstCluster = 1;
- Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ memset(FCB->entry.Fat.Filename, ' ', 11);
+ FCB->entry.Fat.FileSize = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ FCB->entry.Fat.Attrib = FILE_ATTRIBUTE_DIRECTORY;
+ if (pVCB->FatInfo.FatType == FAT32)
+ {
+ CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
+ FCB->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0xffff);
+ FCB->entry.Fat.FirstClusterHigh = (unsigned short)(FirstCluster >> 16);
+
+ while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
+ {
+ Size += pVCB->FatInfo.BytesPerCluster;
+ Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE);
+ }
+ }
+ else
+ {
+ FCB->entry.Fat.FirstCluster = 1;
+ Size = pVCB->FatInfo.rootDirectorySectors * pVCB->FatInfo.BytesPerSector;
+ }
}
+ FCB->ShortHash.Hash = FCB->Hash.Hash;
FCB->RefCount = 2;
FCB->dirIndex = 0;
FCB->RFCB.FileSize.QuadPart = Size;
@@ -435,10 +455,18 @@
RtlAppendUnicodeStringToString(&NameU, &DirContext->ShortNameU);
}
NameU.Buffer[NameU.Length / sizeof(WCHAR)] = 0;
- rcFCB = vfatNewFCB (&NameU);
- memcpy (&rcFCB->entry, &DirContext->FatDirEntry, sizeof (FAT_DIR_ENTRY));
+
+ rcFCB = vfatNewFCB (vcb, &NameU);
+ RtlCopyMemory (&rcFCB->entry, &DirContext->DirEntry, sizeof (DIR_ENTRY));
RtlCopyUnicodeString(&rcFCB->ShortNameU, &DirContext->ShortNameU);
- rcFCB->ShortHash.Hash = vfatNameHash(hash, &rcFCB->ShortNameU);
+ if (vcb->Flags & VCB_IS_FATX)
+ {
+ rcFCB->ShortHash.Hash = rcFCB->Hash.Hash;
+ }
+ else
+ {
+ rcFCB->ShortHash.Hash = vfatNameHash(hash, &rcFCB->ShortNameU);
+ }
if (vfatFCBIsDirectory(rcFCB))
{
@@ -450,7 +478,7 @@
{
Size = vcb->FatInfo.rootDirectorySectors * vcb->FatInfo.BytesPerSector;
}
- else
+ else if (FirstCluster != 0)
{
CurrentCluster = FirstCluster;
while (CurrentCluster != 0xffffffff)
@@ -460,9 +488,13 @@
}
}
}
+ else if (rcFCB->Flags & FCB_IS_FATX_ENTRY)
+ {
+ Size = rcFCB->entry.FatX.FileSize;
+ }
else
{
- Size = rcFCB->entry.FileSize;
+ Size = rcFCB->entry.Fat.FileSize;
}
rcFCB->dirIndex = DirContext->DirIndex;
rcFCB->startIndex = DirContext->StartIndex;
@@ -494,7 +526,7 @@
CHECKPOINT;
return STATUS_INSUFFICIENT_RESOURCES;
}
- memset (newCCB, 0, sizeof (VFATCCB));
+ RtlZeroMemory (newCCB, sizeof (VFATCCB));
fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID |
FO_DIRECT_CACHE_PAGING_READ;
@@ -542,7 +574,7 @@
while (TRUE)
{
- status = vfatGetNextDirEntry(&Context,
+ status = pDeviceExt->GetNextDirEntry(&Context,
&Page,
pDirectoryFCB,
&DirContext,
@@ -562,7 +594,7 @@
&DirContext.LongNameU);
DirContext.LongNameU.Buffer[DirContext.LongNameU.Length / sizeof(WCHAR)] = 0;
DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0;
- if (!ENTRY_VOLUME(&DirContext.FatDirEntry))
+ if (!ENTRY_VOLUME(pDeviceExt, &DirContext.DirEntry))
{
FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);
if (FoundLong == FALSE)
@@ -646,7 +678,7 @@
curr = pFileNameU->Buffer + FCB->PathNameU.Length / sizeof(WCHAR);
last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
}
- memcpy(pFileNameU->Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
+ RtlCopyMemory(pFileNameU->Buffer, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
}
}
else
@@ -699,7 +731,7 @@
curr = prev + parentFCB->LongNameU.Length / sizeof(WCHAR);
last = pFileNameU->Buffer + pFileNameU->Length / sizeof(WCHAR) - 1;
}
- memcpy(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
+ RtlCopyMemory(prev, parentFCB->LongNameU.Buffer, parentFCB->LongNameU.Length);
}
curr++;
prev = curr;
reactos/drivers/fs/vfat
diff -u -r1.38 -r1.39
--- finfo.c 6 Nov 2004 13:44:57 -0000 1.38
+++ finfo.c 5 Dec 2004 16:31:51 -0000 1.39
@@ -1,4 +1,4 @@
-/* $Id: finfo.c,v 1.38 2004/11/06 13:44:57 ekohl Exp $
+/* $Id: finfo.c,v 1.39 2004/12/05 16:31:51 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -6,6 +6,7 @@
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
* Hartmut Birr
+ * Herve Poussineau (reactos@poussine.freesurf.fr)
*
*/
@@ -106,26 +107,47 @@
ASSERT(NULL != DeviceExt);
ASSERT(NULL != BasicInfo);
/* Check volume label bit */
- ASSERT(0 == (FCB->entry.Attrib & 0x08));
+ ASSERT(0 == (*FCB->Attributes & 0x08));
- FsdSystemTimeToDosDateTime(&BasicInfo->CreationTime,
- &FCB->entry.CreationDate,
- &FCB->entry.CreationTime);
- FsdSystemTimeToDosDateTime(&BasicInfo->LastAccessTime,
- &FCB->entry.AccessDate,
+ if (FCB->Flags & FCB_IS_FATX_ENTRY)
+ {
+ FsdSystemTimeToDosDateTime(DeviceExt,
+ &BasicInfo->CreationTime,
+ &FCB->entry.FatX.CreationDate,
+ &FCB->entry.FatX.CreationTime);
+ FsdSystemTimeToDosDateTime(DeviceExt,
+ &BasicInfo->LastAccessTime,
+ &FCB->entry.FatX.AccessDate,
+ &FCB->entry.FatX.AccessTime);
+ FsdSystemTimeToDosDateTime(DeviceExt,
+ &BasicInfo->LastWriteTime,
+ &FCB->entry.FatX.UpdateDate,
+ &FCB->entry.FatX.UpdateTime);
+ }
+ else
+ {
+ FsdSystemTimeToDosDateTime(DeviceExt,
+ &BasicInfo->CreationTime,
+ &FCB->entry.Fat.CreationDate,
+ &FCB->entry.Fat.CreationTime);
+ FsdSystemTimeToDosDateTime(DeviceExt,
+ &BasicInfo->LastAccessTime,
+ &FCB->entry.Fat.AccessDate,
NULL);
- FsdSystemTimeToDosDateTime(&BasicInfo->LastWriteTime,
- &FCB->entry.UpdateDate,
- &FCB->entry.UpdateTime);
+ FsdSystemTimeToDosDateTime(DeviceExt,
+ &BasicInfo->LastWriteTime,
+ &FCB->entry.Fat.UpdateDate,
+ &FCB->entry.Fat.UpdateTime);
+ }
- FCB->entry.Attrib = (unsigned char)((FCB->entry.Attrib &
+ *FCB->Attributes = (unsigned char)((*FCB->Attributes &
(FILE_ATTRIBUTE_DIRECTORY | 0x48)) |
(BasicInfo->FileAttributes &
(FILE_ATTRIBUTE_ARCHIVE |
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_READONLY)));
- DPRINT("Setting attributes 0x%02x\n", FCB->entry.Attrib);
+ DPRINT("Setting attributes 0x%02x\n", *FCB->Attributes);
VfatUpdateEntry(FCB);
@@ -139,23 +161,48 @@
PFILE_BASIC_INFORMATION BasicInfo,
PULONG BufferLength)
{
+ PDEVICE_EXTENSION DeviceExt;
DPRINT("VfatGetBasicInformation()\n");
+
+ DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
- FsdDosDateTimeToSystemTime(FCB->entry.CreationDate,
- FCB->entry.CreationTime,
+ if (FCB->Flags & FCB_IS_FATX_ENTRY)
+ {
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ FCB->entry.FatX.CreationDate,
+ FCB->entry.FatX.CreationTime,
&BasicInfo->CreationTime);
- FsdDosDateTimeToSystemTime(FCB->entry.AccessDate,
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ FCB->entry.FatX.AccessDate,
+ FCB->entry.FatX.AccessTime,
+ &BasicInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ FCB->entry.FatX.UpdateDate,
+ FCB->entry.FatX.UpdateTime,
+ &BasicInfo->LastWriteTime);
+ BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
+ }
+ else
+ {
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ FCB->entry.Fat.CreationDate,
+ FCB->entry.Fat.CreationTime,
+ &BasicInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ FCB->entry.Fat.AccessDate,
0,
&BasicInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(FCB->entry.UpdateDate,
- FCB->entry.UpdateTime,
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ FCB->entry.Fat.UpdateDate,
+ FCB->entry.Fat.UpdateTime,
&BasicInfo->LastWriteTime);
- BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
+ BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
+ }
- BasicInfo->FileAttributes = FCB->entry.Attrib & 0x3f;
+ BasicInfo->FileAttributes = *FCB->Attributes & 0x3f;
/* Synthesize FILE_ATTRIBUTE_NORMAL */
if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
FILE_ATTRIBUTE_ARCHIVE |
@@ -188,7 +235,7 @@
ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
ASSERT(FCB != NULL);
- if (FCB->entry.Attrib & FILE_ATTRIBUTE_READONLY)
+ if (*FCB->Attributes & FILE_ATTRIBUTE_READONLY)
{
return STATUS_CANNOT_DELETE;
}
@@ -259,7 +306,7 @@
return STATUS_BUFFER_OVERFLOW;
NameInfo->FileNameLength = FCB->PathNameU.Length;
- memcpy(NameInfo->FileName, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
+ RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, FCB->PathNameU.Length);
NameInfo->FileName[FCB->PathNameU.Length / sizeof(WCHAR)] = 0;
*BufferLength -= (sizeof(FILE_NAME_INFORMATION) + FCB->PathNameU.Length + sizeof(WCHAR));
@@ -286,6 +333,7 @@
static NTSTATUS
VfatGetNetworkOpenInformation(PVFATFCB Fcb,
+ PDEVICE_EXTENSION DeviceExt,
PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
PULONG BufferLength)
/*
@@ -298,16 +346,38 @@
if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
- FsdDosDateTimeToSystemTime(Fcb->entry.CreationDate,
- Fcb->entry.CreationTime,
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ {
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ Fcb->entry.FatX.CreationDate,
+ Fcb->entry.FatX.CreationTime,
+ &NetworkInfo->CreationTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ Fcb->entry.FatX.AccessDate,
+ Fcb->entry.FatX.AccessTime,
+ &NetworkInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ Fcb->entry.FatX.UpdateDate,
+ Fcb->entry.FatX.UpdateTime,
+ &NetworkInfo->LastWriteTime);
+ NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
+ }
+ else
+ {
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ Fcb->entry.Fat.CreationDate,
+ Fcb->entry.Fat.CreationTime,
&NetworkInfo->CreationTime);
- FsdDosDateTimeToSystemTime(Fcb->entry.AccessDate,
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ Fcb->entry.Fat.AccessDate,
0,
&NetworkInfo->LastAccessTime);
- FsdDosDateTimeToSystemTime(Fcb->entry.UpdateDate,
- Fcb->entry.UpdateTime,
+ FsdDosDateTimeToSystemTime(DeviceExt,
+ Fcb->entry.Fat.UpdateDate,
+ Fcb->entry.Fat.UpdateTime,
&NetworkInfo->LastWriteTime);
- NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
+ NetworkInfo->ChangeTime.QuadPart = NetworkInfo->LastWriteTime.QuadPart;
+ }
if (vfatFCBIsDirectory(Fcb))
{
NetworkInfo->EndOfFile.QuadPart = 0L;
@@ -318,7 +388,7 @@
NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
}
- NetworkInfo->FileAttributes = Fcb->entry.Attrib & 0x3f;
+ NetworkInfo->FileAttributes = *Fcb->Attributes & 0x3f;
*BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
return STATUS_SUCCESS;
@@ -328,12 +398,16 @@
static NTSTATUS
VfatGetAllInformation(PFILE_OBJECT FileObject,
PVFATFCB Fcb,
+ PDEVICE_OBJECT DeviceObject,
PFILE_ALL_INFORMATION Info,
PULONG BufferLength)
/*
* FUNCTION: Retrieve the all file information
*/
{
+ NTSTATUS Status;
+ ULONG InitialBufferLength = *BufferLength;
+
ASSERT(Info);
ASSERT(Fcb);
@@ -341,60 +415,28 @@
return(STATUS_BUFFER_OVERFLOW);
/* Basic Information */
- FsdDosDateTimeToSystemTime(Fcb->entry.CreationDate,
- Fcb->entry.CreationTime,
- &Info->BasicInformation.CreationTime);
- FsdDosDateTimeToSystemTime(Fcb->entry.AccessDate,
- 0,
- &Info->BasicInformation.LastAccessTime);
- FsdDosDateTimeToSystemTime(Fcb->entry.UpdateDate,
- Fcb->entry.UpdateTime,
- &Info->BasicInformation.LastWriteTime);
- Info->BasicInformation.ChangeTime.QuadPart = Info->BasicInformation.LastWriteTime.QuadPart;
- Info->BasicInformation.FileAttributes = Fcb->entry.Attrib & 0x3f;
-
+ Status = VfatGetBasicInformation(FileObject, Fcb, DeviceObject, &Info->BasicInformation, BufferLength);
+ if (!NT_SUCCESS(Status)) return Status;
/* Standard Information */
- if (vfatFCBIsDirectory(Fcb))
- {
- Info->StandardInformation.AllocationSize.QuadPart = 0LL;
- Info->StandardInformation.EndOfFile.QuadPart = 0LL;
- Info->StandardInformation.Directory = TRUE;
- }
- else
- {
- Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
- Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
- Info->StandardInformation.Directory = FALSE;
- }
- Info->StandardInformation.NumberOfLinks = 0;
- Info->StandardInformation.DeletePending = Fcb->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
-
+ Status = VfatGetStandardInformation(Fcb, &Info->StandardInformation, BufferLength);
+ if (!NT_SUCCESS(Status)) return Status;
/* Internal Information */
- /* FIXME: get a real index, that can be used in a create operation */
- Info->InternalInformation.IndexNumber.QuadPart = 0;
-
+ Status = VfatGetInternalInformation(Fcb, &Info->InternalInformation, BufferLength);
+ if (!NT_SUCCESS(Status)) return Status;
/* EA Information */
Info->EaInformation.EaSize = 0;
-
- /* Access Information */
- /* The IO-Manager adds this information */
-
+ /* Access Information: The IO-Manager adds this information */
/* Position Information */
- Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
-
- /* Mode Information */
- /* The IO-Manager adds this information */
-
- /* Alignment Information */
- /* The IO-Manager adds this information */
-
+ Status = VfatGetPositionInformation(FileObject, Fcb, DeviceObject, &Info->PositionInformation, BufferLength);
+ if (!NT_SUCCESS(Status)) return Status;
+ /* Mode Information: The IO-Manager adds this information */
+ /* Alignment Information: The IO-Manager adds this information */
/* Name Information */
- Info->NameInformation.FileNameLength = Fcb->PathNameU.Length;
- RtlCopyMemory(Info->NameInformation.FileName, Fcb->PathNameU.Buffer, Fcb->PathNameU.Length);
- Info->NameInformation.FileName[Fcb->PathNameU.Length / sizeof(WCHAR)] = 0;
-
- *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + Fcb->PathNameU.Length + sizeof(WCHAR));
-
+ Status = VfatGetNameInformation(FileObject, Fcb, DeviceObject, &Info->NameInformation, BufferLength);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ *BufferLength = InitialBufferLength - (sizeof(FILE_ALL_INFORMATION) + Fcb->PathNameU.Length + sizeof(WCHAR));
+
return STATUS_SUCCESS;
}
@@ -410,7 +452,10 @@
}
if (!vfatFCBIsDirectory(Fcb))
{
- Fcb->entry.FileSize = Size;
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ Fcb->entry.FatX.FileSize = Size;
+ else
+ Fcb->entry.Fat.FileSize = Size;
}
Fcb->RFCB.FileSize.QuadPart = Size;
Fcb->RFCB.ValidDataLength.QuadPart = Size;
@@ -438,7 +483,10 @@
DPRINT("VfatSetAllocationSizeInformation()\n");
- OldSize = Fcb->entry.FileSize;
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ OldSize = Fcb->entry.FatX.FileSize;
+ else
+ OldSize = Fcb->entry.Fat.FileSize;
if (AllocationSize->u.HighPart > 0)
{
return STATUS_INVALID_PARAMETER;
@@ -482,8 +530,15 @@
}
return STATUS_DISK_FULL;
}
- Fcb->entry.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
- Fcb->entry.FirstClusterHigh = (unsigned short)((FirstCluster & 0xFFFF0000) >> 16);
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ {
+ Fcb->entry.FatX.FirstCluster = FirstCluster;
+ }
+ else
+ {
+ Fcb->entry.Fat.FirstCluster = (unsigned short)(FirstCluster & 0x0000FFFF);
+ Fcb->entry.Fat.FirstClusterHigh = (unsigned short)((FirstCluster & 0xFFFF0000) >> 16);
+ }
}
else
{
@@ -547,8 +602,15 @@
}
else
{
- Fcb->entry.FirstCluster = 0;
- Fcb->entry.FirstClusterHigh = 0;
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ {
+ Fcb->entry.FatX.FirstCluster = 0;
+ }
+ else
+ {
+ Fcb->entry.Fat.FirstCluster = 0;
+ Fcb->entry.Fat.FirstClusterHigh = 0;
+ }
NCluster = Cluster = FirstCluster;
Status = STATUS_SUCCESS;
@@ -640,12 +702,14 @@
break;
case FileNetworkOpenInformation:
RC = VfatGetNetworkOpenInformation(FCB,
+ IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileAllInformation:
RC = VfatGetAllInformation(IrpContext->FileObject,
FCB,
+ IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
reactos/drivers/fs/vfat
diff -u -r1.36 -r1.37
--- fsctl.c 6 Nov 2004 13:44:57 -0000 1.36
+++ fsctl.c 5 Dec 2004 16:31:51 -0000 1.37
@@ -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: fsctl.c,v 1.36 2004/11/06 13:44:57 ekohl Exp $
+/* $Id: fsctl.c,v 1.37 2004/12/05 16:31:51 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -55,6 +55,7 @@
ULONG Sectors;
LARGE_INTEGER Offset;
struct _BootSector* Boot;
+ struct _BootSectorFatX* BootFatX;
BOOL PartitionInfoIsValid = FALSE;
DPRINT("VfatHasFileSystem\n");
@@ -92,17 +93,15 @@
return Status;
}
PartitionInfoIsValid = TRUE;
-#if defined(DBG) && !defined(NDEBUG)
- DbgPrint("Partition Information:\n");
- DbgPrint("StartingOffset %u\n", PartitionInfo.StartingOffset.QuadPart / 512);
- DbgPrint("PartitionLength %u\n", PartitionInfo.PartitionLength.QuadPart / 512);
- DbgPrint("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
- DbgPrint("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
- DbgPrint("PartitionType %u\n", PartitionInfo.PartitionType);
- DbgPrint("BootIndicator %u\n", PartitionInfo.BootIndicator);
- DbgPrint("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
- DbgPrint("RewritePartition %u\n", PartitionInfo.RewritePartition);
-#endif
+ DPRINT("Partition Information:\n");
+ DPRINT("StartingOffset %u\n", PartitionInfo.StartingOffset.QuadPart / 512);
+ DPRINT("PartitionLength %u\n", PartitionInfo.PartitionLength.QuadPart / 512);
+ DPRINT("HiddenSectors %u\n", PartitionInfo.HiddenSectors);
+ DPRINT("PartitionNumber %u\n", PartitionInfo.PartitionNumber);
+ DPRINT("PartitionType %u\n", PartitionInfo.PartitionType);
+ DPRINT("BootIndicator %u\n", PartitionInfo.BootIndicator);
+ DPRINT("RecognizedPartition %u\n", PartitionInfo.RecognizedPartition);
+ DPRINT("RewritePartition %u\n", PartitionInfo.RewritePartition);
if (PartitionInfo.PartitionType)
{
if (PartitionInfo.PartitionType == PARTITION_FAT_12 ||
@@ -151,20 +150,28 @@
}
Offset.QuadPart = 0;
-
+
+ /* Try to recognize FAT12/FAT16/FAT32 partitions */
Status = VfatReadDisk(DeviceToMount, &Offset, DiskGeometry.BytesPerSector, (PUCHAR) Boot, FALSE);
if (NT_SUCCESS(Status))
{
if (Boot->Signatur1 != 0xaa55)
{
- DPRINT1("Signature %04x\n", Boot->Signatur1);
+ BootFatX = (struct _BootSectorFatX *) Boot;
+ if (BootFatX->SysType[0] != 'F' ||
+ BootFatX->SysType[1] != 'A' ||
+ BootFatX->SysType[2] != 'T' ||
+ BootFatX->SysType[3] != 'X')
+ {
+ DPRINT1("Signature %04x\n", Boot->Signatur1);
+ }
*RecognizedFS=FALSE;
}
if (*RecognizedFS &&
- Boot->BytesPerSector != 512 &&
- Boot->BytesPerSector != 1024 &&
+ Boot->BytesPerSector != 512 &&
+ Boot->BytesPerSector != 1024 &&
Boot->BytesPerSector != 2048 &&
- Boot->BytesPerSector != 4096)
+ Boot->BytesPerSector != 4096)
{
DPRINT1("BytesPerSector %d\n", Boot->BytesPerSector);
*RecognizedFS=FALSE;
@@ -172,7 +179,7 @@
if (*RecognizedFS &&
Boot->FATCount != 1 &&
- Boot->FATCount != 2)
+ Boot->FATCount != 2)
{
DPRINT1("FATCount %d\n", Boot->FATCount);
*RecognizedFS=FALSE;
@@ -180,28 +187,28 @@
if (*RecognizedFS &&
Boot->Media != 0xf0 &&
- Boot->Media != 0xf8 &&
- Boot->Media != 0xf9 &&
- Boot->Media != 0xfa &&
- Boot->Media != 0xfb &&
- Boot->Media != 0xfc &&
- Boot->Media != 0xfd &&
- Boot->Media != 0xfe &&
- Boot->Media != 0xff)
+ Boot->Media != 0xf8 &&
+ Boot->Media != 0xf9 &&
+ Boot->Media != 0xfa &&
+ Boot->Media != 0xfb &&
+ Boot->Media != 0xfc &&
+ Boot->Media != 0xfd &&
+ Boot->Media != 0xfe &&
+ Boot->Media != 0xff)
{
DPRINT1("Media %02x\n", Boot->Media);
*RecognizedFS=FALSE;
}
if (*RecognizedFS &&
- Boot->SectorsPerCluster != 1 &&
- Boot->SectorsPerCluster != 2 &&
+ Boot->SectorsPerCluster != 1 &&
+ Boot->SectorsPerCluster != 2 &&
Boot->SectorsPerCluster != 4 &&
- Boot->SectorsPerCluster != 8 &&
+ Boot->SectorsPerCluster != 8 &&
Boot->SectorsPerCluster != 16 &&
- Boot->SectorsPerCluster != 32 &&
+ Boot->SectorsPerCluster != 32 &&
Boot->SectorsPerCluster != 64 &&
- Boot->SectorsPerCluster != 128)
+ Boot->SectorsPerCluster != 128)
{
DPRINT1("SectorsPerCluster %02x\n", Boot->SectorsPerCluster);
*RecognizedFS=FALSE;
@@ -247,12 +254,12 @@
DPRINT("FAT16\n");
FatInfo.FatType = FAT16;
}
- if (PartitionInfoIsValid &&
- FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)
- {
- CHECKPOINT1;
- *RecognizedFS = FALSE;
- }
+ if (PartitionInfoIsValid &&
+ FatInfo.Sectors > PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector)
+ {
+ CHECKPOINT1;
+ *RecognizedFS = FALSE;
+ }
if (pFatInfo && *RecognizedFS)
{
@@ -262,6 +269,81 @@
}
ExFreePool(Boot);
+
+ if (!*RecognizedFS && PartitionInfoIsValid)
+ {
+ BootFatX = ExAllocatePool(NonPagedPool, sizeof(struct _BootSectorFatX));
+ if (BootFatX == NULL)
+ {
+ *RecognizedFS=FALSE;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Offset.QuadPart = 0;
+
+ /* Try to recognize FATX16/FATX32 partitions (Xbox) */
+ Status = VfatReadDisk(DeviceToMount, &Offset, sizeof(struct _BootSectorFatX), (PUCHAR) BootFatX, FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ *RecognizedFS = TRUE;
+ if (BootFatX->SysType[0] != 'F' ||
+ BootFatX->SysType[1] != 'A' ||
+ BootFatX->SysType[2] != 'T' ||
+ BootFatX->SysType[3] != 'X')
+ {
+ DPRINT1("SysType %c%c%c%c\n", BootFatX->SysType[0], BootFatX->SysType[1], BootFatX->SysType[2], BootFatX->SysType[3]);
+ *RecognizedFS=FALSE;
+ }
+
+ if (*RecognizedFS &&
+ BootFatX->SectorsPerCluster != 1 &&
+ BootFatX->SectorsPerCluster != 2 &&
+ BootFatX->SectorsPerCluster != 4 &&
+ BootFatX->SectorsPerCluster != 8 &&
+ BootFatX->SectorsPerCluster != 16 &&
+ BootFatX->SectorsPerCluster != 32 &&
+ BootFatX->SectorsPerCluster != 64 &&
+ BootFatX->SectorsPerCluster != 128)
+ {
+ DPRINT1("SectorsPerCluster %lu\n", BootFatX->SectorsPerCluster);
+ *RecognizedFS=FALSE;
+ }
+
+ if (*RecognizedFS)
+ {
+ FatInfo.BytesPerSector = DiskGeometry.BytesPerSector;
+ FatInfo.SectorsPerCluster = BootFatX->SectorsPerCluster;
+ FatInfo.rootDirectorySectors = BootFatX->SectorsPerCluster;
+ FatInfo.BytesPerCluster = BootFatX->SectorsPerCluster * DiskGeometry.BytesPerSector;
+ FatInfo.NumberOfClusters = PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerCluster;
+ if (FatInfo.NumberOfClusters < 65525)
+ {
+ DPRINT("FATX16\n");
+ FatInfo.FatType = FATX16;
+ }
+ else
+ {
+ DPRINT("FATX32\n");
+ FatInfo.FatType = FATX32;
+ }
+ FatInfo.VolumeID = BootFatX->VolumeID;
+ FatInfo.FATStart = sizeof(struct _BootSectorFatX) / DiskGeometry.BytesPerSector;
+ FatInfo.FATCount = BootFatX->FATCount;
+ FatInfo.FATSectors =
+ ROUND_UP(FatInfo.NumberOfClusters * (FatInfo.FatType == FATX16 ? 2 : 4), 4096) /
+ FatInfo.BytesPerSector;
+ FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
+ FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
+ FatInfo.Sectors = PartitionInfo.PartitionLength.QuadPart / FatInfo.BytesPerSector;
+ if (pFatInfo && *RecognizedFS)
+ {
+ *pFatInfo = FatInfo;
+ }
+ }
+ }
+ ExFreePool(BootFatX);
+ }
+
DPRINT("VfatHasFileSystem done\n");
return Status;
}
@@ -357,31 +439,65 @@
goto ByeBye;
}
-#ifndef NDEBUG
- DbgPrint("BytesPerSector: %d\n", DeviceExt->FatInfo.BytesPerSector);
- DbgPrint("SectorsPerCluster: %d\n", DeviceExt->FatInfo.SectorsPerCluster);
- DbgPrint("FATCount: %d\n", DeviceExt->FatInfo.FATCount);
- DbgPrint("FATSectors: %d\n", DeviceExt->FatInfo.FATSectors);
- DbgPrint("RootStart: %d\n", DeviceExt->FatInfo.rootStart);
- DbgPrint("DataStart: %d\n", DeviceExt->FatInfo.dataStart);
+ DPRINT("BytesPerSector: %d\n", DeviceExt->FatInfo.BytesPerSector);
+ DPRINT("SectorsPerCluster: %d\n", DeviceExt->FatInfo.SectorsPerCluster);
+ DPRINT("FATCount: %d\n", DeviceExt->FatInfo.FATCount);
+ DPRINT("FATSectors: %d\n", DeviceExt->FatInfo.FATSectors);
+ DPRINT("RootStart: %d\n", DeviceExt->FatInfo.rootStart);
+ DPRINT("DataStart: %d\n", DeviceExt->FatInfo.dataStart);
if (DeviceExt->FatInfo.FatType == FAT32)
{
- DbgPrint("RootCluster: %d\n", DeviceExt->FatInfo.RootCluster);
+ DPRINT("RootCluster: %d\n", DeviceExt->FatInfo.RootCluster);
}
-#endif
- DeviceExt->StorageDevice = DeviceToMount;
- DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
- DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
- DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
- DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
- DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ switch (DeviceExt->FatInfo.FatType)
+ {
+ case FAT12:
+ DeviceExt->GetNextCluster = FAT12GetNextCluster;
+ DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
+ DeviceExt->WriteCluster = FAT12WriteCluster;
+ break;
- DPRINT("FsDeviceObject %lx\n", DeviceObject);
+ case FAT16:
+ case FATX16:
+ DeviceExt->GetNextCluster = FAT16GetNextCluster;
+ DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
+ DeviceExt->WriteCluster = FAT16WriteCluster;
+ break;
+
+ case FAT32:
+ case FATX32:
+ DeviceExt->GetNextCluster = FAT32GetNextCluster;
+ DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
+ DeviceExt->WriteCluster = FAT32WriteCluster;
+ break;
+ }
+
+ if (DeviceExt->FatInfo.FatType == FATX16
+ || DeviceExt->FatInfo.FatType == FATX32)
+ {
+ DeviceExt->Flags |= VCB_IS_FATX;
+ DeviceExt->GetNextDirEntry = FATXGetNextDirEntry;
+ DeviceExt->BaseDateYear = 2000;
+ }
+ else
+ {
+ DeviceExt->GetNextDirEntry = FATGetNextDirEntry;
+ DeviceExt->BaseDateYear = 1980;
+ }
+
+ DeviceExt->StorageDevice = DeviceToMount;
+ DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
+ DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
+ DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
+ DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
+ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ DPRINT("FsDeviceObject %lx\n", DeviceObject);
DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
RtlRosInitUnicodeStringFromLiteral(&NameU, L"\\$$Fat$$");
- Fcb = vfatNewFCB(&NameU);
+ Fcb = vfatNewFCB(DeviceExt, &NameU);
if (Fcb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -394,7 +510,7 @@
goto ByeBye;
}
- memset(Ccb, 0, sizeof (VFATCCB));
+ RtlZeroMemory(Ccb, sizeof (VFATCCB));
DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
DeviceExt->FATFileObject->FsContext = Fcb;
DeviceExt->FATFileObject->FsContext2 = Ccb;
@@ -403,7 +519,7 @@
DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
Fcb->FileObject = DeviceExt->FATFileObject;
- Fcb->Flags = FCB_IS_FAT;
+ Fcb->Flags |= FCB_IS_FAT;
Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
@@ -419,38 +535,17 @@
}
if (!NT_SUCCESS (Status))
{
- DbgPrint ("CcRosInitializeFileCache failed\n");
+ DPRINT1 ("CcRosInitializeFileCache failed\n");
goto ByeBye;
}
DeviceExt->LastAvailableCluster = 2;
ExInitializeResourceLite(&DeviceExt->DirResource);
ExInitializeResourceLite(&DeviceExt->FatResource);
- switch (DeviceExt->FatInfo.FatType)
- {
- case FAT12:
- DeviceExt->GetNextCluster = FAT12GetNextCluster;
- DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
- DeviceExt->WriteCluster = FAT12WriteCluster;
- break;
-
- case FAT16:
- DeviceExt->GetNextCluster = FAT16GetNextCluster;
- DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
- DeviceExt->WriteCluster = FAT16WriteCluster;
- break;
-
- case FAT32:
- DeviceExt->GetNextCluster = FAT32GetNextCluster;
- DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
- DeviceExt->WriteCluster = FAT32WriteCluster;
- break;
- }
-
InitializeListHead(&DeviceExt->FcbListHead);
RtlRosInitUnicodeStringFromLiteral(&NameU, L"\\$$Volume$$");
- VolumeFcb = vfatNewFCB(&NameU);
+ VolumeFcb = vfatNewFCB(DeviceExt, &NameU);
if (VolumeFcb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -471,7 +566,7 @@
/* read volume label */
ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
-
+
Status = STATUS_SUCCESS;
ByeBye:
@@ -737,4 +832,3 @@
VfatFreeIrpContext(IrpContext);
return (Status);
}
-
reactos/drivers/fs/vfat
diff -u -r1.14 -r1.15
--- misc.c 6 Nov 2004 13:44:57 -0000 1.14
+++ misc.c 5 Dec 2004 16:31:51 -0000 1.15
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.14 2004/11/06 13:44:57 ekohl Exp $
+/* $Id: misc.c,v 1.15 2004/12/05 16:31:51 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -41,7 +41,7 @@
goto Fail;
}
- if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
Status = STATUS_INVALID_PARAMETER;
goto Fail;
reactos/drivers/fs/vfat
diff -u -r1.71 -r1.72
--- rw.c 6 Nov 2004 13:44:57 -0000 1.71
+++ rw.c 5 Dec 2004 16:31:51 -0000 1.72
@@ -1,5 +1,5 @@
-/* $Id: rw.c,v 1.71 2004/11/06 13:44:57 ekohl Exp $
+/* $Id: rw.c,v 1.72 2004/12/05 16:31:51 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -592,7 +592,7 @@
BytesPerSector = IrpContext->DeviceExt->FatInfo.BytesPerSector;
/* fail if file is a directory and no paged read */
- if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
+ if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
{
Status = STATUS_INVALID_PARAMETER;
goto ByeBye;
@@ -821,7 +821,7 @@
}
/* fail if file is a directory and no paged read */
- if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
+ if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
{
Status = STATUS_INVALID_PARAMETER;
goto ByeBye;
@@ -1020,14 +1020,26 @@
if (!(IrpContext->Irp->Flags & IRP_PAGING_IO) &&
!(Fcb->Flags & (FCB_IS_FAT|FCB_IS_VOLUME)))
{
- if(!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
+ if(!(*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY))
{
LARGE_INTEGER SystemTime;
// set dates and times
KeQuerySystemTime (&SystemTime);
- FsdSystemTimeToDosDateTime (&SystemTime, &Fcb->entry.UpdateDate,
- &Fcb->entry.UpdateTime);
- Fcb->entry.AccessDate = Fcb->entry.UpdateDate;
+ if (Fcb->Flags & FCB_IS_FATX_ENTRY)
+ {
+ FsdSystemTimeToDosDateTime (IrpContext->DeviceExt,
+ &SystemTime, &Fcb->entry.FatX.UpdateDate,
+ &Fcb->entry.FatX.UpdateTime);
+ Fcb->entry.FatX.AccessDate = Fcb->entry.FatX.UpdateDate;
+ Fcb->entry.FatX.AccessTime = Fcb->entry.FatX.UpdateTime;
+ }
+ else
+ {
+ FsdSystemTimeToDosDateTime (IrpContext->DeviceExt,
+ &SystemTime, &Fcb->entry.Fat.UpdateDate,
+ &Fcb->entry.Fat.UpdateTime);
+ Fcb->entry.Fat.AccessDate = Fcb->entry.Fat.UpdateDate;
+ }
/* set date and times to dirty */
Fcb->Flags |= FCB_IS_DIRTY;
}
reactos/drivers/fs/vfat
diff -u -r1.8 -r1.9
--- shutdown.c 11 Oct 2003 17:51:56 -0000 1.8
+++ shutdown.c 5 Dec 2004 16:31:51 -0000 1.9
@@ -1,4 +1,4 @@
-/* $Id: shutdown.c,v 1.8 2003/10/11 17:51:56 hbirr Exp $
+/* $Id: shutdown.c,v 1.9 2004/12/05 16:31:51 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -48,9 +48,9 @@
Irp->IoStatus.Status = Status;
}
/* FIXME: Unmount the logical volume */
-
- ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
}
+ ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
+
/* FIXME: Free all global acquired resources */
Status = Irp->IoStatus.Status;
reactos/drivers/fs/vfat
diff -u -r1.69 -r1.70
--- vfat.h 6 Nov 2004 13:44:57 -0000 1.69
+++ vfat.h 5 Dec 2004 16:31:51 -0000 1.70
@@ -1,4 +1,4 @@
-/* $Id: vfat.h,v 1.69 2004/11/06 13:44:57 ekohl Exp $ */
+/* $Id: vfat.h,v 1.70 2004/12/05 16:31:51 gvg Exp $ */
#include <ddk/ntifs.h>
@@ -52,6 +52,16 @@
unsigned short Signature1; // 510
} __attribute__((packed));
+struct _BootSectorFatX
+{
+ unsigned char SysType[4]; // 0
+ unsigned long VolumeID; // 4
+ unsigned long SectorsPerCluster; // 8
+ unsigned short FATCount; // 12
+ unsigned long Unknown; // 14
+ unsigned char Unused[4078]; // 18
+} __attribute__((packed));
+
struct _FsInfoSector
{
unsigned long ExtBootSignature2; // 0
@@ -68,10 +78,22 @@
#define VFAT_CASE_LOWER_BASE 8 // base is lower case
#define VFAT_CASE_LOWER_EXT 16 // extension is lower case
-#define ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
-#define ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
-#define ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
-#define ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
+#define ENTRY_DELETED(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_DELETED(&((DirEntry)->FatX)) : FAT_ENTRY_DELETED(&((DirEntry)->Fat)))
+#define ENTRY_VOLUME(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_VOLUME(&((DirEntry)->FatX)) : FAT_ENTRY_VOLUME(&((DirEntry)->Fat)))
+#define ENTRY_END(DeviceExt, DirEntry) ((DeviceExt)->Flags & VCB_IS_FATX ? FATX_ENTRY_END(&((DirEntry)->FatX)) : FAT_ENTRY_END(&((DirEntry)->Fat)))
+
+#define FAT_ENTRY_DELETED(DirEntry) ((DirEntry)->Filename[0] == 0xe5)
+#define FAT_ENTRY_END(DirEntry) ((DirEntry)->Filename[0] == 0)
+#define FAT_ENTRY_LONG(DirEntry) (((DirEntry)->Attrib & 0x3f) == 0x0f)
+#define FAT_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
+
+#define FATX_ENTRY_DELETED(DirEntry) ((DirEntry)->FilenameLength == 0xe5)
+#define FATX_ENTRY_END(DirEntry) ((DirEntry)->FilenameLength == 0xff)
+#define FATX_ENTRY_LONG(DirEntry) (FALSE)
+#define FATX_ENTRY_VOLUME(DirEntry) (((DirEntry)->Attrib & 0x1f) == 0x08)
+
+#define FAT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FAT_DIR_ENTRY))
+#define FATX_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof (FATX_DIR_ENTRY))
struct _FATDirEntry
{
@@ -87,7 +109,32 @@
unsigned long FileSize;
} __attribute__((packed));
-typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
+typedef struct _FATDirEntry FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
+
+struct _FATXDirEntry
+{
+ unsigned char FilenameLength; // 0
+ unsigned char Attrib; // 1
+ unsigned char Filename[42]; // 2
+ unsigned long FirstCluster; // 44
+ unsigned long FileSize; // 48
+ unsigned short UpdateTime; // 52
+ unsigned short UpdateDate; // 54
+ unsigned short CreationTime; // 56
+ unsigned short CreationDate; // 58
+ unsigned short AccessTime; // 60
+ unsigned short AccessDate; // 62
+} __attribute__((packed));
+
+typedef struct _FATXDirEntry FATX_DIR_ENTRY, *PFATX_DIR_ENTRY;
+
+union _DIR_ENTRY
+{
+ FAT_DIR_ENTRY Fat;
+ FATX_DIR_ENTRY FatX;
+};
+
+typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY;
struct _slot
{
@@ -106,12 +153,15 @@
#define BLOCKSIZE 512
-#define FAT16 (1)
-#define FAT12 (2)
-#define FAT32 (3)
+#define FAT16 (1)
+#define FAT12 (2)
+#define FAT32 (3)
+#define FATX16 (4)
+#define FATX32 (5)
#define VCB_VOLUME_LOCKED 0x0001
#define VCB_DISMOUNT_PENDING 0x0002
+#define VCB_IS_FATX 0x0004
typedef struct
{
@@ -133,6 +183,7 @@
} FATINFO, *PFATINFO;
struct _VFATFCB;
+struct _VFAT_DIRENTRY_CONTEXT;
typedef struct _HASHENTRY
{
@@ -150,6 +201,8 @@
typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
+typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
+
typedef struct DEVICE_EXTENSION
{
ERESOURCE DirResource;
@@ -172,6 +225,11 @@
PGET_NEXT_CLUSTER GetNextCluster;
PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
PWRITE_CLUSTER WriteCluster;
+
+ /* Pointers to functions for manipulating directory entries. */
+ PGET_NEXT_DIR_ENTRY GetNextDirEntry;
+
+ ULONG BaseDateYear;
LIST_ENTRY VolumeListEntry;
} DEVICE_EXTENSION, VCB, *PVCB;
@@ -195,7 +253,8 @@
#define FCB_IS_FAT 0x0004
#define FCB_IS_PAGE_FILE 0x0008
#define FCB_IS_VOLUME 0x0010
-#define FCB_IS_DIRTY 0x0020
+#define FCB_IS_DIRTY 0x0020
+#define FCB_IS_FATX_ENTRY 0x0040
typedef struct _VFATFCB
{
@@ -207,7 +266,10 @@
/* end FCB header required by ROS/NT */
/* directory entry for this file or directory */
- FATDirEntry entry;
+ DIR_ENTRY entry;
+
+ /* Pointer to attributes in entry */
+ PUCHAR Attributes;
/* long file name, points into PathNameBuffer */
UNICODE_STRING LongNameU;
@@ -330,7 +392,7 @@
{
ULONG StartIndex;
ULONG DirIndex;
- FAT_DIR_ENTRY FatDirEntry;
+ DIR_ENTRY DirEntry;
UNICODE_STRING LongNameU;
UNICODE_STRING ShortNameU;
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
@@ -379,11 +441,13 @@
NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
-BOOL FsdDosDateTimeToSystemTime (WORD wDosDate,
+BOOL FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt,
+ WORD wDosDate,
WORD wDosTime,
PLARGE_INTEGER SystemTime);
-BOOL FsdSystemTimeToDosDateTime (PLARGE_INTEGER SystemTime,
+BOOL FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt,
+ PLARGE_INTEGER SystemTime,
WORD *pwDosDate,
WORD *pwDosTime);
@@ -451,6 +515,12 @@
NTSTATUS VfatDelEntry(PDEVICE_EXTENSION, PVFATFCB);
+BOOLEAN
+vfatFindDirSpace(PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB pDirFcb,
+ ULONG nbSlots,
+ PULONG start);
+
/* -------------------------------------------------------- string.c */
VOID
@@ -529,11 +599,17 @@
/* ------------------------------------------------------ direntry.c */
ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
- PFAT_DIR_ENTRY pDirEntry);
+ PDIR_ENTRY pDirEntry);
BOOL VfatIsDirectoryEmpty(PVFATFCB Fcb);
-NTSTATUS vfatGetNextDirEntry(PVOID * pContext,
+NTSTATUS FATGetNextDirEntry(PVOID * pContext,
+ PVOID * pPage,
+ IN PVFATFCB pDirFcb,
+ IN PVFAT_DIRENTRY_CONTEXT DirContext,
+ BOOLEAN First);
+
+NTSTATUS FATXGetNextDirEntry(PVOID * pContext,
PVOID * pPage,
IN PVFATFCB pDirFcb,
IN PVFAT_DIRENTRY_CONTEXT DirContext,
@@ -541,7 +617,8 @@
/* ----------------------------------------------------------- fcb.c */
-PVFATFCB vfatNewFCB (PUNICODE_STRING pFileNameU);
+PVFATFCB vfatNewFCB (PDEVICE_EXTENSION pVCB,
+ PUNICODE_STRING pFileNameU);
VOID vfatDestroyFCB (PVFATFCB pFCB);
reactos/drivers/fs/vfat
diff -u -r1.27 -r1.28
--- volume.c 6 Nov 2004 13:44:57 -0000 1.27
+++ volume.c 5 Dec 2004 16:31:51 -0000 1.28
@@ -1,4 +1,4 @@
-/* $Id: volume.c,v 1.27 2004/11/06 13:44:57 ekohl Exp $
+/* $Id: volume.c,v 1.28 2004/12/05 16:31:51 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -6,6 +6,7 @@
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
* Hartmut Birr
+ * Herve Poussineau (reactos@poussine.freesurf.fr)
*/
/* INCLUDES *****************************************************************/
@@ -42,7 +43,7 @@
/* valid entries */
FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
- memcpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel, FsVolumeInfo->VolumeLabelLength);
+ RtlCopyMemory(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel, FsVolumeInfo->VolumeLabelLength);
/* dummy entries */
FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
@@ -94,7 +95,7 @@
FsAttributeInfo->FileSystemNameLength = Length;
- memcpy(FsAttributeInfo->FileSystemName, pName, Length );
+ RtlCopyMemory(FsAttributeInfo->FileSystemName, pName, Length );
DPRINT("Finished FsdGetFsAttributeInformation()\n");
@@ -162,9 +163,140 @@
FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
PFILE_FS_LABEL_INFORMATION FsLabelInfo)
{
+ PDEVICE_EXTENSION DeviceExt;
+ PVOID Context = NULL;
+ ULONG DirIndex = 0;
+ PDIR_ENTRY Entry;
+ PVFATFCB pRootFcb;
+ LARGE_INTEGER FileOffset;
+ BOOL LabelFound = FALSE;
+ DIR_ENTRY VolumeLabelDirEntry;
+ ULONG VolumeLabelDirIndex;
+ ULONG LabelLen;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ OEM_STRING StringO;
+ UNICODE_STRING StringW;
+ CHAR cString[43];
+ ULONG SizeDirEntry;
+ ULONG EntriesPerPage;
+
DPRINT("FsdSetFsLabelInformation()\n");
-
- return(STATUS_NOT_IMPLEMENTED);
+
+ DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ if (sizeof(DeviceObject->Vpb->VolumeLabel) < FsLabelInfo->VolumeLabelLength)
+ {
+ CHECKPOINT;
+ return STATUS_NAME_TOO_LONG;
+ }
+
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ if (FsLabelInfo->VolumeLabelLength / sizeof(WCHAR) > 42)
+ return STATUS_NAME_TOO_LONG;
+ SizeDirEntry = sizeof(FATX_DIR_ENTRY);
+ EntriesPerPage = FATX_ENTRIES_PER_PAGE;
+ }
+ else
+ {
+ if (FsLabelInfo->VolumeLabelLength / sizeof(WCHAR) > 11)
+ return STATUS_NAME_TOO_LONG;
+ SizeDirEntry = sizeof(FAT_DIR_ENTRY);
+ EntriesPerPage = FAT_ENTRIES_PER_PAGE;
+ }
+
+ /* Create Volume label dir entry */
+ LabelLen = FsLabelInfo->VolumeLabelLength / sizeof(WCHAR);
+ RtlZeroMemory(&VolumeLabelDirEntry, SizeDirEntry);
+ StringW.Buffer = FsLabelInfo->VolumeLabel;
+ StringW.Length = StringW.MaximumLength = FsLabelInfo->VolumeLabelLength;
+ StringO.Buffer = cString;
+ StringO.Length = 0;
+ StringO.MaximumLength = 42;
+ Status = RtlUnicodeStringToOemString(&StringO, &StringW, FALSE);
+ if (!NT_SUCCESS(Status))
+ return Status;
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ RtlCopyMemory(VolumeLabelDirEntry.FatX.Filename, cString, LabelLen);
+ memset(&VolumeLabelDirEntry.FatX.Filename[LabelLen], ' ', 42 - LabelLen);
+ VolumeLabelDirEntry.FatX.Attrib = 0x08;
+ }
+ else
+ {
+ RtlCopyMemory(VolumeLabelDirEntry.Fat.Filename, cString, LabelLen);
+ memset(&VolumeLabelDirEntry.Fat.Filename[LabelLen], ' ', 11 - LabelLen);
+ VolumeLabelDirEntry.Fat.Attrib = 0x08;
+ }
+
+ pRootFcb = vfatOpenRootFCB(DeviceExt);
+
+ /* Search existing volume entry on disk */
+ FileOffset.QuadPart = 0;
+ if (CcMapData(pRootFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
+ {
+ while (TRUE)
+ {
+ if (ENTRY_VOLUME(DeviceExt, Entry))
+ {
+ /* Update entry */
+ LabelFound = TRUE;
+ RtlCopyMemory(Entry, &VolumeLabelDirEntry, SizeDirEntry);
+ CcSetDirtyPinnedData(Context, NULL);
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ if (ENTRY_END(DeviceExt, Entry))
+ {
+ break;
+ }
+ DirIndex++;
+ Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
+ if ((DirIndex % EntriesPerPage) == 0)
+ {
+ CcUnpinData(Context);
+ FileOffset.u.LowPart += PAGE_SIZE;
+ if (!CcMapData(pRootFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, &Context, (PVOID*)&Entry))
+ {
+ Context = NULL;
+ break;
+ }
+ }
+ }
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ }
+ if (!LabelFound)
+ {
+ /* Add new entry for label */
+ if (!vfatFindDirSpace(DeviceExt, pRootFcb, 1, &VolumeLabelDirIndex))
+ Status = STATUS_DISK_FULL;
+ else
+ {
+ FileOffset.u.HighPart = 0;
+ FileOffset.u.LowPart = VolumeLabelDirIndex * SizeDirEntry;
+ CcMapData(pRootFcb->FileObject, &FileOffset, SizeDirEntry,
+ TRUE, &Context, (PVOID*)&Entry);
+ RtlCopyMemory(Entry, &VolumeLabelDirEntry, SizeDirEntry);
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ Status = STATUS_SUCCESS;
+ }
+ }
+
+ vfatReleaseFCB(DeviceExt, pRootFcb);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ /* Update volume label in memory */
+ DeviceObject->Vpb->VolumeLabelLength = FsLabelInfo->VolumeLabelLength;
+ RtlCopyMemory(DeviceObject->Vpb->VolumeLabel, FsLabelInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabelLength);
+
+ return Status;
}
@@ -255,7 +387,7 @@
/* PRECONDITION */
ASSERT(IrpContext);
- DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
+ DPRINT ("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
@@ -267,9 +399,9 @@
BufferLength = Stack->Parameters.SetVolume.Length;
SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
- DPRINT1("FsInformationClass %d\n", FsInformationClass);
- DPRINT1("BufferLength %d\n", BufferLength);
- DPRINT1("SystemBuffer %x\n", SystemBuffer);
+ DPRINT ("FsInformationClass %d\n", FsInformationClass);
+ DPRINT ("BufferLength %d\n", BufferLength);
+ DPRINT ("SystemBuffer %x\n", SystemBuffer);
switch(FsInformationClass)
{
CVSspam 0.2.8