mirror of
https://github.com/reactos/reactos.git
synced 2025-07-01 11:51:22 +00:00
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:
parent
52a23385a1
commit
cc2e3f0806
8 changed files with 569 additions and 388 deletions
|
@ -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;
|
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);
|
vfatReleaseFCB (DeviceExt, pFcb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FileObject->FsContext2 = NULL;
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -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]))
|
||||||
if (test2[Offset].attr == 0x0f)
|
|
||||||
{
|
{
|
||||||
vfat_initstr (Name, 256);
|
*Name = 0;
|
||||||
|
if (pIndex2)
|
||||||
|
*pIndex2 = *pIndex; // start of dir entry
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
vfat_initstr (Name, 255);
|
||||||
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);
|
||||||
cpos = 0;
|
cpos = 0;
|
||||||
while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) &&
|
while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) &&
|
||||||
(test2[Offset].attr > 0))
|
(test2[Offset].attr > 0))
|
||||||
{
|
{
|
||||||
|
(*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,
|
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]))
|
||||||
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
|
if (vfatIsDirEntryDeleted(&test[Offset]))
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
if (*Name == 0)
|
||||||
|
{
|
||||||
vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name);
|
vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name);
|
||||||
|
if (pIndex2)
|
||||||
return (TRUE);
|
*pIndex2 = *pIndex;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -259,29 +291,36 @@ 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;
|
CHECKPOINT;
|
||||||
|
@ -289,12 +328,29 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
TempStr[1] = 0;
|
TempStr[1] = 0;
|
||||||
FileToFind = (PWSTR)&TempStr;
|
FileToFind = (PWSTR)&TempStr;
|
||||||
}
|
}
|
||||||
|
if (Parent)
|
||||||
if (Parent == NULL || Parent->entry.FirstCluster == 1)
|
|
||||||
{
|
{
|
||||||
Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */
|
FirstCluster = vfatDirEntryGetFirstCluster(DeviceExt, &Parent->entry);
|
||||||
StartingSector = DeviceExt->rootStart;
|
if (DeviceExt->FatType == FAT32)
|
||||||
NextCluster = 0;
|
{
|
||||||
|
if (FirstCluster == ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster)
|
||||||
|
isRoot = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FirstCluster == 1)
|
||||||
|
isRoot = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0)
|
||||||
|| (FileToFind[0] == '.' && FileToFind[1] == 0))
|
|| (FileToFind[0] == '.' && FileToFind[1] == 0))
|
||||||
{
|
{
|
||||||
|
@ -308,13 +364,16 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -322,46 +381,51 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
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);
|
||||||
Size = ULONG_MAX;
|
|
||||||
if (DeviceExt->FatType == FAT32)
|
|
||||||
NextCluster = Parent->entry.FirstCluster
|
|
||||||
+ Parent->entry.FirstClusterHigh * 65536;
|
|
||||||
else
|
|
||||||
NextCluster = Parent->entry.FirstCluster;
|
|
||||||
StartingSector = ClusterToSector (DeviceExt, NextCluster);
|
|
||||||
if (Parent->entry.FirstCluster == 1 && DeviceExt->FatType != FAT32)
|
|
||||||
{
|
|
||||||
/* read of root directory in FAT16 or FAT12 */
|
|
||||||
StartingSector = DeviceExt->rootStart;
|
|
||||||
}
|
}
|
||||||
}
|
if (pDirIndex && (*pDirIndex))
|
||||||
block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
DirIndex = *pDirIndex;
|
||||||
if (StartSector && (*StartSector))
|
|
||||||
StartingSector = *StartSector;
|
|
||||||
i = (Entry) ? (*Entry) : 0;
|
|
||||||
for (j = 0; j < Size; j++)
|
|
||||||
{
|
|
||||||
/* FIXME: Check status */
|
|
||||||
VfatReadSectors (DeviceExt->StorageDevice, StartingSector, 1, block);
|
|
||||||
|
|
||||||
for (i = (Entry) ? (*Entry) : 0; i < ENTRIES_PER_SECTOR; i++)
|
|
||||||
|
memset (&tmpFileObject, 0, sizeof(FILE_OBJECT));
|
||||||
|
|
||||||
|
Status = VfatOpenFile(DeviceExt, &tmpFileObject, Parent->PathName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (IsVolEntry ((PVOID) block, i))
|
if (pDirIndex)
|
||||||
continue;
|
*pDirIndex = DirIndex;
|
||||||
if (IsLastEntry ((PVOID) block, i))
|
|
||||||
{
|
|
||||||
if (StartSector)
|
|
||||||
*StartSector = StartingSector;
|
|
||||||
if (Entry)
|
|
||||||
*Entry = i;
|
|
||||||
ExFreePool (block);
|
|
||||||
return (STATUS_UNSUCCESSFUL);
|
return (STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
if (GetEntryName
|
Offset = DirIndex % ENTRIES_PER_SECTOR;
|
||||||
((PVOID) block, &i, name, &j, DeviceExt, &StartingSector))
|
first = TRUE;
|
||||||
|
block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
||||||
|
while(TRUE)
|
||||||
{
|
{
|
||||||
vfat8Dot3ToString(((FATDirEntry *) block)[i].Filename,((FATDirEntry *) block)[i].Ext, name2);
|
if (first || Offset == ENTRIES_PER_SECTOR)
|
||||||
|
{
|
||||||
|
first = FALSE;
|
||||||
|
if (Offset == ENTRIES_PER_SECTOR)
|
||||||
|
Offset = 0;
|
||||||
|
Status = VfatReadFile (DeviceExt, &tmpFileObject, block, BLOCKSIZE,
|
||||||
|
(DirIndex - Offset) * sizeof(FATDirEntry), &Read, TRUE);
|
||||||
|
if (!NT_SUCCESS(Status) || Read != BLOCKSIZE)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vfatIsDirEntryVolume(&((FATDirEntry*)block)[Offset]))
|
||||||
|
{
|
||||||
|
Offset++;
|
||||||
|
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 (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
|
||||||
{
|
{
|
||||||
if (Parent && Parent->PathName)
|
if (Parent && Parent->PathName)
|
||||||
|
@ -383,55 +447,24 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
Fcb->ObjectName=&Fcb->ObjectName[1];
|
Fcb->ObjectName=&Fcb->ObjectName[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (&Fcb->entry, &((FATDirEntry *) block)[i],
|
memcpy (&Fcb->entry, &((FATDirEntry *) block)[Offset],
|
||||||
sizeof (FATDirEntry));
|
sizeof (FATDirEntry));
|
||||||
vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH);
|
vfat_wcsncpy (Fcb->ObjectName, name, MAX_PATH);
|
||||||
if (StartSector)
|
if (pDirIndex)
|
||||||
*StartSector = StartingSector;
|
*pDirIndex = DirIndex;
|
||||||
if (Entry)
|
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex);
|
||||||
*Entry = i;
|
|
||||||
ExFreePool (block);
|
ExFreePool (block);
|
||||||
DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
|
VfatCloseFile(DeviceExt, &tmpFileObject);
|
||||||
return (STATUS_SUCCESS);
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Offset++;
|
||||||
|
DirIndex++;
|
||||||
}
|
}
|
||||||
/* not found in this sector, try next : */
|
if (pDirIndex)
|
||||||
|
*pDirIndex = DirIndex;
|
||||||
/* 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)
|
|
||||||
*StartSector = StartingSector;
|
|
||||||
if (Entry)
|
|
||||||
*Entry = i;
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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] == '\\')
|
|
||||||
posCar = i;
|
|
||||||
if (posCar == -1)
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
FileName = &PathFileName[posCar + 1];
|
|
||||||
for (NameLen = 0; FileName[NameLen]; NameLen++);
|
|
||||||
|
|
||||||
// extract directory name from pathname
|
|
||||||
if (posCar == 0)
|
|
||||||
{
|
{
|
||||||
// root dir
|
vfatReleaseFCB(DeviceExt, pFcb);
|
||||||
DirName[0] = L'\\';
|
|
||||||
DirName[1] = 0;
|
|
||||||
}
|
}
|
||||||
else
|
if (!NT_SUCCESS(status))
|
||||||
{
|
{
|
||||||
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
|
if (pDirFcb != NULL)
|
||||||
DirName[posCar] = 0;
|
{
|
||||||
|
vfatReleaseFCB(DeviceExt, pDirFcb);
|
||||||
}
|
}
|
||||||
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;
|
return status;
|
||||||
}
|
}
|
||||||
pDirCcb = (PVFATCCB) FileObject.FsContext2;
|
|
||||||
assert (pDirCcb);
|
pName = ((PVFATCCB)(pFileObject->FsContext2))->pFcb->ObjectName;
|
||||||
pDirFcb = pDirCcb->pFcb;
|
if (*pName == L'\\')
|
||||||
assert (pDirFcb);
|
{
|
||||||
FileFcb.ObjectName = &FileFcb.PathName[0];
|
pName ++;
|
||||||
status = FindFile (DeviceExt, &FileFcb, pDirFcb, FileName, &Sector, &Entry);
|
}
|
||||||
|
status = FindFile (DeviceExt, &Fcb, pDirFcb, pName, &Entry, NULL);
|
||||||
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
|
||||||
|
if (posCar == 0)
|
||||||
|
{
|
||||||
|
// root dir
|
||||||
|
DirName[0] = L'\\';
|
||||||
|
DirName[1] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
|
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
|
||||||
DirName[posCar] = 0;
|
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);
|
||||||
|
@ -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);
|
|
||||||
newCCB->pFcb = newFCB;
|
|
||||||
newCCB->PtrFileObject = pFileObject;
|
|
||||||
newFCB->RefCount++;
|
|
||||||
|
|
||||||
BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
|
|
||||||
if (BytesPerCluster >= PAGESIZE)
|
|
||||||
{
|
{
|
||||||
Status = CcRosInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb,
|
VfatCloseFile (DeviceExt, &FileObject);
|
||||||
BytesPerCluster);
|
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||||
|
{
|
||||||
|
// free the reserved cluster
|
||||||
|
WriteCluster(DeviceExt, CurrentCluster, 0);
|
||||||
}
|
}
|
||||||
else
|
ExFreePool (Buffer);
|
||||||
{
|
return status;
|
||||||
Status = CcRosInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb,
|
|
||||||
PAGESIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// 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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue