mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 23:41:22 +00:00
many changes to :
support one FCB/file and one CCB/open write on existing files open of root directory svn path=/trunk/; revision=148
This commit is contained in:
parent
35f07df64f
commit
66658f3d1a
1 changed files with 354 additions and 258 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -31,10 +33,12 @@
|
||||||
|
|
||||||
#include "vfat.h"
|
#include "vfat.h"
|
||||||
|
|
||||||
|
//#include "dbgpool.c"
|
||||||
|
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
static PDRIVER_OBJECT DriverObject;
|
static PDRIVER_OBJECT DriverObject;
|
||||||
|
static PVfatFCB pFirstFcb;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -54,7 +58,7 @@ ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
,(ULONG)(DeviceExt->FATStart+FATsector), 1,(UCHAR*) Block);
|
,(ULONG)(DeviceExt->FATStart+FATsector), 1,(UCHAR*) Block);
|
||||||
CurrentCluster = Block[FATeis];
|
CurrentCluster = Block[FATeis];
|
||||||
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
||||||
CurrentCluster = 0;
|
CurrentCluster = 0xffffffff;
|
||||||
ExFreePool(Block);
|
ExFreePool(Block);
|
||||||
return(CurrentCluster);
|
return(CurrentCluster);
|
||||||
}
|
}
|
||||||
|
@ -65,17 +69,11 @@ ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
* in-memory FAT
|
* in-memory FAT
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG FATsector;
|
|
||||||
ULONG FATeis;
|
|
||||||
PUSHORT Block;
|
PUSHORT Block;
|
||||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
Block=(PUSHORT)DeviceExt->FAT;
|
||||||
FATsector=CurrentCluster/(512/sizeof(USHORT));
|
CurrentCluster = Block[CurrentCluster];
|
||||||
FATeis=CurrentCluster-(FATsector*256);
|
|
||||||
memcpy(Block,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
|
||||||
CurrentCluster = Block[FATeis];
|
|
||||||
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
||||||
CurrentCluster = 0;
|
CurrentCluster = 0xffffffff;
|
||||||
ExFreePool(Block);
|
|
||||||
DPRINT("Returning %x\n",CurrentCluster);
|
DPRINT("Returning %x\n",CurrentCluster);
|
||||||
return(CurrentCluster);
|
return(CurrentCluster);
|
||||||
}
|
}
|
||||||
|
@ -87,31 +85,25 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned char* CBlock;
|
unsigned char* CBlock;
|
||||||
ULONG FATsector;
|
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
CBlock = ExAllocatePool(NonPagedPool,1024);
|
CBlock = DeviceExt->FAT;
|
||||||
FATsector = (CurrentCluster * 12) / (512 * 8);
|
FATOffset = (CurrentCluster * 12)/ 8;//first byte containing value
|
||||||
memcpy(CBlock,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
|
||||||
FATOffset = (CurrentCluster * 12) % (512 * 8);
|
|
||||||
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
|
||||||
if ((CurrentCluster % 2) == 0)
|
if ((CurrentCluster % 2) == 0)
|
||||||
{
|
{
|
||||||
Entry = CBlock[((FATOffset / 24)*3)];
|
Entry = CBlock[FATOffset];
|
||||||
Entry |= (CBlock[((FATOffset / 24)*3) + 1] & 0xf);
|
Entry |= ((CBlock[FATOffset+1] & 0xf)<<8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Entry = (CBlock[((FATOffset / 24)*3) + 1] >> 4);
|
Entry = (CBlock[FATOffset] >> 4);
|
||||||
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
|
Entry |= (CBlock[FATOffset+1] << 4);
|
||||||
}
|
}
|
||||||
DPRINT("Entry %x\n",Entry);
|
DPRINT("Entry %x\n",Entry);
|
||||||
if (Entry >= 0xff8 && Entry <= 0xfff)
|
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||||
Entry = 0;
|
Entry = 0xffffffff;
|
||||||
CurrentCluster = Entry;
|
DPRINT("Returning %x\n",Entry);
|
||||||
ExFreePool(CBlock);
|
return(Entry);
|
||||||
DPRINT("Returning %x\n",CurrentCluster);
|
|
||||||
return(CurrentCluster);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
|
@ -123,50 +115,136 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
|
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
|
||||||
DeviceExt,CurrentCluster);
|
DeviceExt,CurrentCluster);
|
||||||
if (DeviceExt->FatType == FAT16)
|
if (DeviceExt->FatType == FAT16)
|
||||||
{
|
|
||||||
return(Fat16GetNextCluster(DeviceExt, CurrentCluster));
|
return(Fat16GetNextCluster(DeviceExt, CurrentCluster));
|
||||||
}
|
|
||||||
else if (DeviceExt->FatType == FAT32)
|
else if (DeviceExt->FatType == FAT32)
|
||||||
{
|
|
||||||
return(Fat32GetNextCluster(DeviceExt, CurrentCluster));
|
return(Fat32GetNextCluster(DeviceExt, CurrentCluster));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return(Fat12GetNextCluster(DeviceExt, CurrentCluster));
|
return(Fat12GetNextCluster(DeviceExt, CurrentCluster));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Finds the first available cluster in a FAT16 table
|
* FUNCTION: Finds the first available cluster in a FAT16 table
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG sector;
|
|
||||||
PUSHORT Block;
|
PUSHORT Block;
|
||||||
int i;
|
int i;
|
||||||
|
Block=(PUSHORT)DeviceExt->FAT;
|
||||||
sector = 0;
|
for(i=2;i<(DeviceExt->Boot->FATSectors*256) ;i++)
|
||||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
if(Block[i]==0)
|
||||||
|
return (i);
|
||||||
while(sector<DeviceExt->Boot->FATSectors) {
|
|
||||||
memcpy(Block, DeviceExt->FAT+sector*BLOCKSIZE, BLOCKSIZE);
|
|
||||||
|
|
||||||
for(i=0; i<512; i++) {
|
|
||||||
if(Block[i]==0) {
|
|
||||||
ExFreePool(Block);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sector++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Give an error message (out of disk space) if we reach here) */
|
/* Give an error message (out of disk space) if we reach here) */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG FAT12FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Finds the first available cluster in a FAT12 table
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG FATOffset;
|
||||||
|
ULONG Entry;
|
||||||
|
PUCHAR CBlock=DeviceExt->FAT;
|
||||||
|
ULONG i;
|
||||||
|
for(i=2;i<((DeviceExt->Boot->FATSectors*512*8)/12) ;i++)
|
||||||
|
{
|
||||||
|
FATOffset = (i * 12)/8;
|
||||||
|
if ((i % 2) == 0)
|
||||||
|
{
|
||||||
|
Entry = CBlock[FATOffset];
|
||||||
|
Entry |= ((CBlock[FATOffset + 1] & 0xf)<<8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Entry = (CBlock[FATOffset] >> 4);
|
||||||
|
Entry |= (CBlock[FATOffset + 1] << 4);
|
||||||
|
}
|
||||||
|
if(Entry==0)
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
/* Give an error message (out of disk space) if we reach here) */
|
||||||
|
DbgPrint("Disk full, %d clusters used\n",i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG FAT32FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Finds the first available cluster in a FAT32 table
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG sector;
|
||||||
|
PULONG Block;
|
||||||
|
int i;
|
||||||
|
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
|
for(sector=0
|
||||||
|
;sector< ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32
|
||||||
|
;sector++)
|
||||||
|
{
|
||||||
|
VFATReadSectors(DeviceExt->StorageDevice
|
||||||
|
,(ULONG)(DeviceExt->FATStart+sector), 1,(UCHAR*) Block);
|
||||||
|
|
||||||
|
for(i=0; i<512; i++)
|
||||||
|
{
|
||||||
|
if(Block[i]==0)
|
||||||
|
{
|
||||||
|
ExFreePool(Block);
|
||||||
|
return (i+sector*128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Give an error message (out of disk space) if we reach here) */
|
||||||
ExFreePool(Block);
|
ExFreePool(Block);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
|
ULONG NewValue)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG FATsector;
|
||||||
|
ULONG FATOffset;
|
||||||
|
PUCHAR CBlock=DeviceExt->FAT;
|
||||||
|
int i;
|
||||||
|
FATOffset = (ClusterToWrite * 12)/8;
|
||||||
|
if ((ClusterToWrite % 2) == 0)
|
||||||
|
{
|
||||||
|
CBlock[FATOffset]=NewValue;
|
||||||
|
CBlock[FATOffset + 1] &=0xf0;
|
||||||
|
CBlock[FATOffset + 1]
|
||||||
|
|= (NewValue&0xf00)>>8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBlock[FATOffset] &=0x0f;
|
||||||
|
CBlock[FATOffset]
|
||||||
|
|= (NewValue&0xf)<<4;
|
||||||
|
CBlock[FATOffset+1]=NewValue>>4;
|
||||||
|
}
|
||||||
|
/* Write the changed FAT sector(s) to disk */
|
||||||
|
FATsector=FATOffset/BLOCKSIZE;
|
||||||
|
for(i=0;i<DeviceExt->Boot->FATCount;i++)
|
||||||
|
{
|
||||||
|
if( (FATOffset%BLOCKSIZE)==(BLOCKSIZE-1))//entry is on 2 sectors
|
||||||
|
{
|
||||||
|
VFATWriteSectors(DeviceExt->StorageDevice,
|
||||||
|
DeviceExt->FATStart+FATsector
|
||||||
|
+i*DeviceExt->Boot->FATSectors,
|
||||||
|
2,
|
||||||
|
CBlock+FATsector*512);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VFATWriteSectors(DeviceExt->StorageDevice,
|
||||||
|
DeviceExt->FATStart+FATsector
|
||||||
|
+i*DeviceExt->Boot->FATSectors,
|
||||||
|
1,
|
||||||
|
CBlock+FATsector*512);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG NewValue)
|
ULONG NewValue)
|
||||||
/*
|
/*
|
||||||
|
@ -174,25 +252,43 @@ void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG FATsector;
|
ULONG FATsector;
|
||||||
ULONG FATeis;
|
|
||||||
PUSHORT Block;
|
PUSHORT Block;
|
||||||
|
DbgPrint("FAT16WriteCluster %u : %u\n",ClusterToWrite,NewValue);
|
||||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
Block=(PUSHORT)DeviceExt->FAT;
|
||||||
|
|
||||||
FATsector=ClusterToWrite/(512/sizeof(USHORT));
|
FATsector=ClusterToWrite/(512/sizeof(USHORT));
|
||||||
FATeis=ClusterToWrite-(FATsector*256);
|
|
||||||
|
|
||||||
/* Update the in-memory FAT */
|
/* Update the in-memory FAT */
|
||||||
memcpy(Block, DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
Block[ClusterToWrite] = NewValue;
|
||||||
Block[FATeis] = NewValue;
|
|
||||||
memcpy(DeviceExt->FAT+FATsector*BLOCKSIZE, Block, BLOCKSIZE);
|
|
||||||
|
|
||||||
/* Write the changed FAT sector to disk */
|
/* Write the changed FAT sector to disk */
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors(DeviceExt->StorageDevice,
|
||||||
DeviceExt->FATStart+FATsector,
|
DeviceExt->FATStart+FATsector,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
1,
|
||||||
(UCHAR *)Block);
|
(UCHAR *)Block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
|
ULONG NewValue)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Writes a cluster to the FAT32 physical tables
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG FATsector;
|
||||||
|
ULONG FATeis;
|
||||||
|
PUSHORT Block;
|
||||||
|
DbgPrint("FAT32WriteCluster %u : %u\n",ClusterToWrite,NewValue);
|
||||||
|
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
|
FATsector=ClusterToWrite/128;
|
||||||
|
FATeis=ClusterToWrite-(FATsector*128);
|
||||||
|
/* load sector, change value, then rewrite sector */
|
||||||
|
VFATReadSectors(DeviceExt->StorageDevice,
|
||||||
|
DeviceExt->FATStart+FATsector,
|
||||||
|
1,
|
||||||
|
(UCHAR *)Block);
|
||||||
|
Block[FATeis] = NewValue;
|
||||||
|
VFATWriteSectors(DeviceExt->StorageDevice,
|
||||||
|
DeviceExt->FATStart+FATsector,
|
||||||
|
1,
|
||||||
|
(UCHAR *)Block);
|
||||||
ExFreePool(Block);
|
ExFreePool(Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,9 +298,12 @@ void WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
* FUNCTION: Write a changed FAT entry
|
* FUNCTION: Write a changed FAT entry
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (DeviceExt->FatType == FAT16) {
|
if(DeviceExt->FatType==FAT16)
|
||||||
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
||||||
}
|
else if(DeviceExt->FatType==FAT32)
|
||||||
|
FAT32WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
||||||
|
else
|
||||||
|
FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
|
@ -213,56 +312,34 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG LastCluster, NewCluster;
|
ULONG LastCluster, NewCluster;
|
||||||
BOOLEAN EOF = FALSE;
|
|
||||||
|
|
||||||
DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n",
|
DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n",
|
||||||
DeviceExt,CurrentCluster);
|
DeviceExt,CurrentCluster);
|
||||||
|
|
||||||
/* Find out what was happening in the last cluster's AU */
|
/* Find out what was happening in the last cluster's AU */
|
||||||
|
LastCluster=GetNextCluster(DeviceExt,CurrentCluster);
|
||||||
|
/* Check to see if we must append or overwrite */
|
||||||
|
if (LastCluster==0xffffffff)
|
||||||
|
{//we are after last existing cluster : we must add one to file
|
||||||
|
/* Append */
|
||||||
|
/* Firstly, find the next available open allocation unit */
|
||||||
if(DeviceExt->FatType == FAT16)
|
if(DeviceExt->FatType == FAT16)
|
||||||
{
|
NewCluster = FAT16FindAvailableCluster(DeviceExt);
|
||||||
LastCluster = Fat16GetNextCluster(DeviceExt, CurrentCluster);
|
else if(DeviceExt->FatType == FAT32)
|
||||||
if(LastCluster == 0xFFFF) {
|
NewCluster = FAT32FindAvailableCluster(DeviceExt);
|
||||||
EOF = TRUE;
|
else
|
||||||
}
|
NewCluster = FAT12FindAvailableCluster(DeviceExt);
|
||||||
|
/* Mark the new AU as the EOF */
|
||||||
|
WriteCluster(DeviceExt, NewCluster, 0xFFFFFFFF);
|
||||||
|
/* Now, write the AU of the LastCluster with the value of the newly
|
||||||
|
found AU */
|
||||||
|
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
|
||||||
|
/* Return NewCluster as CurrentCluster */
|
||||||
|
return NewCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LastCluster = Fat12GetNextCluster(DeviceExt, CurrentCluster);
|
|
||||||
if(LastCluster == 0xFFF) {
|
|
||||||
EOF = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check to see if we must append or overwrite */
|
|
||||||
|
|
||||||
if (EOF == TRUE) {
|
|
||||||
|
|
||||||
/* Append */
|
|
||||||
|
|
||||||
/* Firstly, find the next available open allocation unit */
|
|
||||||
NewCluster = FAT16FindAvailableCluster(DeviceExt);
|
|
||||||
|
|
||||||
/* Mark the new AU as the EOF */
|
|
||||||
if(DeviceExt->FatType == FAT16) {
|
|
||||||
FAT16WriteCluster(DeviceExt, NewCluster, 0xFFFF);
|
|
||||||
} else {
|
|
||||||
//FIXME FAT12WriteCluster(DeviceExt, NewCluster, 0xFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now, write the AU of the LastCluster with the value of the newly
|
|
||||||
found AU */
|
|
||||||
WriteCluster(DeviceExt, LastCluster, NewCluster);
|
|
||||||
|
|
||||||
/* Return NewCluster as CurrentCluster */
|
|
||||||
return NewCluster;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Overwrite: Return LastCluster as CurrentCluster */
|
/* Overwrite: Return LastCluster as CurrentCluster */
|
||||||
return LastCluster;
|
return LastCluster;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,11 +350,6 @@ ULONG ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
||||||
* device
|
* device
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
DPRINT("ClusterToSector(Cluster %d)\n",Cluster);
|
|
||||||
DPRINT("DeviceExt->Boot->SectorsPerCluster %d\n",
|
|
||||||
DeviceExt->Boot->SectorsPerCluster);
|
|
||||||
DPRINT("Returning %d\n",DeviceExt->dataStart+
|
|
||||||
((Cluster-2)*DeviceExt->Boot->SectorsPerCluster));
|
|
||||||
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
|
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,6 +464,15 @@ BOOLEAN IsLastEntry(PVOID Block, ULONG Offset)
|
||||||
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0);
|
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN IsVolEntry(PVOID Block, ULONG Offset)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Determine if the given directory entry is a vol entry
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if( (((FATDirEntry *)Block)[Offset].Attrib)==0x28 ) return TRUE;
|
||||||
|
else return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset)
|
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Determines if the given entry is a deleted one
|
* FUNCTION: Determines if the given entry is a deleted one
|
||||||
|
@ -528,8 +609,8 @@ BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2)
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
|
||||||
PFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry)
|
PVfatFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Find a file
|
* FUNCTION: Find a file
|
||||||
*/
|
*/
|
||||||
|
@ -542,18 +623,17 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
ULONG NextCluster;
|
ULONG NextCluster;
|
||||||
DPRINT("FindFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
DPRINT("FindFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
||||||
|
|
||||||
if (Parent == NULL || Parent->entry.FirstCluster == 1)
|
if (Parent == NULL)
|
||||||
{
|
{
|
||||||
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
||||||
StartingSector = DeviceExt->rootStart;
|
StartingSector = DeviceExt->rootStart;
|
||||||
if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0))
|
if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0))
|
||||||
{// it's root !
|
{// it's root : complete essentials fields then return ok
|
||||||
memset(Fcb,0,sizeof(FCB));
|
memset(Fcb,0,sizeof(VfatFCB));
|
||||||
memset(Fcb->entry.Filename,' ',11);
|
memset(Fcb->entry.Filename,' ',11);
|
||||||
Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
|
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
Fcb->entry.FirstCluster=2;
|
Fcb->entry.FirstCluster=2;
|
||||||
else Fcb->entry.FirstCluster=1;
|
else Fcb->entry.FirstCluster=1;//FIXME : is 1 the good value ?
|
||||||
if(StartSector) *StartSector=StartingSector;
|
if(StartSector) *StartSector=StartingSector;
|
||||||
if(Entry) *Entry=0;
|
if(Entry) *Entry=0;
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -565,35 +645,37 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
|
|
||||||
Size = ULONG_MAX;
|
Size = ULONG_MAX;
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
NextCluster = Parent->entry.FirstCluster
|
NextCluster = Parent->entry.FirstCluster+Parent->entry.FirstClusterHigh*65536;
|
||||||
+Parent->entry.FirstClusterHigh*65536;
|
|
||||||
else
|
else
|
||||||
NextCluster = Parent->entry.FirstCluster;
|
NextCluster = Parent->entry.FirstCluster;
|
||||||
StartingSector = ClusterToSector(DeviceExt, NextCluster);
|
StartingSector = ClusterToSector(DeviceExt, NextCluster);
|
||||||
|
if(Parent->entry.FirstCluster==1 && DeviceExt->FatType!=FAT32)
|
||||||
|
{// read of root directory in FAT16 or FAT12
|
||||||
|
StartingSector=DeviceExt->rootStart;
|
||||||
}
|
}
|
||||||
if (Parent != NULL)
|
|
||||||
{
|
|
||||||
DPRINT("Parent->entry.FirstCluster %x\n",Parent->entry.FirstCluster);
|
|
||||||
}
|
}
|
||||||
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
if (StartSector && (*StartSector)) StartingSector=*StartSector;
|
if (StartSector && (*StartSector)) StartingSector=*StartSector;
|
||||||
i=(Entry)?(*Entry):0;
|
i=(Entry)?(*Entry):0;
|
||||||
DbgPrint("FindFile : start at sector %lx, entry %ld\n",StartingSector,i);
|
DPRINT("FindFile : start at sector %lx, entry %ld\n",StartingSector,i);
|
||||||
for (j=0; j<Size; j++)
|
for (j=0; j<Size; j++)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
|
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
|
||||||
|
|
||||||
for (i=(Entry)?(*Entry):0; i<ENTRIES_PER_SECTOR; i++)
|
for (i=(Entry)?(*Entry):0; i<ENTRIES_PER_SECTOR; i++)
|
||||||
{
|
{
|
||||||
|
if (IsVolEntry((PVOID)block,i))
|
||||||
|
continue;
|
||||||
if (IsLastEntry((PVOID)block,i))
|
if (IsLastEntry((PVOID)block,i))
|
||||||
{
|
{
|
||||||
DPRINT("Is last entry\n");
|
|
||||||
ExFreePool(block);
|
ExFreePool(block);
|
||||||
|
if(StartSector) *StartSector=StartingSector;
|
||||||
|
if(Entry) *Entry=i;
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
if (GetEntryName((PVOID)block,&i,name,&j,DeviceExt,&StartingSector))
|
if (GetEntryName((PVOID)block,&i,name,&j,DeviceExt,&StartingSector))
|
||||||
{
|
{
|
||||||
DPRINT("Comparing %w %w\n",name,FileToFind);
|
// DPRINT("Comparing %w %w\n",name,FileToFind);
|
||||||
if (wstrcmpjoki(name,FileToFind))
|
if (wstrcmpjoki(name,FileToFind))
|
||||||
{
|
{
|
||||||
/* In the case of a long filename, the firstcluster is stored in
|
/* In the case of a long filename, the firstcluster is stored in
|
||||||
|
@ -615,8 +697,7 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
}
|
}
|
||||||
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
||||||
sizeof(FATDirEntry));
|
sizeof(FATDirEntry));
|
||||||
vfat_wcsncpy(Fcb->ObjectName,name,251);
|
vfat_wcsncpy(Fcb->ObjectName,name,261);
|
||||||
DPRINT("Fcb->ObjectName %w name %w\n",Fcb->ObjectName,name);
|
|
||||||
ExFreePool(block);
|
ExFreePool(block);
|
||||||
if(StartSector) *StartSector=StartingSector;
|
if(StartSector) *StartSector=StartingSector;
|
||||||
if(Entry) *Entry=i;
|
if(Entry) *Entry=i;
|
||||||
|
@ -624,7 +705,6 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Entry) *Entry=0;
|
|
||||||
// not found in this sector, try next :
|
// not found in this sector, try next :
|
||||||
|
|
||||||
/* It seems that directory sectors cannot be fragmented and therefore,
|
/* It seems that directory sectors cannot be fragmented and therefore,
|
||||||
|
@ -633,6 +713,7 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
lines are commented and not removed */
|
lines are commented and not removed */
|
||||||
|
|
||||||
StartingSector++;
|
StartingSector++;
|
||||||
|
if(Entry) *Entry=0;
|
||||||
/* if (Parent == NULL)
|
/* if (Parent == NULL)
|
||||||
{
|
{
|
||||||
StartingSector++;
|
StartingSector++;
|
||||||
|
@ -640,8 +721,10 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NextCluster = GetNextCluster(DeviceExt,NextCluster);
|
NextCluster = GetNextCluster(DeviceExt,NextCluster);
|
||||||
if (NextCluster == 0)
|
if (NextCluster == 0||NextCluster==0xffffffff)
|
||||||
{
|
{
|
||||||
|
if(StartSector) *StartSector=StartingSector;
|
||||||
|
if(Entry) *Entry=i;
|
||||||
ExFreePool(block);
|
ExFreePool(block);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
@ -649,6 +732,8 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
ExFreePool(block);
|
ExFreePool(block);
|
||||||
|
if(StartSector) *StartSector=StartingSector;
|
||||||
|
if(Entry) *Entry=i;
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +743,23 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
* FUNCTION: Closes a file
|
* FUNCTION: Closes a file
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* NOP */
|
PVfatFCB pFcb;
|
||||||
|
PVfatCCB pCcb;
|
||||||
|
//FIXME : update entry in directory ?
|
||||||
|
pCcb = (PVfatCCB)(FileObject->FsContext2);
|
||||||
|
pFcb = pCcb->pFcb;
|
||||||
|
pFcb->RefCount--;
|
||||||
|
if(pFcb->RefCount<=0)
|
||||||
|
{
|
||||||
|
if(pFcb->prevFcb)
|
||||||
|
pFcb->prevFcb->nextFcb=pFcb->nextFcb;
|
||||||
|
else
|
||||||
|
pFirstFcb=pFcb->nextFcb;
|
||||||
|
if(pFcb->nextFcb)
|
||||||
|
pFcb->nextFcb->prevFcb=pFcb->prevFcb;
|
||||||
|
ExFreePool(pFcb);
|
||||||
|
}
|
||||||
|
ExFreePool(pCcb);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,19 +772,37 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PWSTR current;
|
PWSTR current;
|
||||||
PWSTR next;
|
PWSTR next;
|
||||||
PWSTR string;
|
PWSTR string;
|
||||||
PFCB ParentFcb;
|
PVfatFCB ParentFcb;
|
||||||
PFCB Fcb;
|
PVfatFCB Fcb;
|
||||||
PFCB Temp;
|
PVfatFCB Temp;
|
||||||
|
PVfatCCB newCCB;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("FsdOpenFile(%08lx, %08lx, %08lx)\n",
|
DPRINT("FsdOpenFile(%08lx, %08lx, %08lx)\n",
|
||||||
DeviceExt,
|
DeviceExt,
|
||||||
FileObject,
|
FileObject,
|
||||||
FileName);
|
FileName);
|
||||||
|
// try first to find an existing FCB in memory
|
||||||
|
for (Fcb=pFirstFcb;Fcb; Fcb=Fcb->nextFcb)
|
||||||
|
{
|
||||||
|
if (DeviceExt==Fcb->pDevExt
|
||||||
|
&& wstrcmpi(FileName,Fcb->PathName))
|
||||||
|
{
|
||||||
|
Fcb->RefCount++;
|
||||||
|
FileObject->FsContext =(PVOID) &Fcb->NTRequiredFCB;
|
||||||
|
newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB));
|
||||||
|
memset(newCCB,0,sizeof(VfatCCB));
|
||||||
|
FileObject->FsContext2 = newCCB;
|
||||||
|
newCCB->pFcb=Fcb;
|
||||||
|
newCCB->PtrFileObject=FileObject;
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
string = FileName;
|
string = FileName;
|
||||||
ParentFcb = NULL;
|
ParentFcb = NULL;
|
||||||
Fcb = ExAllocatePool(NonPagedPool, sizeof(FCB));
|
Fcb = ExAllocatePool(NonPagedPool, sizeof(VfatFCB));
|
||||||
|
memset(Fcb,0,sizeof(VfatFCB));
|
||||||
|
Fcb->ObjectName=Fcb->PathName;
|
||||||
next = &string[0];
|
next = &string[0];
|
||||||
current = next+1;
|
current = next+1;
|
||||||
|
|
||||||
|
@ -702,13 +821,15 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
|
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
|
||||||
if (Status != STATUS_SUCCESS)
|
if (Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
/* FIXME: should the FCB be freed here? */
|
/* FIXME: should the VfatFCB be freed here? */
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
Temp = Fcb;
|
Temp = Fcb;
|
||||||
if (ParentFcb == NULL)
|
if (ParentFcb == NULL)
|
||||||
{
|
{
|
||||||
Fcb = ExAllocatePool(NonPagedPool,sizeof(FCB));
|
Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB));
|
||||||
|
memset(Fcb,0,sizeof(VfatFCB));
|
||||||
|
Fcb->ObjectName=Fcb->PathName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -716,10 +837,22 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
ParentFcb = Temp;
|
ParentFcb = Temp;
|
||||||
}
|
}
|
||||||
FileObject->FsContext = ParentFcb;
|
FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB;
|
||||||
DPRINT("file opn, fcb=%x\n",ParentFcb);
|
newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB));
|
||||||
DPRINT("ParentFcb->entry.FileSize %d\n",ParentFcb->entry.FileSize);
|
memset(newCCB,0,sizeof(VfatCCB));
|
||||||
|
FileObject->FsContext2 = newCCB;
|
||||||
|
newCCB->pFcb=ParentFcb;
|
||||||
|
newCCB->PtrFileObject=FileObject;
|
||||||
|
ParentFcb->RefCount++;
|
||||||
|
//FIXME : initialize all fields in FCB and CCB
|
||||||
|
ParentFcb->nextFcb=pFirstFcb;
|
||||||
|
pFirstFcb=ParentFcb;
|
||||||
|
vfat_wcsncpy(ParentFcb->PathName,FileName,261);
|
||||||
|
ParentFcb->ObjectName=Fcb->PathName+(current-string);
|
||||||
|
ParentFcb->pDevExt=DeviceExt;
|
||||||
|
DPRINT("file open, fcb=%x\n",ParentFcb);
|
||||||
|
DPRINT("FileSize %d\n",ParentFcb->entry.FileSize);
|
||||||
|
ExFreePool(Fcb);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +862,7 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||||
* by this fsd
|
* by this fsd
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
DPRINT("FsdHasFileSystem(DeviceToMount %x)\n",DeviceToMount);
|
BootSector* Boot;
|
||||||
|
|
||||||
Boot = ExAllocatePool(NonPagedPool,512);
|
Boot = ExAllocatePool(NonPagedPool,512);
|
||||||
|
|
||||||
|
@ -743,8 +876,7 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
ExFreePool(Boot);
|
ExFreePool(Boot);
|
||||||
|
return(FALSE);
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
@ -824,7 +956,6 @@ void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG Sector;
|
ULONG Sector;
|
||||||
|
|
||||||
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||||
DeviceExt,Buffer,Cluster);
|
DeviceExt,Buffer,Cluster);
|
||||||
|
|
||||||
|
@ -846,41 +977,23 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
ULONG CurrentCluster;
|
ULONG CurrentCluster;
|
||||||
ULONG FileOffset;
|
ULONG FileOffset;
|
||||||
ULONG FirstCluster;
|
ULONG FirstCluster;
|
||||||
PFCB Fcb;
|
PVfatFCB Fcb;
|
||||||
PVOID Temp;
|
PVOID Temp;
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
|
|
||||||
/* PRECONDITION */
|
|
||||||
assert(DeviceExt != NULL);
|
|
||||||
assert(DeviceExt->BytesPerCluster != 0);
|
|
||||||
assert(FileObject != NULL);
|
|
||||||
assert(FileObject->FsContext != NULL);
|
|
||||||
|
|
||||||
DPRINT("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
|
DPRINT("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
|
||||||
"Length %d, ReadOffset %d)\n",
|
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
|
||||||
DeviceExt,
|
Length,ReadOffset);
|
||||||
FileObject,
|
|
||||||
Buffer,
|
|
||||||
Length,
|
|
||||||
ReadOffset);
|
|
||||||
DPRINT("DeviceExt->BytesPerCluster %d\n", DeviceExt->BytesPerCluster);
|
|
||||||
|
|
||||||
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
|
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
|
||||||
Fcb = FileObject->FsContext;
|
Fcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
||||||
CurrentCluster = Fcb->entry.FirstCluster +
|
|
||||||
Fcb->entry.FirstClusterHigh * 65536;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
CurrentCluster = Fcb->entry.FirstCluster;
|
CurrentCluster = Fcb->entry.FirstCluster;
|
||||||
}
|
|
||||||
if (CurrentCluster<2)
|
if (CurrentCluster<2)
|
||||||
{
|
return STATUS_UNSUCCESSFUL;// FIXME : root of FAT16 or FAT12
|
||||||
/* FIXME : root of FAT16 ? */
|
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ReadOffset >= Fcb->entry.FileSize)
|
if (ReadOffset >= Fcb->entry.FileSize)
|
||||||
{
|
{
|
||||||
|
@ -892,11 +1005,12 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
*LengthRead = 0;
|
*LengthRead = 0;
|
||||||
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
||||||
/* FIXME: optimize by remembering the last cluster read and using if possible */
|
if(!Temp) return STATUS_UNSUCCESSFUL;
|
||||||
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
||||||
{
|
{
|
||||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||||
}
|
}
|
||||||
|
CHECKPOINT;
|
||||||
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
@ -912,12 +1026,13 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
Length = Length - TempLength;
|
Length = Length - TempLength;
|
||||||
Buffer = Buffer + TempLength;
|
Buffer = Buffer + TempLength;
|
||||||
}
|
}
|
||||||
|
CHECKPOINT;
|
||||||
while (Length > DeviceExt->BytesPerCluster)
|
while (Length > DeviceExt->BytesPerCluster)
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt, Buffer, CurrentCluster);
|
VFATLoadCluster(DeviceExt, Buffer, CurrentCluster);
|
||||||
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0xffffffff)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -927,6 +1042,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
||||||
Length = Length - DeviceExt->BytesPerCluster;
|
Length = Length - DeviceExt->BytesPerCluster;
|
||||||
}
|
}
|
||||||
|
CHECKPOINT;
|
||||||
if (Length > 0)
|
if (Length > 0)
|
||||||
{
|
{
|
||||||
(*LengthRead) = (*LengthRead) + Length;
|
(*LengthRead) = (*LengthRead) + Length;
|
||||||
|
@ -946,14 +1062,13 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
ULONG CurrentCluster;
|
ULONG CurrentCluster;
|
||||||
ULONG FileOffset;
|
ULONG FileOffset;
|
||||||
ULONG FirstCluster;
|
ULONG FirstCluster;
|
||||||
PFCB Fcb;
|
PVfatFCB Fcb;
|
||||||
PVOID Temp;
|
PVOID Temp;
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
|
|
||||||
/* Locate the first cluster of the file */
|
/* Locate the first cluster of the file */
|
||||||
|
|
||||||
FirstCluster = WriteOffset / DeviceExt->BytesPerCluster;
|
FirstCluster = WriteOffset / DeviceExt->BytesPerCluster;
|
||||||
Fcb = FileObject->FsContext;
|
Fcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
||||||
else
|
else
|
||||||
|
@ -980,20 +1095,15 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
{
|
{
|
||||||
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
||||||
(WriteOffset % DeviceExt->BytesPerCluster));
|
(WriteOffset % DeviceExt->BytesPerCluster));
|
||||||
|
|
||||||
/* Read in the existing cluster data */
|
/* Read in the existing cluster data */
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
|
||||||
/* Overwrite the last parts of the data as necessary */
|
/* Overwrite the last parts of the data as necessary */
|
||||||
memcpy(Temp + WriteOffset % DeviceExt->BytesPerCluster, Buffer,
|
memcpy(Temp + (WriteOffset % DeviceExt->BytesPerCluster), Buffer,
|
||||||
TempLength);
|
TempLength);
|
||||||
|
|
||||||
/* Write the cluster back */
|
/* Write the cluster back */
|
||||||
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
|
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
|
||||||
/* Next write cluster */
|
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
|
||||||
|
|
||||||
Length = Length - TempLength;
|
Length = Length - TempLength;
|
||||||
Buffer = Buffer + TempLength;
|
Buffer = Buffer + TempLength;
|
||||||
}
|
}
|
||||||
|
@ -1003,14 +1113,16 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
while (Length > DeviceExt->BytesPerCluster)
|
while (Length > DeviceExt->BytesPerCluster)
|
||||||
{
|
{
|
||||||
VFATWriteCluster(DeviceExt, Buffer, CurrentCluster);
|
/* Next write cluster */
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
||||||
|
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
VFATWriteCluster(DeviceExt, Buffer, CurrentCluster);
|
||||||
|
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
||||||
|
|
||||||
|
|
||||||
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
||||||
Length = Length - DeviceExt->BytesPerCluster;
|
Length = Length - DeviceExt->BytesPerCluster;
|
||||||
|
@ -1021,10 +1133,20 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
if (Length > 0)
|
if (Length > 0)
|
||||||
{
|
{
|
||||||
|
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
||||||
|
if (CurrentCluster == 0)
|
||||||
|
{
|
||||||
|
ExFreePool(Temp);
|
||||||
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
memcpy(Temp, Buffer, Length);
|
memcpy(Temp, Buffer, Length);
|
||||||
VFATWriteCluster(DeviceExt, Temp, CurrentCluster);
|
VFATWriteCluster(DeviceExt, Temp, CurrentCluster);
|
||||||
}
|
}
|
||||||
|
//FIXME : set last write time and date
|
||||||
|
if(Fcb->entry.FileSize<WriteOffset+Length)
|
||||||
|
Fcb->entry.FileSize=WriteOffset+Length;
|
||||||
|
//FIXME : update entry in directory
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -1063,14 +1185,21 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
Irp);
|
Irp);
|
||||||
|
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
CHECKPOINT;
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
|
CHECKPOINT;
|
||||||
DeviceExt = DeviceObject->DeviceExtension;
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
CHECKPOINT;
|
||||||
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
|
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
|
CHECKPOINT;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -1112,23 +1241,14 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
PDEVICE_EXTENSION DeviceExt;
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG LengthRead;
|
ULONG LengthRead;
|
||||||
|
|
||||||
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||||
|
|
||||||
/* Precondition / Initialization */
|
|
||||||
assert(Irp != NULL);
|
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
assert(Stack != NULL);
|
|
||||||
FileObject = Stack->FileObject;
|
|
||||||
assert(FileObject != NULL);
|
|
||||||
DeviceExt = DeviceObject->DeviceExtension;
|
|
||||||
assert(DeviceExt != NULL);
|
|
||||||
|
|
||||||
Length = Stack->Parameters.Read.Length;
|
Length = Stack->Parameters.Read.Length;
|
||||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||||
Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Read.ByteOffset);
|
Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Read.ByteOffset);
|
||||||
|
@ -1167,8 +1287,7 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
|
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
|
||||||
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||||
DeviceToMount);
|
DeviceToMount);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
@ -1181,9 +1300,7 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("FsdFileSystemControl(DevObj %08lx, Irp %08lx)\n", DeviceObject, Irp);
|
DPRINT("VFAT FSC\n");
|
||||||
|
|
||||||
/* FIXME: should make sure that this is actually a mount request! */
|
|
||||||
|
|
||||||
if (FsdHasFileSystem(DeviceToMount))
|
if (FsdHasFileSystem(DeviceToMount))
|
||||||
{
|
{
|
||||||
|
@ -1203,23 +1320,15 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FsdGetStandardInformation(PVfatFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_STANDARD_INFORMATION StandardInfo)
|
PFILE_STANDARD_INFORMATION StandardInfo)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the standard file information
|
* FUNCTION: Retrieve the standard file information
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PDEVICE_EXTENSION DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
unsigned long AllocSize;
|
unsigned long AllocSize;
|
||||||
|
|
||||||
DeviceExtension = DeviceObject->DeviceExtension;
|
|
||||||
|
|
||||||
/* PRECONDITION */
|
|
||||||
assert(DeviceExtension != NULL);
|
|
||||||
assert(DeviceExtension->BytesPerCluster != 0);
|
|
||||||
assert(StandardInfo != NULL);
|
|
||||||
assert(FCB != NULL);
|
|
||||||
|
|
||||||
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
|
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
|
||||||
|
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
|
@ -1245,42 +1354,29 @@ NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
* FUNCTION: Retrieve the specified file information
|
* FUNCTION: Retrieve the specified file information
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
NTSTATUS RC;
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PIO_STACK_LOCATION Stack;
|
FILE_INFORMATION_CLASS FileInformationClass =
|
||||||
FILE_INFORMATION_CLASS FileInformationClass;
|
Stack->Parameters.QueryFile.FileInformationClass;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
PFCB FCB;
|
PVfatFCB FCB = NULL;
|
||||||
// PCCB CCB;
|
// PVfatCCB CCB = NULL;
|
||||||
|
|
||||||
|
NTSTATUS RC = STATUS_SUCCESS;
|
||||||
void *SystemBuffer;
|
void *SystemBuffer;
|
||||||
|
|
||||||
/* PRECONDITION */
|
|
||||||
assert(DeviceObject != NULL);
|
|
||||||
assert(Irp != NULL);
|
|
||||||
|
|
||||||
/* INITIALIZATION */
|
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
|
|
||||||
FileObject = NULL;
|
|
||||||
FCB = NULL;
|
|
||||||
// PCCB CCB = NULL;
|
|
||||||
RC = STATUS_SUCCESS;
|
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
// CCB = (PCCB)(FileObject->FsContext2);
|
// CCB = (PVfatCCB)(FileObject->FsContext2);
|
||||||
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
||||||
FCB = (PFCB)(FileObject->FsContext);
|
FCB = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
|
||||||
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
|
||||||
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
|
|
||||||
DPRINT("FsdQueryInformation(DevObj %08lx, Irp %08lx)\n", DeviceObject, Irp);
|
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
switch(FileInformationClass) {
|
switch(FileInformationClass) {
|
||||||
case FileStandardInformation:
|
case FileStandardInformation:
|
||||||
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
|
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RC = STATUS_INVALID_PARAMETER;
|
RC=STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RC;
|
return RC;
|
||||||
|
@ -1301,8 +1397,8 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
UNICODE_STRING ustr;
|
UNICODE_STRING ustr;
|
||||||
ANSI_STRING astr;
|
ANSI_STRING astr;
|
||||||
|
|
||||||
DbgPrint("VFAT 0.0.5\n");
|
DbgPrint("VFAT 0.0.6\n");
|
||||||
|
pFirstFcb=NULL;
|
||||||
DriverObject = _DriverObject;
|
DriverObject = _DriverObject;
|
||||||
|
|
||||||
RtlInitAnsiString(&astr,"\\Device\\VFAT");
|
RtlInitAnsiString(&astr,"\\Device\\VFAT");
|
||||||
|
@ -1314,7 +1410,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject->Flags = DO_DIRECT_IO;
|
DeviceObject->Flags=0;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
|
||||||
DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
|
DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue