mirror of
https://github.com/reactos/reactos.git
synced 2025-07-23 08:33:47 +00:00
All:
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:
parent
2c21decf9c
commit
d09531b121
14 changed files with 1484 additions and 1195 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"..")
|
||||
|
|
378
reactos/drivers/fs/vfat/fsctl.c
Normal file
378
reactos/drivers/fs/vfat/fsctl.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue