mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
- Release streaming file object for directories in vfatReleaseFCB.
- Removed initialization of caching in vfatAttacheFCBToFileObject. The cache for files is initialized at the first read/write operation. - Merged vfatExtendSpace and VfatSetAllocationSizeInformation in one function. svn path=/trunk/; revision=3339
This commit is contained in:
parent
01d5ad9279
commit
6130c02167
6 changed files with 157 additions and 226 deletions
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: create.c,v 1.43 2002/08/14 20:58:31 dwelch Exp $
|
/* $Id: create.c,v 1.44 2002/08/17 15:15:50 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: services/fs/vfat/create.c
|
* FILE: services/fs/vfat/create.c
|
||||||
|
@ -759,7 +759,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
Irp->IoStatus.Information = FILE_CREATED;
|
Irp->IoStatus.Information = FILE_CREATED;
|
||||||
VfatSetAllocationSizeInformation(FileObject,
|
VfatSetAllocationSizeInformation(FileObject,
|
||||||
pFcb,
|
pFcb,
|
||||||
DeviceObject,
|
DeviceExt,
|
||||||
&Irp->Overlay.AllocationSize);
|
&Irp->Overlay.AllocationSize);
|
||||||
VfatSetExtendedAttributes(FileObject,
|
VfatSetExtendedAttributes(FileObject,
|
||||||
Irp->AssociatedIrp.SystemBuffer,
|
Irp->AssociatedIrp.SystemBuffer,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dirwr.c,v 1.27 2002/08/14 20:58:31 dwelch Exp $
|
/* $Id: dirwr.c,v 1.28 2002/08/17 15:15:50 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -135,6 +135,7 @@ findDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||||
*start = i - nbFree;
|
*start = i - nbFree;
|
||||||
if (*start + nbSlots > count)
|
if (*start + nbSlots > count)
|
||||||
{
|
{
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
// extend the directory
|
// extend the directory
|
||||||
if (vfatFCBIsRoot(pDirFcb) && DeviceExt->FatInfo.FatType != FAT32)
|
if (vfatFCBIsRoot(pDirFcb) && DeviceExt->FatInfo.FatType != FAT32)
|
||||||
|
@ -142,8 +143,9 @@ findDirSpace(PDEVICE_EXTENSION DeviceExt,
|
||||||
// We can't extend a root directory on a FAT12/FAT16 partition
|
// We can't extend a root directory on a FAT12/FAT16 partition
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
Status = vfatExtendSpace (DeviceExt, pDirFcb->FileObject,
|
AllocationSize.QuadPart = pDirFcb->RFCB.FileSize.u.LowPart + DeviceExt->FatInfo.BytesPerCluster;
|
||||||
pDirFcb->RFCB.FileSize.u.LowPart + DeviceExt->FatInfo.BytesPerCluster);
|
Status = VfatSetAllocationSizeInformation(pDirFcb->FileObject, pDirFcb,
|
||||||
|
DeviceExt, &AllocationSize);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -488,12 +490,12 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
}
|
}
|
||||||
|
|
||||||
size = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
|
size = DeviceExt->FatInfo.BytesPerCluster / sizeof(FATDirEntry);
|
||||||
|
FileOffset.u.HighPart = 0;
|
||||||
|
FileOffset.u.LowPart = start * sizeof(FATDirEntry);
|
||||||
if (start / size == (start + nbSlots - 1) / size)
|
if (start / size == (start + nbSlots - 1) / size)
|
||||||
{
|
{
|
||||||
// one cluster
|
// one cluster
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
FileOffset.u.HighPart = 0;
|
|
||||||
FileOffset.u.LowPart = start * sizeof(FATDirEntry);
|
|
||||||
CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FATDirEntry),
|
CcMapData (pDirFcb->FileObject, &FileOffset, nbSlots * sizeof(FATDirEntry),
|
||||||
TRUE, &Context, (PVOID*)&pFatEntry);
|
TRUE, &Context, (PVOID*)&pFatEntry);
|
||||||
memcpy(pFatEntry, Buffer, nbSlots * sizeof(FATDirEntry));
|
memcpy(pFatEntry, Buffer, nbSlots * sizeof(FATDirEntry));
|
||||||
|
@ -502,8 +504,6 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
// two clusters
|
// two clusters
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
FileOffset.u.HighPart = 0;
|
|
||||||
FileOffset.u.LowPart = start * sizeof(FATDirEntry);
|
|
||||||
size = DeviceExt->FatInfo.BytesPerCluster -
|
size = DeviceExt->FatInfo.BytesPerCluster -
|
||||||
(start * sizeof(FATDirEntry)) % DeviceExt->FatInfo.BytesPerCluster;
|
(start * sizeof(FATDirEntry)) % DeviceExt->FatInfo.BytesPerCluster;
|
||||||
CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
|
CcMapData (pDirFcb->FileObject, &FileOffset, size, TRUE,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: fcb.c,v 1.17 2002/08/14 20:58:31 dwelch Exp $
|
/* $Id: fcb.c,v 1.18 2002/08/17 15:15:50 hbirr Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* FILE: fcb.c
|
* FILE: fcb.c
|
||||||
|
@ -105,9 +105,18 @@ vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
|
||||||
if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
|
if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
|
||||||
{
|
{
|
||||||
RemoveEntryList (&pFCB->FcbListEntry);
|
RemoveEntryList (&pFCB->FcbListEntry);
|
||||||
|
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||||
|
if (vfatFCBIsDirectory(pVCB, pFCB))
|
||||||
|
{
|
||||||
|
CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb);
|
||||||
|
ExFreePool(pFCB->FileObject->FsContext2);
|
||||||
|
pFCB->FileObject->FsContext2 = NULL;
|
||||||
|
ObDereferenceObject(pFCB->FileObject);
|
||||||
|
}
|
||||||
vfatDestroyFCB (pFCB);
|
vfatDestroyFCB (pFCB);
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
else
|
||||||
|
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -190,7 +199,6 @@ vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb)
|
||||||
KeBugCheck (0);
|
KeBugCheck (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject (fileObject);
|
|
||||||
fcb->Flags |= FCB_CACHE_INITIALIZED;
|
fcb->Flags |= FCB_CACHE_INITIALIZED;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -349,24 +357,6 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
|
||||||
newCCB->pFcb = fcb;
|
newCCB->pFcb = fcb;
|
||||||
newCCB->PtrFileObject = fileObject;
|
newCCB->PtrFileObject = fileObject;
|
||||||
fcb->pDevExt = vcb;
|
fcb->pDevExt = vcb;
|
||||||
|
|
||||||
if (!(fcb->Flags & FCB_CACHE_INITIALIZED))
|
|
||||||
{
|
|
||||||
ULONG fileCacheQuantum;
|
|
||||||
|
|
||||||
fileCacheQuantum = (vcb->FatInfo.BytesPerCluster >= PAGESIZE) ?
|
|
||||||
vcb->FatInfo.BytesPerCluster : PAGESIZE;
|
|
||||||
status = CcRosInitializeFileCache (fileObject,
|
|
||||||
&fcb->RFCB.Bcb,
|
|
||||||
fileCacheQuantum);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
DbgPrint ("CcRosInitializeFileCache failed\n");
|
|
||||||
KeBugCheck (0);
|
|
||||||
}
|
|
||||||
fcb->Flags |= FCB_CACHE_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT ("file open: fcb:%x file size: %d\n", fcb, fcb->entry.FileSize);
|
DPRINT ("file open: fcb:%x file size: %d\n", fcb, fcb->entry.FileSize);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: finfo.c,v 1.16 2002/08/17 14:14:19 dwelch Exp $
|
/* $Id: finfo.c,v 1.17 2002/08/17 15:15:50 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -347,90 +347,130 @@ VfatGetAllInformation(PFILE_OBJECT FileObject,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
||||||
PVFATFCB Fcb,
|
PVFATFCB Fcb,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PLARGE_INTEGER AllocationSize)
|
PLARGE_INTEGER AllocationSize)
|
||||||
{
|
{
|
||||||
ULONG OldSize;
|
ULONG OldSize;
|
||||||
ULONG FirstCluster;
|
|
||||||
ULONG Cluster;
|
ULONG Cluster;
|
||||||
ULONG i;
|
ULONG Offset;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PDEVICE_EXTENSION DeviceExt =
|
|
||||||
(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
||||||
ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
|
ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
|
||||||
ULONG NewSize = AllocationSize->u.LowPart;
|
ULONG NewSize = AllocationSize->u.LowPart;
|
||||||
ULONG PreviousCluster;
|
ULONG NCluster;
|
||||||
|
|
||||||
|
DPRINT1("VfatSetAllocationSizeInformation()\n");
|
||||||
|
|
||||||
OldSize = Fcb->entry.FileSize;
|
OldSize = Fcb->entry.FileSize;
|
||||||
if (OldSize == AllocationSize->u.LowPart)
|
if (AllocationSize->u.HighPart > 0)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
if (OldSize == NewSize)
|
||||||
{
|
{
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
Fcb->entry.FileSize = AllocationSize->u.LowPart;
|
Cluster = vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry);
|
||||||
Fcb->RFCB.AllocationSize = *AllocationSize;
|
|
||||||
Fcb->RFCB.FileSize = *AllocationSize;
|
if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
|
||||||
Fcb->RFCB.ValidDataLength = *AllocationSize;
|
{
|
||||||
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
|
if (Cluster == 0)
|
||||||
|
|
||||||
if (DeviceExt->FatInfo.FatType == FAT32)
|
|
||||||
{
|
{
|
||||||
FirstCluster = Fcb->entry.FirstCluster +
|
Status = NextCluster (DeviceExt, Fcb, Cluster, &Cluster, TRUE);
|
||||||
Fcb->entry.FirstClusterHigh * 65536;
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NextCluster failed.\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
if (Cluster == 0xffffffff)
|
||||||
|
{
|
||||||
|
return STATUS_DISK_FULL;
|
||||||
|
}
|
||||||
|
Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
|
||||||
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
||||||
|
&NCluster, TRUE);
|
||||||
|
if (NCluster == 0xffffffff)
|
||||||
|
{
|
||||||
|
/* disk is full */
|
||||||
|
NCluster = Cluster;
|
||||||
|
while (Cluster != 0xffffffff)
|
||||||
|
{
|
||||||
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
||||||
|
WriteCluster (DeviceExt, Cluster, 0);
|
||||||
|
Cluster = NCluster;
|
||||||
|
}
|
||||||
|
return STATUS_DISK_FULL;
|
||||||
|
}
|
||||||
|
Fcb->entry.FirstCluster = (Cluster & 0x0000FFFF);
|
||||||
|
Fcb->entry.FirstClusterHigh = (Cluster & 0xFFFF0000) >> 16;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
|
||||||
|
Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
|
||||||
|
&Cluster, FALSE);
|
||||||
|
/* Cluster points now to the last cluster within the chain */
|
||||||
|
Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
|
||||||
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
||||||
|
&NCluster, TRUE);
|
||||||
|
if (NCluster == 0xffffffff)
|
||||||
|
{
|
||||||
|
/* disk is full */
|
||||||
|
NCluster = Cluster;
|
||||||
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
||||||
|
WriteCluster(DeviceExt, Cluster, 0xffffffff);
|
||||||
|
Cluster = NCluster;
|
||||||
|
while (Cluster != 0xffffffff)
|
||||||
|
{
|
||||||
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
||||||
|
WriteCluster (DeviceExt, Cluster, 0);
|
||||||
|
Cluster = NCluster;
|
||||||
|
}
|
||||||
|
return STATUS_DISK_FULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (NewSize <= Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize)
|
||||||
|
{
|
||||||
|
if (NewSize > 0)
|
||||||
|
{
|
||||||
|
Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
|
||||||
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
||||||
|
&Cluster, FALSE);
|
||||||
|
}
|
||||||
|
NCluster = Cluster;
|
||||||
|
Status = NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
||||||
|
WriteCluster(DeviceExt, Cluster, 0xffffffff);
|
||||||
|
Cluster = NCluster;
|
||||||
|
while (Cluster != 0xffffffff)
|
||||||
|
{
|
||||||
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
||||||
|
WriteCluster (DeviceExt, Cluster, 0);
|
||||||
|
Cluster = NCluster;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fcb->entry.FileSize = NewSize;
|
||||||
|
if (NewSize > 0)
|
||||||
|
{
|
||||||
|
Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize - 1, ClusterSize);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FirstCluster = Fcb->entry.FirstCluster;
|
Fcb->RFCB.AllocationSize.QuadPart = 0LL;
|
||||||
}
|
Fcb->entry.FirstCluster = 0;
|
||||||
Cluster = FirstCluster;
|
Fcb->entry.FirstClusterHigh = 0;
|
||||||
|
}
|
||||||
if (OldSize > NewSize &&
|
Fcb->RFCB.FileSize.QuadPart = NewSize;
|
||||||
ROUND_UP(OldSize, ClusterSize) > ROUND_DOWN(NewSize, ClusterSize))
|
Fcb->RFCB.ValidDataLength.QuadPart = NewSize;
|
||||||
{
|
|
||||||
/* Seek to the new end of the file. */
|
|
||||||
for (i = 0; i < (NewSize / ClusterSize); i++)
|
|
||||||
{
|
|
||||||
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, FALSE);
|
|
||||||
}
|
|
||||||
/* Terminate the FAT chain at this point. */
|
|
||||||
if (NewSize > 0)
|
|
||||||
{
|
|
||||||
PreviousCluster = Cluster;
|
|
||||||
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, FALSE);
|
|
||||||
WriteCluster (DeviceExt, PreviousCluster, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
/* Free everything beyond this point. */
|
|
||||||
while (Cluster != 0xffffffff && Cluster > 1)
|
|
||||||
{
|
|
||||||
PreviousCluster = Cluster;
|
|
||||||
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, FALSE);
|
|
||||||
WriteCluster (DeviceExt, PreviousCluster, 0);
|
|
||||||
}
|
|
||||||
if (NewSize == 0)
|
|
||||||
{
|
|
||||||
Fcb->entry.FirstCluster = 0;
|
|
||||||
Fcb->entry.FirstClusterHigh = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (NewSize > OldSize &&
|
|
||||||
ROUND_UP(NewSize, ClusterSize) > ROUND_DOWN(OldSize, ClusterSize))
|
|
||||||
{
|
|
||||||
/* Seek to the new end of the file. */
|
|
||||||
if (OldSize == 0)
|
|
||||||
{
|
|
||||||
assert(FirstCluster == 0);
|
|
||||||
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, TRUE);
|
|
||||||
FirstCluster = Cluster;
|
|
||||||
Fcb->entry.FirstCluster = (FirstCluster & 0x0000FFFF) >> 0;
|
|
||||||
Fcb->entry.FirstClusterHigh = (FirstCluster & 0xFFFF0000) >> 16;
|
|
||||||
}
|
|
||||||
for (i = 0; i < (NewSize / ClusterSize); i++)
|
|
||||||
{
|
|
||||||
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (FileObject->SectionObjectPointers->SharedCacheMap != NULL)
|
||||||
|
{
|
||||||
|
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
|
||||||
|
}
|
||||||
|
DPRINT1("\n");
|
||||||
/* Update the on-disk directory entry */
|
/* Update the on-disk directory entry */
|
||||||
VfatUpdateEntry(DeviceExt, FileObject);
|
VfatUpdateEntry(DeviceExt, FileObject);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
|
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
|
@ -591,7 +631,7 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
case FileEndOfFileInformation:
|
case FileEndOfFileInformation:
|
||||||
RC = VfatSetAllocationSizeInformation(IrpContext->FileObject,
|
RC = VfatSetAllocationSizeInformation(IrpContext->FileObject,
|
||||||
FCB,
|
FCB,
|
||||||
IrpContext->DeviceObject,
|
IrpContext->DeviceExt,
|
||||||
(PLARGE_INTEGER)SystemBuffer);
|
(PLARGE_INTEGER)SystemBuffer);
|
||||||
break;
|
break;
|
||||||
case FileBasicInformation:
|
case FileBasicInformation:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
/* $Id: rw.c,v 1.44 2002/08/14 20:58:31 dwelch Exp $
|
/* $Id: rw.c,v 1.45 2002/08/17 15:15:50 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -575,123 +575,6 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize)
|
|
||||||
{
|
|
||||||
ULONG FirstCluster;
|
|
||||||
ULONG CurrentCluster;
|
|
||||||
ULONG NewCluster;
|
|
||||||
NTSTATUS Status;
|
|
||||||
PVFATFCB pFcb;
|
|
||||||
|
|
||||||
|
|
||||||
pFcb = ((PVFATCCB) (pFileObject->FsContext2))->pFcb;
|
|
||||||
|
|
||||||
DPRINT ("New Size %d, AllocationSize %d, BytesPerCluster %d\n", NewSize,
|
|
||||||
(ULONG)pFcb->RFCB.AllocationSize.QuadPart, pDeviceExt->FatInfo.BytesPerCluster);
|
|
||||||
|
|
||||||
FirstCluster = CurrentCluster = vfatDirEntryGetFirstCluster (pDeviceExt, &pFcb->entry);
|
|
||||||
|
|
||||||
if (NewSize > pFcb->RFCB.AllocationSize.QuadPart || FirstCluster==0)
|
|
||||||
{
|
|
||||||
// size on disk must be extended
|
|
||||||
if (FirstCluster == 0)
|
|
||||||
{
|
|
||||||
// file of size zero
|
|
||||||
Status = NextCluster (pDeviceExt, pFcb, FirstCluster, &CurrentCluster, TRUE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("NextCluster failed, Status %x\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
NewCluster = FirstCluster = CurrentCluster;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster,
|
|
||||||
pFcb->RFCB.AllocationSize.QuadPart - pDeviceExt->FatInfo.BytesPerCluster,
|
|
||||||
&CurrentCluster, FALSE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("OffsetToCluster failed, Status %x\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
if (CurrentCluster == 0xffffffff)
|
|
||||||
{
|
|
||||||
DPRINT1("Not enough disk space.\n");
|
|
||||||
return STATUS_DISK_FULL;
|
|
||||||
}
|
|
||||||
// CurrentCluster zeigt jetzt auf den letzten Cluster in der Kette
|
|
||||||
NewCluster = CurrentCluster;
|
|
||||||
Status = NextCluster(pDeviceExt, pFcb, FirstCluster, &NewCluster, FALSE);
|
|
||||||
if (NewCluster != 0xffffffff)
|
|
||||||
{
|
|
||||||
DPRINT1("Difference between size from direntry and the FAT.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster,
|
|
||||||
ROUND_DOWN(NewSize-1, pDeviceExt->FatInfo.BytesPerCluster),
|
|
||||||
&NewCluster, TRUE);
|
|
||||||
if (!NT_SUCCESS(Status) || NewCluster == 0xffffffff)
|
|
||||||
{
|
|
||||||
DPRINT1("Not enough free space on disk\n");
|
|
||||||
if (pFcb->RFCB.AllocationSize.QuadPart > 0)
|
|
||||||
{
|
|
||||||
NewCluster = CurrentCluster;
|
|
||||||
// FIXME: check status
|
|
||||||
NextCluster(pDeviceExt, pFcb, FirstCluster, &NewCluster, FALSE);
|
|
||||||
WriteCluster(pDeviceExt, CurrentCluster, 0xffffffff);
|
|
||||||
}
|
|
||||||
// free the allocated space
|
|
||||||
while (NewCluster != 0xffffffff)
|
|
||||||
{
|
|
||||||
CurrentCluster = NewCluster;
|
|
||||||
// FIXME: check status
|
|
||||||
NextCluster (pDeviceExt, pFcb, FirstCluster, &NewCluster, FALSE);
|
|
||||||
WriteCluster (pDeviceExt, CurrentCluster, 0);
|
|
||||||
}
|
|
||||||
return STATUS_DISK_FULL;
|
|
||||||
}
|
|
||||||
if (pFcb->RFCB.AllocationSize.QuadPart == 0)
|
|
||||||
{
|
|
||||||
pFcb->entry.FirstCluster = FirstCluster;
|
|
||||||
if(pDeviceExt->FatInfo.FatType == FAT32)
|
|
||||||
pFcb->entry.FirstClusterHigh = FirstCluster >> 16;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
pFcb->RFCB.ValidDataLength.QuadPart = pFcb->RFCB.AllocationSize.QuadPart;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pFcb->entry.FileSize = NewSize;
|
|
||||||
pFcb->RFCB.FileSize.QuadPart = NewSize;
|
|
||||||
pFcb->RFCB.ValidDataLength.QuadPart = NewSize;
|
|
||||||
}
|
|
||||||
CcSetFileSizes(pFileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (NewSize > pFcb->RFCB.FileSize.QuadPart)
|
|
||||||
{
|
|
||||||
// size on disk must not be extended
|
|
||||||
if (!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
{
|
|
||||||
pFcb->entry.FileSize = NewSize;
|
|
||||||
}
|
|
||||||
pFcb->RFCB.FileSize.QuadPart = NewSize;
|
|
||||||
CcSetFileSizes(pFileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatRead(PVFAT_IRP_CONTEXT IrpContext)
|
VfatRead(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
{
|
{
|
||||||
|
@ -809,6 +692,16 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
if (IrpContext->FileObject->PrivateCacheMap == NULL)
|
||||||
|
{
|
||||||
|
ULONG CacheSize;
|
||||||
|
CacheSize = IrpContext->DeviceExt->FatInfo.BytesPerCluster;
|
||||||
|
if (CacheSize < PAGESIZE)
|
||||||
|
{
|
||||||
|
CacheSize = PAGESIZE;
|
||||||
|
}
|
||||||
|
CcRosInitializeFileCache(IrpContext->FileObject, &Fcb->RFCB.Bcb, CacheSize);
|
||||||
|
}
|
||||||
if (!CcCopyRead(IrpContext->FileObject, &ByteOffset, Length,
|
if (!CcCopyRead(IrpContext->FileObject, &ByteOffset, Length,
|
||||||
IrpContext->Flags & IRPCONTEXT_CANWAIT, Buffer,
|
IrpContext->Flags & IRPCONTEXT_CANWAIT, Buffer,
|
||||||
&IrpContext->Irp->IoStatus))
|
&IrpContext->Irp->IoStatus))
|
||||||
|
@ -1039,8 +932,10 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
|
|
||||||
if (!(Fcb->Flags & (FCB_IS_FAT|FCB_IS_VOLUME)) && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
|
if (!(Fcb->Flags & (FCB_IS_FAT|FCB_IS_VOLUME)) && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
|
||||||
{
|
{
|
||||||
Status = vfatExtendSpace(IrpContext->DeviceExt, IrpContext->FileObject,
|
LARGE_INTEGER AllocationSize;
|
||||||
ByteOffset.u.LowPart + Length);
|
AllocationSize.QuadPart = ByteOffset.u.LowPart + Length;
|
||||||
|
Status = VfatSetAllocationSizeInformation(IrpContext->FileObject, Fcb,
|
||||||
|
IrpContext->DeviceExt, &AllocationSize);
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
if (!NT_SUCCESS (Status))
|
if (!NT_SUCCESS (Status))
|
||||||
{
|
{
|
||||||
|
@ -1067,7 +962,16 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
if (IrpContext->FileObject->PrivateCacheMap == NULL)
|
||||||
|
{
|
||||||
|
ULONG CacheSize;
|
||||||
|
CacheSize = IrpContext->DeviceExt->FatInfo.BytesPerCluster;
|
||||||
|
if (CacheSize < PAGESIZE)
|
||||||
|
{
|
||||||
|
CacheSize = PAGESIZE;
|
||||||
|
}
|
||||||
|
CcRosInitializeFileCache(IrpContext->FileObject, &Fcb->RFCB.Bcb, CacheSize);
|
||||||
|
}
|
||||||
if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length,
|
if (CcCopyWrite(IrpContext->FileObject, &ByteOffset, Length,
|
||||||
1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer))
|
1 /*IrpContext->Flags & IRPCONTEXT_CANWAIT*/, Buffer))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: vfat.h,v 1.44 2002/08/14 20:58:32 dwelch Exp $ */
|
/* $Id: vfat.h,v 1.45 2002/08/17 15:15:50 hbirr Exp $ */
|
||||||
|
|
||||||
#include <ddk/ntifs.h>
|
#include <ddk/ntifs.h>
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ struct _BootSector
|
||||||
unsigned char Drive, Res1, Sig;
|
unsigned char Drive, Res1, Sig;
|
||||||
unsigned long VolumeID;
|
unsigned long VolumeID;
|
||||||
unsigned char VolumeLabel[11], SysType[8];
|
unsigned char VolumeLabel[11], SysType[8];
|
||||||
unsigned char Res2[450];
|
unsigned char Res2[446];
|
||||||
|
unsigned long Signatur1;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct _BootSector32
|
struct _BootSector32
|
||||||
|
@ -327,7 +328,7 @@ NTSTATUS VfatSetInformation (PVFAT_IRP_CONTEXT IrpContext);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
||||||
PVFATFCB Fcb,
|
PVFATFCB Fcb,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PLARGE_INTEGER AllocationSize);
|
PLARGE_INTEGER AllocationSize);
|
||||||
|
|
||||||
/* --------------------------------------------------------- iface.c */
|
/* --------------------------------------------------------- iface.c */
|
||||||
|
@ -477,10 +478,6 @@ NTSTATUS VfatRead (PVFAT_IRP_CONTEXT IrpContext);
|
||||||
|
|
||||||
NTSTATUS VfatWrite (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,
|
NTSTATUS VfatWriteFile (PDEVICE_EXTENSION DeviceExt,
|
||||||
PFILE_OBJECT FileObject,
|
PFILE_OBJECT FileObject,
|
||||||
PVOID Buffer,
|
PVOID Buffer,
|
||||||
|
|
Loading…
Reference in a new issue