mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 09:03:25 +00:00
some bugfixes
work on write operations svn path=/trunk/; revision=161
This commit is contained in:
parent
a044d562b8
commit
93b8081eed
1 changed files with 206 additions and 127 deletions
|
@ -37,8 +37,8 @@
|
||||||
|
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
static PDRIVER_OBJECT DriverObject;
|
static PDRIVER_OBJECT VFATDriverObject;
|
||||||
static PVfatFCB pFirstFcb;
|
PVfatFCB pFirstFcb;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -332,7 +332,8 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
WriteCluster(DeviceExt, NewCluster, 0xFFFFFFFF);
|
WriteCluster(DeviceExt, NewCluster, 0xFFFFFFFF);
|
||||||
/* Now, write the AU of the LastCluster with the value of the newly
|
/* Now, write the AU of the LastCluster with the value of the newly
|
||||||
found AU */
|
found AU */
|
||||||
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
|
if(CurrentCluster)
|
||||||
|
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
|
||||||
/* Return NewCluster as CurrentCluster */
|
/* Return NewCluster as CurrentCluster */
|
||||||
return NewCluster;
|
return NewCluster;
|
||||||
}
|
}
|
||||||
|
@ -424,15 +425,13 @@ wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount)
|
||||||
* FUNCTION: Copy a string for use with long file names
|
* FUNCTION: Copy a string for use with long file names
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0;i<wcount;i++)
|
for (i=0;i<wcount;i++)
|
||||||
{
|
{
|
||||||
*dest=src[i];
|
dest[i]=src[i];
|
||||||
dest++;
|
if(!dest[i]) break;
|
||||||
}
|
}
|
||||||
dest=dest-wcount;
|
|
||||||
|
|
||||||
return(dest);
|
return(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,10 +477,9 @@ 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
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Checks special character (short names) or attrib=0 (long names) */
|
/* Checks special character */
|
||||||
|
|
||||||
return ((((FATDirEntry *)Block)[Offset].Filename[0] == 0xe5) ||
|
return ((((FATDirEntry *)Block)[Offset].Filename[0] == 0xe5));
|
||||||
(((FATDirEntry *)Block)[Offset].Attrib == 0x00));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop,
|
BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop,
|
||||||
|
@ -633,6 +631,7 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
|
||||||
memset(Fcb,0,sizeof(VfatFCB));
|
memset(Fcb,0,sizeof(VfatFCB));
|
||||||
memset(Fcb->entry.Filename,' ',11);
|
memset(Fcb->entry.Filename,' ',11);
|
||||||
Fcb->entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE;
|
Fcb->entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE;
|
||||||
|
Fcb->entry.Attrib=FILE_ATTRIBUTE_DIRECTORY;
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
Fcb->entry.FirstCluster=2;
|
Fcb->entry.FirstCluster=2;
|
||||||
else Fcb->entry.FirstCluster=1;//FIXME : is 1 the good value for mark root?
|
else Fcb->entry.FirstCluster=1;//FIXME : is 1 the good value for mark root?
|
||||||
|
@ -684,23 +683,16 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
|
||||||
/* In the case of a long filename, the firstcluster is stored in
|
/* In the case of a long filename, the firstcluster is stored in
|
||||||
the next record -- where it's short name is */
|
the next record -- where it's short name is */
|
||||||
if(((FATDirEntry *)block)[i].Attrib==0x0f) i++;
|
if(((FATDirEntry *)block)[i].Attrib==0x0f) i++;
|
||||||
// if(DeviceExt->FatType==FAT32)
|
|
||||||
// {
|
|
||||||
// if(((FATDirEntry *)block)[i].FirstCluster==0
|
|
||||||
// &&((FATDirEntry *)block)[i].FirstClusterHigh==0
|
|
||||||
// ) i++;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// if(((FATDirEntry *)block)[i].FirstCluster==0) i++;
|
|
||||||
if( i==(ENTRIES_PER_SECTOR))
|
if( i==(ENTRIES_PER_SECTOR))
|
||||||
{// entry is in next sector
|
{// entry is in next sector
|
||||||
StartingSector++;
|
StartingSector++;
|
||||||
|
//FIXME : treat case of next sector fragmented
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
|
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
|
||||||
i=0;
|
i=0;
|
||||||
}
|
}
|
||||||
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
||||||
sizeof(FATDirEntry));
|
sizeof(FATDirEntry));
|
||||||
vfat_wcsncpy(Fcb->ObjectName,name,261);
|
vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH);
|
||||||
ExFreePool(block);
|
ExFreePool(block);
|
||||||
if(StartSector) *StartSector=StartingSector;
|
if(StartSector) *StartSector=StartingSector;
|
||||||
if(Entry) *Entry=i;
|
if(Entry) *Entry=i;
|
||||||
|
@ -782,6 +774,7 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
DeviceExt,
|
DeviceExt,
|
||||||
FileObject,
|
FileObject,
|
||||||
FileName);
|
FileName);
|
||||||
|
//FIXME : treat relative name
|
||||||
// try first to find an existing FCB in memory
|
// try first to find an existing FCB in memory
|
||||||
for (Fcb=pFirstFcb;Fcb; Fcb=Fcb->nextFcb)
|
for (Fcb=pFirstFcb;Fcb; Fcb=Fcb->nextFcb)
|
||||||
{
|
{
|
||||||
|
@ -806,44 +799,39 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
next = &string[0];
|
next = &string[0];
|
||||||
current = next+1;
|
current = next+1;
|
||||||
|
|
||||||
|
if(*next==0) // root
|
||||||
|
{
|
||||||
|
Status = FindFile(DeviceExt,Fcb,ParentFcb,next,NULL,NULL);
|
||||||
|
ParentFcb=Fcb;
|
||||||
|
Fcb=NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
while (next!=NULL)
|
while (next!=NULL)
|
||||||
|
{
|
||||||
|
*next = '\\';
|
||||||
|
current = next+1;
|
||||||
|
next = wcschr(next+1,'\\');
|
||||||
|
if (next!=NULL)
|
||||||
|
*next=0;
|
||||||
|
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
|
||||||
|
if (Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
DPRINT("current %w next %x\n",current,next);
|
if (Fcb != NULL)
|
||||||
|
ExFreePool(Fcb);
|
||||||
*next = '\\';
|
if (ParentFcb != NULL)
|
||||||
current = next+1;
|
ExFreePool(ParentFcb);
|
||||||
next = wcschr(next+1,'\\');
|
return(Status);
|
||||||
if (next!=NULL)
|
|
||||||
{
|
|
||||||
*next=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
|
|
||||||
if (Status != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
if (Fcb != NULL)
|
|
||||||
{
|
|
||||||
ExFreePool(Fcb);
|
|
||||||
}
|
|
||||||
if (ParentFcb != NULL)
|
|
||||||
{
|
|
||||||
ExFreePool(ParentFcb);
|
|
||||||
}
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
Temp = Fcb;
|
|
||||||
if (ParentFcb == NULL)
|
|
||||||
{
|
|
||||||
Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB));
|
|
||||||
memset(Fcb,0,sizeof(VfatFCB));
|
|
||||||
Fcb->ObjectName=Fcb->PathName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Fcb = ParentFcb;
|
|
||||||
}
|
|
||||||
ParentFcb = Temp;
|
|
||||||
}
|
}
|
||||||
|
Temp = Fcb;
|
||||||
|
if (ParentFcb == NULL)
|
||||||
|
{
|
||||||
|
Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB));
|
||||||
|
memset(Fcb,0,sizeof(VfatFCB));
|
||||||
|
Fcb->ObjectName=Fcb->PathName;
|
||||||
|
}
|
||||||
|
else Fcb = ParentFcb;
|
||||||
|
ParentFcb = Temp;
|
||||||
|
}
|
||||||
FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB;
|
FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB;
|
||||||
newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB));
|
newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB));
|
||||||
memset(newCCB,0,sizeof(VfatCCB));
|
memset(newCCB,0,sizeof(VfatCCB));
|
||||||
|
@ -854,12 +842,12 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
//FIXME : initialize all fields in FCB and CCB
|
//FIXME : initialize all fields in FCB and CCB
|
||||||
ParentFcb->nextFcb=pFirstFcb;
|
ParentFcb->nextFcb=pFirstFcb;
|
||||||
pFirstFcb=ParentFcb;
|
pFirstFcb=ParentFcb;
|
||||||
vfat_wcsncpy(ParentFcb->PathName,FileName,261);
|
vfat_wcsncpy(ParentFcb->PathName,FileName,MAX_PATH);
|
||||||
ParentFcb->ObjectName=Fcb->PathName+(current-string);
|
ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName);
|
||||||
ParentFcb->pDevExt=DeviceExt;
|
ParentFcb->pDevExt=DeviceExt;
|
||||||
DPRINT("file open, fcb=%x\n",ParentFcb);
|
DPRINT("file open, fcb=%x\n",ParentFcb);
|
||||||
DPRINT("FileSize %d\n",ParentFcb->entry.FileSize);
|
DPRINT("FileSize %d\n",ParentFcb->entry.FileSize);
|
||||||
ExFreePool(Fcb);
|
if(Fcb) ExFreePool(Fcb);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -998,22 +986,22 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
|
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
|
||||||
Length,ReadOffset);
|
Length,ReadOffset);
|
||||||
|
|
||||||
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
|
|
||||||
Fcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
|
Fcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
CurrentCluster = Fcb->entry.FirstCluster
|
CurrentCluster = Fcb->entry.FirstCluster
|
||||||
+Fcb->entry.FirstClusterHigh*65536;
|
+Fcb->entry.FirstClusterHigh*65536;
|
||||||
else
|
else
|
||||||
CurrentCluster = Fcb->entry.FirstCluster;
|
CurrentCluster = Fcb->entry.FirstCluster;
|
||||||
if (CurrentCluster<2)
|
FirstCluster=CurrentCluster;
|
||||||
return STATUS_UNSUCCESSFUL;// FIXME : root of FAT16 or FAT12
|
|
||||||
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
||||||
|
|
||||||
if (ReadOffset >= Fcb->entry.FileSize)
|
if (ReadOffset >= Fcb->entry.FileSize
|
||||||
|
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
{
|
{
|
||||||
return(STATUS_END_OF_FILE);
|
return(STATUS_END_OF_FILE);
|
||||||
}
|
}
|
||||||
if ((ReadOffset + Length) > Fcb->entry.FileSize)
|
if ((ReadOffset + Length) > Fcb->entry.FileSize
|
||||||
|
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
{
|
{
|
||||||
Length = Fcb->entry.FileSize - ReadOffset;
|
Length = Fcb->entry.FileSize - ReadOffset;
|
||||||
}
|
}
|
||||||
|
@ -1021,16 +1009,31 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
/* FIXME: optimize by remembering the last cluster read and using if possible */
|
/* FIXME: optimize by remembering the last cluster read and using if possible */
|
||||||
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
||||||
if(!Temp) return STATUS_UNSUCCESSFUL;
|
if(!Temp) return STATUS_UNSUCCESSFUL;
|
||||||
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
if (FirstCluster==1)
|
||||||
{
|
{ //root of FAT16 or FAT12
|
||||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
CurrentCluster=DeviceExt->rootStart+ReadOffset
|
||||||
|
/(DeviceExt->BytesPerCluster)*DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
for (FileOffset=0; FileOffset < ReadOffset / DeviceExt->BytesPerCluster
|
||||||
|
; FileOffset++)
|
||||||
|
{
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||||
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
if (FirstCluster==1)
|
||||||
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
{
|
||||||
|
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Temp);
|
||||||
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
}
|
||||||
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
||||||
(ReadOffset % DeviceExt->BytesPerCluster));
|
(ReadOffset % DeviceExt->BytesPerCluster));
|
||||||
|
|
||||||
|
@ -1042,11 +1045,19 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
Buffer = Buffer + TempLength;
|
Buffer = Buffer + TempLength;
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
while (Length > DeviceExt->BytesPerCluster)
|
while (Length >= DeviceExt->BytesPerCluster)
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt, Buffer, CurrentCluster);
|
if (FirstCluster==1)
|
||||||
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
{
|
||||||
|
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Buffer);
|
||||||
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VFATLoadCluster(DeviceExt,Buffer,CurrentCluster);
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
}
|
||||||
if (CurrentCluster == 0xffffffff)
|
if (CurrentCluster == 0xffffffff)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
|
@ -1061,7 +1072,17 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
if (Length > 0)
|
if (Length > 0)
|
||||||
{
|
{
|
||||||
(*LengthRead) = (*LengthRead) + Length;
|
(*LengthRead) = (*LengthRead) + Length;
|
||||||
VFATLoadCluster(DeviceExt, Temp, CurrentCluster);
|
if (FirstCluster==1)
|
||||||
|
{
|
||||||
|
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Temp);
|
||||||
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
}
|
||||||
memcpy(Buffer, Temp, Length);
|
memcpy(Buffer, Temp, Length);
|
||||||
}
|
}
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
|
@ -1079,25 +1100,42 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
ULONG FirstCluster;
|
ULONG FirstCluster;
|
||||||
PVfatFCB Fcb;
|
PVfatFCB Fcb;
|
||||||
PVOID Temp;
|
PVOID Temp;
|
||||||
ULONG TempLength;
|
ULONG TempLength,Length2=Length;
|
||||||
|
|
||||||
/* Locate the first cluster of the file */
|
/* Locate the first cluster of the file */
|
||||||
FirstCluster = WriteOffset / DeviceExt->BytesPerCluster;
|
|
||||||
Fcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
|
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;
|
||||||
|
FirstCluster=CurrentCluster;
|
||||||
/* Allocate a buffer to hold 1 cluster of data */
|
/* Allocate a buffer to hold 1 cluster of data */
|
||||||
|
|
||||||
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
||||||
|
|
||||||
/* Find the cluster according to the offset in the file */
|
/* Find the cluster according to the offset in the file */
|
||||||
|
|
||||||
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
if (CurrentCluster==1)
|
||||||
|
{ //root of FAT16 or FAT12
|
||||||
|
CurrentCluster=DeviceExt->rootStart+WriteOffset
|
||||||
|
/DeviceExt->BytesPerCluster*DeviceExt->Boot->SectorsPerCluster;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (CurrentCluster==0)
|
||||||
|
{// file of size 0
|
||||||
|
CurrentCluster=GetNextWriteCluster(DeviceExt,0);
|
||||||
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
Fcb->entry.FirstClusterHigh=CurrentCluster>>16;
|
||||||
|
Fcb->entry.FirstCluster=CurrentCluster;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Fcb->entry.FirstCluster=CurrentCluster;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (FileOffset=0; FileOffset < WriteOffset / DeviceExt->BytesPerCluster; FileOffset++)
|
||||||
|
{
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
|
||||||
|
@ -1107,61 +1145,94 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((WriteOffset % DeviceExt->BytesPerCluster)!=0)
|
if ((WriteOffset % DeviceExt->BytesPerCluster)!=0)
|
||||||
{
|
{
|
||||||
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);
|
if (FirstCluster==1)
|
||||||
|
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Temp);
|
||||||
|
else
|
||||||
|
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);
|
if (FirstCluster==1)
|
||||||
Length = Length - TempLength;
|
{
|
||||||
Buffer = Buffer + TempLength;
|
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Temp);
|
||||||
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
}
|
||||||
|
Length2 -= TempLength;
|
||||||
|
Buffer = Buffer + TempLength;
|
||||||
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
|
||||||
/* Write the buffer in chunks of 1 cluster */
|
/* Write the buffer in chunks of 1 cluster */
|
||||||
|
|
||||||
while (Length > DeviceExt->BytesPerCluster)
|
while (Length2 >= DeviceExt->BytesPerCluster)
|
||||||
{
|
{
|
||||||
/* Next write cluster */
|
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
VFATWriteCluster(DeviceExt, Buffer, CurrentCluster);
|
if (FirstCluster==1)
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
{
|
||||||
|
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Buffer);
|
||||||
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
Length = Length - DeviceExt->BytesPerCluster;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VFATWriteCluster(DeviceExt,Buffer,CurrentCluster);
|
||||||
|
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
||||||
|
}
|
||||||
|
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
||||||
|
Length2 -= DeviceExt->BytesPerCluster;
|
||||||
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
|
||||||
/* Write the remainder */
|
/* Write the remainder */
|
||||||
|
|
||||||
if (Length > 0)
|
if (Length2 > 0)
|
||||||
{
|
{
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
/* Read in the existing cluster data */
|
||||||
memcpy(Temp, Buffer, Length);
|
if (FirstCluster==1)
|
||||||
VFATWriteCluster(DeviceExt, Temp, CurrentCluster);
|
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Temp);
|
||||||
|
else
|
||||||
|
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
|
memcpy(Temp, Buffer, Length2);
|
||||||
|
if (FirstCluster==1)
|
||||||
|
{
|
||||||
|
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
|
||||||
|
,DeviceExt->Boot->SectorsPerCluster,Temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
|
||||||
}
|
}
|
||||||
//FIXME : set last write time and date
|
//FIXME : set last write time and date
|
||||||
if(Fcb->entry.FileSize<WriteOffset+Length)
|
if(Fcb->entry.FileSize<WriteOffset+Length
|
||||||
|
&& !(Fcb->entry.Attrib &FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
{
|
||||||
Fcb->entry.FileSize=WriteOffset+Length;
|
Fcb->entry.FileSize=WriteOffset+Length;
|
||||||
//FIXME : update entry in directory
|
// update entry in directory
|
||||||
|
updEntry(DeviceExt,FileObject);
|
||||||
|
}
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -1194,27 +1265,35 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PDEVICE_EXTENSION DeviceExt;
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
ULONG RequestedDisposition,RequestedOptions;
|
||||||
|
|
||||||
DPRINT("FsdCreate(DeviceObject %08lx, Irp %08lx)\n",
|
DPRINT("FsdCreate(DeviceObject %08lx, Irp %08lx)\n",
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
Irp);
|
Irp);
|
||||||
|
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
CHECKPOINT;
|
RequestedDisposition = ((Stack->Parameters.Create.Options>>24)&0xff);
|
||||||
|
RequestedOptions=Stack->Parameters.Create.Options&FILE_VALID_OPTION_FLAGS;
|
||||||
|
DbgPrint("CROptions=%x\n",Stack->Parameters.Create.Options);
|
||||||
|
DbgPrint("REquestedOptions=%x\n",RequestedOptions);
|
||||||
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;
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if(RequestedDisposition==FILE_CREATE
|
||||||
|
||RequestedDisposition==FILE_OPEN_IF
|
||||||
|
||RequestedDisposition==FILE_OVERWRITE_IF)
|
||||||
|
{
|
||||||
|
DbgPrint("try to create file\n");
|
||||||
|
Status=addEntry(DeviceExt,FileObject,RequestedOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1375,7 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PDEVICE_EXTENSION DeviceExt;
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
|
||||||
IoCreateDevice(DriverObject,
|
IoCreateDevice(VFATDriverObject,
|
||||||
sizeof(DEVICE_EXTENSION),
|
sizeof(DEVICE_EXTENSION),
|
||||||
NULL,
|
NULL,
|
||||||
FILE_DEVICE_FILE_SYSTEM,
|
FILE_DEVICE_FILE_SYSTEM,
|
||||||
|
@ -1444,11 +1523,11 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
|
|
||||||
DbgPrint("VFAT 0.0.6\n");
|
DbgPrint("VFAT 0.0.6\n");
|
||||||
pFirstFcb=NULL;
|
pFirstFcb=NULL;
|
||||||
DriverObject = _DriverObject;
|
VFATDriverObject = _DriverObject;
|
||||||
|
|
||||||
RtlInitAnsiString(&astr,"\\Device\\VFAT");
|
RtlInitAnsiString(&astr,"\\Device\\VFAT");
|
||||||
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
|
RtlAnsiStringToUnicodeString(&ustr,&astr,TRUE);
|
||||||
ret = IoCreateDevice(DriverObject,0,&ustr,
|
ret = IoCreateDevice(VFATDriverObject,0,&ustr,
|
||||||
FILE_DEVICE_FILE_SYSTEM,0,FALSE,&DeviceObject);
|
FILE_DEVICE_FILE_SYSTEM,0,FALSE,&DeviceObject);
|
||||||
if (ret!=STATUS_SUCCESS)
|
if (ret!=STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -1456,18 +1535,18 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject->Flags = DO_DIRECT_IO;
|
DeviceObject->Flags = DO_DIRECT_IO;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
|
VFATDriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
|
VFATDriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
|
||||||
DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
|
VFATDriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
|
||||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
VFATDriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
||||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
VFATDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||||
FsdFileSystemControl;
|
FsdFileSystemControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
VFATDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||||
FsdQueryInformation;
|
FsdQueryInformation;
|
||||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
VFATDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||||
FsdDirectoryControl;
|
FsdDirectoryControl;
|
||||||
|
|
||||||
DriverObject->DriverUnload = NULL;
|
VFATDriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
IoRegisterFileSystem(DeviceObject);
|
IoRegisterFileSystem(DeviceObject);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue