Added support for directory/file removing/deleting.

Fixed the overwriting bug between addEntry() and updEntry().
Change FindFile() from serach with a sector and index to search with a single index.

svn path=/trunk/; revision=2171
This commit is contained in:
Hartmut Birr 2001-08-14 20:47:30 +00:00
parent 52a23385a1
commit cc2e3f0806
8 changed files with 569 additions and 388 deletions

View file

@ -1,4 +1,4 @@
/* $Id: close.c,v 1.7 2001/05/10 04:02:21 rex Exp $ /* $Id: close.c,v 1.8 2001/08/14 20:47:30 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -26,6 +26,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
{ {
PVFATFCB pFcb; PVFATFCB pFcb;
PVFATCCB pCcb; PVFATCCB pCcb;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n", DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n",
DeviceExt, FileObject); DeviceExt, FileObject);
@ -38,12 +39,30 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
{ {
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
if (FileObject->FileName.Buffer)
{
// This a FO, that was created outside from FSD.
// Some FO's are created with IoCreateStreamFileObject() insid from FSD.
// This FO's haven't a FileName.
pFcb = pCcb->pFcb;
if (FileObject->DeletePending)
{
if (pFcb->Flags & FCB_DELETE_PENDING)
{
delEntry (DeviceExt, FileObject);
}
else
Status = STATUS_DELETE_PENDING;
}
FileObject->FsContext2 = NULL;
vfatReleaseFCB (DeviceExt, pFcb);
}
else
FileObject->FsContext2 = NULL;
pFcb = pCcb->pFcb;
vfatReleaseFCB (DeviceExt, pFcb);
ExFreePool (pCcb); ExFreePool (pCcb);
return STATUS_SUCCESS; return Status;
} }
NTSTATUS STDCALL NTSTATUS STDCALL
@ -59,7 +78,9 @@ VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp)
DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
ExAcquireResourceExclusiveLite (&DeviceExtension->DirResource, TRUE);
Status = VfatCloseFile (DeviceExtension, FileObject); Status = VfatCloseFile (DeviceExtension, FileObject);
ExReleaseResourceLite (&DeviceExtension->DirResource);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.31 2001/08/03 19:00:41 hbirr Exp $ /* $Id: create.c,v 1.32 2001/08/14 20:47:30 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -97,84 +97,116 @@ static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pN
pName [toIndex] = L'\0'; pName [toIndex] = L'\0';
} }
BOOLEAN NTSTATUS
GetEntryName (PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop, GetEntryName(PDEVICE_EXTENSION DeviceExt,
PDEVICE_EXTENSION DeviceExt, ULONG * _StartingSector) PVOID Block,
PFILE_OBJECT FileObject,
PWSTR Name,
PULONG pIndex,
PULONG pIndex2)
/* /*
* 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; NTSTATUS Status;
slot *test2; FATDirEntry * test;
ULONG Offset = *_Offset; slot * test2;
ULONG StartingSector = *_StartingSector;
ULONG jloop = *_jloop;
ULONG cpos; ULONG cpos;
ULONG Offset = *pIndex % ENTRIES_PER_SECTOR;
test = (FATDirEntry *) Block; ULONG Read;
test2 = (slot *) Block;
*Name = 0; *Name = 0;
while (TRUE)
if (IsDeletedEntry (Block, Offset))
{ {
return (FALSE); test = (FATDirEntry *) Block;
} test2 = (slot *) Block;
if (vfatIsDirEntryEndMarker(&test[Offset]))
{
return STATUS_NO_MORE_ENTRIES;
}
if (test2[Offset].attr == 0x0f && !vfatIsDirEntryDeleted(&test[Offset]))
{
*Name = 0;
if (pIndex2)
*pIndex2 = *pIndex; // start of dir entry
if (test2[Offset].attr == 0x0f) DPRINT (" long name entry found at %d\n", *pIndex);
{
vfat_initstr (Name, 256);
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);
cpos = 0; DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) && 5, test2 [Offset].name0_4,
(test2[Offset].attr > 0)) 6, test2 [Offset].name5_10,
2, test2 [Offset].name11_12);
vfat_initstr (Name, 255);
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);
DPRINT (" longName: [%S]\n", Name);
cpos = 0;
while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) &&
(test2[Offset].attr > 0))
{ {
Offset++; (*pIndex)++;
Offset++;
if (Offset == ENTRIES_PER_SECTOR) if (Offset == ENTRIES_PER_SECTOR)
{ {
Offset = 0; Offset = 0;
/* FIXME: Check status */ Status = VfatReadFile (DeviceExt, FileObject, Block, BLOCKSIZE,
GetNextSector (DeviceExt, StartingSector, &StartingSector, FALSE); *pIndex * sizeof(FATDirEntry), &Read, TRUE);
jloop++; if (!NT_SUCCESS(Status) || Read != BLOCKSIZE)
/* FIXME: Check status */ {
VfatReadSectors (DeviceExt->StorageDevice, return STATUS_NO_MORE_ENTRIES;
StartingSector, 1, Block); }
test2 = (slot *) Block; test2 = (slot *) Block;
} }
DPRINT (" long name entry found at %d\n", *pIndex);
DPRINT (" name chunk1:[%.*S] chunk2:[%.*S] chunk3:[%.*S]\n",
5, test2 [Offset].name0_4,
6, test2 [Offset].name5_10,
2, test2 [Offset].name11_12);
cpos++; cpos++;
vfat_movstr (Name, 13, 0, cpos * 13); vfat_movstr (Name, 13, 0, cpos * 13);
vfat_wcsncpy (Name, test2[Offset].name0_4, 5); vfat_wcsncpy (Name, test2[Offset].name0_4, 5);
vfat_wcsncat (Name, test2[Offset].name5_10, 5, 6); vfat_wcsncat (Name, test2[Offset].name5_10, 5, 6);
vfat_wcsncat (Name, test2[Offset].name11_12, 11, 2); vfat_wcsncat (Name, test2[Offset].name11_12, 11, 2);
DPRINT (" longName: [%S]\n", Name);
} }
(*pIndex)++;
Offset++; Offset++;
if (Offset == ENTRIES_PER_SECTOR) if (Offset == ENTRIES_PER_SECTOR)
{ {
Offset = 0; Offset = 0;
/* FIXME: Check status */ Status = VfatReadFile (DeviceExt, FileObject, Block, BLOCKSIZE,
GetNextSector (DeviceExt, StartingSector, &StartingSector, FALSE); *pIndex * sizeof(FATDirEntry), &Read, TRUE);
jloop++; if (!NT_SUCCESS(Status) || Read != BLOCKSIZE)
/* FIXME: Check status */ {
VfatReadSectors (DeviceExt->StorageDevice, StartingSector, 1, Block); return STATUS_NO_MORE_ENTRIES;
test2 = (slot *) Block; }
test2 = (slot *) Block;
test = (FATDirEntry*) Block;
}
} }
*_Offset = Offset;
*_jloop = jloop;
*_StartingSector = StartingSector;
if (IsDeletedEntry (Block, Offset))
return FALSE;
else else
return TRUE; {
} if (vfatIsDirEntryEndMarker(&test[Offset]))
vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name); return STATUS_NO_MORE_ENTRIES;
if (vfatIsDirEntryDeleted(&test[Offset]))
return (TRUE); return STATUS_UNSUCCESSFUL;
if (*Name == 0)
{
vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name);
if (pIndex2)
*pIndex2 = *pIndex;
}
break;
}
}
return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS
@ -259,44 +291,68 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
return (STATUS_UNSUCCESSFUL); return (STATUS_UNSUCCESSFUL);
} }
NTSTATUS NTSTATUS
FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, FindFile (PDEVICE_EXTENSION DeviceExt,
PVFATFCB Parent, PWSTR FileToFind, ULONG * StartSector, PVFATFCB Fcb,
ULONG * Entry) PVFATFCB Parent,
PWSTR FileToFind,
ULONG *pDirIndex,
ULONG *pDirIndex2)
/* /*
* FUNCTION: Find a file * FUNCTION: Find a file
*/ */
{ {
ULONG i, j;
ULONG Size;
char *block;
WCHAR name[256]; WCHAR name[256];
WCHAR name2[14]; WCHAR name2[14];
ULONG StartingSector; FILE_OBJECT tmpFileObject;
ULONG NextCluster; char * block;
WCHAR TempStr[2]; WCHAR TempStr[2];
NTSTATUS Status; NTSTATUS Status;
ULONG len; ULONG len;
ULONG DirIndex;
ULONG Offset;
ULONG FirstCluster;
ULONG Read;
BOOL isRoot;
BOOL first;
// DPRINT ("FindFile(Parent %x, FileToFind '%S')\n", Parent, FileToFind); DPRINT ("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n", Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName); DPRINT ("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName);
isRoot = FALSE;
DirIndex = 0;
if (wcslen (FileToFind) == 0) if (wcslen (FileToFind) == 0)
{
CHECKPOINT;
TempStr[0] = (WCHAR) '.';
TempStr[1] = 0;
FileToFind = (PWSTR)&TempStr;
}
if (Parent)
{
FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Parent->entry);
if (DeviceExt->FatType == FAT32)
{ {
CHECKPOINT; if (FirstCluster == ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster)
TempStr[0] = (WCHAR) '.'; isRoot = TRUE;
TempStr[1] = 0;
FileToFind = (PWSTR)&TempStr;
} }
else
if (Parent == NULL || Parent->entry.FirstCluster == 1)
{ {
Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */ if (FirstCluster == 1)
StartingSector = DeviceExt->rootStart; isRoot = TRUE;
NextCluster = 0; }
if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0) }
|| (FileToFind[0] == '.' && FileToFind[1] == 0)) else
isRoot = TRUE;
if (isRoot)
{
if (DeviceExt->FatType == FAT32)
FirstCluster = ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster;
else
FirstCluster = 1;
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 */
CHECKPOINT; CHECKPOINT;
@ -308,130 +364,107 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE; Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
Fcb->entry.FirstCluster = 2; {
Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0];
Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1];
}
else else
Fcb->entry.FirstCluster = 1; Fcb->entry.FirstCluster = 1;
if (StartSector) if (pDirIndex)
*StartSector = StartingSector; *pDirIndex = 0;
if (Entry) if (pDirIndex2)
*Entry = 0; *pDirIndex2 = 0;
DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName); DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
return (STATUS_SUCCESS); return (STATUS_SUCCESS);
} }
} }
else else
{ {
DPRINT ("Parent->entry.FileSize %x\n", Parent->entry.FileSize); DPRINT ("Parent->entry.FileSize %x\n", Parent->entry.FileSize);
FirstCluster = vfatDirEntryGetFirstCluster (DeviceExt, &Parent->entry);
}
if (pDirIndex && (*pDirIndex))
DirIndex = *pDirIndex;
Size = ULONG_MAX;
if (DeviceExt->FatType == FAT32) memset (&tmpFileObject, 0, sizeof(FILE_OBJECT));
NextCluster = Parent->entry.FirstCluster
+ Parent->entry.FirstClusterHigh * 65536; Status = VfatOpenFile(DeviceExt, &tmpFileObject, Parent->PathName);
else if (!NT_SUCCESS(Status))
NextCluster = Parent->entry.FirstCluster; {
StartingSector = ClusterToSector (DeviceExt, NextCluster); if (pDirIndex)
if (Parent->entry.FirstCluster == 1 && DeviceExt->FatType != FAT32) *pDirIndex = DirIndex;
{ return (STATUS_UNSUCCESSFUL);
/* read of root directory in FAT16 or FAT12 */ }
StartingSector = DeviceExt->rootStart; Offset = DirIndex % ENTRIES_PER_SECTOR;
} first = TRUE;
}
block = ExAllocatePool (NonPagedPool, BLOCKSIZE); block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
if (StartSector && (*StartSector)) while(TRUE)
StartingSector = *StartSector; {
i = (Entry) ? (*Entry) : 0; if (first || Offset == ENTRIES_PER_SECTOR)
for (j = 0; j < Size; j++)
{ {
/* FIXME: Check status */ first = FALSE;
VfatReadSectors (DeviceExt->StorageDevice, StartingSector, 1, block); if (Offset == ENTRIES_PER_SECTOR)
Offset = 0;
for (i = (Entry) ? (*Entry) : 0; i < ENTRIES_PER_SECTOR; i++) Status = VfatReadFile (DeviceExt, &tmpFileObject, block, BLOCKSIZE,
{ (DirIndex - Offset) * sizeof(FATDirEntry), &Read, TRUE);
if (IsVolEntry ((PVOID) block, i)) if (!NT_SUCCESS(Status) || Read != BLOCKSIZE)
continue; {
if (IsLastEntry ((PVOID) block, i)) break;
{ }
if (StartSector)
*StartSector = StartingSector;
if (Entry)
*Entry = i;
ExFreePool (block);
return (STATUS_UNSUCCESSFUL);
}
if (GetEntryName
((PVOID) block, &i, name, &j, DeviceExt, &StartingSector))
{
vfat8Dot3ToString(((FATDirEntry *) block)[i].Filename,((FATDirEntry *) block)[i].Ext, name2);
if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
{
if (Parent && Parent->PathName)
{
len = wcslen(Parent->PathName);
CHECKPOINT;
memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR));
Fcb->ObjectName=&Fcb->PathName[len];
if (len != 1 || Fcb->PathName[0] != '\\')
{
Fcb->ObjectName[0] = '\\';
Fcb->ObjectName = &Fcb->ObjectName[1];
}
}
else
{
Fcb->ObjectName=Fcb->PathName;
Fcb->ObjectName[0]='\\';
Fcb->ObjectName=&Fcb->ObjectName[1];
}
memcpy (&Fcb->entry, &((FATDirEntry *) block)[i],
sizeof (FATDirEntry));
vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH);
if (StartSector)
*StartSector = StartingSector;
if (Entry)
*Entry = i;
ExFreePool (block);
DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
return (STATUS_SUCCESS);
}
}
}
/* not found in this sector, try next : */
/* directory can be fragmented although it is best to keep them
unfragmented. Should we change this to also use GetNextSector?
GetNextSector was originally implemented to handle the case above */
if (Entry)
*Entry = 0;
/* FIXME: Check status */
GetNextSector (DeviceExt, StartingSector, &StartingSector, FALSE);
if ((Parent != NULL && Parent->entry.FirstCluster != 1)
|| DeviceExt->FatType == FAT32)
{
if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1))
{
Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster,
FALSE);
if (NextCluster == 0 || NextCluster == 0xffffffff)
{
if (StartSector)
*StartSector = StartingSector;
if (Entry)
*Entry = i;
ExFreePool (block);
return (STATUS_UNSUCCESSFUL);
}
StartingSector = ClusterToSector (DeviceExt, NextCluster);
}
}
} }
if (StartSector) if (vfatIsDirEntryVolume(&((FATDirEntry*)block)[Offset]))
*StartSector = StartingSector; {
if (Entry) Offset++;
*Entry = i; DirIndex++;
continue;
}
Status = GetEntryName (DeviceExt, block, &tmpFileObject, name, &DirIndex, pDirIndex2);
if (Status == STATUS_NO_MORE_ENTRIES)
break;
Offset = DirIndex % ENTRIES_PER_SECTOR;
if (NT_SUCCESS(Status))
{
vfat8Dot3ToString(((FATDirEntry *) block)[Offset].Filename,((FATDirEntry *) block)[Offset].Ext, name2);
if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
{
if (Parent && Parent->PathName)
{
len = wcslen(Parent->PathName);
CHECKPOINT;
memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR));
Fcb->ObjectName=&Fcb->PathName[len];
if (len != 1 || Fcb->PathName[0] != '\\')
{
Fcb->ObjectName[0] = '\\';
Fcb->ObjectName = &Fcb->ObjectName[1];
}
}
else
{
Fcb->ObjectName=Fcb->PathName;
Fcb->ObjectName[0]='\\';
Fcb->ObjectName=&Fcb->ObjectName[1];
}
memcpy (&Fcb->entry, &((FATDirEntry *) block)[Offset],
sizeof (FATDirEntry));
vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH);
if (pDirIndex)
*pDirIndex = DirIndex;
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex);
ExFreePool (block);
VfatCloseFile(DeviceExt, &tmpFileObject);
return STATUS_SUCCESS;
}
}
Offset++;
DirIndex++;
}
if (pDirIndex)
*pDirIndex = DirIndex;
ExFreePool (block); ExFreePool (block);
VfatCloseFile(DeviceExt, &tmpFileObject);
return (STATUS_UNSUCCESSFUL); return (STATUS_UNSUCCESSFUL);
} }
@ -518,7 +551,13 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
return Status; return Status;
} }
} }
if (Fcb->Flags & FCB_DELETE_PENDING)
{
vfatReleaseFCB (DeviceExt, Fcb);
if (AbsFileName)
ExFreePool (AbsFileName);
return STATUS_DELETE_PENDING;
}
DPRINT ("Attaching FCB to fileObject\n"); DPRINT ("Attaching FCB to fileObject\n");
Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject); Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
@ -561,7 +600,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
c = FileObject->FileName.Buffer; c = FileObject->FileName.Buffer;
while (*c != 0) while (*c != 0)
{ {
if (*c == L'*' || *c == L'?') if (*c == L'*' || *c == L'?' || (*c == L'\\' && c[1] == L'\\'))
{ {
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID; Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
@ -583,6 +622,11 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
return Status; return Status;
} }
if (Status == STATUS_DELETE_PENDING)
{
Irp->IoStatus.Status = Status;
return Status;
}
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
/* /*
@ -609,22 +653,22 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
} }
} }
else else
{ {
/* /*
* Otherwise fail if the caller wanted to create a new file * Otherwise fail if the caller wanted to create a new file
*/ */
if (RequestedDisposition == FILE_CREATE) if (RequestedDisposition == FILE_CREATE)
{ {
Irp->IoStatus.Information = FILE_EXISTS; Irp->IoStatus.Information = FILE_EXISTS;
Status = STATUS_OBJECT_NAME_COLLISION; Status = STATUS_OBJECT_NAME_COLLISION;
} }
pCcb = FileObject->FsContext2; pCcb = FileObject->FsContext2;
pFcb = pCcb->pFcb; pFcb = pCcb->pFcb;
/* /*
* If requested then delete the file and create a new one with the * If requested then delete the file and create a new one with the
* same name * same name
*/ */
if (RequestedDisposition == FILE_SUPERSEDE) if (RequestedDisposition == FILE_SUPERSEDE)
{ {
ULONG Cluster, NextCluster; ULONG Cluster, NextCluster;
/* FIXME set size to 0 and free clusters */ /* FIXME set size to 0 and free clusters */
@ -638,34 +682,34 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
pFcb->entry.FirstClusterHigh = 0; pFcb->entry.FirstClusterHigh = 0;
updEntry (DeviceExt, FileObject); updEntry (DeviceExt, FileObject);
while (Cluster != 0xffffffff && Cluster > 1) while (Cluster != 0xffffffff && Cluster > 1)
{ {
Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, TRUE); Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, TRUE);
WriteCluster (DeviceExt, Cluster, 0); WriteCluster (DeviceExt, Cluster, 0);
Cluster = NextCluster; Cluster = NextCluster;
} }
} }
/* /*
* Check the file has the requested attributes * Check the file has the requested attributes
*/ */
if ((RequestedOptions & FILE_NON_DIRECTORY_FILE) if ((RequestedOptions & FILE_NON_DIRECTORY_FILE)
&& (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) && (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{ {
Status = STATUS_FILE_IS_A_DIRECTORY; Status = STATUS_FILE_IS_A_DIRECTORY;
} }
if ((RequestedOptions & FILE_DIRECTORY_FILE) if ((RequestedOptions & FILE_DIRECTORY_FILE)
&& !(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) && !(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{ {
Status = STATUS_NOT_A_DIRECTORY; Status = STATUS_NOT_A_DIRECTORY;
} }
/* FIXME : test share access */ /* FIXME : test share access */
/* FIXME : test write access if requested */ /* FIXME : test write access if requested */
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
VfatCloseFile (DeviceExt, FileObject); VfatCloseFile (DeviceExt, FileObject);
else else
Irp->IoStatus.Information = FILE_OPENED; Irp->IoStatus.Information = FILE_OPENED;
/* FIXME : make supersed or overwrite if requested */ /* FIXME : make supersed or overwrite if requested */
} }
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;

View file

@ -276,8 +276,8 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
if (OldSector) if (OldSector)
pCcb->StartEntry++; pCcb->StartEntry++;
RC = RC =
FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartSector, FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL);
&pCcb->StartEntry); pCcb->StartSector = 1;
DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC, DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC,
pCcb->StartSector, pCcb->StartEntry); pCcb->StartSector, pCcb->StartEntry);
if (NT_SUCCESS (RC)) if (NT_SUCCESS (RC))

