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
This commit is contained in:
Hartmut Birr 2002-03-18 22:37:13 +00:00
parent 2c21decf9c
commit d09531b121
14 changed files with 1484 additions and 1195 deletions

View file

@ -141,3 +141,67 @@ VfatWriteSectors (IN PDEVICE_OBJECT pDeviceObject,
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;
}

View file

@ -1,4 +1,4 @@
/* $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
@ -220,80 +220,60 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
* 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;
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);
}
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 : */
/* directory can be fragmented although it is best to keep them
unfragmented.*/
StartingSector++;
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);
pFcb = vfatOpenRootFCB (DeviceExt);
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++;
}
if (Context)
{
CcUnpinData(Context);
}
vfatReleaseFCB (DeviceExt, pFcb);
return STATUS_SUCCESS;
}
NTSTATUS
@ -336,9 +316,9 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
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
@ -351,8 +331,8 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
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;
@ -366,9 +346,9 @@ FindFile (PDEVICE_EXTENSION DeviceExt,
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];
@ -630,7 +610,11 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
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;
@ -694,7 +678,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
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
@ -726,15 +710,15 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
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;

View file

@ -1,5 +1,5 @@
/*
* $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
@ -136,8 +136,8 @@ VfatGetFileDirectoryInformation (PVFATFCB pFcb,
&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;
@ -170,8 +170,8 @@ VfatGetFileFullDirectoryInformation (PVFATFCB pFcb,
&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=;
@ -205,8 +205,8 @@ VfatGetFileBothInformation (PVFATFCB pFcb,
&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=;
@ -255,10 +255,11 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
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,
@ -272,12 +273,13 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
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;
@ -369,11 +371,7 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
{
RC = STATUS_SUCCESS;
}
if (IrpContext->Flags & IRPCONTEXT_CANWAIT)
{
ExReleaseResourceLite(&pFcb->MainResource);
}
ExReleaseResourceLite(&pFcb->MainResource);
return RC;
}

View file

@ -1,4 +1,4 @@
/* $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
@ -20,11 +20,11 @@
#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
@ -33,7 +33,7 @@ vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
{
ULONG cluster;
if (pDeviceExt->FatType == FAT32)
if (pDeviceExt->FatInfo.FatType == FAT32)
{
cluster = pFatDirEntry->FirstCluster +
pFatDirEntry->FirstClusterHigh * 65536;

View file

@ -1,4 +1,4 @@
/* $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
@ -31,69 +31,10 @@ vfatIsShortIllegal(char c)
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;
@ -118,9 +59,10 @@ NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
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);
@ -128,42 +70,147 @@ NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
}
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
@ -186,9 +233,8 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
}
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
@ -196,21 +242,29 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
// 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++)
@ -223,13 +277,18 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
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]))
@ -240,13 +299,20 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
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)
{
@ -254,10 +320,14 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
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);
@ -266,15 +336,19 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
{
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';
@ -286,38 +360,44 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
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)
{
@ -337,150 +417,148 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
/* 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;
}
else
{
pSlots[i].id = nbSlots - i - 1 + 0x40;
}
pSlots[i].alias_checksum = pSlots[0].alias_checksum;
//FIXME pSlots[i].start=;
memcpy (pSlots[i].name0_4, DirName + (nbSlots - i - 2) * 13, 10);
memcpy (pSlots[i].name5_10, DirName + (nbSlots - i - 2) * 13 + 5, 12);
memcpy (pSlots[i].name11_12, DirName + (nbSlots - i - 2) * 13 + 11, 4);
}
//try to find nbSlots contiguous entries frees in directory
for (i = 0, status = STATUS_SUCCESS; status == STATUS_SUCCESS; i++)
{
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;
}
DPRINT ("nbSlots %d nbFree %d, entry number %d\n", nbSlots, nbFree, i);
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);
}
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)
if (DeviceExt->FatInfo.FatType == FAT32)
{
// free the reserved cluster
WriteCluster(DeviceExt, CurrentCluster, 0);
pEntry->FirstClusterHigh = CurrentCluster >> 16;
}
ExFreePool (Buffer);
return status;
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
{
// 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)
{
// 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 == (DeviceExt->FatInfo.RootCluster & 0xffff) &&
pFatEntry[1].FirstClusterHigh == (DeviceExt->FatInfo.RootCluster >> 16))
{
pFatEntry[1].FirstCluster = 0;
pFatEntry[1].FirstClusterHigh = 0;
}
}
else
{
if (pFatEntry[1].FirstCluster == 1)
{
pFatEntry[1].FirstCluster = 0;
}
}
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
}
vfatReleaseFCB (DeviceExt, pDirFcb);
ExFreePool (Buffer);
DPRINT ("addentry ok\n");
@ -490,8 +568,8 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
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;
@ -502,7 +580,8 @@ delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
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);
@ -524,18 +603,38 @@ delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
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);
@ -544,6 +643,7 @@ delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
CurrentCluster = NextCluster;
}
}
vfatReleaseFCB(DeviceExt, pDirFcb);
return status;
}

View file

@ -1,5 +1,5 @@
/*
* $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
@ -24,8 +24,8 @@
#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 ****************************************************************/
@ -98,7 +98,7 @@ Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table
*/
{
PUCHAR CBlock;
PUSHORT CBlock;
ULONG FATOffset;
ULONG Entry;
NTSTATUS Status;
@ -110,22 +110,18 @@ Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt,
*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)
@ -152,15 +148,16 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
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)
{
@ -169,14 +166,17 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
{
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;
@ -186,8 +186,12 @@ FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt,
}
FatLength = StartCluster * 2;
StartCluster = 2;
if (Context != NULL)
{
CcUnpinData(Context);
Context =NULL;
}
}
CcUnpinData(Context);
return(STATUS_DISK_FULL);
}
@ -201,38 +205,35 @@ FAT12FindAvailableCluster(PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
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)
{
@ -256,243 +257,229 @@ FAT32FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
*/
{
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)
for (i = StartCluster * 4; i < FatLength; i += 4, Block++)
{
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))
{
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
Block = (PULONG)(BaseAddress + i % ChunkSize);
}
if ((*Block & 0x0fffffff) == 0)
{
DPRINT("Found available cluster 0x%x\n", i / 4);
DeviceExt->LastAvailableCluster = *Cluster = i / 4;
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
if(!CcMapData(DeviceExt->FATFileObject, &Offset, ChunkSize, 1, &Context, &BaseAddress))
{
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
}
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;
}
}
FatLength = StartCluster * 4;
for (i = 8; i < FatLength; i += 4)
{
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))
{
DPRINT1("CcMapData(Offset %x, Length %d) failed\n", (ULONG)Offset.QuadPart, ChunkSize);
return STATUS_UNSUCCESSFUL;
}
}
if ((*((PULONG)(BaseAddress + (i % ChunkSize))) & 0x0fffffff) == 0)
{
DPRINT("Found available cluster 0x%x\n", i / 4);
DeviceExt->LastAvailableCluster = *Cluster = i / 4;
CcUnpinData(Context);
return(STATUS_SUCCESS);
}
}
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);
ChunkSize = CACHEPAGESIZE(DeviceExt);
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 2;
numberofclusters = ((DeviceExt->Boot->Sectors ? DeviceExt->Boot->Sectors : DeviceExt->Boot->SectorsHuge)-DeviceExt->dataStart)/DeviceExt->Boot->SectorsPerCluster+2;
numberofsectors = (numberofclusters + 255) / 256;
numberofclusters %= 256;
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);
ChunkSize = CACHEPAGESIZE(DeviceExt);
FatLength = (DeviceExt->FatInfo.NumberOfClusters + 2) * 4;
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;
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
*/
@ -507,7 +494,7 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
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;
}
@ -518,12 +505,14 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
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;
@ -538,7 +527,8 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt,
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
*/
@ -550,6 +540,7 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
PUSHORT Cluster;
ChunkSize = CACHEPAGESIZE(DeviceExt);
FATOffset = ClusterToWrite * 2;
@ -560,7 +551,9 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
}
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);
@ -569,7 +562,8 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt,
NTSTATUS
FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ClusterToWrite,
ULONG NewValue)
ULONG NewValue,
PULONG OldValue)
/*
* FUNCTION: Writes a cluster to the FAT32 physical tables
*/
@ -581,6 +575,7 @@ FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt,
ULONG ChunkSize;
PVOID Context;
LARGE_INTEGER Offset;
PULONG Cluster;
ChunkSize = CACHEPAGESIZE(DeviceExt);
@ -592,13 +587,13 @@ FAT32WriteCluster(PDEVICE_EXTENSION 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);
}
@ -612,19 +607,28 @@ WriteCluster(PDEVICE_EXTENSION DeviceExt,
*/
{
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);
}
@ -636,8 +640,8 @@ ClusterToSector(PDEVICE_EXTENSION DeviceExt,
* device
*/
{
return DeviceExt->dataStart +
((Cluster - 2) * DeviceExt->Boot->SectorsPerCluster);
return DeviceExt->FatInfo.dataStart +
((Cluster - 2) * DeviceExt->FatInfo.SectorsPerCluster);
}
NTSTATUS
@ -654,7 +658,7 @@ VfatRawReadCluster(PDEVICE_EXTENSION DeviceExt,
if (FirstCluster == 1)
{
return VfatReadSectors(DeviceExt->StorageDevice, Cluster,
DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
else
{
@ -662,7 +666,7 @@ VfatRawReadCluster(PDEVICE_EXTENSION DeviceExt,
Sector = ClusterToSector(DeviceExt, Cluster);
return VfatReadSectors(DeviceExt->StorageDevice, Sector,
DeviceExt->Boot->SectorsPerCluster * Count, Buffer);
DeviceExt->FatInfo.SectorsPerCluster * Count, Buffer);
}
}
@ -685,14 +689,14 @@ VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt,
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);
}
@ -708,8 +712,8 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
{
NTSTATUS Status;
// DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
// DeviceExt, CurrentCluster);
DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
DeviceExt, CurrentCluster);
if (!Extend)
{
@ -719,7 +723,7 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
{
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
}
CHECKPOINT;
/*
* If the file hasn't any clusters allocated then we need special
* handling
@ -728,16 +732,18 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
{
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))
@ -767,11 +773,11 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
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);
}
@ -785,7 +791,7 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
/* 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))
@ -794,7 +800,7 @@ GetNextCluster(PDEVICE_EXTENSION DeviceExt,
return(Status);
}
}
else if (DeviceExt->FatType == FAT32)
else if (DeviceExt->FatInfo.FatType == FAT32)
{
Status = FAT32FindAvailableCluster(DeviceExt, &NewCluster);
if (!NT_SUCCESS(Status))
@ -839,7 +845,7 @@ GetNextSector(PDEVICE_EXTENSION DeviceExt,
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;
@ -847,7 +853,7 @@ GetNextSector(PDEVICE_EXTENSION DeviceExt,
}
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))

View file

@ -1,4 +1,4 @@
/* $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
@ -156,7 +156,6 @@ vfatFCBInitializeCache (PVCB vcb, PVFATFCB fcb)
{
NTSTATUS status;
PFILE_OBJECT fileObject;
ULONG bytesPerCluster;
ULONG fileCacheQuantum;
PVFATCCB newCCB;
@ -180,9 +179,8 @@ vfatFCBInitializeCache (PVCB vcb, PVFATFCB fcb)
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,
@ -208,25 +206,25 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB)
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;
@ -298,14 +296,14 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
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);
}
}
@ -317,7 +315,7 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
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++;
@ -353,11 +351,10 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
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);

View file

@ -1,4 +1,4 @@
/* $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
@ -37,7 +37,7 @@ VfatGetStandardInformation(PVFATFCB FCB,
DeviceExtension = DeviceObject->DeviceExtension;
/* PRECONDITION */
assert (DeviceExtension != NULL);
assert (DeviceExtension->BytesPerCluster != 0);
assert (DeviceExtension->FatInfo.BytesPerCluster != 0);
assert (StandardInfo != NULL);
assert (FCB != NULL);
@ -143,7 +143,7 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
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"..")

View file

@ -0,0 +1,378 @@
/* $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);
}

View file

@ -1,4 +1,4 @@
/* $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
@ -35,355 +35,13 @@
/* 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
@ -399,14 +57,12 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
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);
@ -414,32 +70,30 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
{
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;
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;
VfatDriverObject->DriverUnload = NULL;
DriverObject->DriverUnload = NULL;
IoRegisterFileSystem(DeviceObject);
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -1,4 +1,4 @@
# $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 = ../../..
@ -22,7 +22,8 @@ TARGET_OBJECTS = \
shutdown.o \
string.o \
volume.o \
misc.o
misc.o \
fsctl.o
DEP_OBJECTS = $(TARGET_OBJECTS)

View file

@ -1,5 +1,5 @@
/* $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
@ -121,7 +121,7 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
}
if (FirstCluster == 1)
{
(*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster;
(*CurrentCluster) += DeviceExt->FatInfo.SectorsPerCluster;
return(STATUS_SUCCESS);
}
else
@ -176,7 +176,7 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
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)
@ -238,14 +238,14 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
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);
@ -271,14 +271,14 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
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);
@ -318,7 +318,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
/* PRECONDITION */
assert (DeviceExt != NULL);
assert (DeviceExt->BytesPerCluster != 0);
assert (DeviceExt->FatInfo.BytesPerCluster != 0);
assert (FileObject != NULL);
assert (FileObject->FsContext2 != NULL);
@ -351,7 +351,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
}
Status = VfatReadSectors(DeviceExt->StorageDevice,
DeviceExt->FATStart + ReadOffset / BLOCKSIZE,
DeviceExt->FatInfo.FATStart + ReadOffset / BLOCKSIZE,
Length / BLOCKSIZE, Buffer);
if (NT_SUCCESS(Status))
{
@ -388,9 +388,9 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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;
}
}
@ -413,7 +413,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Status = OffsetToCluster(DeviceExt,
Fcb,
FirstCluster,
ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster),
ROUND_DOWN(ReadOffset, DeviceExt->FatInfo.BytesPerCluster),
&CurrentCluster,
FALSE);
if (!NT_SUCCESS(Status))
@ -424,15 +424,15 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
* 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))
{
@ -443,7 +443,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
}
}
while (Length >= DeviceExt->BytesPerCluster &&
while (Length >= DeviceExt->FatInfo.BytesPerCluster &&
CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{
StartCluster = CurrentCluster;
@ -453,25 +453,25 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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;
@ -485,7 +485,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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);
@ -500,19 +500,19 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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);
@ -520,7 +520,7 @@ VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
}
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
@ -531,7 +531,7 @@ VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
*CurrentCluster, 1);
if (!NT_SUCCESS(Status))
{
if (InternalLength != DeviceExt->BytesPerCluster)
if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
{
ExFreePool(BaseAddress);
}
@ -545,7 +545,7 @@ VfatWriteCluster(PDEVICE_EXTENSION DeviceExt,
DPRINT("Writing 0x%x\n", *CurrentCluster);
Status = VfatRawWriteCluster(DeviceExt, FirstCluster, BaseAddress,
*CurrentCluster, 1);
if (InternalLength != DeviceExt->BytesPerCluster)
if (InternalLength != DeviceExt->FatInfo.BytesPerCluster)
{
ExFreePool(BaseAddress);
}
@ -611,10 +611,10 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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))
{
@ -639,7 +639,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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;
@ -664,7 +664,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Status = OffsetToCluster(DeviceExt,
Fcb,
FirstCluster,
ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster),
ROUND_DOWN(WriteOffset, DeviceExt->FatInfo.BytesPerCluster),
&CurrentCluster,
FALSE);
if (!NT_SUCCESS(Status) || CurrentCluster == 0xffffffff)
@ -673,23 +673,24 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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))
{
@ -699,7 +700,8 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
}
}
while (Length >= DeviceExt->BytesPerCluster && CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
while (Length >= DeviceExt->FatInfo.BytesPerCluster &&
CurrentCluster != 0xffffffff && NT_SUCCESS(Status))
{
StartCluster = CurrentCluster;
Count = 0;
@ -710,15 +712,15 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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;
@ -796,7 +798,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
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);
@ -817,7 +819,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
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))
{
@ -839,7 +841,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
}
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)
{
@ -864,10 +866,10 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
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;

View file

@ -1,4 +1,4 @@
/* $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>
@ -61,12 +61,13 @@ struct _BootBackupSector
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));
@ -76,13 +77,13 @@ typedef struct _FATDirEntry FATDirEntry, FAT_DIR_ENTRY, *PFAT_DIR_ENTRY;
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));
@ -94,6 +95,27 @@ typedef struct _slot slot;
#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;
@ -104,15 +126,23 @@ typedef struct
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
@ -137,11 +167,13 @@ typedef struct _VFATFCB
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
{
@ -156,7 +188,8 @@ 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))
@ -169,14 +202,16 @@ typedef struct __DOSTIME
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
@ -194,216 +229,299 @@ typedef struct
}
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);
BOOL FsdDosDateTimeToFileTime (WORD wDosDate,
WORD wDosTime,
TIME *FileTime);
NTSTATUS
NextCluster(PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
ULONG FirstCluster,
PULONG CurrentCluster,
BOOLEAN Extend);
BOOL FsdFileTimeToDosDateTime (TIME *FileTime,
WORD *pwDosDate,
WORD *pwDosTime);
/* internal functions in blockdev.c */
NTSTATUS
VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN UCHAR* Buffer);
/* -------------------------------------------------------- create.c */
NTSTATUS
VfatWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN UCHAR* Buffer);
NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext);
/* internal functions in dir.c : */
BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime);
BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime);
NTSTATUS VfatOpenFile (PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PWSTR FileName);
/* 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);
NTSTATUS FindFile (PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
PVFATFCB Parent,
PWSTR FileToFind,
PULONG pDirIndex,
PULONG pDirIndex2);
/* 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);
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);
/*
* 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 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);
/* ----------------------------------------------------------- fat.c */
/* --------------------------------------------------------- create.c */
NTSTATUS OffsetToCluster (PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb,
ULONG FirstCluster,
ULONG FileOffset,
PULONG Cluster,
BOOLEAN Extend);
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);
ULONG ClusterToSector (PDEVICE_EXTENSION DeviceExt,
ULONG Cluster);
/* ----------------------------------------------- DirEntry Functions */
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 */
/* ----------------------------------------------------------- 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);
PVFATFCB vfatNewFCB (PWCHAR pFileName);
/* ------------------------------------------------------------- rw.c */
VOID vfatDestroyFCB (PVFATFCB pFCB);
NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize);
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 */
/* ------------------------------------------------------------- misc.c */
NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext);
PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp);
VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT IrpContext);
NTSTATUS STDCALL VfatBuildRequest (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);
/*
PVOID VfatGetUserBuffer(IN PIRP);
NTSTATUS VfatLockUserBuffer(IN PIRP, IN ULONG,
IN LOCK_OPERATION);
*/
/* EOF */

View file

@ -1,4 +1,4 @@
/* $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
@ -62,29 +62,39 @@ FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
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);
@ -106,35 +116,11 @@ FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
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))
@ -216,7 +202,8 @@ NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
break;
case FileFsAttributeInformation:
RC = FsdGetFsAttributeInformation(SystemBuffer,
RC = FsdGetFsAttributeInformation(IrpContext->DeviceObject->DeviceExtension,
SystemBuffer,
&BufferLength);
break;