correct bug in FindFile : support fragmented directories

suppress \ at end of filename

svn path=/trunk/; revision=222
This commit is contained in:
jean 1999-02-10 12:52:48 +00:00
parent 4b8117cedc
commit a649212d32

View file

@ -1,5 +1,4 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -33,7 +32,6 @@
#include "vfat.h" #include "vfat.h"
//#include "dbgpool.c"
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
@ -75,7 +73,6 @@ ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
CurrentCluster = Block[CurrentCluster]; CurrentCluster = Block[CurrentCluster];
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff) if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff; CurrentCluster = 0xffffffff;
DPRINT("Returning %x\n",CurrentCluster);
return(CurrentCluster); return(CurrentCluster);
} }
@ -100,10 +97,8 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
Entry = (CBlock[FATOffset] >> 4); Entry = (CBlock[FATOffset] >> 4);
Entry |= (CBlock[FATOffset+1] << 4); Entry |= (CBlock[FATOffset+1] << 4);
} }
DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff) if (Entry >= 0xff8 && Entry <= 0xfff)
Entry = 0xffffffff; Entry = 0xffffffff;
DPRINT("Returning %x\n",Entry);
return(Entry); return(Entry);
} }
@ -113,8 +108,6 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
*/ */
{ {
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
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)
@ -313,9 +306,7 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
*/ */
{ {
ULONG LastCluster, NewCluster; ULONG LastCluster, NewCluster;
DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n", UCHAR *Buffer2;
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); LastCluster=GetNextCluster(DeviceExt,CurrentCluster);
/* Check to see if we must append or overwrite */ /* Check to see if we must append or overwrite */
@ -335,6 +326,11 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
found AU */ found AU */
if(CurrentCluster) if(CurrentCluster)
WriteCluster(DeviceExt, CurrentCluster, NewCluster); WriteCluster(DeviceExt, CurrentCluster, NewCluster);
// fill cluster with zero : essential for directories, not for file
Buffer2=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
memset(Buffer2,0,DeviceExt->BytesPerCluster);
VFATWriteCluster(DeviceExt,Buffer2,NewCluster);
ExFreePool(Buffer2);
/* Return NewCluster as CurrentCluster */ /* Return NewCluster as CurrentCluster */
return NewCluster; return NewCluster;
} }
@ -436,7 +432,7 @@ wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount)
return(dest); return(dest);
} }
wchar_t * vfat_movstr(const wchar_t *src, ULONG dpos, wchar_t * vfat_movstr(wchar_t *src, ULONG dpos,
ULONG spos, ULONG len) ULONG spos, ULONG len)
/* /*
* FUNCTION: Move the characters in a string to a new position in the same * FUNCTION: Move the characters in a string to a new position in the same
@ -465,109 +461,87 @@ wchar_t * vfat_movstr(const wchar_t *src, ULONG dpos,
return(src); return(src);
} }
BOOLEAN IsLastEntry(PVOID Block, ULONG Offset) BOOLEAN IsLastEntry(FATDirEntry *pEntry)
/* /*
* FUNCTION: Determine if the given directory entry is the last * FUNCTION: Determine if the given directory entry is the last
*/ */
{ {
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0); return(pEntry->Filename[0] == 0);
} }
BOOLEAN IsVolEntry(PVOID Block, ULONG Offset) BOOLEAN IsVolEntry(FATDirEntry *pEntry)
/* /*
* FUNCTION: Determine if the given directory entry is a vol entry * FUNCTION: Determine if the given directory entry is a vol entry
*/ */
{ {
if( (((FATDirEntry *)Block)[Offset].Attrib)==0x28 ) return TRUE; if( (pEntry->Attrib)==0x28 ) return TRUE;
else return FALSE; else return FALSE;
} }
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset) BOOLEAN IsDeletedEntry(FATDirEntry *pEntry)
/* /*
* FUNCTION: Determines if the given entry is a deleted one * FUNCTION: Determines if the given entry is a deleted one
*/ */
{ {
/* Checks special character */ /* Checks special character */
return (pEntry->Filename[0] == 0xe5);
return ((((FATDirEntry *)Block)[Offset].Filename[0] == 0xe5));
} }
BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop, BOOLEAN GetEntryName(PDEVICE_EXTENSION DeviceExt,PVfatFCB pFcb,PULONG pEntry
PDEVICE_EXTENSION DeviceExt, ULONG * _StartingSector) , PWSTR Name,FATDirEntry *pFatEntry)
/* /*
* FUNCTION: Retrieves the file name, be it in short or long file name format * FUNCTION: Retrieves the file name, be it in short or long file name format
*/ */
{ {
FATDirEntry* test; slot* test2;
slot* test2; ULONG cpos,LengthRead;
ULONG Offset = *_Offset; NTSTATUS Status;
ULONG StartingSector = *_StartingSector;
ULONG jloop = *_jloop;
ULONG cpos;
WCHAR tmp[256];
test = (FATDirEntry *)Block; test2 = (slot *)pFatEntry;
test2 = (slot *)Block;
*Name = 0; *Name = 0;
if (IsDeletedEntry(Block,Offset)) if (IsDeletedEntry(pFatEntry))
{ {
return(FALSE); return(FALSE);
} }
if(test2[Offset].attr == 0x0f) if(test2->attr == 0x0f)
{ // long name : we read the long name, then we read the entry
vfat_initstr(Name, 256);
vfat_wcsncpy(Name,test2->name0_4,5);
vfat_wcsncat(Name,test2->name5_10,5,6);
vfat_wcsncat(Name,test2->name11_12,11,2);
cpos=0;
while((test2->id!=0x41) && (test2->id!=0x01) &&
(test2->attr>0))
{ {
vfat_initstr(Name, 256); (*pEntry)++;
vfat_wcsncpy(Name,test2[Offset].name0_4,5); Status=FsdReadFile(DeviceExt,pFcb,pFatEntry,sizeof(FATDirEntry)
vfat_wcsncat(Name,test2[Offset].name5_10,5,6); ,(*pEntry)*sizeof(FATDirEntry),&LengthRead);
vfat_wcsncat(Name,test2[Offset].name11_12,11,2); if(!(NT_SUCCESS(Status))) return FALSE;
cpos++;
cpos=0; vfat_movstr(Name, 13, 0, cpos*13);
while((test2[Offset].id!=0x41) && (test2[Offset].id!=0x01) && vfat_wcsncpy(Name,test2->name0_4, 5);
(test2[Offset].attr>0)) vfat_wcsncat(Name,test2->name5_10,5,6);
{ vfat_wcsncat(Name,test2->name11_12,11,2);
Offset++; }
if(Offset==ENTRIES_PER_SECTOR) { // now read the entry
Offset=0; (*pEntry)++;
StartingSector++;//FIXME : nor always the next sector Status=FsdReadFile(DeviceExt,pFcb,pFatEntry,sizeof(FATDirEntry)
jloop++; ,(*pEntry)*sizeof(FATDirEntry),&LengthRead);
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,Block); if (IsDeletedEntry(pFatEntry))
test2 = (slot *)Block;
}
cpos++;
vfat_movstr(Name, 13, 0, cpos*13);
vfat_wcsncpy(Name, test2[Offset].name0_4, 5);
vfat_wcsncat(Name,test2[Offset].name5_10,5,6);
vfat_wcsncat(Name,test2[Offset].name11_12,11,2);
}
if (IsDeletedEntry(Block,Offset+1))
{
Offset++;
*_Offset = Offset;
*_jloop = jloop;
*_StartingSector = StartingSector;
return(FALSE); return(FALSE);
} return(TRUE);
}
*_Offset = Offset;
*_jloop = jloop;
*_StartingSector = StartingSector;
return(TRUE);
}
RtlAnsiToUnicode(Name,test[Offset].Filename,8); RtlAnsiToUnicode(Name,pFatEntry->Filename,8);
if (test[Offset].Ext[0]!=' ') if (pFatEntry->Ext[0]!=' ')
{ {
RtlCatAnsiToUnicode(Name,".",1); RtlCatAnsiToUnicode(Name,".",1);
} }
RtlCatAnsiToUnicode(Name,test[Offset].Ext,3); RtlCatAnsiToUnicode(Name,pFatEntry->Ext,3);
*_Offset = Offset;
return(TRUE); return(TRUE);
} }
@ -615,39 +589,22 @@ BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2)
} }
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb, NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
PVfatFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry) PVfatFCB Parent, PWSTR FileToFind,ULONG *Entry)
/* /*
* FUNCTION: Find a file * FUNCTION: Find a file
*/ */
{ {
ULONG i, j; ULONG i;
ULONG Size; ULONG Size;
char* block;
WCHAR name[256]; WCHAR name[256];
ULONG StartingSector; FATDirEntry FatEntry;
ULONG NextCluster; NTSTATUS Status;
WCHAR TempStr[2]; ULONG LengthRead;
VfatFCB TempFcb;
DPRINT("FindFile(Parent %x, FileToFind '%w')\n",Parent,FileToFind);
if (wcslen(FileToFind)==0)
{
TempStr[0] = (WCHAR)'.';
TempStr[1] = 0;
FileToFind=&TempStr;
}
if (Parent != NULL)
{
DPRINT("Parent->entry.FirstCluster %d\n",Parent->entry.FirstCluster);
}
if (Parent == NULL||Parent->entry.FirstCluster==1) if (Parent == NULL||Parent->entry.FirstCluster==1)
{ {
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
StartingSector = DeviceExt->rootStart; if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0))
NextCluster=0;
if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0) ||
(FileToFind[0]=='.' && FileToFind[1]==0))
{// it's root : complete essentials fields then return ok {// it's root : complete essentials fields then return ok
memset(Fcb,0,sizeof(VfatFCB)); memset(Fcb,0,sizeof(VfatFCB));
memset(Fcb->entry.Filename,' ',11); memset(Fcb->entry.Filename,' ',11);
@ -656,96 +613,47 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
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?
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=0; if(Entry) *Entry=0;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
} }
else if (Parent==NULL)
{ {
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize); memset(&TempFcb,0,sizeof(VfatFCB));
memset(TempFcb.entry.Filename,' ',11);
Size = ULONG_MAX; TempFcb.entry.FileSize=DeviceExt->rootDirectorySectors*BLOCKSIZE;
if (DeviceExt->FatType == FAT32) TempFcb.entry.Attrib=FILE_ATTRIBUTE_DIRECTORY;
NextCluster = Parent->entry.FirstCluster if (DeviceExt->FatType == FAT32)
+Parent->entry.FirstClusterHigh*65536; TempFcb.entry.FirstCluster=2;
else else
NextCluster = Parent->entry.FirstCluster; TempFcb.entry.FirstCluster=1;//FIXME : is 1 the good value for mark root?
StartingSector = ClusterToSector(DeviceExt, NextCluster); Parent=&TempFcb;
if(Parent->entry.FirstCluster==1 && DeviceExt->FatType!=FAT32)
{// read of root directory in FAT16 or FAT12
StartingSector=DeviceExt->rootStart;
}
} }
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
if (StartSector && (*StartSector)) StartingSector=*StartSector;
i=(Entry)?(*Entry):0; i=(Entry)?(*Entry):0;
DPRINT("FindFile : start at sector %lx, entry %ld\n",StartingSector,i); for(; ; i++)
for (j=0; j<Size; j++)
{ {
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block); Status=FsdReadFile(DeviceExt,Parent,&FatEntry,sizeof(FATDirEntry)
,i*sizeof(FATDirEntry),&LengthRead);
for (i=(Entry)?(*Entry):0; i<ENTRIES_PER_SECTOR; i++) if(!NT_SUCCESS(Status))
break;
if (IsVolEntry(&FatEntry))
continue;
if (IsLastEntry(&FatEntry))
{ {
if (IsVolEntry((PVOID)block,i)) if(Entry) *Entry=i;
continue; return(STATUS_UNSUCCESSFUL);
if (IsLastEntry((PVOID)block,i))
{
ExFreePool(block);
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
return(STATUS_UNSUCCESSFUL);
}
if (GetEntryName((PVOID)block,&i,name,&j,DeviceExt,&StartingSector))
{
DPRINT("Comparing '%w' '%w'\n",name,FileToFind);
if (wstrcmpjoki(name,FileToFind))
{
/* In the case of a long filename, the firstcluster is stored in
the next record -- where it's short name is */
if(((FATDirEntry *)block)[i].Attrib==0x0f) i++;
if( i==(ENTRIES_PER_SECTOR))
{// entry is in next sector
StartingSector++;
//FIXME : treat case of next sector fragmented
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
i=0;
}
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
sizeof(FATDirEntry));
vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH);
ExFreePool(block);
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
return(STATUS_SUCCESS);
}
}
} }
// not found in this sector, try next : if (GetEntryName(DeviceExt,Parent,&i,name,&FatEntry))
/* directory can be fragmented although it is best to keep them
unfragmented */
if(Entry) *Entry=0;
StartingSector++;
if ((Parent != NULL && Parent->entry.FirstCluster!=1)
|| DeviceExt->FatType ==FAT32)
{ {
if(StartingSector==ClusterToSector(DeviceExt,NextCluster+1)) if (wstrcmpjoki(name,FileToFind))
{ {
NextCluster = GetNextCluster(DeviceExt,NextCluster); memcpy(&Fcb->entry,&FatEntry,sizeof(FATDirEntry));
if (NextCluster == 0||NextCluster==0xffffffff) vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH);
{ if(Entry) *Entry=i;
if(StartSector) *StartSector=StartingSector; return(STATUS_SUCCESS);
if(Entry) *Entry=i;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
StartingSector = ClusterToSector(DeviceExt,NextCluster);
} }
} }
} }
ExFreePool(block);
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i; if(Entry) *Entry=i;
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
@ -758,21 +666,9 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
{ {
PVfatFCB pFcb; PVfatFCB pFcb;
PVfatCCB pCcb; PVfatCCB pCcb;
DPRINT("FsdCloseFile(DeviceExt %x, FileObject %x)\n",
DeviceExt,FileObject);
//FIXME : update entry in directory ? //FIXME : update entry in directory ?
pCcb = (PVfatCCB)(FileObject->FsContext2); pCcb = (PVfatCCB)(FileObject->FsContext2);
DPRINT("pCcb %x\n",pCcb);
if (pCcb == NULL)
{
return(STATUS_SUCCESS);
}
pFcb = pCcb->pFcb; pFcb = pCcb->pFcb;
pFcb->RefCount--; pFcb->RefCount--;
if(pFcb->RefCount<=0) if(pFcb->RefCount<=0)
{ {
@ -805,13 +701,10 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PFILE_OBJECT pRelFileObject; PFILE_OBJECT pRelFileObject;
PWSTR AbsFileName=NULL; PWSTR AbsFileName=NULL;
short i,j; short i,j;
if(FileObject->FileName.Length>0
DPRINT("FsdOpenFile(%08lx, %08lx, %w)\n", && FileName[FileObject->FileName.Length-1]=='\\')
DeviceExt, FileName[FileObject->FileName.Length-1]=0;
FileObject, // treat relative name
FileName);
//FIXME : treat relative name
if(FileObject->RelatedFileObject) if(FileObject->RelatedFileObject)
{ {
DbgPrint("try related for %w\n",FileName); DbgPrint("try related for %w\n",FileName);
@ -828,7 +721,7 @@ DbgPrint("try related for %w\n",FileName);
return Status; return Status;
} }
// construct absolute path name // construct absolute path name
AbsFileName=ExAllocatePool(NonPagedPool,MAX_PATH); AbsFileName=ExAllocatePool(NonPagedPool,MAX_PATH*sizeof(WCHAR));
for (i=0;pRelFcb->PathName[i];i++) for (i=0;pRelFcb->PathName[i];i++)
AbsFileName[i]=pRelFcb->PathName[i]; AbsFileName[i]=pRelFcb->PathName[i];
AbsFileName[i++]='\\'; AbsFileName[i++]='\\';
@ -860,60 +753,63 @@ DbgPrint("try related for %w\n",FileName);
Fcb = ExAllocatePool(NonPagedPool, sizeof(VfatFCB)); Fcb = ExAllocatePool(NonPagedPool, sizeof(VfatFCB));
memset(Fcb,0,sizeof(VfatFCB)); memset(Fcb,0,sizeof(VfatFCB));
Fcb->ObjectName=Fcb->PathName; Fcb->ObjectName=Fcb->PathName;
next = &string[0]; next = &string[0];
current = next+1;
if(*next==0) // root
{
Status = FindFile(DeviceExt,Fcb,ParentFcb,next,NULL);
ParentFcb=Fcb;
Fcb=NULL;
}
else
while (next!=NULL) while (next!=NULL)
{ {
*next = '\\'; *next = '\\';
current = next+1; current = next+1;
next = wcschr(next+1,'\\'); next = wcschr(next+1,'\\');
if (next!=NULL) if (next!=NULL)
{ *next=0;
*next=0; Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL);
} if (Status != STATUS_SUCCESS)
DPRINT("current '%w'\n",current); {
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL); if (Fcb != NULL)
if (Status != STATUS_SUCCESS) ExFreePool(Fcb);
{ if (ParentFcb != NULL)
if (Fcb != NULL) ExFreePool(ParentFcb);
ExFreePool(Fcb); if(AbsFileName)ExFreePool(AbsFileName);
if (ParentFcb != NULL) return(Status);
ExFreePool(ParentFcb); }
if(AbsFileName)ExFreePool(AbsFileName); Temp = Fcb;
return(Status); if (ParentFcb == NULL)
} {
Temp = Fcb; Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB));
if (ParentFcb == NULL) memset(Fcb,0,sizeof(VfatFCB));
{ Fcb->ObjectName=Fcb->PathName;
Fcb = ExAllocatePool(NonPagedPool,sizeof(VfatFCB)); }
memset(Fcb,0,sizeof(VfatFCB)); else Fcb = ParentFcb;
Fcb->ObjectName=Fcb->PathName; ParentFcb = Temp;
}
else Fcb = ParentFcb;
ParentFcb = Temp;
} }
FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB; CHECKPOINT;
newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB)); FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB;
memset(newCCB,0,sizeof(VfatCCB)); newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB));
FileObject->FsContext2 = newCCB; memset(newCCB,0,sizeof(VfatCCB));
newCCB->pFcb=ParentFcb; FileObject->FsContext2 = newCCB;
newCCB->PtrFileObject=FileObject; newCCB->pFcb=ParentFcb;
ParentFcb->RefCount++; newCCB->PtrFileObject=FileObject;
//FIXME : initialize all fields in FCB and CCB ParentFcb->RefCount++;
ParentFcb->nextFcb=pFirstFcb; //FIXME : initialize all fields in FCB and CCB
pFirstFcb=ParentFcb; ParentFcb->nextFcb=pFirstFcb;
pFirstFcb=ParentFcb;
vfat_wcsncpy(ParentFcb->PathName,FileName,MAX_PATH); vfat_wcsncpy(ParentFcb->PathName,FileName,MAX_PATH);
ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName); ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName);
ParentFcb->pDevExt=DeviceExt; ParentFcb->pDevExt=DeviceExt;
DPRINT("file open, fcb=%x\n",ParentFcb); if(Fcb) ExFreePool(Fcb);
DPRINT("FileSize %d\n",ParentFcb->entry.FileSize); if(AbsFileName)ExFreePool(AbsFileName);
if(Fcb) ExFreePool(Fcb);
if(AbsFileName)ExFreePool(AbsFileName);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
/* /*
* FUNCTION: Tests if the device contains a filesystem that can be mounted * FUNCTION: Tests if the device contains a filesystem that can be mounted
* by this fsd * by this fsd
@ -921,7 +817,7 @@ DbgPrint("try related for %w\n",FileName);
{ {
BootSector* Boot; BootSector* Boot;
Boot = ExAllocatePool(NonPagedPool,512); Boot = ExAllocatePool(NonPagedPool,BLOCKSIZE);
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot); VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
@ -944,8 +840,7 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
{ {
DPRINT("Mounting VFAT device..."); DPRINT("Mounting VFAT device...");
DPRINT("DeviceExt %x\n",DeviceExt); DPRINT("DeviceExt %x\n",DeviceExt);
DeviceExt->Boot = ExAllocatePool(NonPagedPool,BLOCKSIZE);
DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot); VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot);
DPRINT("DeviceExt->Boot->BytesPerSector %x\n", DPRINT("DeviceExt->Boot->BytesPerSector %x\n",
@ -995,10 +890,6 @@ void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
*/ */
{ {
ULONG Sector; ULONG Sector;
DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
DeviceExt,Buffer,Cluster);
Sector = ClusterToSector(DeviceExt, Cluster); Sector = ClusterToSector(DeviceExt, Cluster);
VFATReadSectors(DeviceExt->StorageDevice, VFATReadSectors(DeviceExt->StorageDevice,
@ -1013,9 +904,6 @@ void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
*/ */
{ {
ULONG Sector; ULONG Sector;
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
DeviceExt,Buffer,Cluster);
Sector = ClusterToSector(DeviceExt, Cluster); Sector = ClusterToSector(DeviceExt, Cluster);
VFATWriteSectors(DeviceExt->StorageDevice, VFATWriteSectors(DeviceExt->StorageDevice,
@ -1024,7 +912,7 @@ void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
Buffer); Buffer);
} }
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
PVOID Buffer, ULONG Length, ULONG ReadOffset, PVOID Buffer, ULONG Length, ULONG ReadOffset,
PULONG LengthRead) PULONG LengthRead)
/* /*
@ -1034,29 +922,19 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG FileOffset; ULONG FileOffset;
ULONG FirstCluster; ULONG FirstCluster;
PVfatFCB Fcb;
PVOID Temp; PVOID Temp;
ULONG TempLength; ULONG TempLength;
/* PRECONDITION */ /* PRECONDITION */
assert(DeviceExt != NULL); assert(DeviceExt != NULL);
assert(DeviceExt->BytesPerCluster != 0); assert(DeviceExt->BytesPerCluster != 0);
assert(FileObject != NULL);
assert(FileObject->FsContext != NULL);
DPRINT("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
Length,ReadOffset);
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;
FirstCluster=CurrentCluster; FirstCluster=CurrentCluster;
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
if (ReadOffset >= Fcb->entry.FileSize if (ReadOffset >= Fcb->entry.FileSize
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) && !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{ {
@ -1082,7 +960,6 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
{ {
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster); CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
} }
CHECKPOINT;
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0) if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
{ {
if (FirstCluster==1) if (FirstCluster==1)
@ -1106,7 +983,6 @@ 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)
{ {
if (FirstCluster==1) if (FirstCluster==1)
@ -1130,7 +1006,6 @@ 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;
@ -1151,7 +1026,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
PVOID Buffer, ULONG Length, ULONG WriteOffset) PVOID Buffer, ULONG Length, ULONG WriteOffset)
/* /*
* FUNCTION: Writes data to file * FUNCTION: Writes data to file
@ -1160,17 +1035,19 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
ULONG CurrentCluster; ULONG CurrentCluster;
ULONG FileOffset; ULONG FileOffset;
ULONG FirstCluster; ULONG FirstCluster;
PVfatFCB Fcb;
PVfatCCB pCcb;
PVOID Temp; PVOID Temp;
ULONG TempLength,Length2=Length; ULONG TempLength,Length2=Length;
CHECKPOINT;
/* Locate the first cluster of the file */ /* Locate the first cluster of the file */
assert(FileObject);
pCcb=(PVfatCCB)(FileObject->FsContext2);
assert(pCcb);
Fcb = pCcb->pFcb;
assert(Fcb); assert(Fcb);
if(WriteOffset==FILE_WRITE_TO_END_OF_FILE)
WriteOffset=Fcb->entry.FileSize;
if(!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) && WriteOffset>Fcb->entry.FileSize)
{
//FIXME : we must extend the file with null bytes then write buffer
return STATUS_UNSUCCESSFUL;
}
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
@ -1275,22 +1152,18 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
if (Length2 > 0) if (Length2 > 0)
{ {
CHECKPOINT;
if (CurrentCluster == 0) if (CurrentCluster == 0)
{ {
ExFreePool(Temp); ExFreePool(Temp);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
CHECKPOINT;
/* Read in the existing cluster data */ /* Read in the existing cluster data */
if (FirstCluster==1) if (FirstCluster==1)
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp); ,DeviceExt->Boot->SectorsPerCluster,Temp);
else else
VFATLoadCluster(DeviceExt,Temp,CurrentCluster); VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
CHECKPOINT;
memcpy(Temp, Buffer, Length2); memcpy(Temp, Buffer, Length2);
CHECKPOINT;
if (FirstCluster==1) if (FirstCluster==1)
{ {
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
@ -1299,14 +1172,13 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
else else
VFATWriteCluster(DeviceExt,Temp,CurrentCluster); VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
} }
CHECKPOINT;
//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.Attrib &FILE_ATTRIBUTE_DIRECTORY))
{ {
Fcb->entry.FileSize=WriteOffset+Length; Fcb->entry.FileSize=WriteOffset+Length;
// update entry in directory // update entry in directory
updEntry(DeviceExt,FileObject); updEntry(DeviceExt,Fcb);
} }
ExFreePool(Temp); ExFreePool(Temp);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -1322,8 +1194,6 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
DPRINT("FsdClose(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
Status = FsdCloseFile(DeviceExtension,FileObject); Status = FsdCloseFile(DeviceExtension,FileObject);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
@ -1345,7 +1215,6 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
ULONG RequestedDisposition,RequestedOptions; ULONG RequestedDisposition,RequestedOptions;
PVfatCCB pCcb; PVfatCCB pCcb;
PVfatFCB pFcb; PVfatFCB pFcb;
assert(DeviceObject); assert(DeviceObject);
assert(Irp); assert(Irp);
if(DeviceObject->Size==sizeof(DEVICE_OBJECT)) if(DeviceObject->Size==sizeof(DEVICE_OBJECT))
@ -1430,6 +1299,7 @@ NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PFILE_OBJECT FileObject = Stack->FileObject; PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
PVfatFCB pFcb;
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp); DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
@ -1437,7 +1307,9 @@ NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset); Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset);
Status = FsdWriteFile(DeviceExt,FileObject,Buffer,Length,Offset); assert(FileObject->FsContext2 != NULL);
pFcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
Status = FsdWriteFile(DeviceExt,pFcb,Buffer,Length,Offset);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length; Irp->IoStatus.Information = Length;
@ -1459,9 +1331,8 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PDEVICE_EXTENSION DeviceExt; PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status; NTSTATUS Status;
ULONG LengthRead; ULONG LengthRead;
PVfatFCB pFcb;
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
/* Precondition / Initialization */ /* Precondition / Initialization */
assert(Irp != NULL); assert(Irp != NULL);
Stack = IoGetCurrentIrpStackLocation(Irp); Stack = IoGetCurrentIrpStackLocation(Irp);
@ -1475,7 +1346,9 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
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);
Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset, assert(FileObject->FsContext2 != NULL);
pFcb = ((PVfatCCB)(FileObject->FsContext2))->pFcb;
Status = FsdReadFile(DeviceExt,pFcb,Buffer,Length,Offset,
&LengthRead); &LengthRead);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
@ -1539,7 +1412,6 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status); return(Status);
} }