Changed directory and fat access to pining-interface.
Removed unused values from DEVICE_EXTENSION structure.
Changed calculation of available and free clusters.
Changed mount and type determining procedure.
Moved some functions to fsctl.c
volume.c:
Added FAT32 fs type.
dirw.c:
Fixed a directory creation bug on FAT32 (Thanks to Eric Kohl).
Fixed a directory deletion bug.
dir.c:
Fixed a dead lock in DoQuery.
Fixed some memory leakages.
svn path=/trunk/; revision=2737
DPRINT ("Block request succeeded\n");
return (STATUS_SUCCESS);
}
+
+NTSTATUS
+VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG CtlCode,
+ IN PVOID InputBuffer,
+ IN ULONG InputBufferSize,
+ IN OUT PVOID OutputBuffer,
+ IN OUT PULONG pOutputBufferSize)
+{
+ ULONG OutputBufferSize = 0;
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+
+ DPRINT("VfatBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
+ "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
+ "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
+ InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize,
+ pOutputBufferSize ? *pOutputBufferSize : 0);
+
+ if (pOutputBufferSize)
+ {
+ OutputBufferSize = *pOutputBufferSize;
+ }
+
+ KeInitializeEvent (&Event, NotificationEvent, FALSE);
+
+ DPRINT("Building device I/O control request ...\n");
+ Irp = IoBuildDeviceIoControlRequest(CtlCode,
+ DeviceObject,
+ InputBuffer,
+ InputBufferSize,
+ OutputBuffer,
+ OutputBufferSize,
+ FALSE,
+ &Event,
+ &IoStatus);
+
+ if (Irp == NULL)
+ {
+ DPRINT("IoBuildDeviceIoControlRequest failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ DPRINT ("Calling IO Driver... with irp %x\n", Irp);
+ Status = IoCallDriver(DeviceObject, Irp);
+
+ DPRINT ("Waiting for IO Operation for %x\n", Irp);
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT ("Operation pending\n");
+ KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
+ DPRINT ("Getting IO Status... for %x\n", Irp);
+
+ Status = IoStatus.Status;
+ }
+ if (OutputBufferSize)
+ {
+ *pOutputBufferSize = OutputBufferSize;
+ }
+ DPRINT("Returning Status %x\n", Status);
+ return Status;
+}
-/* $Id: create.c,v 1.38 2002/02/08 02:57:09 chorns Exp $
+/* $Id: create.c,v 1.39 2002/03/18 22:37:12 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FUNCTION: Read the volume label
*/
{
- ULONG i = 0;
- ULONG j;
- ULONG Size;
- char *block;
- ULONG StartingSector;
- ULONG NextCluster;
- NTSTATUS Status;
+ PVOID Context = NULL;
+ ULONG Offset = 0;
+ ULONG DirIndex = 0;
+ FATDirEntry* Entry;
+ PVFATFCB pFcb;
+ LARGE_INTEGER FileOffset;
- Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */
- StartingSector = DeviceExt->rootStart;
- NextCluster = 0;
+ *(Vpb->VolumeLabel) = 0;
+ Vpb->VolumeLabelLength = 0;
- block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
- DPRINT ("ReadVolumeLabel : start at sector %lx, entry %ld\n", StartingSector, i);
- for (j = 0; j < Size; j++)
- {
- /* FIXME: Check status */
- Status = VfatReadSectors (DeviceExt->StorageDevice, StartingSector, 1, block);
- if (!NT_SUCCESS(Status))
- {
- *(Vpb->VolumeLabel) = 0;
- Vpb->VolumeLabelLength = 0;
- ExFreePool(block);
- return(Status);
- }
+ pFcb = vfatOpenRootFCB (DeviceExt);
- for (i = 0; i < ENTRIES_PER_SECTOR; i++)
- {
- if (IsVolEntry ((PVOID) block, i))
- {
- FATDirEntry *test = (FATDirEntry *) block;
-
- /* copy volume label */
- vfat8Dot3ToVolumeLabel (test[i].Filename, test[i].Ext, Vpb->VolumeLabel);
- Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel);
-
- ExFreePool (block);
- return (STATUS_SUCCESS);
- }
- if (IsLastEntry ((PVOID) block, i))
- {
- *(Vpb->VolumeLabel) = 0;
- Vpb->VolumeLabelLength = 0;
- ExFreePool (block);
- return (STATUS_UNSUCCESSFUL);
- }
- }
- /* not found in this sector, try next : */
+ while (TRUE)
+ {
+ if (Context == NULL || Offset == ENTRIES_PER_PAGE)
+ {
+ if (Offset == ENTRIES_PER_PAGE)
+ {
+ Offset = 0;
+ }
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ FileOffset.u.HighPart = 0;
+ FileOffset.u.LowPart = (DirIndex - Offset) * sizeof(FATDirEntry);
+ if (!CcMapData(pFcb->FileObject, &FileOffset, PAGESIZE, TRUE, &Context, (PVOID*)&Entry))
+ {
+ Context = NULL;
+ break;
+ }
+ }
+ if (IsVolEntry(Entry, Offset))
+ {
+ /* copy volume label */
+ vfat8Dot3ToVolumeLabel (Entry[Offset].Filename, Entry[Offset].Ext, Vpb->VolumeLabel);
+ Vpb->VolumeLabelLength = wcslen (Vpb->VolumeLabel) * sizeof(WCHAR);
+ break;
+ }
+ if (IsLastEntry(Entry, Offset))
+ {
+ break;
+ }
+ Offset++;
+ DirIndex++;
+ }
- /* directory can be fragmented although it is best to keep them
- unfragmented.*/
- StartingSector++;
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ vfatReleaseFCB (DeviceExt, pFcb);
- if (DeviceExt->FatType == FAT32)
- {
- if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1))
- {
- Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster,
- FALSE);
- if (NextCluster == 0 || NextCluster == 0xffffffff)
- {
- *(Vpb->VolumeLabel) = 0;
- Vpb->VolumeLabelLength = 0;
- ExFreePool (block);
- return (STATUS_UNSUCCESSFUL);
- }
- StartingSector = ClusterToSector (DeviceExt, NextCluster);
- }
- }
- }
- *(Vpb->VolumeLabel) = 0;
- Vpb->VolumeLabelLength = 0;
- ExFreePool (block);
- return (STATUS_UNSUCCESSFUL);
+ return STATUS_SUCCESS;
}
NTSTATUS
if (Parent)
{
FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Parent->entry);
- if (DeviceExt->FatType == FAT32)
+ if (DeviceExt->FatInfo.FatType == FAT32)
{
- if (FirstCluster == ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster)
+ if (FirstCluster == DeviceExt->FatInfo.RootCluster)
isRoot = TRUE;
}
else
isRoot = TRUE;
if (isRoot)
{
- if (DeviceExt->FatType == FAT32)
- FirstCluster = ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster;
+ if (DeviceExt->FatInfo.FatType == FAT32)
+ FirstCluster = DeviceExt->FatInfo.RootCluster;
else
FirstCluster = 1;
CHECKPOINT;
Fcb->PathName[0]='\\';
Fcb->ObjectName = &Fcb->PathName[1];
- Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
+ Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE;
Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
- if (DeviceExt->FatType == FAT32)
+ if (DeviceExt->FatInfo.FatType == FAT32)
{
Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0];
Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1];
Irp->IoStatus.Status = Status;
return Status;
}
-
+ if (Status == STATUS_INVALID_PARAMETER)
+ {
+ Irp->IoStatus.Status = Status;
+ return Status;
+ }
if (Status == STATUS_DELETE_PENDING)
{
Irp->IoStatus.Status = Status;
ULONG Cluster, NextCluster;
/* FIXME set size to 0 and free clusters */
pFcb->entry.FileSize = 0;
- if (DeviceExt->FatType == FAT32)
+ if (DeviceExt->FatInfo.FatType == FAT32)
Cluster = pFcb->entry.FirstCluster
+ pFcb->entry.FirstClusterHigh * 65536;
else
ULONG CurrentCluster, NextCluster, i;
DPRINT("Open an existing paging file\n");
pFcb->Flags |= FCB_IS_PAGE_FILE;
- pFcb->FatChainSize =
- ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) / DeviceExt->BytesPerCluster);
+ pFcb->FatChainSize =
+ ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) / DeviceExt->FatInfo.BytesPerCluster);
if (pFcb->FatChainSize)
{
pFcb->FatChain = ExAllocatePool(NonPagedPool,
pFcb->FatChainSize * sizeof(ULONG));
}
- if (DeviceExt->FatType == FAT32)
+ if (DeviceExt->FatInfo.FatType == FAT32)
{
CurrentCluster = pFcb->entry.FirstCluster +
pFcb->entry.FirstClusterHigh * 65536;
/*
- * $Id: dir.c,v 1.23 2002/02/05 21:31:03 hbirr Exp $
+ * $Id: dir.c,v 1.24 2002/03/18 22:37:12 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
&pInfo->ChangeTime);
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
/* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
+ AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
+ DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
pInfo->AllocationSize.QuadPart = AllocSize;
pInfo->FileAttributes = pFcb->entry.Attrib;
&pInfo->ChangeTime);
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
/* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
+ AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
+ DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
pInfo->AllocationSize.QuadPart = AllocSize;
pInfo->FileAttributes = pFcb->entry.Attrib;
// pInfo->EaSize=;
&pInfo->ChangeTime);
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
/* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
+ AllocSize = ((pFcb->entry.FileSize + DeviceExt->FatInfo.BytesPerCluster - 1) /
+ DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.BytesPerCluster;
pInfo->AllocationSize.QuadPart = AllocSize;
pInfo->FileAttributes = pFcb->entry.Attrib;
// pInfo->EaSize=;
if (!pCcb->DirectorySearchPattern)
{
First = TRUE;
- pCcb->DirectorySearchPattern =
+ pCcb->DirectorySearchPattern =
ExAllocatePool(NonPagedPool, pSearchPattern->Length + sizeof(WCHAR));
if (!pCcb->DirectorySearchPattern)
{
+ ExReleaseResourceLite(&pFcb->MainResource);
return STATUS_INSUFFICIENT_RESOURCES;
}
memcpy(pCcb->DirectorySearchPattern, pSearchPattern->Buffer,
pCcb->DirectorySearchPattern = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
if (!pCcb->DirectorySearchPattern)
{
+ ExReleaseResourceLite(&pFcb->MainResource);
return STATUS_INSUFFICIENT_RESOURCES;
}
pCcb->DirectorySearchPattern[0] = L'*';
pCcb->DirectorySearchPattern[1] = 0;
- }
-
+ }
+
if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED)
{
pCcb->Entry = pCcb->CurrentByteOffset.u.LowPart;
{
RC = STATUS_SUCCESS;
}
- if (IrpContext->Flags & IRPCONTEXT_CANWAIT)
- {
- ExReleaseResourceLite(&pFcb->MainResource);
- }
-
+ ExReleaseResourceLite(&pFcb->MainResource);
return RC;
}
-/* $Id: direntry.c,v 1.5 2001/10/10 22:14:34 hbirr Exp $
+/* $Id: direntry.c,v 1.6 2002/03/18 22:37:12 hbirr Exp $
*
*
* FILE: DirEntry.c
#include "vfat.h"
-#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
- (pDeviceExt)->BytesPerCluster : PAGESIZE)
+#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGESIZE ? \
+ (pDeviceExt)->FatInfo.BytesPerCluster : PAGESIZE)
#define ENTRIES_PER_CACHEPAGE(pDeviceExt) (ENTRIES_PER_SECTOR * \
- (CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->BytesPerSector)))
+ (CACHEPAGESIZE(pDeviceExt) / ((pDeviceExt)->FatInfo.BytesPerSector)))
ULONG
{
ULONG cluster;
- if (pDeviceExt->FatType == FAT32)
+ if (pDeviceExt->FatInfo.FatType == FAT32)
{
cluster = pFatDirEntry->FirstCluster +
pFatDirEntry->FirstClusterHigh * 65536;
-/* $Id: dirwr.c,v 1.23 2002/01/08 00:49:01 dwelch Exp $
+/* $Id: dirwr.c,v 1.24 2002/03/18 22:37:12 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
return FALSE;
}
-/*
- * Copies a file name into a directory slot (long file name entry)
- * and fills trailing slot space with 0xFFFF. This keeps scandisk
- * from complaining.
- */
-static VOID
-FillSlot (slot * Slot, WCHAR * FileName)
-{
- BOOLEAN fill = FALSE;
- WCHAR *src = FileName;
- WCHAR *dst;
- int i;
-
- i = 5;
- dst = Slot->name0_4;
- while (i-- > 0)
- {
- if (fill == FALSE)
- *dst = *src;
- else
- *dst = 0xffff;
-
- if (fill == FALSE && (*src == 0))
- fill = TRUE;
- dst++;
- src++;
- }
-
- i = 6;
- dst = Slot->name5_10;
- while (i-- > 0)
- {
- if (fill == FALSE)
- *dst = *src;
- else
- *dst = 0xffff;
-
- if (fill == FALSE && (*src == 0))
- fill = TRUE;
- dst++;
- src++;
- }
-
- i = 2;
- dst = Slot->name11_12;
- while (i-- > 0)
- {
- if (fill == FALSE)
- *dst = *src;
- else
- *dst = 0xffff;
-
- if (fill == FALSE && (*src == 0))
- fill = TRUE;
- dst++;
- src++;
- }
-}
-
NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
/*
- update an existing FAT entry
-*/
+ * update an existing FAT entry
+ */
{
PVOID Context;
PVOID Buffer;
return status;
}
- Offset.QuadPart = pFcb->dirIndex * sizeof(FATDirEntry);
- if(CcMapData (pDirFcb->FileObject, &Offset, sizeof(FATDirEntry),
- TRUE, &Context, &Buffer))
+ Offset.u.HighPart = 0;
+ Offset.u.LowPart = pFcb->dirIndex * sizeof(FATDirEntry);
+ if (CcMapData (pDirFcb->FileObject, &Offset, sizeof(FATDirEntry),
+ TRUE, &Context, (PVOID*)&Buffer))
{
memcpy(Buffer, &pFcb->entry, sizeof(FATDirEntry));
CcSetDirtyPinnedData(Context, NULL);
}
else
DPRINT1 ("Failed write to \'%S\'.\n", pDirFcb->PathName);
- vfatReleaseFCB(DeviceExt, pDirFcb);
+ vfatReleaseFCB(DeviceExt, pDirFcb);
return STATUS_SUCCESS;
}
+BOOLEAN
+findDirSpace(PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB pDirFcb,
+ ULONG nbSlots,
+ PULONG start)
+{
+/*
+ * try to find contiguous entries frees in directory,
+ * extend a directory if is neccesary
+ */
+ LARGE_INTEGER FileOffset;
+ ULONG i, count, size, nbFree = 0;
+ FATDirEntry* pFatEntry;
+ PVOID Context = NULL;
+ NTSTATUS Status;
+ 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 (Context == NULL || (i % size) == 0)
+ {
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ // FIXME: check return value
+ CcMapData (pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster,
+ TRUE, &Context, (PVOID*)&pFatEntry);
+ FileOffset.u.LowPart += DeviceExt->FatInfo.BytesPerCluster;
+ }
+ if (vfatIsDirEntryEndMarker(pFatEntry))
+ {
+ break;
+ }
+ if (vfatIsDirEntryDeleted(pFatEntry))
+ {
+ nbFree++;
+ }
+ else
+ {
+ nbFree = 0;
+ }
+ if (nbFree == nbSlots)
+ {
+ break;
+ }
+ }
+ if (Context)
+ {
+ CcUnpinData(Context);
+ }
+ if (nbFree == nbSlots)
+ {
+ // found enough contiguous free slots
+ *start = i - nbSlots + 1;
+ }
+ else
+ {
+ *start = i - nbFree;
+ if (*start + nbSlots > count)
+ {
+ CHECKPOINT;
+ // extend the directory
+ if (vfatFCBIsRoot(pDirFcb) && DeviceExt->FatInfo.FatType != FAT32)
+ {
+ // We can't extend a root directory on a FAT12/FAT16 partition
+ return FALSE;
+ }
+ Status = vfatExtendSpace (DeviceExt, pDirFcb->FileObject,
+ pDirFcb->RFCB.FileSize.u.LowPart + DeviceExt->FatInfo.BytesPerCluster);
+ if (!NT_SUCCESS(Status))
+ {
+ return FALSE;
+ }
+ // clear the new dir cluster
+ FileOffset.u.LowPart = pDirFcb->RFCB.FileSize.QuadPart -
+ DeviceExt->FatInfo.BytesPerCluster;
+ CcMapData (pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster,
+ TRUE, &Context, (PVOID*)&pFatEntry);
+ 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),
+ TRUE, &Context, (PVOID*)&pFatEntry);
+ RtlZeroMemory(pFatEntry, sizeof(FATDirEntry));
+ }
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ }
+ DPRINT ("nbSlots %d nbFree %d, entry number %d\n", nbSlots, nbFree, *start);
+ return TRUE;
+}
+
NTSTATUS
addEntry (PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT pFileObject, ULONG RequestedOptions, UCHAR ReqAttr)
+ PFILE_OBJECT pFileObject,
+ ULONG RequestedOptions,
+ UCHAR ReqAttr)
/*
create a new FAT entry
*/
{
WCHAR DirName[MAX_PATH], *FileName, *PathFileName;
VFATFCB FileFcb;
- FATDirEntry FatEntry;
- NTSTATUS status;
- FATDirEntry *pEntry;
+ PVOID Context = NULL;
+ FATDirEntry *pFatEntry, *pEntry;
slot *pSlots;
- ULONG LengthRead, Offset;
- short nbSlots = 0, nbFree = 0, i, j, posCar, NameLen;
- PUCHAR Buffer, Buffer2;
+ short nbSlots = 0, nbFree = 0, j, posCar, NameLen;
+ PUCHAR Buffer;
BOOLEAN needTilde = FALSE, needLong = FALSE;
PVFATFCB newFCB;
ULONG CurrentCluster;
- LARGE_INTEGER SystemTime, LocalTime;
+ LARGE_INTEGER SystemTime, LocalTime, FileOffset;
NTSTATUS Status = STATUS_SUCCESS;
PVFATFCB pDirFcb;
+ ULONG start, size;
+ long i;
PathFileName = pFileObject->FileName.Buffer;
DPRINT ("addEntry: Pathname=%S\n", PathFileName);
//find last \ in PathFileName
posCar = -1;
for (i = 0; PathFileName[i]; i++)
- if (PathFileName[i] == '\\')
+ {
+ if (PathFileName[i] == L'\\')
+ {
posCar = i;
+ }
+ }
if (posCar == -1)
+ {
return STATUS_UNSUCCESSFUL;
+ }
FileName = &PathFileName[posCar + 1];
for (NameLen = 0; FileName[NameLen]; NameLen++);
// extract directory name from pathname
}
nbSlots = (NameLen + 12) / 13 + 1; //nb of entry needed for long name+normal entry
DPRINT ("NameLen= %d, nbSlots =%d\n", NameLen, nbSlots);
- Buffer =
- ExAllocatePool (NonPagedPool, (nbSlots + 1) * sizeof (FATDirEntry));
- memset (Buffer, 0, (nbSlots + 1) * sizeof (FATDirEntry));
+ Buffer = ExAllocatePool (NonPagedPool, nbSlots * sizeof (FATDirEntry));
+ RtlZeroMemory (Buffer, nbSlots * sizeof (FATDirEntry));
pEntry = (FATDirEntry *) (Buffer + (nbSlots - 1) * sizeof (FATDirEntry));
pSlots = (slot *) Buffer;
// create 8.3 name
// find last point in name
posCar = j = 0;
for (i = 0; FileName[i]; i++)
+ {
if (FileName[i] == '.')
{
posCar = i;
if (i == j)
+ {
j++;
+ }
}
+ }
if (!posCar)
+ {
posCar = i;
+ }
if (posCar < j)
{
posCar = i;
needTilde = TRUE;
}
if (posCar > 8)
+ {
needTilde = TRUE;
+ }
//copy 8 characters max
memset (pEntry, ' ', 11);
for (i = 0, j = 0; j < 8 && i < posCar; i++)
else
{
if (FileName[i] == '.')
+ {
needTilde = TRUE;
+ }
else
+ {
pEntry->Filename[j++] = toupper ((char) FileName[i]);
+ }
}
}
//copy extension
if (FileName[posCar])
+ {
for (j = 0, i = posCar + 1; FileName[i] && j < 3; i++)
{
if (vfatIsShortIllegal(FileName[i]))
else
{
if (FileName[i] == '.')
+ {
needTilde = TRUE;
+ }
else
- pEntry->Ext[j++] = toupper ((char) (FileName[i] & 0x7F));
+ {
+ pEntry->Ext[j++] = toupper ((char) (FileName[i] & 0x7F));
+ }
}
}
+ }
if (FileName[i])
+ {
needTilde = TRUE;
+ }
//find good value for tilde
if (needTilde)
{
DPRINT ("searching a good value for tilde\n");
for (posCar = 0; posCar < 8 && pEntry->Filename[posCar] != ' '; posCar++);
if (posCar == 0) // ??????????????????????
+ {
pEntry->Filename[posCar++] = '_';
+ }
posCar += 2;
if (posCar > 8)
+ {
posCar = 8;
+ }
pEntry->Filename[posCar - 2] = '~';
pEntry->Filename[posCar - 1] = '1';
vfat8Dot3ToString (pEntry->Filename, pEntry->Ext, DirName);
{
DirName[posCar-1] = '0' + i;
pEntry->Filename[posCar - 1] = '0' + i;
- status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
- if (!NT_SUCCESS(status))
- break;
+ Status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
}
if (i == 10)
{
posCar++;
if (posCar > 8)
+ {
posCar = 8;
+ }
pEntry->Filename[posCar - 3] = '~';
pEntry->Filename[posCar - 2] = '1';
pEntry->Filename[posCar - 1] = '0';
DirName[posCar - 2] = '0' + i / 10;
pEntry->Filename[posCar - 1] = '0' + i % 10;
pEntry->Filename[posCar - 2] = '0' + i / 10;
- status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
- if (!NT_SUCCESS(status))
- break;
+ Status = FindFile (DeviceExt, &FileFcb, pDirFcb, DirName, NULL, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
}
if (i == 100) //FIXME : what to do after 99 tilde ?
- {
- vfatReleaseFCB(DeviceExt, pDirFcb);
- ExFreePool (Buffer);
- return STATUS_UNSUCCESSFUL;
- }
+ {
+ vfatReleaseFCB(DeviceExt, pDirFcb);
+ ExFreePool (Buffer);
+ return STATUS_UNSUCCESSFUL;
+ }
}
}
else
{
DPRINT ("check if long name entry needed, needlong=%d\n", needLong);
for (i = 0; i < posCar; i++)
- if ((USHORT) pEntry->Filename[i] != FileName[i])
- {
- DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
- needLong = TRUE;
- }
- if (FileName[i])
- {
- i++; //jump on point char
- for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
- if ((USHORT) pEntry->Ext[j++] != FileName[i])
- {
- DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i],
- FileName[i]);
+ {
+ if ((USHORT) pEntry->Filename[i] != FileName[i])
+ {
+ DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
needLong = TRUE;
}
}
+ if (FileName[i])
+ {
+ i++; //jump on point char
+ for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
+ {
+ if ((USHORT) pEntry->Ext[j++] != FileName[i])
+ {
+ DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i],
+ FileName[i]);
+ needLong = TRUE;
+ }
+ }
+ }
}
if (needLong == FALSE)
{
/* set attributes */
pEntry->Attrib = ReqAttr;
if (RequestedOptions & FILE_DIRECTORY_FILE)
+ {
pEntry->Attrib |= FILE_ATTRIBUTE_DIRECTORY;
-
+ }
/* set dates and times */
KeQuerySystemTime (&SystemTime);
ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
- FsdFileTimeToDosDateTime ((TIME *) & LocalTime,
- &pEntry->CreationDate, &pEntry->CreationTime);
+ FsdFileTimeToDosDateTime ((TIME *) & LocalTime, &pEntry->CreationDate,
+ &pEntry->CreationTime);
pEntry->UpdateDate = pEntry->CreationDate;
pEntry->UpdateTime = pEntry->CreationTime;
pEntry->AccessDate = pEntry->CreationDate;
// calculate checksum for 8.3 name
for (pSlots[0].alias_checksum = i = 0; i < 11; i++)
- {
- pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
- | ((pSlots[0].alias_checksum & 0xfe) >> 1))
- + pEntry->Filename[i]);
- }
+ {
+ pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
+ | ((pSlots[0].alias_checksum & 0xfe) >> 1))
+ + pEntry->Filename[i]);
+ }
//construct slots and entry
for (i = nbSlots - 2; i >= 0; i--)
+ {
+ DPRINT ("construct slot %d\n", i);
+ pSlots[i].attr = 0xf;
+ if (i)
{
- DPRINT ("construct slot %d\n", i);
- pSlots[i].attr = 0xf;
- if (i)
- pSlots[i].id = nbSlots - i - 1;
- else
- pSlots[i].id = nbSlots - i - 1 + 0x40;
- pSlots[i].alias_checksum = pSlots[0].alias_checksum;
-//FIXME pSlots[i].start=;
- FillSlot (&pSlots[i], FileName + (nbSlots - i - 2) * 13);
+ pSlots[i].id = nbSlots - i - 1;
}
-
- //try to find nbSlots contiguous entries frees in directory
- for (i = 0, status = STATUS_SUCCESS; status == STATUS_SUCCESS; i++)
+ else
{
- status =
- VfatReadFile (DeviceExt, pDirFcb->FileObject,
- &FatEntry, sizeof (FATDirEntry),
- i * sizeof (FATDirEntry), &LengthRead, FALSE);
- if (status == STATUS_END_OF_FILE)
- break;
- if (!NT_SUCCESS (status))
- {
- DPRINT1 ("VfatReadFile failed to read the directory entry\n");
- break;
- }
- if (LengthRead != sizeof (FATDirEntry))
- {
- DPRINT1 ("VfatReadFile did not read a complete directory entry\n");
- break;
- }
- if (vfatIsDirEntryEndMarker(&FatEntry))
- break;
- if (vfatIsDirEntryDeleted(&FatEntry))
- nbFree++;
- else
- nbFree = 0;
-
- if (nbFree == nbSlots)
- break;
+ pSlots[i].id = nbSlots - i - 1 + 0x40;
}
- DPRINT ("nbSlots %d nbFree %d, entry number %d\n", nbSlots, nbFree, i);
+ pSlots[i].alias_checksum = pSlots[0].alias_checksum;
+//FIXME pSlots[i].start=;
+ memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10);
+ memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12);
+ memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4);
+ }
+
+ //try to find nbSlots contiguous entries frees in directory
+ if (!findDirSpace(DeviceExt, pDirFcb, nbSlots, &start))
+ {
+ vfatReleaseFCB(DeviceExt, pDirFcb);
+ ExFreePool (Buffer);
+ return STATUS_DISK_FULL;
+ }
if (RequestedOptions & FILE_DIRECTORY_FILE)
- {
+ {
CurrentCluster = 0xffffffff;
- status = NextCluster (DeviceExt, NULL, 0, &CurrentCluster, TRUE);
- if (CurrentCluster == 0xffffffff || !NT_SUCCESS(status))
+ Status = NextCluster (DeviceExt, NULL, 0, &CurrentCluster, TRUE);
+ if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
{
vfatReleaseFCB(DeviceExt, pDirFcb);
ExFreePool (Buffer);
- if (!NT_SUCCESS(status))
+ if (!NT_SUCCESS(Status))
{
- return status;
+ return Status;
}
return STATUS_DISK_FULL;
}
- // zero the cluster
- Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
- memset (Buffer2, 0, DeviceExt->BytesPerCluster);
- VfatRawWriteCluster (DeviceExt, 0, Buffer2, CurrentCluster, 1);
- ExFreePool (Buffer2);
- if (DeviceExt->FatType == FAT32)
- {
- pEntry->FirstClusterHigh = CurrentCluster >> 16;
- pEntry->FirstCluster = CurrentCluster;
- }
- else
- pEntry->FirstCluster = CurrentCluster;
- }
- if (nbFree == nbSlots)
- { //use old slots
- Offset = (i - nbSlots + 1) * sizeof (FATDirEntry);
- status =
- VfatWriteFile (DeviceExt, pDirFcb->FileObject,
- Buffer, sizeof (FATDirEntry) * nbSlots,
- Offset, FALSE, FALSE);
- DPRINT ("VfatWriteFile() returned: %x\n", status);
+ if (DeviceExt->FatInfo.FatType == FAT32)
+ {
+ pEntry->FirstClusterHigh = CurrentCluster >> 16;
}
+ pEntry->FirstCluster = CurrentCluster;
+ }
+
+ size = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
+ if (start / size == (start + nbSlots - 1) / size)
+ {
+ // one cluster
+ CHECKPOINT;
+ FileOffset.u.HighPart = 0;
+ FileOffset.u.LowPart = start * sizeof(FATDirEntry);
+ CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FATDirEntry),
+ TRUE, &Context, (PVOID*)&pFatEntry);
+ memcpy(pFatEntry, Buffer, nbSlots * sizeof(FATDirEntry));
+ }
else
- { //write at end of directory
- Offset = (i - nbFree) * sizeof (FATDirEntry);
- status =
- VfatWriteFile (DeviceExt, pDirFcb->FileObject,
- Buffer, sizeof (FATDirEntry) * (nbSlots + 1),
- Offset, FALSE, FALSE);
- }
- DPRINT ("write entry offset %d status=%x\n", Offset, status);
- if (!NT_SUCCESS(status))
{
- vfatReleaseFCB (DeviceExt, pDirFcb);
- if (RequestedOptions & FILE_DIRECTORY_FILE)
- {
- // free the reserved cluster
- WriteCluster(DeviceExt, CurrentCluster, 0);
- }
- ExFreePool (Buffer);
- return status;
+ // two clusters
+ CHECKPOINT;
+ FileOffset.u.HighPart = 0;
+ FileOffset.u.LowPart = start * sizeof(FATDirEntry);
+ size = DeviceExt->FatInfo.BytesPerCluster -
+ (start * sizeof(FATDirEntry)) % DeviceExt->FatInfo.BytesPerCluster;
+ CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
+ &Context, (PVOID*)&pFatEntry);
+ memcpy(pFatEntry, Buffer, size);
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ FileOffset.u.LowPart += size;
+ CcMapData (pDirFcb->FileObject, &FileOffset,
+ nbSlots * sizeof(FATDirEntry) - size,
+ TRUE, &Context, (PVOID*)&pFatEntry);
+ memcpy(pFatEntry, (PVOID)Buffer + size, nbSlots * sizeof(FATDirEntry) - size);
}
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
// FEXME: check status
- vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName,
- pEntry, Offset / sizeof(FATDirEntry) + nbSlots-1, &newFCB);
+ vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry,
+ start + nbSlots - 1, &newFCB);
vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
DPRINT ("new : entry=%11.11s\n", pEntry->Filename);
if (RequestedOptions & FILE_DIRECTORY_FILE)
+ {
+ FileOffset.QuadPart = 0;
+ CcMapData (pFileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster, TRUE,
+ &Context, (PVOID*)&pFatEntry);
+ // clear the new directory cluster
+ RtlZeroMemory (pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
+ // create '.' and '..'
+ memcpy (&pFatEntry[0].Attrib, &pEntry->Attrib, sizeof(FATDirEntry) - 11);
+ memcpy (pFatEntry[0].Filename, ". ", 11);
+ memcpy (&pFatEntry[1].Attrib, &pEntry->Attrib, sizeof(FATDirEntry) - 11);
+ memcpy (pFatEntry[1].Filename, ".. ", 11);
+ pFatEntry[1].FirstCluster = pDirFcb->entry.FirstCluster;
+ pFatEntry[1].FirstClusterHigh = pDirFcb->entry.FirstClusterHigh;
+ if (DeviceExt->FatInfo.FatType == FAT32)
+ {
+ if (pFatEntry[1].FirstCluster == (DeviceExt->FatInfo.RootCluster & 0xffff) &&
+ pFatEntry[1].FirstClusterHigh == (DeviceExt->FatInfo.RootCluster >> 16))
+ {
+ pFatEntry[1].FirstCluster = 0;
+ pFatEntry[1].FirstClusterHigh = 0;
+ }
+ }
+ else
{
- // create . and ..
- memcpy (pEntry->Filename, ". ", 11);
- status =
- VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
- 0L, FALSE, FALSE);
- pEntry->FirstCluster = pDirFcb->entry.FirstCluster;
- pEntry->FirstClusterHigh = pDirFcb->entry.FirstClusterHigh;
- memcpy (pEntry->Filename, ".. ", 11);
- if (pEntry->FirstCluster == 1 && DeviceExt->FatType != FAT32)
- pEntry->FirstCluster = 0;
- status =
- VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
- sizeof (FATDirEntry), FALSE, FALSE);
+ if (pFatEntry[1].FirstCluster == 1)
+ {
+ pFatEntry[1].FirstCluster = 0;
+ }
}
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ }
vfatReleaseFCB (DeviceExt, pDirFcb);
ExFreePool (Buffer);
DPRINT ("addentry ok\n");
NTSTATUS
delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
/*
- deleting an existing FAT entry
-*/
+ * deleting an existing FAT entry
+ */
{
VFATFCB Fcb;
PVFATFCB pFcb = NULL, pDirFcb = NULL;
DPRINT ("delEntry PathFileName \'%S\'\n", pFileObject->FileName.Buffer);
- status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb, pFileObject->FileName.Buffer);
+ status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb,
+ pFileObject->FileName.Buffer);
if (pFcb != NULL)
{
vfatReleaseFCB(DeviceExt, pFcb);
if (NT_SUCCESS(status))
{
+ PVOID Context = NULL;
+ LARGE_INTEGER Offset;
+ FATDirEntry* pDirEntry;
DPRINT ("delete entry: %d to %d\n", startEntry, Entry);
+ Offset.u.HighPart = 0;
for (i = startEntry; i <= Entry; i++)
{
- // FIXME: using Cc-functions
- VfatReadFile (DeviceExt, pDirFcb->FileObject, &DirEntry,
- sizeof (FATDirEntry), i * sizeof(FATDirEntry), &Read, FALSE);
- DirEntry.Filename[0] = 0xe5;
- // FIXME: check status
- VfatWriteFile (DeviceExt, pDirFcb->FileObject, &DirEntry,
- sizeof(FATDirEntry), i * sizeof(FATDirEntry), FALSE, FALSE);
+ if (Context == NULL || ((i * sizeof(FATDirEntry)) % PAGESIZE) == 0)
+ {
+ if (Context)
+ {
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ }
+ Offset.u.LowPart = (i * sizeof(FATDirEntry) / PAGESIZE) * PAGESIZE;
+ CcMapData (pDirFcb->FileObject, &Offset, PAGESIZE, TRUE,
+ &Context, (PVOID*)&pDirEntry);
+ }
+ pDirEntry[i % (PAGESIZE / sizeof(FATDirEntry))].Filename[0] = 0xe5;
+ if (i == Entry)
+ {
+ CurrentCluster =
+ vfatDirEntryGetFirstCluster (DeviceExt,
+ &pDirEntry[i % (PAGESIZE / sizeof(FATDirEntry))]);
+ }
}
- CurrentCluster = vfatDirEntryGetFirstCluster (DeviceExt, &DirEntry);
+ if (Context)
+ {
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ }
+
while (CurrentCluster && CurrentCluster != 0xffffffff)
{
GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, FALSE);
CurrentCluster = NextCluster;
}
}
+ vfatReleaseFCB(DeviceExt, pDirFcb);
return status;
}
/*
- * $Id: fat.c,v 1.35 2001/11/20 23:40:26 hbirr Exp $
+ * $Id: fat.c,v 1.36 2002/03/18 22:37:12 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
-#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
- (pDeviceExt)->BytesPerCluster : PAGESIZE)
+#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGESIZE ? \
+ (pDeviceExt)->FatInfo.BytesPerCluster : PAGESIZE)
/* FUNCTIONS ****************************************************************/
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table
*/
{
- PUCHAR CBlock;
+ PUSHORT CBlock;
ULONG FATOffset;
ULONG Entry;
NTSTATUS Status;
*NextCluster = 0;
Offset.QuadPart = 0;
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+ if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
- CBlock = (PUCHAR)BaseAddress;
-
- FATOffset = (CurrentCluster * 12) / 8; /* first byte containing value */
+ CBlock = (PUSHORT)(BaseAddress + (CurrentCluster * 12) / 8);
if ((CurrentCluster % 2) == 0)
{
- Entry = CBlock[FATOffset];
- Entry |= ((CBlock[FATOffset+1] & 0xf)<<8);
+ Entry = *CBlock & 0x0fff;
}
else
{
- Entry = (CBlock[FATOffset] >> 4);
- Entry |= (CBlock[FATOffset+1] << 4);
+ Entry = *CBlock >> 4;
}
// DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff)
ULONG ChunkSize;
PVOID Context = 0;
LARGE_INTEGER Offset;
+ PUSHORT Block;
ChunkSize = CACHEPAGESIZE(DeviceExt);
- FatLength = DeviceExt->NumberOfClusters * 2;
+ FatLength = (DeviceExt->FatInfo.NumberOfClusters +2 ) * 2;
*Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
for (j = 0; j < 2; j++)
{
- for (i = StartCluster * 2; i < FatLength; i += 2)
+ for (i = StartCluster * 2; i < FatLength; i += 2, Block++)
{
if ((i % ChunkSize) == 0 || Context == NULL)
{
{
CcUnpinData(Context);
}
+ CHECKPOINT;
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
+ CHECKPOINT;
+ Block = (PUSHORT)(BaseAddress + i % ChunkSize);
}
- if (*((PUSHORT)(BaseAddress + (i % ChunkSize))) == 0)
+ if (*Block == 0)
{
DPRINT("Found available cluster 0x%x\n", i / 2);
DeviceExt->LastAvailableCluster = *Cluster = i / 2;
}
FatLength = StartCluster * 2;
StartCluster = 2;
+ if (Context != NULL)
+ {
+ CcUnpinData(Context);
+ Context =NULL;
+ }
}
- CcUnpinData(Context);
return(STATUS_DISK_FULL);
}
ULONG FATOffset;
ULONG StartCluster;
ULONG Entry;
- PUCHAR CBlock;
+ PUSHORT CBlock;
ULONG i, j;
PVOID BaseAddress;
NTSTATUS Status;
PVOID Context;
LARGE_INTEGER Offset;
- FatLength = DeviceExt->NumberOfClusters;
+ FatLength = DeviceExt->FatInfo.NumberOfClusters + 2;
*Cluster = 0;
StartCluster = DeviceExt->LastAvailableCluster;
Offset.QuadPart = 0;
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+ if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
{
- DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, DeviceExt->Boot->FATSectors * BLOCKSIZE);
+ DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, DeviceExt->FatInfo.FATSectors * BLOCKSIZE);
return STATUS_UNSUCCESSFUL;
}
- CBlock = (PUCHAR)BaseAddress;
for (j = 0; j < 2; j++)
{
for (i = StartCluster; i < FatLength; i++)
{
- FATOffset = (i * 12) / 8;
+ CBlock = (PUSHORT)(BaseAddress + (i * 12) / 8);
if ((i % 2) == 0)
{
- Entry = CBlock[FATOffset];
- Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
+ Entry = *CBlock & 0xfff;
}
else
{
- Entry = (CBlock[FATOffset] >> 4);
- Entry |= (CBlock[FATOffset + 1] << 4);
+ Entry = *CBlock >> 4;
}
if (Entry == 0)
{
*/
{
ULONG FatLength;
- ULONG i;
+ ULONG StartCluster;
+ ULONG i, j;
NTSTATUS Status;
PVOID BaseAddress;
ULONG ChunkSize;
- PVOID Context = NULL;
+ PVOID Context = 0;
LARGE_INTEGER Offset;
- ULONG StartCluster;
+ PULONG Block;
ChunkSize = CACHEPAGESIZE(DeviceExt);
- FatLength = DeviceExt->NumberOfClusters * 4;
- StartCluster = DeviceExt->LastAvailableCluster;
- if (StartCluster == 0)
- {
- StartCluster = 2;
- }
-
+ FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 4;
*Cluster = 0;
+ StartCluster = DeviceExt->LastAvailableCluster;
- for (i = StartCluster * 4; i < FatLength; i += 4)
+ for (j = 0; j < 2; j++)
{
- if ((i % ChunkSize) == 0 || Context == NULL)
- {
- Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
- if (Context != NULL)
- {
- CcUnpinData(Context);
- }
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+ for (i = StartCluster * 4; i < FatLength; i += 4, Block++)
+ {
+ if ((i % ChunkSize) == 0 || Context == NULL)
{
- DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
- return STATUS_UNSUCCESSFUL;
- }
- }
- if ((*((PULONG)(BaseAddress + (i % ChunkSize))) & 0x0fffffff) == 0)
+ Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
+ if (Context != NULL)
{
- DPRINT("Found available cluster 0x%x\n", i / 4);
- DeviceExt->LastAvailableCluster = *Cluster = i / 4;
- CcUnpinData(Context);
- return(STATUS_SUCCESS);
+ CcUnpinData(Context);
}
- }
- FatLength = StartCluster * 4;
- for (i = 8; i < FatLength; i += 4)
- {
- if ((i % ChunkSize) == 0 || Context == NULL)
+ if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
- Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
- if (Context != NULL)
- {
- CcUnpinData(Context);
+ DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
+ return STATUS_UNSUCCESSFUL;
+ }
+ Block = (PULONG)(BaseAddress + i % ChunkSize);
}
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
+
+ if ((*Block & 0x0fffffff) == 0)
{
- DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
- return STATUS_UNSUCCESSFUL;
+ DPRINT("Found available cluster 0x%x\n", i / 4);
+ DeviceExt->LastAvailableCluster = *Cluster = i / 4;
+ CcUnpinData(Context);
+ return(STATUS_SUCCESS);
}
- }
- if ((*((PULONG)(BaseAddress + (i % ChunkSize))) & 0x0fffffff) == 0)
- {
- DPRINT("Found available cluster 0x%x\n", i / 4);
- DeviceExt->LastAvailableCluster = *Cluster = i / 4;
+ }
+ FatLength = StartCluster * 4;
+ StartCluster = 2;
+ if (Context != NULL)
+ {
CcUnpinData(Context);
- return(STATUS_SUCCESS);
- }
+ Context=NULL;
+ }
}
- CcUnpinData(Context);
return (STATUS_DISK_FULL);
}
NTSTATUS
-FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER Clusters)
+FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free cluster in a FAT12 table
*/
{
ULONG FATOffset;
ULONG Entry;
- PUCHAR CBlock;
+ PVOID BaseAddress;
ULONG ulCount = 0;
ULONG i;
- PVOID BaseAddress;
NTSTATUS Status;
ULONG numberofclusters;
LARGE_INTEGER Offset;
PVOID Context;
+ PUSHORT CBlock;
- ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
Offset.QuadPart = 0;
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+ if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
{
- ExReleaseResourceLite (&DeviceExt->FatResource);
return STATUS_UNSUCCESSFUL;
}
- CBlock = (PUCHAR)BaseAddress;
- numberofclusters = DeviceExt->NumberOfClusters;
+
+ numberofclusters = DeviceExt->FatInfo.NumberOfClusters + 2;
for (i = 2; i < numberofclusters; i++)
{
- FATOffset = (i * 12) / 8;
+ CBlock = (PUSHORT)(BaseAddress + (i * 12) / 8);
if ((i % 2) == 0)
{
- Entry = CBlock[FATOffset];
- Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
+ Entry = *CBlock & 0x0fff;
}
else
{
- Entry = (CBlock[FATOffset] >> 4);
- Entry |= (CBlock[FATOffset + 1] << 4);
+ Entry = *CBlock >> 4;
}
if (Entry == 0)
ulCount++;
}
CcUnpinData(Context);
- ExReleaseResourceLite (&DeviceExt->FatResource);
-
- Clusters->QuadPart = ulCount;
+ DeviceExt->AvailableClusters = ulCount;
+ DeviceExt->AvailableClustersValid = TRUE;
return(STATUS_SUCCESS);
}
NTSTATUS
-FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER Clusters)
+FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT16 table
*/
{
PUSHORT Block;
+ PVOID BaseAddress = NULL;
ULONG ulCount = 0;
ULONG i;
- ULONG numberofclusters;
- ULONG numberofsectors;
- ULONG sector;
- ULONG forto;
+ ULONG ChunkSize;
NTSTATUS Status;
+ PVOID Context = NULL;
+ LARGE_INTEGER Offset;
+ ULONG FatLength;
- ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
- Block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
-
- numberofclusters = ((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2;
- numberofsectors = (numberofclusters + 255) / 256;
- numberofclusters %= 256;
+ ChunkSize = CACHEPAGESIZE(DeviceExt);
+ FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 2;
- for (sector = 0; sector < numberofsectors; sector++)
+ for (i = 4; i< FatLength; i += 2, Block++)
+ {
+ if ((i % ChunkSize) == 0 || Context == NULL)
{
- Status = VfatReadSectors(DeviceExt->StorageDevice,
- DeviceExt->FATStart + sector,
- 1,
- (PUCHAR)Block);
- if (!NT_SUCCESS(Status))
+ DPRINT("%d\n", i/2);
+ if (Context)
{
- ExFreePool(Block);
- ExReleaseResourceLite(&DeviceExt->FatResource);
- return(Status);
+ CcUnpinData(Context);
}
-
- if (sector == numberofsectors - 1)
- forto = numberofclusters;
- else
- forto = 256;
-
- for (i = 0; i < forto; i++)
+ Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
+ if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
- if (Block[i] == 0)
+ return STATUS_UNSUCCESSFUL;
+ }
+ Block = (PUSHORT)(BaseAddress + i % ChunkSize);
+ }
+ if (*Block == 0)
ulCount++;
}
- }
- ExReleaseResourceLite (&DeviceExt->FatResource);
- Clusters->QuadPart = ulCount;
- ExFreePool(Block);
+ DeviceExt->AvailableClusters = ulCount;
+ DeviceExt->AvailableClustersValid = TRUE;
+ CcUnpinData(Context);
return(STATUS_SUCCESS);
}
NTSTATUS
-FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER Clusters)
+FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT32 table
*/
{
- ULONG sector;
PULONG Block;
+ PVOID BaseAddress = NULL;
ULONG ulCount = 0;
- ULONG i,forto;
- ULONG numberofclusters;
- ULONG numberofsectors;
+ ULONG i;
+ ULONG ChunkSize;
NTSTATUS Status;
+ PVOID Context = NULL;
+ LARGE_INTEGER Offset;
+ ULONG FatLength;
- ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
-
- Block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
-
- numberofclusters = ((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2;
- numberofsectors = (numberofclusters +127) / 128;
- numberofclusters %= 128;
+ ChunkSize = CACHEPAGESIZE(DeviceExt);
+ FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 4;
- for (sector = 0; sector < numberofsectors; sector++)
- {
- Status = VfatReadSectors(DeviceExt->StorageDevice,
- (ULONG) (DeviceExt->FATStart + sector), 1,
- (UCHAR *) Block);
- if (!NT_SUCCESS(Status))
+ for (i = 8; i< FatLength; i += 4, Block++)
+ {
+ if ((i % ChunkSize) == 0 || Context == NULL)
+ {
+ if (Context)
{
- ExFreePool(Block);
- ExReleaseResourceLite(&DeviceExt->FatResource);
- return(Status);
+ CcUnpinData(Context);
}
-
- if (sector == numberofsectors - 1)
- forto=numberofclusters;
- else
- forto=128;
- for (i = 0; i < forto; i++)
+ Offset.QuadPart = ROUND_DOWN(i, ChunkSize);
+ if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
- if ((Block[i] & 0x0fffffff) == 0)
- ulCount++;
+ return STATUS_UNSUCCESSFUL;
}
- }
- ExFreePool (Block);
- ExReleaseResourceLite (&DeviceExt->FatResource);
+ Block = (PULONG)(BaseAddress + i % ChunkSize);
+ }
+ if ((*Block & 0x0fffffff) == 0)
+ ulCount++;
+ }
- Clusters->QuadPart = ulCount;
+ DeviceExt->AvailableClusters = ulCount;
+ DeviceExt->AvailableClustersValid = TRUE;
+ CcUnpinData(Context);
return(STATUS_SUCCESS);
}
+NTSTATUS
+CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
+ PLARGE_INTEGER Clusters)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
+ if (!DeviceExt->AvailableClustersValid)
+ {
+ if (DeviceExt->FatInfo.FatType == FAT12)
+ Status = FAT12CountAvailableClusters(DeviceExt);
+ else if (DeviceExt->FatInfo.FatType == FAT16)
+ Status = FAT16CountAvailableClusters(DeviceExt);
+ else
+ Status = FAT32CountAvailableClusters(DeviceExt);
+ }
+ Clusters->QuadPart = DeviceExt->AvailableClusters;
+ ExReleaseResourceLite (&DeviceExt->FatResource);
+
+ return Status;
+}
+
+
+
+
+
NTSTATUS
FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
- ULONG NewValue)
+ ULONG NewValue,
+ PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
*/
LARGE_INTEGER Offset;
Offset.QuadPart = 0;
- if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->Boot->FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
+ if(!CcMapData(DeviceExt->FATFileObject, &Offset, DeviceExt->FatInfo.FATSectors * BLOCKSIZE, 1, &Context, &BaseAddress))
{
return STATUS_UNSUCCESSFUL;
}
NewValue, ClusterToWrite, FATOffset);
if ((ClusterToWrite % 2) == 0)
{
+ *OldValue = CBlock[FATOffset] + ((CBlock[FATOffset + 1] & 0x0f) << 8);
CBlock[FATOffset] = NewValue;
CBlock[FATOffset + 1] &= 0xf0;
CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
}
else
{
+ *OldValue = (CBlock[FATOffset] >> 4) + (CBlock[FATOffset + 1] << 4);
CBlock[FATOffset] &= 0x0f;
CBlock[FATOffset] |= (NewValue & 0xf) << 4;
CBlock[FATOffset + 1] = NewValue >> 4;
NTSTATUS
FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
- ULONG NewValue)
+ ULONG NewValue,
+ PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
*/
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
+ PUSHORT Cluster;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = ClusterToWrite * 2;
}
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
ClusterToWrite);
- *((PUSHORT)(BaseAddress + (FATOffset % ChunkSize))) = NewValue;
+ Cluster = ((PUSHORT)(BaseAddress + (FATOffset % ChunkSize)));
+ *OldValue = *Cluster;
+ *Cluster = NewValue;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
return(STATUS_SUCCESS);
NTSTATUS
FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
- ULONG NewValue)
+ ULONG NewValue,
+ PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT32 physical tables
*/
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
+ PULONG Cluster;
ChunkSize = CACHEPAGESIZE(DeviceExt);
}
DPRINT("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
ClusterToWrite);
- *((PULONG)(BaseAddress + (FATOffset % ChunkSize))) = NewValue & 0x0fffffff;
+ Cluster = ((PULONG)(BaseAddress + (FATOffset % ChunkSize)));
+ *OldValue = *Cluster & 0x0fffffff;
+ *Cluster = (*Cluster & 0xf0000000) | (NewValue & 0x0fffffff);
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
- DPRINT("DeviceExt->Boot->FATSectors %d\n",
- ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32);
return(STATUS_SUCCESS);
}
*/
{
NTSTATUS Status;
-
- if (DeviceExt->FatType == FAT16)
+ ULONG OldValue;
+ ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE);
+ if (DeviceExt->FatInfo.FatType == FAT16)
{
- Status = FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
+ Status = FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
}
- else if (DeviceExt->FatType == FAT32)
+ else if (DeviceExt->FatInfo.FatType == FAT32)
{
- Status = FAT32WriteCluster(DeviceExt, ClusterToWrite, NewValue);
+ Status = FAT32WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
}
else
{
- Status = FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
+ Status = FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue, &OldValue);
}
+ if (DeviceExt->AvailableClustersValid)
+ {
+ if (OldValue && NewValue == 0)
+ InterlockedIncrement(&DeviceExt->AvailableClusters);
+ else if (OldValue == 0 && NewValue)
+ InterlockedDecrement(&DeviceExt->AvailableClusters);
+ }
+ ExReleaseResourceLite(&DeviceExt->FatResource);
return(Status);
}
* device
*/
{
- return DeviceExt->dataStart +
- ((Cluster - 2) * DeviceExt->Boot->SectorsPerCluster);
+ return DeviceExt->FatInfo.dataStart +
+ ((Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
}
NTSTATUS
if (FirstCluster == 1)
{
return VfatReadSectors(DeviceExt->StorageDevice, Cluster,
- DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+ DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
else
{
Sector = ClusterToSector(DeviceExt, Cluster);
return VfatReadSectors(DeviceExt->StorageDevice, Sector,
- DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+ DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
}
if (FirstCluster == 1)
{
Status = VfatWriteSectors(DeviceExt->StorageDevice, Cluster,
- DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+ DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
else
{
Sector = ClusterToSector(DeviceExt, Cluster);
Status = VfatWriteSectors(DeviceExt->StorageDevice, Sector,
- DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
+ DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
return(Status);
}
{
NTSTATUS Status;
-// DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
-// DeviceExt, CurrentCluster);
+ DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
+ DeviceExt, CurrentCluster);
if (!Extend)
{
{
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
}
-
+ CHECKPOINT;
/*
* If the file hasn't any clusters allocated then we need special
* handling
{
ULONG NewCluster;
- if (DeviceExt->FatType == FAT16)
+ if (DeviceExt->FatInfo.FatType == FAT16)
{
+ CHECKPOINT;
Status = FAT16FindAvailableCluster(DeviceExt, &NewCluster);
+ CHECKPOINT;
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&DeviceExt->FatResource);
return(Status);
}
}
- else if (DeviceExt->FatType == FAT32)
+ else if (DeviceExt->FatInfo.FatType == FAT32)
{
Status = FAT32FindAvailableCluster(DeviceExt, &NewCluster);
if (!NT_SUCCESS(Status))
return(STATUS_UNSUCCESSFUL);
}
- if (DeviceExt->FatType == FAT16)
+ if (DeviceExt->FatInfo.FatType == FAT16)
{
Status = Fat16GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
}
- else if (DeviceExt->FatType == FAT32)
+ else if (DeviceExt->FatInfo.FatType == FAT32)
{
Status = Fat32GetNextCluster(DeviceExt, CurrentCluster, NextCluster);
}
/* We are after last existing cluster, we must add one to file */
/* Firstly, find the next available open allocation unit */
- if (DeviceExt->FatType == FAT16)
+ if (DeviceExt->FatInfo.FatType == FAT16)
{
Status = FAT16FindAvailableCluster(DeviceExt, &NewCluster);
if (!NT_SUCCESS(Status))
return(Status);
}
}
- else if (DeviceExt->FatType == FAT32)
+ else if (DeviceExt->FatInfo.FatType == FAT32)
{
Status = FAT32FindAvailableCluster(DeviceExt, &NewCluster);
if (!NT_SUCCESS(Status))
DPRINT("GetNextSector(DeviceExt %x, CurrentSector %x)\n",
DeviceExt,
CurrentSector);
- if (CurrentSector<DeviceExt->dataStart || ((CurrentSector - DeviceExt->dataStart + 1) % DeviceExt -> Boot -> SectorsPerCluster))
+ if (CurrentSector<DeviceExt->FatInfo.dataStart || ((CurrentSector - DeviceExt->FatInfo.dataStart + 1) % DeviceExt->FatInfo.SectorsPerCluster))
/* Basically, if the next sequential sector would be on a cluster border, then we'll need to check in the FAT */
{
(*NextSector)=CurrentSector+1;
}
else
{
- CurrentSector = (CurrentSector - DeviceExt->dataStart) / DeviceExt -> Boot -> SectorsPerCluster + 2;
+ CurrentSector = (CurrentSector - DeviceExt->FatInfo.dataStart) / DeviceExt->FatInfo.SectorsPerCluster + 2;
Status = GetNextCluster(DeviceExt, CurrentSector, NextSector, Extend);
if (!NT_SUCCESS(Status))
-/* $Id: fcb.c,v 1.13 2002/01/15 21:54:51 hbirr Exp $
+/* $Id: fcb.c,v 1.14 2002/03/18 22:37:12 hbirr Exp $
*
*
* FILE: fcb.c
{
NTSTATUS status;
PFILE_OBJECT fileObject;
- ULONG bytesPerCluster;
ULONG fileCacheQuantum;
PVFATCCB newCCB;
fcb->pDevExt = vcb;
- bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
- fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ?
- bytesPerCluster : PAGESIZE;
+ fileCacheQuantum = (vcb->FatInfo.BytesPerCluster >= PAGESIZE) ?
+ vcb->FatInfo.BytesPerCluster : PAGESIZE;
status = CcRosInitializeFileCache (fileObject,
&fcb->RFCB.Bcb,
FCB = vfatNewFCB(L"\\");
memset(FCB->entry.Filename, ' ', 11);
- FCB->entry.FileSize = pVCB->rootDirectorySectors * BLOCKSIZE;
+ FCB->entry.FileSize = pVCB->FatInfo.rootDirectorySectors * BLOCKSIZE;
FCB->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
- if (pVCB->FatType == FAT32)
+ if (pVCB->FatInfo.FatType == FAT32)
{
- CurrentCluster = FirstCluster = ((struct _BootSector32*)(pVCB->Boot))->RootCluster;
+ CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster;
FCB->entry.FirstCluster = FirstCluster & 0xffff;
FCB->entry.FirstClusterHigh = FirstCluster >> 16;
CurrentCluster = FirstCluster;
while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{
- Size += pVCB->BytesPerCluster;
+ Size += pVCB->FatInfo.BytesPerCluster;
Status = NextCluster (pVCB, NULL, FirstCluster, &CurrentCluster, FALSE);
}
}
else
{
FCB->entry.FirstCluster = 1;
- Size = pVCB->rootDirectorySectors * BLOCKSIZE;
+ Size = pVCB->FatInfo.rootDirectorySectors * BLOCKSIZE;
}
FCB->RefCount = 1;
FCB->dirIndex = 0;
FirstCluster = vfatDirEntryGetFirstCluster (vcb, &rcFCB->entry);
if (FirstCluster == 1)
{
- Size = vcb->rootDirectorySectors * BLOCKSIZE;
+ Size = vcb->FatInfo.rootDirectorySectors * BLOCKSIZE;
}
else
{
CurrentCluster = FirstCluster;
while (CurrentCluster != 0xffffffff)
{
- Size += vcb->BytesPerCluster;
+ Size += vcb->FatInfo.BytesPerCluster;
Status = NextCluster (vcb, NULL, FirstCluster, &CurrentCluster, FALSE);
}
}
rcFCB->dirIndex = dirIndex;
rcFCB->RFCB.FileSize.QuadPart = Size;
rcFCB->RFCB.ValidDataLength.QuadPart = Size;
- rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->BytesPerCluster);
+ rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, vcb->FatInfo.BytesPerCluster);
// DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
vfatFCBInitializeCache (vcb, rcFCB);
rcFCB->RefCount++;
if (!(fcb->Flags & FCB_CACHE_INITIALIZED))
{
- ULONG bytesPerCluster;
ULONG fileCacheQuantum;
- bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
- fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ? bytesPerCluster : PAGESIZE;
+ fileCacheQuantum = (vcb->FatInfo.BytesPerCluster >= PAGESIZE) ?
+ vcb->FatInfo.BytesPerCluster : PAGESIZE;
status = CcRosInitializeFileCache (fileObject,
&fcb->RFCB.Bcb,
fileCacheQuantum);
-/* $Id: finfo.c,v 1.11 2001/11/02 22:47:36 hbirr Exp $
+/* $Id: finfo.c,v 1.12 2002/03/18 22:37:12 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
DeviceExtension = DeviceObject->DeviceExtension;
/* PRECONDITION */
assert (DeviceExtension != NULL);
- assert (DeviceExtension->BytesPerCluster != 0);
+ assert (DeviceExtension->FatInfo.BytesPerCluster != 0);
assert (StandardInfo != NULL);
assert (FCB != NULL);
DPRINT ("FsdSetDispositionInformation()\n");
assert (DeviceExt != NULL);
- assert (DeviceExt->BytesPerCluster != 0);
+ assert (DeviceExt->FatInfo.BytesPerCluster != 0);
assert (FCB != NULL);
if (!wcscmp(FCB->PathName, L"\\") || !wcscmp(FCB->ObjectName, L"..")
--- /dev/null
+/* $Id: fsctl.c,v 1.1 2002/03/18 22:37:13 hbirr Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/vfat/fsctl.c
+ * PURPOSE: VFAT Filesystem
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <wchar.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#include "vfat.h"
+
+/* FUNCTIONS ****************************************************************/
+
+#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGESIZE ? \
+ (pDeviceExt)->FatInfo.BytesPerCluster : PAGESIZE)
+
+
+static NTSTATUS
+VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
+ PBOOLEAN RecognizedFS,
+ PFATINFO pFatInfo)
+{
+ NTSTATUS Status;
+ PARTITION_INFORMATION PartitionInfo;
+ DISK_GEOMETRY DiskGeometry;
+ FATINFO FatInfo;
+ ULONG Size;
+ ULONG Sectors;
+ struct _BootSector* Boot;
+
+ *RecognizedFS = FALSE;
+
+ Size = sizeof(DISK_GEOMETRY);
+ Status = VfatBlockDeviceIoControl(DeviceToMount,
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL,
+ 0,
+ &DiskGeometry,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("VfatBlockDeviceIoControl faild (%x)\n", Status);
+ return Status;
+ }
+ if (DiskGeometry.MediaType == FixedMedia)
+ {
+ // We have found a hard disk
+ Size = sizeof(PARTITION_INFORMATION);
+ Status = VfatBlockDeviceIoControl(DeviceToMount,
+ IOCTL_DISK_GET_PARTITION_INFO,
+ NULL,
+ 0,
+ &PartitionInfo,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("VfatBlockDeviceIoControl faild (%x)\n", Status);
+ return Status;
+ }
+#ifdef DBG
+ 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
+ if (PartitionInfo.PartitionType == PTDOS3xPrimary ||
+ PartitionInfo.PartitionType == PTOLDDOS16Bit ||
+ PartitionInfo.PartitionType == PTDos5xPrimary ||
+ PartitionInfo.PartitionType == PTWin95FAT32 ||
+ PartitionInfo.PartitionType == PTWin95FAT32LBA ||
+ PartitionInfo.PartitionType == PTWin95FAT16LBA)
+ {
+ *RecognizedFS = TRUE;
+ }
+ }
+ else if (DiskGeometry.MediaType > Unknown && DiskGeometry.MediaType < RemovableMedia)
+ {
+ *RecognizedFS = TRUE;
+ }
+ if (*RecognizedFS == FALSE)
+ {
+ return STATUS_SUCCESS;
+ }
+ReadSector:
+ Boot = ExAllocatePool(NonPagedPool, BLOCKSIZE);
+ if (Boot == NULL)
+ {
+ *RecognizedFS=FALSE;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ Status = VfatReadSectors(DeviceToMount, 0, 1, (PUCHAR) Boot);
+ if (NT_SUCCESS(Status))
+ {
+ FatInfo.VolumeID = Boot->VolumeID;
+ FatInfo.FATStart = Boot->ReservedSectors;
+ FatInfo.FATCount = Boot->FATCount;
+ FatInfo.FATSectors = Boot->FATSectors ? Boot->FATSectors : ((struct _BootSector32*) Boot)->FATSectors32;
+ FatInfo.BytesPerSector = Boot->BytesPerSector;
+ FatInfo.SectorsPerCluster = Boot->SectorsPerCluster;
+ FatInfo.BytesPerCluster = FatInfo.BytesPerSector * FatInfo.SectorsPerCluster;
+ FatInfo.rootDirectorySectors = ((Boot->RootEntries * 32) + Boot->BytesPerSector - 1) / Boot->BytesPerSector;
+ FatInfo.rootStart = FatInfo.FATStart + FatInfo.FATCount * FatInfo.FATSectors;
+ FatInfo.dataStart = FatInfo.rootStart + FatInfo.rootDirectorySectors;
+ Sectors = Boot->Sectors ? Boot->Sectors : Boot->SectorsHuge;
+ Sectors -= Boot->ReservedSectors + FatInfo.FATCount * FatInfo.FATSectors + FatInfo.rootDirectorySectors;
+ FatInfo.NumberOfClusters = Sectors / Boot->SectorsPerCluster;
+ if (FatInfo.NumberOfClusters < 4085)
+ {
+ DPRINT("FAT12\n");
+ FatInfo.FatType = FAT12;
+ }
+ else if (FatInfo.NumberOfClusters >= 65525)
+ {
+ DPRINT("FAT32\n");
+ FatInfo.FatType = FAT32;
+ FatInfo.RootCluster = ((struct _BootSector32*) Boot)->RootCluster;
+ FatInfo.rootStart = FatInfo.dataStart + ((FatInfo.RootCluster - 2) * FatInfo.SectorsPerCluster);
+ FatInfo.VolumeID = ((struct _BootSector32*) Boot)->VolumeID;
+ }
+ else
+ {
+ DPRINT("FAT16\n");
+ FatInfo.FatType = FAT16;
+ }
+ if (pFatInfo)
+ {
+ *pFatInfo = FatInfo;
+ }
+ }
+ ExFreePool(Boot);
+ return Status;
+}
+
+static NTSTATUS
+VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
+ PDEVICE_OBJECT DeviceToMount)
+/*
+ * FUNCTION: Mounts the device
+ */
+{
+ NTSTATUS Status;
+ BOOLEAN RecognizedFS;
+
+ DPRINT1("Mounting VFAT device...\n");
+
+ Status = VfatHasFileSystem(DeviceToMount, &RecognizedFS, &DeviceExt->FatInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ if (DeviceExt->FatInfo.BytesPerCluster >= PAGESIZE &&
+ (DeviceExt->FatInfo.BytesPerCluster % PAGESIZE) != 0)
+ {
+ DbgPrint("(%s:%d) Invalid cluster size\n", __FILE__, __LINE__);
+ KeBugCheck(0);
+ }
+ else if (DeviceExt->FatInfo.BytesPerCluster < PAGESIZE &&
+ (PAGESIZE % DeviceExt->FatInfo.BytesPerCluster) != 0)
+ {
+ DbgPrint("(%s:%d) Invalid cluster size2\n", __FILE__, __LINE__);
+ KeBugCheck(0);
+ }
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS
+VfatMount (PVFAT_IRP_CONTEXT IrpContext)
+/*
+ * FUNCTION: Mount the filesystem
+ */
+{
+ PDEVICE_OBJECT DeviceObject = NULL;
+ PDEVICE_EXTENSION DeviceExt = NULL;
+ BOOLEAN RecognizedFS;
+ NTSTATUS Status;
+ PVFATFCB Fcb = NULL;
+ PVFATCCB Ccb = NULL;
+ LARGE_INTEGER timeout;
+
+ DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
+
+ assert (IrpContext);
+
+ if (IrpContext->DeviceObject != VfatGlobalData->DeviceObject)
+ {
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ goto ByeBye;
+ }
+
+ Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ goto ByeBye;
+ }
+
+ if (RecognizedFS == FALSE)
+ {
+ DPRINT("VFAT: Unrecognized Volume\n");
+ Status = STATUS_UNRECOGNIZED_VOLUME;
+ goto ByeBye;
+ }
+
+ DPRINT("VFAT: Recognized volume\n");
+ Status = IoCreateDevice(VfatGlobalData->DriverObject,
+ sizeof (DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_FILE_SYSTEM,
+ 0,
+ FALSE,
+ &DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ goto ByeBye;
+ }
+
+ DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
+ DeviceExt = (PVOID) DeviceObject->DeviceExtension;
+ RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION));
+
+ /* use same vpb as device disk */
+ DeviceObject->Vpb = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
+ Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ /* FIXME: delete device object */
+ goto ByeBye;
+ }
+
+#ifdef DBG
+ 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);
+ if (DeviceExt->FatInfo.FatType == FAT32)
+ {
+ DbgPrint("RootCluster: %d\n", DeviceExt->FatInfo.RootCluster);
+ }
+#endif
+ DeviceObject->Vpb->Flags |= VPB_MOUNTED;
+ DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
+
+ DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
+ Fcb = vfatNewFCB(NULL);
+ if (Fcb == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto ByeBye;
+ }
+ Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
+ if (Ccb == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto ByeBye;
+ }
+ memset(Ccb, 0, sizeof (VFATCCB));
+ DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
+ DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB;
+ DeviceExt->FATFileObject->FsContext2 = Ccb;
+ DeviceExt->FATFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
+ DeviceExt->FATFileObject->PrivateCacheMap = NULL;
+ DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
+ Ccb->pFcb = Fcb;
+ Ccb->PtrFileObject = DeviceExt->FATFileObject;
+ Fcb->FileObject = DeviceExt->FATFileObject;
+ Fcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
+
+ Fcb->Flags = FCB_IS_FAT;
+
+ if (DeviceExt->FatInfo.FatType != FAT12)
+ {
+ Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+ Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+ Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->FatInfo.FATSectors * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
+ Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
+ }
+ else
+ {
+ Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+ Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->FatInfo.FATSectors * BLOCKSIZE;
+ Fcb->RFCB.AllocationSize.QuadPart = 2 * PAGESIZE;
+ Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, 2 * PAGESIZE);
+ }
+ if (!NT_SUCCESS (Status))
+ {
+ DbgPrint ("CcRosInitializeFileCache failed\n");
+ goto ByeBye;
+ }
+ DeviceExt->LastAvailableCluster = 0;
+ ExInitializeResourceLite(&DeviceExt->DirResource);
+ ExInitializeResourceLite(&DeviceExt->FatResource);
+
+ KeInitializeSpinLock(&DeviceExt->FcbListLock);
+ InitializeListHead(&DeviceExt->FcbListHead);
+
+ /* read serial number */
+ DeviceObject->Vpb->SerialNumber = DeviceExt->FatInfo.VolumeID;
+
+ /* read volume label */
+ ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
+
+ Status = STATUS_SUCCESS;
+
+ByeBye:
+
+ if (!NT_SUCCESS(Status))
+ {
+ // cleanup
+ if (DeviceExt && DeviceExt->FATFileObject)
+ ObDereferenceObject (DeviceExt->FATFileObject);
+ if (Fcb)
+ ExFreePool(Fcb);
+ if (Ccb)
+ ExFreePool(Ccb);
+ if (DeviceObject)
+ IoDeleteDevice(DeviceObject);
+ }
+ return Status;
+}
+
+NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
+/*
+ * FUNCTION: File system control
+ */
+{
+
+ NTSTATUS Status;
+
+ DPRINT("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
+
+ assert (IrpContext);
+
+ switch (IrpContext->MinorFunction)
+ {
+ case IRP_MN_USER_FS_REQUEST:
+ DPRINT("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+
+ case IRP_MN_MOUNT_VOLUME:
+ Status = VfatMount(IrpContext);
+ break;
+
+ case IRP_MN_VERIFY_VOLUME:
+ DPRINT("VFAT FSC: IRP_MN_VERIFY_VOLUME\n");
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+
+ default:
+ DPRINT("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ IrpContext->Irp->IoStatus.Status = Status;
+ IrpContext->Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+ VfatFreeIrpContext(IrpContext);
+ return (Status);
+}
+
-/* $Id: iface.c,v 1.61 2002/02/08 02:57:09 chorns Exp $
+/* $Id: iface.c,v 1.62 2002/03/18 22:37:12 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* GLOBALS *****************************************************************/
-#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
- (pDeviceExt)->BytesPerCluster : PAGESIZE)
-static PDRIVER_OBJECT VfatDriverObject;
+PVFAT_GLOBAL_DATA VfatGlobalData;
/* FUNCTIONS ****************************************************************/
-static NTSTATUS
-VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
- PBOOLEAN RecognizedFS)
-/*
- * FUNCTION: Tests if the device contains a filesystem that can be mounted
- * by this fsd
- */
-{
- BootSector *Boot;
- NTSTATUS Status;
-
- Boot = ExAllocatePool(NonPagedPool, 512);
-
- Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) Boot);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- DPRINT("Boot->SysType %.5s\n", Boot->SysType);
- if (strncmp(Boot->SysType, "FAT12", 5) == 0 ||
- strncmp(Boot->SysType, "FAT16", 5) == 0 ||
- strncmp(((struct _BootSector32 *) (Boot))->SysType, "FAT32", 5) == 0)
- {
- *RecognizedFS = TRUE;
- }
- else
- {
- *RecognizedFS = FALSE;
- }
-
- ExFreePool(Boot);
-
- return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS
-VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
- PDEVICE_OBJECT DeviceToMount)
-/*
- * FUNCTION: Mounts the device
- */
-{
- NTSTATUS Status;
-
- DPRINT("Mounting VFAT device...");
- DPRINT("DeviceExt %x\n", DeviceExt);
-
- DeviceExt->Boot = ExAllocatePool(NonPagedPool, 512);
-
- Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) DeviceExt->Boot);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- DeviceExt->FATStart = DeviceExt->Boot->ReservedSectors;
- DeviceExt->rootDirectorySectors =
- (DeviceExt->Boot->RootEntries * 32) / DeviceExt->Boot->BytesPerSector;
- DeviceExt->rootStart =
- DeviceExt->FATStart +
- DeviceExt->Boot->FATCount * DeviceExt->Boot->FATSectors;
- DeviceExt->dataStart =
- DeviceExt->rootStart + DeviceExt->rootDirectorySectors;
- DeviceExt->BytesPerSector = DeviceExt->Boot->BytesPerSector;
- DeviceExt->FATEntriesPerSector = DeviceExt->Boot->BytesPerSector / 32;
- DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
- DeviceExt->Boot->BytesPerSector;
-
- if (DeviceExt->BytesPerCluster >= PAGESIZE &&
- (DeviceExt->BytesPerCluster % PAGESIZE) != 0)
- {
- DbgPrint("Invalid cluster size\n");
- KeBugCheck(0);
- }
- else if (DeviceExt->BytesPerCluster < PAGESIZE &&
- (PAGESIZE % DeviceExt->BytesPerCluster) != 0)
- {
- DbgPrint("Invalid cluster size2\n");
- KeBugCheck(0);
- }
-
- if (strncmp (DeviceExt->Boot->SysType, "FAT12", 5) == 0)
- {
- DPRINT("FAT12\n");
- DeviceExt->FatType = FAT12;
- }
- else if (strncmp
- (((struct _BootSector32 *) (DeviceExt->Boot))->SysType, "FAT32",
- 5) == 0)
- {
- DPRINT("FAT32\n");
- DeviceExt->FatType = FAT32;
- DeviceExt->rootDirectorySectors = DeviceExt->Boot->SectorsPerCluster;
- DeviceExt->dataStart = DeviceExt->FATStart + DeviceExt->Boot->FATCount
- * ((struct _BootSector32 *) (DeviceExt->Boot))->FATSectors32;
- DeviceExt->rootStart = ClusterToSector (DeviceExt,
- ((struct _BootSector32 *)(DeviceExt->Boot))->RootCluster);
- }
- else
- {
- DPRINT("FAT16\n");
- DeviceExt->FatType = FAT16;
- }
-
- return(STATUS_SUCCESS);
-}
-
-
-static NTSTATUS
-VfatMount (PVFAT_IRP_CONTEXT IrpContext)
-/*
- * FUNCTION: Mount the filesystem
- */
-{
- PDEVICE_OBJECT DeviceObject = NULL;
- PDEVICE_EXTENSION DeviceExt = NULL;
- BOOLEAN RecognizedFS;
- NTSTATUS Status;
- PVFATFCB Fcb = NULL;
- PVFATCCB Ccb = NULL;
-
- DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
-
- assert (IrpContext);
-
- Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS);
- if (!NT_SUCCESS(Status))
- {
- goto ByeBye;
- }
-
- if (RecognizedFS == FALSE)
- {
- DPRINT("VFAT: Unrecognized Volume\n");
- Status = STATUS_UNRECOGNIZED_VOLUME;
- goto ByeBye;
- }
-
- DPRINT("VFAT: Recognized volume\n");
-
- Status = IoCreateDevice(VfatDriverObject,
- sizeof (DEVICE_EXTENSION),
- NULL,
- FILE_DEVICE_FILE_SYSTEM,
- 0,
- FALSE,
- &DeviceObject);
- if (!NT_SUCCESS(Status))
- {
- goto ByeBye;
- }
-
- DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
- DeviceExt = (PVOID) DeviceObject->DeviceExtension;
- RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION));
-
- /* use same vpb as device disk */
- DeviceObject->Vpb = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
- Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
- if (!NT_SUCCESS(Status))
- {
- /* FIXME: delete device object */
- goto ByeBye;
- }
-
-#ifdef DBG
- DbgPrint("BytesPerSector: %d\n", DeviceExt->Boot->BytesPerSector);
- DbgPrint("SectorsPerCluster: %d\n", DeviceExt->Boot->SectorsPerCluster);
- DbgPrint("ReservedSectors: %d\n", DeviceExt->Boot->ReservedSectors);
- DbgPrint("FATCount: %d\n", DeviceExt->Boot->FATCount);
- DbgPrint("RootEntries: %d\n", DeviceExt->Boot->RootEntries);
- DbgPrint("Sectors: %d\n", DeviceExt->Boot->Sectors);
- DbgPrint("FATSectors: %d\n", DeviceExt->Boot->FATSectors);
- DbgPrint("SectorsPerTrack: %d\n", DeviceExt->Boot->SectorsPerTrack);
- DbgPrint("Heads: %d\n", DeviceExt->Boot->Heads);
- DbgPrint("HiddenSectors: %d\n", DeviceExt->Boot->HiddenSectors);
- DbgPrint("SectorsHuge: %d\n", DeviceExt->Boot->SectorsHuge);
- DbgPrint("RootStart: %d\n", DeviceExt->rootStart);
- DbgPrint("DataStart: %d\n", DeviceExt->dataStart);
- if (DeviceExt->FatType == FAT32)
- {
- DbgPrint("FATSectors32: %d\n",
- ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32);
- DbgPrint("RootCluster: %d\n",
- ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster);
- DbgPrint("FSInfoSector: %d\n",
- ((struct _BootSector32*)(DeviceExt->Boot))->FSInfoSector);
- DbgPrint("BootBackup: %d\n",
- ((struct _BootSector32*)(DeviceExt->Boot))->BootBackup);
- }
-#endif
- DeviceObject->Vpb->Flags |= VPB_MOUNTED;
- DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
-
- DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
- Fcb = vfatNewFCB(NULL);
- if (Fcb == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto ByeBye;
- }
- Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
- if (Ccb == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto ByeBye;
- }
- memset(Ccb, 0, sizeof (VFATCCB));
- DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
- DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB;
- DeviceExt->FATFileObject->FsContext2 = Ccb;
- DeviceExt->FATFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
- Ccb->pFcb = Fcb;
- Ccb->PtrFileObject = DeviceExt->FATFileObject;
- Fcb->FileObject = DeviceExt->FATFileObject;
- Fcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
-
- Fcb->Flags = FCB_IS_FAT;
-
- if (DeviceExt->Boot->Sectors != 0)
- {
- DeviceExt->NumberOfClusters = (DeviceExt->Boot->Sectors - DeviceExt->dataStart)
- / DeviceExt->Boot->SectorsPerCluster + 2;
- }
- else
- {
- DeviceExt->NumberOfClusters = (DeviceExt->Boot->SectorsHuge - DeviceExt->dataStart)
- / DeviceExt->Boot->SectorsPerCluster + 2;
- }
- if (DeviceExt->FatType == FAT32)
- {
- Fcb->RFCB.FileSize.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
- Fcb->RFCB.ValidDataLength.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
- Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
- Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
- }
- else
- {
- if (DeviceExt->FatType == FAT16)
- {
- Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
- Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
- Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->Boot->FATSectors * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
- Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
- }
- else
- {
- Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
- Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
- Fcb->RFCB.AllocationSize.QuadPart = 2 * PAGESIZE;
- Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, 2 * PAGESIZE);
- }
- }
- if (!NT_SUCCESS (Status))
- {
- DbgPrint ("CcRosInitializeFileCache failed\n");
- goto ByeBye;
- }
-
- DeviceExt->LastAvailableCluster = 0;
- ExInitializeResourceLite(&DeviceExt->DirResource);
- ExInitializeResourceLite(&DeviceExt->FatResource);
-
- KeInitializeSpinLock(&DeviceExt->FcbListLock);
- InitializeListHead(&DeviceExt->FcbListHead);
-
- /* read serial number */
- if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
- DeviceObject->Vpb->SerialNumber =
- ((struct _BootSector *) (DeviceExt->Boot))->VolumeID;
- else if (DeviceExt->FatType == FAT32)
- DeviceObject->Vpb->SerialNumber =
- ((struct _BootSector32 *) (DeviceExt->Boot))->VolumeID;
-
- /* read volume label */
- ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
- Status = STATUS_SUCCESS;
-
-ByeBye:
-
- if (!NT_SUCCESS(Status))
- {
- // cleanup
- if (DeviceExt && DeviceExt->FATFileObject)
- ObDereferenceObject (DeviceExt->FATFileObject);
- if (Fcb)
- ExFreePool(Fcb);
- if (Ccb)
- ExFreePool(Ccb);
- if (DeviceObject)
- IoDeleteDevice(DeviceObject);
- }
- return Status;
-}
-
-
-NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
-/*
- * FUNCTION: File system control
- */
-{
-
- NTSTATUS Status;
-
- DPRINT("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
-
- assert (IrpContext);
-
- switch (IrpContext->MinorFunction)
- {
- case IRP_MN_USER_FS_REQUEST:
- DPRINT("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
-
- case IRP_MN_MOUNT_VOLUME:
- Status = VfatMount(IrpContext);
- break;
-
- case IRP_MN_VERIFY_VOLUME:
- DPRINT("VFAT FSC: IRP_MN_VERIFY_VOLUME\n");
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
-
- default:
- DPRINT("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction);
- Status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
-
- IrpContext->Irp->IoStatus.Status = Status;
- IrpContext->Irp->IoStatus.Information = 0;
-
- IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
- return (Status);
-}
-
-
NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT _DriverObject,
+DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
DPRINT("VFAT 0.0.6\n");
- VfatDriverObject = _DriverObject;
-
RtlInitUnicodeString(&DeviceName,
L"\\Device\\Vfat");
- Status = IoCreateDevice(VfatDriverObject,
- 0,
+ Status = IoCreateDevice(DriverObject,
+ sizeof(VFAT_GLOBAL_DATA),
&DeviceName,
- FILE_DEVICE_FILE_SYSTEM,
+ FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
{
return (Status);
}
+ VfatGlobalData = DeviceObject->DeviceExtension;
+ RtlZeroMemory (VfatGlobalData, sizeof(VFAT_GLOBAL_DATA));
+ VfatGlobalData->DriverObject = DriverObject;
+ VfatGlobalData->DeviceObject = DeviceObject;
DeviceObject->Flags = DO_DIRECT_IO;
- VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
- VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
- VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
- VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
- VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
- VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
- VfatBuildRequest;
- VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
- VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
-
- VfatDriverObject->DriverUnload = NULL;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = VfatBuildRequest;
+ DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
+ DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
+
+ DriverObject->DriverUnload = NULL;
IoRegisterFileSystem(DeviceObject);
-
return STATUS_SUCCESS;
}
/* EOF */
+
-# $Id: makefile,v 1.37 2002/01/08 00:49:01 dwelch Exp $
+# $Id: makefile,v 1.38 2002/03/18 22:37:13 hbirr Exp $
PATH_TO_TOP = ../../..
shutdown.o \
string.o \
volume.o \
- misc.o
+ misc.o \
+ fsctl.o
DEP_OBJECTS = $(TARGET_OBJECTS)
-/* $Id: rw.c,v 1.38 2002/01/27 03:25:44 dwelch Exp $
+/* $Id: rw.c,v 1.39 2002/03/18 22:37:13 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
}
if (FirstCluster == 1)
{
- (*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
+ (*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
return(STATUS_SUCCESS);
}
else
if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE)
{
ULONG NCluster;
- ULONG Offset = FileOffset / DeviceExt->BytesPerCluster;
+ ULONG Offset = FileOffset / DeviceExt->FatInfo.BytesPerCluster;
PULONG FatChain;
int i;
if (Fcb->FatChainSize == 0)
if (FirstCluster == 1)
{
/* root of FAT16 or FAT12 */
- *Cluster = DeviceExt->rootStart + FileOffset
- / (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster;
+ *Cluster = DeviceExt->FatInfo.rootStart + FileOffset
+ / (DeviceExt->FatInfo.BytesPerCluster) * DeviceExt->FatInfo.SectorsPerCluster;
return(STATUS_SUCCESS);
}
else
{
CurrentCluster = FirstCluster;
- for (i = 0; i < FileOffset / DeviceExt->BytesPerCluster; i++)
+ for (i = 0; i < FileOffset / DeviceExt->FatInfo.BytesPerCluster; i++)
{
Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster,
Extend);
PVOID BaseAddress = NULL;
NTSTATUS Status;
- if (InternalLength == DeviceExt->BytesPerCluster)
+ if (InternalLength == DeviceExt->FatInfo.BytesPerCluster)
{
Status = VfatRawReadCluster(DeviceExt, FirstCluster,
Destination, *CurrentCluster, 1);
}
else
{
- BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->BytesPerCluster);
+ BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->FatInfo.BytesPerCluster);
if (BaseAddress == NULL)
{
return(STATUS_NO_MEMORY);
/* PRECONDITION */
assert (DeviceExt != NULL);
- assert (DeviceExt->BytesPerCluster != 0);
+ assert (DeviceExt->FatInfo.BytesPerCluster != 0);
assert (FileObject != NULL);
assert (FileObject->FsContext2 != NULL);
}
Status = VfatReadSectors(DeviceExt->StorageDevice,
- DeviceExt->FATStart + ReadOffset / BLOCKSIZE,
+ DeviceExt->FatInfo.FATStart + ReadOffset / BLOCKSIZE,
Length / BLOCKSIZE, Buffer);
if (NT_SUCCESS(Status))
{
if (FirstCluster == 1)
{
/* root directory of FAT12 or FAT16 */
- if (ReadOffset + Length > DeviceExt->rootDirectorySectors * BLOCKSIZE)
+ if (ReadOffset + Length > DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE)
{
- Length = DeviceExt->rootDirectorySectors * BLOCKSIZE - ReadOffset;
+ Length = DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE - ReadOffset;
}
}
Status = OffsetToCluster(DeviceExt,
Fcb,
FirstCluster,
- ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster),
+ ROUND_DOWN(ReadOffset, DeviceExt->FatInfo.BytesPerCluster),
&CurrentCluster,
FALSE);
if (!NT_SUCCESS(Status))
* If the read doesn't begin on a chunk boundary then we need special
* handling
*/
- if ((ReadOffset % DeviceExt->BytesPerCluster) != 0 )
+ if ((ReadOffset % DeviceExt->FatInfo.BytesPerCluster) != 0 )
{
- TempLength = min (Length, DeviceExt->BytesPerCluster -
- (ReadOffset % DeviceExt->BytesPerCluster));
+ TempLength = min (Length, DeviceExt->FatInfo.BytesPerCluster -
+ (ReadOffset % DeviceExt->FatInfo.BytesPerCluster));
Ccb->LastCluster = CurrentCluster;
- Ccb->LastOffset = ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster);
+ Ccb->LastOffset = ROUND_DOWN(ReadOffset, DeviceExt->FatInfo.BytesPerCluster);
Status = VfatReadCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster,
Buffer,
- ReadOffset % DeviceExt->BytesPerCluster,
+ ReadOffset % DeviceExt->FatInfo.BytesPerCluster,
TempLength);
if (NT_SUCCESS(Status))
{
}
}
- while (Length >= DeviceExt->BytesPerCluster &&
+ while (Length >= DeviceExt->FatInfo.BytesPerCluster &&
CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{
StartCluster = CurrentCluster;
do
{
ClusterCount++;
- BytesDone += DeviceExt->BytesPerCluster;
+ BytesDone += DeviceExt->FatInfo.BytesPerCluster;
Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster,
FALSE);
}
while (StartCluster + ClusterCount == CurrentCluster &&
NT_SUCCESS(Status) &&
- Length - BytesDone >= DeviceExt->BytesPerCluster);
+ Length - BytesDone >= DeviceExt->FatInfo.BytesPerCluster);
DPRINT("Count %d, Start %x Next %x\n", ClusterCount, StartCluster,
CurrentCluster);
Ccb->LastCluster = StartCluster + (ClusterCount - 1);
Ccb->LastOffset = ReadOffset +
- (ClusterCount - 1) * DeviceExt->BytesPerCluster;
+ (ClusterCount - 1) * DeviceExt->FatInfo.BytesPerCluster;
Status = VfatRawReadCluster(DeviceExt, FirstCluster, Buffer,
StartCluster, ClusterCount);
if (NT_SUCCESS(Status))
{
- ClusterCount *= DeviceExt->BytesPerCluster;
+ ClusterCount *= DeviceExt->FatInfo.BytesPerCluster;
(*LengthRead) = (*LengthRead) + ClusterCount;
Buffer += ClusterCount;
Length -= ClusterCount;
if (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{
Ccb->LastCluster = CurrentCluster;
- Ccb->LastOffset = ReadOffset + DeviceExt->BytesPerCluster;
+ Ccb->LastOffset = ReadOffset + DeviceExt->FatInfo.BytesPerCluster;
Status = VfatReadCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster,
Buffer, 0, Length);
NTSTATUS
VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
- ULONG StartOffset,
- ULONG FirstCluster,
- PULONG CurrentCluster,
- PVOID Source,
- ULONG InternalOffset,
- ULONG InternalLength)
+ ULONG StartOffset,
+ ULONG FirstCluster,
+ PULONG CurrentCluster,
+ PVOID Source,
+ ULONG InternalOffset,
+ ULONG InternalLength)
{
PVOID BaseAddress;
NTSTATUS Status;
- if (InternalLength != DeviceExt->BytesPerCluster)
+ if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
{
- BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->BytesPerCluster);
+ BaseAddress = ExAllocatePool(NonPagedPool, DeviceExt->FatInfo.BytesPerCluster);
if (BaseAddress == NULL)
{
return(STATUS_NO_MEMORY);
}
else
BaseAddress = Source;
- if (InternalLength != DeviceExt->BytesPerCluster)
+ if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
{
/*
* If the data in the cache isn't valid or we are bypassing the
*CurrentCluster, 1);
if (!NT_SUCCESS(Status))
{
- if (InternalLength != DeviceExt->BytesPerCluster)
+ if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
{
ExFreePool(BaseAddress);
}
DPRINT("Writing 0x%x\n", *CurrentCluster);
Status = VfatRawWriteCluster(DeviceExt, FirstCluster, BaseAddress,
*CurrentCluster, 1);
- if (InternalLength != DeviceExt->BytesPerCluster)
+ if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
{
ExFreePool(BaseAddress);
}
Length = (ULONG)Fcb->RFCB.FileSize.QuadPart - WriteOffset;
}
- for (Count = 0; Count < DeviceExt->Boot->FATCount; Count++)
+ for (Count = 0; Count < DeviceExt->FatInfo.FATCount; Count++)
{
Status = VfatWriteSectors(DeviceExt->StorageDevice,
- DeviceExt->FATStart + (Count * (ULONG)Fcb->RFCB.FileSize.QuadPart + WriteOffset) / BLOCKSIZE,
+ DeviceExt->FatInfo.FATStart + (Count * (ULONG)Fcb->RFCB.FileSize.QuadPart + WriteOffset) / BLOCKSIZE,
Length / BLOCKSIZE, Buffer);
if (!NT_SUCCESS(Status))
{
if (FirstCluster == 1)
{
// root directory of FAT12 od FAT16
- if (WriteOffset + Length > DeviceExt->rootDirectorySectors * BLOCKSIZE)
+ if (WriteOffset + Length > DeviceExt->FatInfo.rootDirectorySectors * BLOCKSIZE)
{
DPRINT("Writing over the end of the root directory on FAT12/16\n");
return STATUS_END_OF_FILE;
Status = OffsetToCluster(DeviceExt,
Fcb,
FirstCluster,
- ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster),
+ ROUND_DOWN(WriteOffset, DeviceExt->FatInfo.BytesPerCluster),
&CurrentCluster,
FALSE);
if (!NT_SUCCESS(Status) || CurrentCluster == 0xffffffff)
return(Status);
}
pCcb->LastCluster = CurrentCluster;
- pCcb->LastOffset = ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster);
+ pCcb->LastOffset = ROUND_DOWN(WriteOffset, DeviceExt->FatInfo.BytesPerCluster);
/*
* If the offset in the cluster doesn't fall on the cluster boundary
* then we have to write only from the specified offset
*/
Status = STATUS_SUCCESS;
- if ((WriteOffset % DeviceExt->BytesPerCluster) != 0)
+ if ((WriteOffset % DeviceExt->FatInfo.BytesPerCluster) != 0)
{
- TempLength = min (Length, DeviceExt->BytesPerCluster - (WriteOffset % DeviceExt->BytesPerCluster));
+ TempLength = min (Length, DeviceExt->FatInfo.BytesPerCluster
+ - (WriteOffset % DeviceExt->FatInfo.BytesPerCluster));
Status = VfatWriteCluster(DeviceExt,
Fcb,
- ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster),
+ ROUND_DOWN(WriteOffset, DeviceExt->FatInfo.BytesPerCluster),
FirstCluster,
&CurrentCluster,
Buffer,
- WriteOffset % DeviceExt->BytesPerCluster,
+ WriteOffset % DeviceExt->FatInfo.BytesPerCluster,
TempLength);
if (NT_SUCCESS(Status))
{
}
}
- while (Length >= DeviceExt->BytesPerCluster && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
+ while (Length >= DeviceExt->FatInfo.BytesPerCluster &&
+ CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{
StartCluster = CurrentCluster;
Count = 0;
Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE);
}
while (StartCluster + Count == CurrentCluster && NT_SUCCESS(Status) &&
- Length - Count * DeviceExt->BytesPerCluster >= DeviceExt->BytesPerCluster);
+ Length - Count * DeviceExt->FatInfo.BytesPerCluster >= DeviceExt->FatInfo.BytesPerCluster);
pCcb->LastCluster = StartCluster + (Count - 1);
- pCcb->LastOffset = WriteOffset + (Count - 1) * DeviceExt->BytesPerCluster;
+ pCcb->LastOffset = WriteOffset + (Count - 1) * DeviceExt->FatInfo.BytesPerCluster;
Status = VfatRawWriteCluster(DeviceExt, FirstCluster, Buffer, StartCluster, Count);
if (NT_SUCCESS(Status))
{
- Count *= DeviceExt->BytesPerCluster;
+ Count *= DeviceExt->FatInfo.BytesPerCluster;
Buffer += Count;
Length -= Count;
WriteOffset += Count;
pFcb = ((PVFATCCB) (pFileObject->FsContext2))->pFcb;
DPRINT ("New Size %d, AllocationSize %d, BytesPerCluster %d\n", NewSize,
- (ULONG)pFcb->RFCB.AllocationSize.QuadPart, pDeviceExt->BytesPerCluster);
+ (ULONG)pFcb->RFCB.AllocationSize.QuadPart, pDeviceExt->FatInfo.BytesPerCluster);
FirstCluster = CurrentCluster = vfatDirEntryGetFirstCluster (pDeviceExt, &pFcb->entry);
else
{
Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster,
- pFcb->RFCB.AllocationSize.QuadPart - pDeviceExt->BytesPerCluster,
+ pFcb->RFCB.AllocationSize.QuadPart - pDeviceExt->FatInfo.BytesPerCluster,
&CurrentCluster, FALSE);
if (!NT_SUCCESS(Status))
{
}
Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster,
- ROUND_DOWN(NewSize-1, pDeviceExt->BytesPerCluster),
+ ROUND_DOWN(NewSize-1, pDeviceExt->FatInfo.BytesPerCluster),
&NewCluster, TRUE);
if (!NT_SUCCESS(Status) || NewCluster == 0xffffffff)
{
if (pFcb->RFCB.AllocationSize.QuadPart == 0)
{
pFcb->entry.FirstCluster = FirstCluster;
- if(pDeviceExt->FatType == FAT32)
+ if(pDeviceExt->FatInfo.FatType == FAT32)
pFcb->entry.FirstClusterHigh = FirstCluster >> 16;
}
- pFcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize, pDeviceExt->BytesPerCluster);
+ pFcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize, pDeviceExt->FatInfo.BytesPerCluster);
if (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
{
pFcb->RFCB.FileSize.QuadPart = pFcb->RFCB.AllocationSize.QuadPart;
-/* $Id: vfat.h,v 1.39 2002/02/05 21:31:03 hbirr Exp $ */
+/* $Id: vfat.h,v 1.40 2002/03/18 22:37:13 hbirr Exp $ */
#include <ddk/ntifs.h>
typedef struct _BootSector BootSector;
-struct _FATDirEntry {
+struct _FATDirEntry
+{
unsigned char Filename[8], Ext[3], Attrib, Res[2];
unsigned short CreationTime,CreationDate,AccessDate;
- unsigned short FirstClusterHigh;// higher
- unsigned short UpdateTime;//time create/update
- unsigned short UpdateDate;//date create/update
+ unsigned short FirstClusterHigh; // higher
+ unsigned short UpdateTime; //time create/update
+ unsigned short UpdateDate; //date create/update
unsigned short FirstCluster;
unsigned long FileSize;
} __attribute__((packed));
struct _slot
{
unsigned char id; // sequence number for slot
- WCHAR name0_4[5]; // first 5 characters in name
+ WCHAR name0_4[5]; // first 5 characters in name
unsigned char attr; // attribute byte
unsigned char reserved; // always 0
unsigned char alias_checksum; // checksum for 8.3 alias
- WCHAR name5_10[6]; // 6 more characters in name
+ WCHAR name5_10[6]; // 6 more characters in name
unsigned char start[2]; // starting cluster number
- WCHAR name11_12[2]; // last 2 characters in name
+ WCHAR name11_12[2]; // last 2 characters in name
} __attribute__((packed));
#define FAT12 (2)
#define FAT32 (3)
+#define VCB_VOLUME_LOCKED 0x0001
+#define VCB_DISMOUNT_PENDING 0x0002
+
+typedef struct
+{
+ ULONG VolumeID;
+ ULONG FATStart;
+ ULONG FATCount;
+ ULONG FATSectors;
+ ULONG rootDirectorySectors;
+ ULONG rootStart;
+ ULONG dataStart;
+ ULONG RootCluster;
+ ULONG SectorsPerCluster;
+ ULONG BytesPerSector;
+ ULONG BytesPerCluster;
+ ULONG NumberOfClusters;
+ ULONG FatType;
+}
+FATINFO, *PFATINFO;
+
typedef struct
{
ERESOURCE DirResource;
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT FATFileObject;
- BootSector *Boot;
- int rootDirectorySectors, FATStart, rootStart, dataStart;
- int BytesPerSector;
- int FATEntriesPerSector, FATUnit;
- ULONG BytesPerCluster;
- ULONG FatType;
+ FATINFO FatInfo;
ULONG LastAvailableCluster;
- ULONG NumberOfClusters;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
+ ULONG AvailableClusters;
+ BOOLEAN AvailableClustersValid;
+ ULONG Flags;
+}
+DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
+
+typedef struct
+{
+ PDRIVER_OBJECT DriverObject;
+ PDEVICE_OBJECT DeviceObject;
+ ULONG Flags;
+}
+VFAT_GLOBAL_DATA, *PVFAT_GLOBAL_DATA;
+
+extern PVFAT_GLOBAL_DATA VfatGlobalData;
#define FCB_CACHE_INITIALIZED 0x0001
#define FCB_DELETE_PENDING 0x0002
ULONG dirIndex;
ERESOURCE PagingIoResource;
ERESOURCE MainResource;
+ ULONG TimerCount;
/* Structure members used only for paging files. */
ULONG FatChainSize;
PULONG FatChain;
-} VFATFCB, *PVFATFCB;
+}
+VFATFCB, *PVFATFCB;
typedef struct _VFATCCB
{
ULONG LastCluster;
ULONG LastOffset;
-} VFATCCB, *PVFATCCB;
+}
+VFATCCB, *PVFATCCB;
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
WORD Second:5;
WORD Minute:6;
WORD Hour:5;
-} DOSTIME, *PDOSTIME;
+}
+DOSTIME, *PDOSTIME;
typedef struct __DOSDATE
{
WORD Day:5;
WORD Month:4;
WORD Year:5;
-} DOSDATE, *PDOSDATE;
+}
+DOSDATE, *PDOSDATE;
#define IRPCONTEXT_CANWAIT 0x0001
}
VFAT_IRP_CONTEXT, *PVFAT_IRP_CONTEXT;
+/* ------------------------------------------------------ shutdown.c */
+
+NTSTATUS STDCALL VfatShutdown (PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
+/* -------------------------------------------------------- volume.c */
+
+NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+/* ------------------------------------------------------ blockdev.c */
+
+NTSTATUS VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
+ IN ULONG DiskSector,
+ IN ULONG SectorCount,
+ IN PUCHAR Buffer);
+
+NTSTATUS VfatWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
+ IN ULONG DiskSector,
+ IN ULONG SectorCount,
+ IN PUCHAR Buffer);
+
+NTSTATUS VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG CtlCode,
+ IN PVOID InputBuffer,
+ IN ULONG InputBufferSize,
+ IN OUT PVOID OutputBuffer,
+ IN OUT PULONG pOutputBufferSize);
+
+/* ----------------------------------------------------------- dir.c */
-/* functions called by i/o manager : */
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatRead (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatClose (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT);
-NTSTATUS STDCALL
-VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS VfatQueryVolumeInformation (PVFAT_IRP_CONTEXT);
-NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT);
-
-
-NTSTATUS
-NextCluster(PDEVICE_EXTENSION DeviceExt,
- PVFATFCB Fcb,
- ULONG FirstCluster,
- PULONG CurrentCluster,
- BOOLEAN Extend);
-
-/* internal functions in blockdev.c */
-NTSTATUS
-VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
- IN ULONG DiskSector,
- IN ULONG SectorCount,
- IN UCHAR* Buffer);
-
-NTSTATUS
-VfatWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
- IN ULONG DiskSector,
- IN ULONG SectorCount,
- IN UCHAR* Buffer);
-
-/* internal functions in dir.c : */
-BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime);
-BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime);
-
-/* internal functions in iface.c : */
-NTSTATUS
-FindFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
- PVFATFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
-NTSTATUS
-VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject);
-NTSTATUS
-VfatOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PWSTR FileName);
-NTSTATUS
-VfatReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PVOID Buffer, ULONG Length, ULONG ReadOffset,
- PULONG LengthRead, ULONG NoCache);
-NTSTATUS
-VfatWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
- PVOID Buffer, ULONG Length, ULONG WriteOffset, BOOLEAN NoCache, BOOLEAN PageIo);
-NTSTATUS
-GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG FirstCluster,
- ULONG CurrentCluster,
- PULONG NextCluster);
-BOOLEAN
-IsDeletedEntry(PVOID Block, ULONG Offset);
-BOOLEAN
-IsLastEntry(PVOID Block, ULONG Offset);
-wchar_t*
-vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
-
-/* internal functions in dirwr.c */
-NTSTATUS
-addEntry(PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr);
-NTSTATUS
-updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
-NTSTATUS
-delEntry(PDEVICE_EXTENSION, PFILE_OBJECT);
-/*
- * String functions
- */
-VOID
-vfat_initstr(wchar_t *wstr, ULONG wsize);
-wchar_t*
-vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount);
-wchar_t*
-vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
-wchar_t*
-vfat_movstr(wchar_t *src, ULONG dpos, ULONG spos, ULONG len);
-BOOLEAN
-wstrcmpi(PWSTR s1, PWSTR s2);
-BOOLEAN
-wstrcmpjoki(PWSTR s1, PWSTR s2);
-PWCHAR vfatGetNextPathElement (PWCHAR pFileName);
-void vfatWSubString (PWCHAR pTarget, const PWCHAR pSource, size_t pLength);
+BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
+ WORD wDosTime,
+ TIME *FileTime);
+
+BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
+ WORD *pwDosDate,
+ WORD *pwDosTime);
+
+/* -------------------------------------------------------- create.c */
+
+NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject,
+ PWSTR FileName);
+
+NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB Fcb,
+ PVFATFCB Parent,
+ PWSTR FileToFind,
+ PULONG pDirIndex,
+ PULONG pDirIndex2);
+
+VOID vfat8Dot3ToString (PCHAR pBasename,
+ PCHAR pExtension,
+ PWSTR pName);
+
+NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt,
+ PVPB Vpb);
+
+BOOLEAN IsDeletedEntry (PVOID Block,
+ ULONG Offset);
+
+BOOLEAN IsLastEntry (PVOID Block,
+ ULONG Offset);
+
+/* --------------------------------------------------------- close.c */
+
+NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatCloseFile(PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject);
+
+/* ------------------------------------------------------- cleanup.c */
+
+NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext);
+
+/* --------------------------------------------------------- fsctl.c */
+
+NTSTATUS VfatFileSystemControl (PVFAT_IRP_CONTEXT IrpContext);
+
+/* --------------------------------------------------------- finfo.c */
+
+NTSTATUS VfatQueryInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
+
+/* --------------------------------------------------------- iface.c */
+
+NTSTATUS STDCALL DriverEntry (PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath);
+
+/* --------------------------------------------------------- dirwr.c */
+
+NTSTATUS addEntry (PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT pFileObject,
+ ULONG RequestedOptions,UCHAR ReqAttr);
+
+NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT pFileObject);
+
+NTSTATUS delEntry(PDEVICE_EXTENSION,
+ PFILE_OBJECT);
+
+/* -------------------------------------------------------- string.c */
+
+VOID vfat_initstr (wchar_t *wstr,
+ ULONG wsize);
+
+wchar_t* vfat_wcsncat (wchar_t * dest,
+ const wchar_t * src,
+ size_t wstart,
+ size_t wcount);
+
+wchar_t* vfat_wcsncpy (wchar_t * dest,
+ const wchar_t *src,
+ size_t wcount);
+
+wchar_t* vfat_movstr (wchar_t *src,
+ ULONG dpos,
+ ULONG spos,
+ ULONG len);
+
+BOOLEAN wstrcmpi (PWSTR s1,
+ PWSTR s2);
+
+BOOLEAN wstrcmpjoki (PWSTR s1,
+ PWSTR s2);
+
+PWCHAR vfatGetNextPathElement (PWCHAR pFileName);
+
+VOID vfatWSubString (PWCHAR pTarget,
+ const PWCHAR pSource,
+ size_t pLength);
+
BOOL vfatIsFileNameValid (PWCHAR pFileName);
-/*
- * functions from fat.c
- */
-NTSTATUS
-OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
- PVFATFCB Fcb,
- ULONG FirstCluster,
- ULONG FileOffset,
- PULONG Cluster,
- BOOLEAN Extend);
-ULONG
-ClusterToSector(PDEVICE_EXTENSION DeviceExt,
- ULONG Cluster);
-NTSTATUS
-GetNextCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG CurrentCluster,
- PULONG NextCluster,
- BOOLEAN Extend);
-NTSTATUS
-GetNextSector(PDEVICE_EXTENSION DeviceExt,
- ULONG CurrentSector,
- PULONG NextSector,
- BOOLEAN Extend);
-NTSTATUS
-VfatRawReadCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG FirstCluster,
- PVOID Buffer,
- ULONG Cluster,
- ULONG Count);
-NTSTATUS
-VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG FirstCluster,
- PVOID Buffer,
- ULONG Cluster,
- ULONG Count);
-NTSTATUS
-FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER Clusters);
-NTSTATUS
-FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER Clusters);
-NTSTATUS
-FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt,
- PLARGE_INTEGER Clusters);
-NTSTATUS
-WriteCluster(PDEVICE_EXTENSION DeviceExt,
- ULONG ClusterToWrite,
- ULONG NewValue);
-
-/* --------------------------------------------------------- create.c */
-
-void vfat8Dot3ToString (PCHAR pBasename, PCHAR pExtension, PWSTR pName);
-NTSTATUS
-ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
-NTSTATUS
-VfatOpenFile(PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT FileObject,
- PWSTR FileName);
-
-/* ----------------------------------------------- DirEntry Functions */
+/* ----------------------------------------------------------- fat.c */
+
+NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB Fcb,
+ ULONG FirstCluster,
+ ULONG FileOffset,
+ PULONG Cluster,
+ BOOLEAN Extend);
+
+ULONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
+ ULONG Cluster);
+
+NTSTATUS GetNextCluster (PDEVICE_EXTENSION DeviceExt,
+ ULONG CurrentCluster,
+ PULONG NextCluster,
+ BOOLEAN Extend);
+
+NTSTATUS GetNextSector (PDEVICE_EXTENSION DeviceExt,
+ ULONG CurrentSector,
+ PULONG NextSector,
+ BOOLEAN Extend);
+
+NTSTATUS VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
+ ULONG FirstCluster,
+ PVOID Buffer,
+ ULONG Cluster,
+ ULONG Count);
+
+NTSTATUS VfatRawWriteCluster (PDEVICE_EXTENSION DeviceExt,
+ ULONG FirstCluster,
+ PVOID Buffer,
+ ULONG Cluster,
+ ULONG Count);
+
+NTSTATUS CountAvailableClusters (PDEVICE_EXTENSION DeviceExt,
+ PLARGE_INTEGER Clusters);
+
+/* ------------------------------------------------------ direntry.c */
ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
PFAT_DIR_ENTRY pDirEntry);
+
BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
+
BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
+
BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
-void vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry, PWSTR pEntryName);
+
+VOID vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry,
+ PWSTR pEntryName);
+
NTSTATUS vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
PVFATFCB pDirectoryFCB,
ULONG * pDirectoryIndex,
PWSTR pLongFileName,
PFAT_DIR_ENTRY pDirEntry);
-/* ----------------------------------------------------- FCB Functions */
-
-PVFATFCB vfatNewFCB (PWCHAR pFileName);
-void vfatDestroyFCB (PVFATFCB pFCB);
-void vfatGrabFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB);
-void vfatReleaseFCB (PDEVICE_EXTENSION pVCB, PVFATFCB pFCB);
-void vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
- PVFATFCB pFCB);
-PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
- PWSTR pFileName);
-PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
-PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
-BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB, PVFATFCB FCB);
-NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
- PVFATFCB fcb,
- PFILE_OBJECT fileObject);
-NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
- PVFATFCB parentFCB,
- PWSTR elementName,
- PVFATFCB * fileFCB);
-NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
- PVFATFCB *pParentFCB,
- PVFATFCB *pFCB,
- const PWSTR pFileName);
-NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb,
- PVFATFCB directoryFCB,
- PWSTR longName,
- PFAT_DIR_ENTRY dirEntry,
- ULONG dirIndex,
- PVFATFCB * fileFCB);
-
-/* ------------------------------------------------------------- rw.c */
-
-NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize);
-
-/* ------------------------------------------------------------- misc.c */
+/* ----------------------------------------------------------- fcb.c */
+
+PVFATFCB vfatNewFCB (PWCHAR pFileName);
+
+VOID vfatDestroyFCB (PVFATFCB pFCB);
+
+VOID vfatGrabFCB (PDEVICE_EXTENSION pVCB,
+ PVFATFCB pFCB);
+
+VOID vfatReleaseFCB (PDEVICE_EXTENSION pVCB,
+ PVFATFCB pFCB);
+
+VOID vfatAddFCBToTable (PDEVICE_EXTENSION pVCB,
+ PVFATFCB pFCB);
+
+PVFATFCB vfatGrabFCBFromTable (PDEVICE_EXTENSION pDeviceExt,
+ PWSTR pFileName);
+
+PVFATFCB vfatMakeRootFCB (PDEVICE_EXTENSION pVCB);
+
+PVFATFCB vfatOpenRootFCB (PDEVICE_EXTENSION pVCB);
+
+BOOL vfatFCBIsDirectory (PDEVICE_EXTENSION pVCB,
+ PVFATFCB FCB);
+
+NTSTATUS vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
+ PVFATFCB fcb,
+ PFILE_OBJECT fileObject);
+
+NTSTATUS vfatDirFindFile (PDEVICE_EXTENSION pVCB,
+ PVFATFCB parentFCB,
+ PWSTR elementName,
+ PVFATFCB * fileFCB);
+
+NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
+ PVFATFCB *pParentFCB,
+ PVFATFCB *pFCB,
+ const PWSTR pFileName);
+
+NTSTATUS vfatMakeFCBFromDirEntry (PVCB vcb,
+ PVFATFCB directoryFCB,
+ PWSTR longName,
+ PFAT_DIR_ENTRY dirEntry,
+ ULONG dirIndex,
+ PVFATFCB * fileFCB);
+
+/* ------------------------------------------------------------ rw.c */
+
+NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext);
+
+NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt,
+ PFILE_OBJECT pFileObject,
+ ULONG NewSize);
+/*
+NTSTATUS VfatWriteFile (PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject,
+ PVOID Buffer,
+ ULONG Length,
+ ULONG WriteOffset,
+ BOOLEAN NoCache,
+ BOOLEAN PageIo);
+
+
+NTSTATUS VfatReadFile (PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject,
+ PVOID Buffer, ULONG Length,
+ ULONG ReadOffset,
+ PULONG LengthRead,
+ ULONG NoCache);
+*/
+
+NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB Fcb,
+ ULONG FirstCluster,
+ PULONG CurrentCluster,
+ BOOLEAN Extend);
+
+/* ----------------------------------------------------------- misc.c */
+
NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
-PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
-NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL VfatBuildRequest (PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+/*
+PVOID VfatGetUserBuffer(IN PIRP);
+
+NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
+ IN LOCK_OPERATION);
+*/
+
+/* EOF */
-/* $Id: volume.c,v 1.14 2001/11/02 22:47:36 hbirr Exp $
+/* $Id: volume.c,v 1.15 2002/03/18 22:37:13 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
static NTSTATUS
-FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
+FsdGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
+ PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
PULONG BufferLength)
{
+ ULONG Length = DeviceExt->FatInfo.FatType == FAT32 ? 10 : 6;
+
DPRINT("FsdGetFsAttributeInformation()\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
DPRINT("BufferLength %lu\n", *BufferLength);
- DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6));
+ DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length));
if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
return STATUS_INFO_LENGTH_MISMATCH;
- if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6))
+ if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length))
return STATUS_BUFFER_OVERFLOW;
FsAttributeInfo->FileSystemAttributes =
FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
FsAttributeInfo->MaximumComponentNameLength = 255;
- FsAttributeInfo->FileSystemNameLength = 6;
- wcscpy(FsAttributeInfo->FileSystemName, L"FAT");
+ FsAttributeInfo->FileSystemNameLength = Length;
+ if (DeviceExt->FatInfo.FatType == FAT32)
+ {
+ memcpy(FsAttributeInfo->FileSystemName, L"FAT32", 10);
+ }
+ else
+ {
+ memcpy(FsAttributeInfo->FileSystemName, L"FAT", 6);
+ }
DPRINT("Finished FsdGetFsAttributeInformation()\n");
- *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6);
+ *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length);
DPRINT("BufferLength %lu\n", *BufferLength);
return(STATUS_SUCCESS);
return(STATUS_BUFFER_OVERFLOW);
DeviceExt = DeviceObject->DeviceExtension;
+ Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->AvailableAllocationUnits);
- if (DeviceExt->FatType == FAT32)
- {
- struct _BootSector32 *BootSect =
- (struct _BootSector32 *) DeviceExt->Boot;
-
- FsSizeInfo->TotalAllocationUnits.QuadPart = ((BootSect->Sectors ? BootSect->Sectors : BootSect->SectorsHuge)-DeviceExt->dataStart)/BootSect->SectorsPerCluster;
-
- Status = FAT32CountAvailableClusters(DeviceExt,
- &FsSizeInfo->AvailableAllocationUnits);
-
- FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
- FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
- }
- else
- {
- struct _BootSector *BootSect = (struct _BootSector *) DeviceExt->Boot;
-
- FsSizeInfo->TotalAllocationUnits.QuadPart = ((BootSect->Sectors ? BootSect->Sectors : BootSect->SectorsHuge)-DeviceExt->dataStart)/BootSect->SectorsPerCluster;
-
- if (DeviceExt->FatType == FAT16)
- Status = FAT16CountAvailableClusters(DeviceExt,
- &FsSizeInfo->AvailableAllocationUnits);
- else
- Status = FAT12CountAvailableClusters(DeviceExt,
- &FsSizeInfo->AvailableAllocationUnits);
- FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
- FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
- }
+ FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->FatInfo.NumberOfClusters;
+ FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->FatInfo.SectorsPerCluster;
+ FsSizeInfo->BytesPerSector = DeviceExt->FatInfo.BytesPerSector;
DPRINT("Finished FsdGetFsSizeInformation()\n");
if (NT_SUCCESS(Status))
break;
case FileFsAttributeInformation:
- RC = FsdGetFsAttributeInformation(SystemBuffer,
+ RC = FsdGetFsAttributeInformation(IrpContext->DeviceObject->DeviceExtension,
+ SystemBuffer,
&BufferLength);
break;