View file

@ -1,4 +1,4 @@
/* $Id: dirwr.c,v 1.20 2001/08/03 19:01:17 hbirr Exp $ /* $Id: dirwr.c,v 1.21 2001/08/14 20:47:30 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -90,81 +90,58 @@ FillSlot (slot * Slot, WCHAR * FileName)
} }
} }
NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject) NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
/* /*
update an existing FAT entry update an existing FAT entry
*/ */
{ {
WCHAR DirName[MAX_PATH], *FileName, *PathFileName; VFATFCB Fcb;
VFATFCB FileFcb; VFATCCB Ccb;
ULONG Sector = 0, Entry = 0; ULONG Entry = 0;
PUCHAR Buffer;
FATDirEntry *pEntries;
NTSTATUS status; NTSTATUS status;
FILE_OBJECT FileObject; FILE_OBJECT FileObject;
PVFATCCB pDirCcb; PVFATFCB pDirFcb = NULL, pFcb = NULL;
PVFATFCB pDirFcb, pFcb; PWCHAR pName;
short i, posCar, NameLen;
PathFileName = pFileObject->FileName.Buffer; DPRINT ("updEntry PathFileName \'%S\'\n", pFileObject->FileName.Buffer);
pFcb = ((PVFATCCB) pFileObject->FsContext2)->pFcb;
DPRINT ("PathFileName \'%S\'\n", PathFileName);
//find last \ in PathFileName status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb, pFileObject->FileName.Buffer);
posCar = -1; if (pFcb != NULL)
for (i = 0; PathFileName[i]; i++) {
if (PathFileName[i] == '\\') vfatReleaseFCB(DeviceExt, pFcb);
posCar = i; }
if (posCar == -1) if (!NT_SUCCESS(status))
return STATUS_UNSUCCESSFUL; {
FileName = &PathFileName[posCar + 1]; if (pDirFcb != NULL)
for (NameLen = 0; FileName[NameLen]; NameLen++); {
vfatReleaseFCB(DeviceExt, pDirFcb);
}
return status;
}
// extract directory name from pathname pName = ((PVFATCCB)(pFileObject->FsContext2))->pFcb->ObjectName;
if (posCar == 0) if (*pName == L'\\')
{ {
// root dir pName ++;
DirName[0] = L'\\'; }
DirName[1] = 0; status = FindFile (DeviceExt, &Fcb, pDirFcb, pName, &Entry, NULL);
}
else
{
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
DirName[posCar] = 0;
}
if (FileName[0] == 0 && DirName[0] == 0)
return STATUS_SUCCESS; //root : nothing to do ?
memset (&FileObject, 0, sizeof (FILE_OBJECT));
DPRINT ("open directory \'%S\' for update of entry \'%S\'\n", DirName,
FileName);
status = VfatOpenFile (DeviceExt, &FileObject, DirName);
if (!NT_SUCCESS (status))
{
DbgPrint ("Failed to open \'%S\'. Status %lx\n", DirName, status);
return status;
}
pDirCcb = (PVFATCCB) FileObject.FsContext2;
assert (pDirCcb);
pDirFcb = pDirCcb->pFcb;
assert (pDirFcb);
FileFcb.ObjectName = &FileFcb.PathName[0];
status = FindFile (DeviceExt, &FileFcb, pDirFcb, FileName, &Sector, &Entry);
if (NT_SUCCESS (status)) if (NT_SUCCESS (status))
{ {
Buffer = ExAllocatePool (NonPagedPool, BLOCKSIZE); DPRINT ("update entry: %d\n", Entry);
DPRINT ("update entry: sector %d, entry %d\n", Sector, Entry); memset (&FileObject, 0, sizeof(FILE_OBJECT));
VfatReadSectors (DeviceExt->StorageDevice, Sector, 1, Buffer); memset (&Ccb, 0, sizeof(VFATCCB));
pEntries = (FATDirEntry *) Buffer; FileObject.FsContext2 = &Ccb;
memcpy (&pEntries[Entry], &pFcb->entry, sizeof (FATDirEntry)); FileObject.FsContext = &pDirFcb->RFCB;
VfatWriteSectors (DeviceExt->StorageDevice, Sector, 1, Buffer); Ccb.pFcb = pDirFcb;
ExFreePool (Buffer); status = VfatWriteFile(DeviceExt, &FileObject, &pFcb->entry,
sizeof(FATDirEntry), Entry * sizeof(FATDirEntry), FALSE);
if (!NT_SUCCESS (status))
DbgPrint ("Failed to open \'%S\'. Status %lx\n", pDirFcb->PathName, status);
} }
VfatCloseFile (DeviceExt, &FileObject); vfatReleaseFCB(DeviceExt, pDirFcb);
return status; return status;
} }
NTSTATUS NTSTATUS
addEntry (PDEVICE_EXTENSION DeviceExt, addEntry (PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT pFileObject, ULONG RequestedOptions, UCHAR ReqAttr) PFILE_OBJECT pFileObject, ULONG RequestedOptions, UCHAR ReqAttr)
@ -184,11 +161,9 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
PUCHAR Buffer, Buffer2; PUCHAR Buffer, Buffer2;
BOOLEAN needTilde = FALSE, needLong = FALSE; BOOLEAN needTilde = FALSE, needLong = FALSE;
PVFATFCB newFCB; PVFATFCB newFCB;
PVFATCCB newCCB;
ULONG CurrentCluster; ULONG CurrentCluster;
LARGE_INTEGER SystemTime, LocalTime; LARGE_INTEGER SystemTime, LocalTime;
ULONG BytesPerCluster; NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS Status;
PVFATFCB pFcb; PVFATFCB pFcb;
PVFATCCB pCcb; PVFATCCB pCcb;
@ -204,8 +179,17 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
FileName = &PathFileName[posCar + 1]; FileName = &PathFileName[posCar + 1];
for (NameLen = 0; FileName[NameLen]; NameLen++); for (NameLen = 0; FileName[NameLen]; NameLen++);
// extract directory name from pathname // extract directory name from pathname
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR)); if (posCar == 0)
DirName[posCar] = 0; {
// root dir
DirName[0] = L'\\';
DirName[1] = 0;
}
else
{
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
DirName[posCar] = 0;
}
// open parent directory // open parent directory
memset (&FileObject, 0, sizeof (FILE_OBJECT)); memset (&FileObject, 0, sizeof (FILE_OBJECT));
status = VfatOpenFile (DeviceExt, &FileObject, DirName); status = VfatOpenFile (DeviceExt, &FileObject, DirName);
@ -420,7 +404,9 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
DPRINT1 ("VfatReadFile did not read a complete directory entry\n"); DPRINT1 ("VfatReadFile did not read a complete directory entry\n");
break; break;
} }
if (IsDeletedEntry (&FatEntry, 0)) if (vfatIsDirEntryEndMarker(&FatEntry))
break;
if (vfatIsDirEntryDeleted(&FatEntry))
nbFree++; nbFree++;
else else
nbFree = 0; nbFree = 0;
@ -432,7 +418,18 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
if (RequestedOptions & FILE_DIRECTORY_FILE) if (RequestedOptions & FILE_DIRECTORY_FILE)
{ {
NextCluster (DeviceExt, 0, &CurrentCluster, TRUE); CurrentCluster = 0xffffffff;
status = NextCluster (DeviceExt, 0, &CurrentCluster, TRUE);
if (CurrentCluster == 0xffffffff || !NT_SUCCESS(status))
{
VfatCloseFile (DeviceExt, &FileObject);
ExFreePool (Buffer);
if (!NT_SUCCESS(status))
{
return status;
}
return STATUS_DISK_FULL;
}
// zero the cluster // zero the cluster
Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster); Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
memset (Buffer2, 0, DeviceExt->BytesPerCluster); memset (Buffer2, 0, DeviceExt->BytesPerCluster);
@ -452,7 +449,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
status = status =
VfatWriteFile (DeviceExt, &FileObject, Buffer, VfatWriteFile (DeviceExt, &FileObject, Buffer,
sizeof (FATDirEntry) * nbSlots, Offset, FALSE); sizeof (FATDirEntry) * nbSlots, Offset, FALSE);
DPRINT ("VfatWriteFile() returned: %x\n", status); DPRINT ("VfatWriteFile() returned: %x\n", status);
} }
else else
{ //write at end of directory { //write at end of directory
@ -462,40 +459,25 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
sizeof (FATDirEntry) * (nbSlots + 1), Offset, FALSE); sizeof (FATDirEntry) * (nbSlots + 1), Offset, FALSE);
} }
DPRINT ("write entry offset %d status=%x\n", Offset, status); DPRINT ("write entry offset %d status=%x\n", Offset, status);
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB)); if (!NT_SUCCESS(status))
memset (newCCB, 0, sizeof (VFATCCB)); {
newFCB = vfatNewFCB (NULL); VfatCloseFile (DeviceExt, &FileObject);
newCCB->pFcb = newFCB; if (RequestedOptions & FILE_DIRECTORY_FILE)
newCCB->PtrFileObject = pFileObject;
newFCB->RefCount++;
BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
if (BytesPerCluster >= PAGESIZE)
{ {
Status = CcRosInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb, // free the reserved cluster
BytesPerCluster); WriteCluster(DeviceExt, CurrentCluster, 0);
}
else
{
Status = CcRosInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb,
PAGESIZE);
} }
ExFreePool (Buffer);
return status;
}
/* // FEXME: check status
* FIXME : initialize all fields in FCB and CCB vfatMakeFCBFromDirEntry (DeviceExt, pFcb, FileName, pEntry, &newFCB);
*/ vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
vfatAddFCBToTable (DeviceExt, newFCB);
memcpy (&newFCB->entry, pEntry, sizeof (FATDirEntry));
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename); DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
DPRINT ("new : entry=%11.11s\n", pEntry->Filename); DPRINT ("new : entry=%11.11s\n", pEntry->Filename);
vfat_wcsncpy (newFCB->PathName, PathFileName, MAX_PATH);
newFCB->ObjectName = newFCB->PathName + (PathFileName - FileName);
newFCB->pDevExt = DeviceExt;
pFileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
pFileObject->SectionObjectPointers = &newFCB->SectionObjectPointers;
pFileObject->FsContext = (PVOID)&newFCB->RFCB;
pFileObject->FsContext2 = newCCB;
if (RequestedOptions & FILE_DIRECTORY_FILE) if (RequestedOptions & FILE_DIRECTORY_FILE)
{ {
// create . and .. // create . and ..
@ -520,4 +502,72 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS
delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
/*
deleting an existing FAT entry
*/
{
VFATFCB Fcb;
PVFATFCB pFcb = NULL, pDirFcb = NULL;
NTSTATUS status;
PWSTR pName;
ULONG Entry = 0, startEntry, Read, CurrentCluster, NextCluster, i;
FILE_OBJECT FileObject;
VFATCCB Ccb;
FATDirEntry DirEntry;
DPRINT ("delEntry PathFileName \'%S\'\n", pFileObject->FileName.Buffer);
status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb, pFileObject->FileName.Buffer);
if (pFcb != NULL)
{
vfatReleaseFCB(DeviceExt, pFcb);
}
if (!NT_SUCCESS(status))
{
if (pDirFcb != NULL)
{
vfatReleaseFCB(DeviceExt, pDirFcb);
}
return status;
}
pName = ((PVFATCCB)(pFileObject->FsContext2))->pFcb->ObjectName;
if (*pName == L'\\')
{
pName ++;
}
status = FindFile (DeviceExt, &Fcb, pDirFcb, pName, &Entry, &startEntry);
if (NT_SUCCESS(status))
{
DPRINT ("delete entry: %d to %d\n", startEntry, Entry);
memset (&FileObject, 0, sizeof(FILE_OBJECT));
memset (&Ccb, 0, sizeof(VFATCCB));
FileObject.FsContext2 = &Ccb;
FileObject.FsContext = &pDirFcb->RFCB;
Ccb.pFcb = pDirFcb;
for (i = startEntry; i <= Entry; i++)
{
// FIXME: check status
VfatReadFile (DeviceExt, &FileObject, &DirEntry, sizeof (FATDirEntry),
i * sizeof(FATDirEntry), &Read, FALSE);
DirEntry.Filename[0] = 0xe5;
// FIXME: check status
VfatWriteFile (DeviceExt, &FileObject, &DirEntry, sizeof(FATDirEntry),
i * sizeof(FATDirEntry), FALSE);
}
CurrentCluster = vfatDirEntryGetFirstCluster (DeviceExt, &DirEntry);
while (CurrentCluster && CurrentCluster != 0xffffffff)
{
GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, FALSE);
// FIXME: check status
WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster;
}
}
return status;
}
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: fcb.c,v 1.8 2001/07/28 07:05:56 hbirr Exp $ /* $Id: fcb.c,v 1.9 2001/08/14 20:47:30 hbirr Exp $
* *
* *
* FILE: fcb.c * FILE: fcb.c
@ -95,7 +95,7 @@ vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
pFCB->RefCount--; pFCB->RefCount--;
if (pFCB->RefCount <= 0 && !vfatFCBIsDirectory (pVCB, pFCB)) if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
{ {
RemoveEntryList (&pFCB->FcbListEntry); RemoveEntryList (&pFCB->FcbListEntry);
CcRosReleaseFileCache (NULL, pFCB->RFCB.Bcb); CcRosReleaseFileCache (NULL, pFCB->RFCB.Bcb);
@ -183,7 +183,7 @@ vfatFCBInitializeCache (PVCB vcb, PVFATFCB fcb)
KeBugCheck (0); KeBugCheck (0);
} }
ObDereferenceObject (fileObject); ObDereferenceObject (fileObject);
fcb->isCacheInitialized = TRUE; fcb->Flags |= FCB_CACHE_INITIALIZED;
return status; return status;
} }
@ -356,8 +356,9 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY)); memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY));
vfatFCBInitializeCache (vcb, rcFCB); vfatFCBInitializeCache (vcb, rcFCB);
rcFCB->RefCount++;
vfatAddFCBToTable (vcb, rcFCB); vfatAddFCBToTable (vcb, rcFCB);
vfatGrabFCB (vcb, rcFCB); // vfatGrabFCB (vcb, rcFCB);
*fileFCB = rcFCB; *fileFCB = rcFCB;
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -387,7 +388,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
newCCB->PtrFileObject = fileObject; newCCB->PtrFileObject = fileObject;
fcb->pDevExt = vcb; fcb->pDevExt = vcb;
if (!fcb->isCacheInitialized) if (!(fcb->Flags & FCB_CACHE_INITIALIZED))
{ {
ULONG bytesPerCluster; ULONG bytesPerCluster;
ULONG fileCacheQuantum; ULONG fileCacheQuantum;
@ -403,7 +404,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
DbgPrint ("CcRosInitializeFileCache failed\n"); DbgPrint ("CcRosInitializeFileCache failed\n");
KeBugCheck (0); KeBugCheck (0);
} }
fcb->isCacheInitialized = TRUE; fcb->Flags |= FCB_CACHE_INITIALIZED;
} }
DPRINT ("file open: fcb:%x file size: %d\n", fcb, fcb->entry.FileSize); DPRINT ("file open: fcb:%x file size: %d\n", fcb, fcb->entry.FileSize);

View file

@ -1,4 +1,4 @@
/* $Id: finfo.c,v 1.8 2001/06/12 12:35:42 ekohl Exp $ /* $Id: finfo.c,v 1.9 2001/08/14 20:47:30 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -145,11 +145,65 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PFILE_DISPOSITION_INFORMATION DispositionInfo) PFILE_DISPOSITION_INFORMATION DispositionInfo)
{ {
KIRQL oldIrql;
VFATFCB tmpFcb;
WCHAR star[2];
ULONG Index;
NTSTATUS Status = STATUS_SUCCESS;
int count;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
DPRINT ("FsdSetDispositionInformation()\n"); DPRINT ("FsdSetDispositionInformation()\n");
FileObject->DeletePending = DispositionInfo->DoDeleteFile; assert (DeviceExt != NULL);
assert (DeviceExt->BytesPerCluster != 0);
assert (FCB != NULL);
return (STATUS_SUCCESS); if (!wcscmp(FCB->PathName, L"\\") || !wcscmp(FCB->ObjectName, L"..")
|| !wcscmp(FCB->ObjectName, L"."))
{
// we cannot delete a '.', '..' or the root directory
return STATUS_ACCESS_DENIED;
}
if (DispositionInfo->DoDeleteFile)
{
KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql);
count = FCB->RefCount;
if (FCB->RefCount > 1)
Status = STATUS_ACCESS_DENIED;
else
{
FCB->Flags |= FCB_DELETE_PENDING;
FileObject->DeletePending = TRUE;
}
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
DPRINT("RefCount:%d\n", count);
if (NT_SUCCESS(Status) && vfatFCBIsDirectory(DeviceExt, FCB))
{
memset (&tmpFcb, 0, sizeof(VFATFCB));
tmpFcb.ObjectName = tmpFcb.PathName;
star[0] = L'*';
star[1] = 0;
// skip '.' and '..', start by 2
Index = 2;
Status = FindFile (DeviceExt, &tmpFcb, FCB, star, &Index, NULL);
if (NT_SUCCESS(Status))
{
DPRINT1("found: \'%S\'\n", tmpFcb.PathName);
Status = STATUS_DIRECTORY_NOT_EMPTY;
FCB->Flags &= ~FCB_DELETE_PENDING;
FileObject->DeletePending = FALSE;
}
else
{
Status = STATUS_SUCCESS;
}
}
}
else
FileObject->DeletePending = FALSE;
return Status;
} }
static NTSTATUS static NTSTATUS

View file

@ -1,5 +1,5 @@
/* $Id: rw.c,v 1.30 2001/08/08 19:04:13 hbirr Exp $ /* $Id: rw.c,v 1.31 2001/08/14 20:47:30 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -366,7 +366,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
assert (DeviceExt != NULL); assert (DeviceExt != NULL);
assert (DeviceExt->BytesPerCluster != 0); assert (DeviceExt->BytesPerCluster != 0);
assert (FileObject != NULL); assert (FileObject != NULL);
assert (FileObject->FsContext != NULL); assert (FileObject->FsContext2 != NULL);
DPRINT("VfatReadFile(DeviceExt %x, FileObject %x, Buffer %x, " DPRINT("VfatReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
"Length %d, ReadOffset 0x%x)\n", DeviceExt, FileObject, Buffer, "Length %d, ReadOffset 0x%x)\n", DeviceExt, FileObject, Buffer,

View file

@ -1,4 +1,4 @@
/* $Id: vfat.h,v 1.34 2001/07/28 07:05:56 hbirr Exp $ */ /* $Id: vfat.h,v 1.35 2001/08/14 20:47:30 hbirr Exp $ */
#include <ddk/ntifs.h> #include <ddk/ntifs.h>
@ -115,6 +115,9 @@ typedef struct
ULONG FatType; ULONG FatType;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB; } DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
#define FCB_CACHE_INITIALIZED 0x0001
#define FCB_DELETE_PENDING 0x0002
typedef struct _VFATFCB typedef struct _VFATFCB
{ {
REACTOS_COMMON_FCB_HEADER RFCB; REACTOS_COMMON_FCB_HEADER RFCB;
@ -128,7 +131,7 @@ typedef struct _VFATFCB
PDEVICE_EXTENSION pDevExt; PDEVICE_EXTENSION pDevExt;
LIST_ENTRY FcbListEntry; LIST_ENTRY FcbListEntry;
struct _VFATFCB* parentFcb; struct _VFATFCB* parentFcb;
BOOL isCacheInitialized; ULONG Flags;
} VFATFCB, *PVFATFCB; } VFATFCB, *PVFATFCB;
typedef struct _VFATCCB typedef struct _VFATCCB
@ -253,6 +256,8 @@ addEntry(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr); PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr);
NTSTATUS NTSTATUS
updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject); updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
NTSTATUS
delEntry(PDEVICE_EXTENSION, PFILE_OBJECT);
/* /*
* String functions * String functions
@ -335,6 +340,7 @@ ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt,
PFAT_DIR_ENTRY pDirEntry); PFAT_DIR_ENTRY pDirEntry);
BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry); BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry); BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
void vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry, PWSTR pEntryName); void vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry, PWSTR pEntryName);
NTSTATUS vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt, NTSTATUS vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
PVFATFCB pDirectoryFCB, PVFATFCB pDirectoryFCB,
@ -375,6 +381,11 @@ NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
PVFATFCB *pParentFCB, PVFATFCB *pParentFCB,
PVFATFCB *pFCB, PVFATFCB *pFCB,
const PWSTR pFileName); const PWSTR pFileName);
NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb,
PVFATFCB directoryFCB,
PWSTR longName,
PFAT_DIR_ENTRY dirEntry,
PVFATFCB * fileFCB);