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
-/* $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
* PROJECT: ReactOS kernel
/* FUNCTIONS ****************************************************************/
-NTSTATUS
+NTSTATUS
VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
/*
* FUNCTION: Closes a file
{
PVFATFCB pFcb;
PVFATCCB pCcb;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n",
DeviceExt, FileObject);
{
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);
- return STATUS_SUCCESS;
+ return Status;
}
NTSTATUS STDCALL
DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
+ ExAcquireResourceExclusiveLite (&DeviceExtension->DirResource, TRUE);
Status = VfatCloseFile (DeviceExtension, FileObject);
+ ExReleaseResourceLite (&DeviceExtension->DirResource);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
-/* $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
* PROJECT: ReactOS kernel
pName [toIndex] = L'\0';
}
-BOOLEAN
-GetEntryName (PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop,
- PDEVICE_EXTENSION DeviceExt, ULONG * _StartingSector)
+NTSTATUS
+GetEntryName(PDEVICE_EXTENSION DeviceExt,
+ 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
*/
{
- FATDirEntry *test;
- slot *test2;
- ULONG Offset = *_Offset;
- ULONG StartingSector = *_StartingSector;
- ULONG jloop = *_jloop;
+ NTSTATUS Status;
+ FATDirEntry * test;
+ slot * test2;
ULONG cpos;
-
- test = (FATDirEntry *) Block;
- test2 = (slot *) Block;
+ ULONG Offset = *pIndex % ENTRIES_PER_SECTOR;
+ ULONG Read;
*Name = 0;
-
- if (IsDeletedEntry (Block, Offset))
- {
- return (FALSE);
- }
-
- if (test2[Offset].attr == 0x0f)
+ while (TRUE)
{
- 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;
- while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) &&
- (test2[Offset].attr > 0))
+ 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
+
+ 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_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)
- {
- Offset = 0;
- /* FIXME: Check status */
- GetNextSector (DeviceExt, StartingSector, &StartingSector, FALSE);
- jloop++;
- /* FIXME: Check status */
- VfatReadSectors (DeviceExt->StorageDevice,
- StartingSector, 1, Block);
+ {
+ Offset = 0;
+ Status = VfatReadFile (DeviceExt, FileObject, Block, BLOCKSIZE,
+ *pIndex * sizeof(FATDirEntry), &Read, TRUE);
+ if (!NT_SUCCESS(Status) || Read != BLOCKSIZE)
+ {
+ return STATUS_NO_MORE_ENTRIES;
+ }
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++;
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);
- }
- Offset++;
- if (Offset == ENTRIES_PER_SECTOR)
- {
- Offset = 0;
- /* FIXME: Check status */
- GetNextSector (DeviceExt, StartingSector, &StartingSector, FALSE);
- jloop++;
- /* FIXME: Check status */
- VfatReadSectors (DeviceExt->StorageDevice, StartingSector, 1, Block);
- test2 = (slot *) Block;
+ DPRINT (" longName: [%S]\n", Name);
+ }
+ (*pIndex)++;
+ Offset++;
+ if (Offset == ENTRIES_PER_SECTOR)
+ {
+ Offset = 0;
+ Status = VfatReadFile (DeviceExt, FileObject, Block, BLOCKSIZE,
+ *pIndex * sizeof(FATDirEntry), &Read, TRUE);
+ if (!NT_SUCCESS(Status) || Read != BLOCKSIZE)
+ {
+ return STATUS_NO_MORE_ENTRIES;
+ }
+ test2 = (slot *) Block;
+ test = (FATDirEntry*) Block;
+ }
}
-
- *_Offset = Offset;
- *_jloop = jloop;
- *_StartingSector = StartingSector;
-
- if (IsDeletedEntry (Block, Offset))
- return FALSE;
else
- return TRUE;
- }
- vfat8Dot3ToString (test[Offset].Filename, test[Offset].Ext, Name);
-
- 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);
+ if (pIndex2)
+ *pIndex2 = *pIndex;
+ }
+ break;
+ }
+ }
+ return STATUS_SUCCESS;
}
NTSTATUS
return (STATUS_UNSUCCESSFUL);
}
-
NTSTATUS
-FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
- PVFATFCB Parent, PWSTR FileToFind, ULONG * StartSector,
- ULONG * Entry)
+FindFile (PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB Fcb,
+ PVFATFCB Parent,
+ PWSTR FileToFind,
+ ULONG *pDirIndex,
+ ULONG *pDirIndex2)
/*
* FUNCTION: Find a file
*/
{
- ULONG i, j;
- ULONG Size;
- char *block;
WCHAR name[256];
WCHAR name2[14];
- ULONG StartingSector;
- ULONG NextCluster;
+ FILE_OBJECT tmpFileObject;
+ char * block;
WCHAR TempStr[2];
NTSTATUS Status;
ULONG len;
-
-// DPRINT ("FindFile(Parent %x, FileToFind '%S')\n", Parent, FileToFind);
- DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName);
-
+ ULONG DirIndex;
+ ULONG Offset;
+ ULONG FirstCluster;
+ ULONG Read;
+ BOOL isRoot;
+ BOOL first;
+
+ 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);
+
+ isRoot = FALSE;
+ DirIndex = 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;
- TempStr[0] = (WCHAR) '.';
- TempStr[1] = 0;
- FileToFind = (PWSTR)&TempStr;
+ if (FirstCluster == ((struct _BootSector32*)(DeviceExt->Boot))->RootCluster)
+ isRoot = TRUE;
}
-
- if (Parent == NULL || Parent->entry.FirstCluster == 1)
+ else
{
- Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */
- StartingSector = DeviceExt->rootStart;
- NextCluster = 0;
- if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0)
- || (FileToFind[0] == '.' && FileToFind[1] == 0))
+ 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)
+ || (FileToFind[0] == '.' && FileToFind[1] == 0))
{
/* it's root : complete essentials fields then return ok */
CHECKPOINT;
Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY;
if (DeviceExt->FatType == FAT32)
- Fcb->entry.FirstCluster = 2;
+ {
+ Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0];
+ Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1];
+ }
else
Fcb->entry.FirstCluster = 1;
- if (StartSector)
- *StartSector = StartingSector;
- if (Entry)
- *Entry = 0;
- DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
+ if (pDirIndex)
+ *pDirIndex = 0;
+ if (pDirIndex2)
+ *pDirIndex2 = 0;
+ DPRINT("FindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
return (STATUS_SUCCESS);
}
- }
+ }
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)
- 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;
- }
- }
+
+ memset (&tmpFileObject, 0, sizeof(FILE_OBJECT));
+
+ Status = VfatOpenFile(DeviceExt, &tmpFileObject, Parent->PathName);
+ if (!NT_SUCCESS(Status))
+ {
+ if (pDirIndex)
+ *pDirIndex = DirIndex;
+ return (STATUS_UNSUCCESSFUL);
+ }
+ Offset = DirIndex % ENTRIES_PER_SECTOR;
+ first = TRUE;
block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
- if (StartSector && (*StartSector))
- StartingSector = *StartSector;
- i = (Entry) ? (*Entry) : 0;
- for (j = 0; j < Size; j++)
+ while(TRUE)
+ {
+ if (first || Offset == ENTRIES_PER_SECTOR)
{
- /* FIXME: Check status */
- VfatReadSectors (DeviceExt->StorageDevice, StartingSector, 1, block);
-
- for (i = (Entry) ? (*Entry) : 0; i < ENTRIES_PER_SECTOR; i++)
+ 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))
{
- if (IsVolEntry ((PVOID) block, i))
- continue;
- if (IsLastEntry ((PVOID) block, i))
- {
- 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))
+ vfat8Dot3ToString(((FATDirEntry *) block)[Offset].Filename,((FATDirEntry *) block)[Offset].Ext, name2);
+ if (wstrcmpjoki (name, FileToFind) || wstrcmpjoki (name2, FileToFind))
+ {
+ if (Parent && Parent->PathName)
{
- 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] != '\\')
{
- 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[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)
+ else
{
- if (StartSector)
- *StartSector = StartingSector;
- if (Entry)
- *Entry = i;
- ExFreePool (block);
- return (STATUS_UNSUCCESSFUL);
+ Fcb->ObjectName=Fcb->PathName;
+ Fcb->ObjectName[0]='\\';
+ Fcb->ObjectName=&Fcb->ObjectName[1];
}
- StartingSector = ClusterToSector (DeviceExt, NextCluster);
- }
- }
+
+ 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;
+ }
}
- if (StartSector)
- *StartSector = StartingSector;
- if (Entry)
- *Entry = i;
+ Offset++;
+ DirIndex++;
+ }
+ if (pDirIndex)
+ *pDirIndex = DirIndex;
ExFreePool (block);
+ VfatCloseFile(DeviceExt, &tmpFileObject);
return (STATUS_UNSUCCESSFUL);
}
-NTSTATUS
-vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject,
+NTSTATUS
+vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject,
PWSTR pRelativeFileName,
PWSTR *pAbsoluteFilename)
{
fcb = ccb->pFcb;
assert (fcb);
- /* verify related object is a directory and target name
+ /* verify related object is a directory and target name
don't start with \. */
- if (!(fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ if (!(fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|| (pRelativeFileName[0] != '\\'))
{
return STATUS_INVALID_PARAMETER;
}
/* construct absolute path name */
- assert (wcslen (fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
+ assert (wcslen (fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
<= MAX_PATH);
rcName = ExAllocatePool (NonPagedPool, MAX_PATH);
wcscpy (rcName, fcb->PathName);
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");
Status = vfatAttachFCBToFileObject (DeviceExt, Fcb, FileObject);
FileObject = Stack->FileObject;
DeviceExt = DeviceObject->DeviceExtension;
assert (DeviceExt);
-
+
/*
* Check for illegal characters in the file name
*/
c = FileObject->FileName.Buffer;
while (*c != 0)
{
- if (*c == L'*' || *c == L'?')
+ if (*c == L'*' || *c == L'?' || (*c == L'\\' && c[1] == L'\\'))
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_OBJECT_NAME_INVALID;
return Status;
}
+ if (Status == STATUS_DELETE_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+ return Status;
+ }
if (!NT_SUCCESS (Status))
{
/*
* If the file open failed then create the required file
*/
- if (RequestedDisposition == FILE_CREATE ||
- RequestedDisposition == FILE_OPEN_IF ||
- RequestedDisposition == FILE_OVERWRITE_IF ||
+ if (RequestedDisposition == FILE_CREATE ||
+ RequestedDisposition == FILE_OPEN_IF ||
+ RequestedDisposition == FILE_OVERWRITE_IF ||
RequestedDisposition == FILE_SUPERSEDE)
{
CHECKPOINT;
- Status =
+ Status =
addEntry (DeviceExt, FileObject, RequestedOptions,
(Stack->Parameters.
Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
}
}
else
- {
- /*
- * Otherwise fail if the caller wanted to create a new file
- */
- if (RequestedDisposition == FILE_CREATE)
+ {
+ /*
+ * Otherwise fail if the caller wanted to create a new file
+ */
+ if (RequestedDisposition == FILE_CREATE)
{
Irp->IoStatus.Information = FILE_EXISTS;
Status = STATUS_OBJECT_NAME_COLLISION;
- }
- pCcb = FileObject->FsContext2;
- pFcb = pCcb->pFcb;
- /*
- * If requested then delete the file and create a new one with the
- * same name
- */
- if (RequestedDisposition == FILE_SUPERSEDE)
+ }
+ pCcb = FileObject->FsContext2;
+ pFcb = pCcb->pFcb;
+ /*
+ * If requested then delete the file and create a new one with the
+ * same name
+ */
+ if (RequestedDisposition == FILE_SUPERSEDE)
{
ULONG Cluster, NextCluster;
/* FIXME set size to 0 and free clusters */
pFcb->entry.FirstClusterHigh = 0;
updEntry (DeviceExt, FileObject);
while (Cluster != 0xffffffff && Cluster > 1)
- {
- Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, TRUE);
- WriteCluster (DeviceExt, Cluster, 0);
- Cluster = NextCluster;
- }
+ {
+ Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, TRUE);
+ WriteCluster (DeviceExt, Cluster, 0);
+ Cluster = NextCluster;
+ }
}
- /*
- * Check the file has the requested attributes
- */
- if ((RequestedOptions & FILE_NON_DIRECTORY_FILE)
+ /*
+ * Check the file has the requested attributes
+ */
+ if ((RequestedOptions & FILE_NON_DIRECTORY_FILE)
&& (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{
Status = STATUS_FILE_IS_A_DIRECTORY;
}
- if ((RequestedOptions & FILE_DIRECTORY_FILE)
+ if ((RequestedOptions & FILE_DIRECTORY_FILE)
&& !(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{
Status = STATUS_NOT_A_DIRECTORY;
}
/* FIXME : test share access */
/* FIXME : test write access if requested */
- if (!NT_SUCCESS (Status))
- VfatCloseFile (DeviceExt, FileObject);
- else
- Irp->IoStatus.Information = FILE_OPENED;
+ if (!NT_SUCCESS (Status))
+ VfatCloseFile (DeviceExt, FileObject);
+ else
+ Irp->IoStatus.Information = FILE_OPENED;
/* FIXME : make supersed or overwrite if requested */
- }
+ }
Irp->IoStatus.Status = Status;
assert (DeviceObject);
assert (Irp);
-
+
if (DeviceObject->Size == sizeof (DEVICE_OBJECT))
{
/* DeviceObject represents FileSystem instead of logical volume */
ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE);
Status = VfatCreateFile (DeviceObject, Irp);
-
+
ExReleaseResourceLite (&DeviceExt->DirResource);
-
+
Irp->IoStatus.Status = Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
if (OldSector)
pCcb->StartEntry++;
RC =
- FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartSector,
- &pCcb->StartEntry);
+ FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL);
+ pCcb->StartSector = 1;
DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC,
pCcb->StartSector, pCcb->StartEntry);
if (NT_SUCCESS (RC))
-/* $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
* PROJECT: ReactOS kernel
}
}
-
NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
/*
update an existing FAT entry
*/
{
- WCHAR DirName[MAX_PATH], *FileName, *PathFileName;
- VFATFCB FileFcb;
- ULONG Sector = 0, Entry = 0;
- PUCHAR Buffer;
- FATDirEntry *pEntries;
+ VFATFCB Fcb;
+ VFATCCB Ccb;
+ ULONG Entry = 0;
NTSTATUS status;
FILE_OBJECT FileObject;
- PVFATCCB pDirCcb;
- PVFATFCB pDirFcb, pFcb;
- short i, posCar, NameLen;
+ PVFATFCB pDirFcb = NULL, pFcb = NULL;
+ PWCHAR pName;
- PathFileName = pFileObject->FileName.Buffer;
- pFcb = ((PVFATCCB) pFileObject->FsContext2)->pFcb;
- DPRINT ("PathFileName \'%S\'\n", PathFileName);
+ DPRINT ("updEntry PathFileName \'%S\'\n", pFileObject->FileName.Buffer);
- //find last \ in PathFileName
- posCar = -1;
- 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
- DirName[0] = L'\\';
- DirName[1] = 0;
- }
- 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))
+ status = vfatGetFCBForFile(DeviceExt, &pDirFcb, &pFcb, pFileObject->FileName.Buffer);
+ if (pFcb != NULL)
+ {
+ vfatReleaseFCB(DeviceExt, pFcb);
+ }
+ if (!NT_SUCCESS(status))
+ {
+ if (pDirFcb != NULL)
{
- DbgPrint ("Failed to open \'%S\'. Status %lx\n", DirName, status);
- return status;
+ vfatReleaseFCB(DeviceExt, pDirFcb);
}
- pDirCcb = (PVFATCCB) FileObject.FsContext2;
- assert (pDirCcb);
- pDirFcb = pDirCcb->pFcb;
- assert (pDirFcb);
- FileFcb.ObjectName = &FileFcb.PathName[0];
- status = FindFile (DeviceExt, &FileFcb, pDirFcb, FileName, &Sector, &Entry);
+ return status;
+ }
+
+ pName = ((PVFATCCB)(pFileObject->FsContext2))->pFcb->ObjectName;
+ if (*pName == L'\\')
+ {
+ pName ++;
+ }
+ status = FindFile (DeviceExt, &Fcb, pDirFcb, pName, &Entry, NULL);
if (NT_SUCCESS (status))
{
- Buffer = ExAllocatePool (NonPagedPool, BLOCKSIZE);
- DPRINT ("update entry: sector %d, entry %d\n", Sector, Entry);
- VfatReadSectors (DeviceExt->StorageDevice, Sector, 1, Buffer);
- pEntries = (FATDirEntry *) Buffer;
- memcpy (&pEntries[Entry], &pFcb->entry, sizeof (FATDirEntry));
- VfatWriteSectors (DeviceExt->StorageDevice, Sector, 1, Buffer);
- ExFreePool (Buffer);
+ DPRINT ("update entry: %d\n", Entry);
+ memset (&FileObject, 0, sizeof(FILE_OBJECT));
+ memset (&Ccb, 0, sizeof(VFATCCB));
+ FileObject.FsContext2 = &Ccb;
+ FileObject.FsContext = &pDirFcb->RFCB;
+ Ccb.pFcb = pDirFcb;
+ 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;
}
-
NTSTATUS
addEntry (PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT pFileObject, ULONG RequestedOptions, UCHAR ReqAttr)
PUCHAR Buffer, Buffer2;
BOOLEAN needTilde = FALSE, needLong = FALSE;
PVFATFCB newFCB;
- PVFATCCB newCCB;
ULONG CurrentCluster;
LARGE_INTEGER SystemTime, LocalTime;
- ULONG BytesPerCluster;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
PVFATFCB pFcb;
PVFATCCB pCcb;
FileName = &PathFileName[posCar + 1];
for (NameLen = 0; FileName[NameLen]; NameLen++);
// extract directory name from pathname
- memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
- DirName[posCar] = 0;
+ if (posCar == 0)
+ {
+ // root dir
+ DirName[0] = L'\\';
+ DirName[1] = 0;
+ }
+ else
+ {
+ memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
+ DirName[posCar] = 0;
+ }
// open parent directory
memset (&FileObject, 0, sizeof (FILE_OBJECT));
status = VfatOpenFile (DeviceExt, &FileObject, DirName);
DPRINT1 ("VfatReadFile did not read a complete directory entry\n");
break;
}
- if (IsDeletedEntry (&FatEntry, 0))
+ if (vfatIsDirEntryEndMarker(&FatEntry))
+ break;
+ if (vfatIsDirEntryDeleted(&FatEntry))
nbFree++;
else
nbFree = 0;
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
Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
memset (Buffer2, 0, DeviceExt->BytesPerCluster);
status =
VfatWriteFile (DeviceExt, &FileObject, Buffer,
sizeof (FATDirEntry) * nbSlots, Offset, FALSE);
- DPRINT ("VfatWriteFile() returned: %x\n", status);
+ DPRINT ("VfatWriteFile() returned: %x\n", status);
}
else
{ //write at end of directory
sizeof (FATDirEntry) * (nbSlots + 1), Offset, FALSE);
}
DPRINT ("write entry offset %d status=%x\n", Offset, status);
- newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB));
- 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,
- BytesPerCluster);
- }
- else
+ if (!NT_SUCCESS(status))
+ {
+ VfatCloseFile (DeviceExt, &FileObject);
+ if (RequestedOptions & FILE_DIRECTORY_FILE)
{
- Status = CcRosInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb,
- PAGESIZE);
+ // free the reserved cluster
+ WriteCluster(DeviceExt, CurrentCluster, 0);
}
+ ExFreePool (Buffer);
+ return status;
+ }
- /*
- * FIXME : initialize all fields in FCB and CCB
- */
- vfatAddFCBToTable (DeviceExt, newFCB);
+ // FEXME: check status
+ vfatMakeFCBFromDirEntry (DeviceExt, pFcb, FileName, pEntry, &newFCB);
+ vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject);
- memcpy (&newFCB->entry, pEntry, sizeof (FATDirEntry));
DPRINT ("new : entry=%11.11s\n", newFCB->entry.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)
{
// create . and ..
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 */
-/* $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
KIRQL oldIrql;
DPRINT ("grabbing FCB at %x: %S, refCount:%d\n",
- pFCB,
+ pFCB,
pFCB->PathName,
pFCB->RefCount);
KIRQL oldIrql;
DPRINT ("releasing FCB at %x: %S, refCount:%d\n",
- pFCB,
+ pFCB,
pFCB->PathName,
pFCB->RefCount);
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
pFCB->RefCount--;
- if (pFCB->RefCount <= 0 && !vfatFCBIsDirectory (pVCB, pFCB))
+ if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
{
RemoveEntryList (&pFCB->FcbListEntry);
CcRosReleaseFileCache (NULL, pFCB->RFCB.Bcb);
fcb->pDevExt = vcb;
bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
- fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ?
+ fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ?
bytesPerCluster : PAGESIZE;
- status = CcRosInitializeFileCache (fileObject,
+ status = CcRosInitializeFileCache (fileObject,
&fcb->RFCB.Bcb,
fileCacheQuantum);
if (!NT_SUCCESS (status))
KeBugCheck (0);
}
ObDereferenceObject (fileObject);
- fcb->isCacheInitialized = TRUE;
+ fcb->Flags |= FCB_CACHE_INITIALIZED;
return status;
}
if (!valid)
{
currentCluster = vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry);
- status = OffsetToCluster (pDeviceExt,
- vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
- pOffset,
+ status = OffsetToCluster (pDeviceExt,
+ vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
+ pOffset,
¤tCluster,
pExtend);
if (!NT_SUCCESS (status))
{
for (i = 0; i < (PAGESIZE / pDeviceExt->BytesPerCluster); i++)
{
- status = VfatRawReadCluster (pDeviceExt,
+ status = VfatRawReadCluster (pDeviceExt,
vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
- ((PCHAR)*pBuffer) +
+ ((PCHAR)*pBuffer) +
(i * pDeviceExt->BytesPerCluster),
currentCluster);
if (!NT_SUCCESS (status))
CcRosReleaseCacheSegment(pFCB->RFCB.Bcb, *pCacheSegment, FALSE);
return status;
}
- status = NextCluster (pDeviceExt,
- vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
- ¤tCluster,
+ status = NextCluster (pDeviceExt,
+ vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
+ ¤tCluster,
pExtend);
if (!NT_SUCCESS (status))
{
}
else
{
- status = VfatRawReadCluster (pDeviceExt,
+ status = VfatRawReadCluster (pDeviceExt,
vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry),
*pBuffer,
currentCluster);
{
FCB = vfatMakeRootFCB (pVCB);
}
-
+
return FCB;
}
memcpy (&rcFCB->entry, dirEntry, sizeof (FAT_DIR_ENTRY));
vfatFCBInitializeCache (vcb, rcFCB);
+ rcFCB->RefCount++;
vfatAddFCBToTable (vcb, rcFCB);
- vfatGrabFCB (vcb, rcFCB);
+// vfatGrabFCB (vcb, rcFCB);
*fileFCB = rcFCB;
return STATUS_SUCCESS;
}
NTSTATUS
-vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
+vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb,
PVFATFCB fcb,
PFILE_OBJECT fileObject)
{
newCCB->PtrFileObject = fileObject;
fcb->pDevExt = vcb;
- if (!fcb->isCacheInitialized)
+ if (!(fcb->Flags & FCB_CACHE_INITIALIZED))
{
ULONG bytesPerCluster;
ULONG fileCacheQuantum;
bytesPerCluster = vcb->Boot->SectorsPerCluster * BLOCKSIZE;
- fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ? bytesPerCluster :
+ fileCacheQuantum = (bytesPerCluster >= PAGESIZE) ? bytesPerCluster :
PAGESIZE;
- status = CcRosInitializeFileCache (fileObject,
+ status = CcRosInitializeFileCache (fileObject,
&fcb->RFCB.Bcb,
fileCacheQuantum);
if (!NT_SUCCESS (status))
DbgPrint ("CcRosInitializeFileCache failed\n");
KeBugCheck (0);
}
- fcb->isCacheInitialized = TRUE;
+ fcb->Flags |= FCB_CACHE_INITIALIZED;
}
DPRINT ("file open: fcb:%x file size: %d\n", fcb, fcb->entry.FileSize);
}
NTSTATUS
-vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
- PVFATFCB pDirectoryFCB,
+vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt,
+ PVFATFCB pDirectoryFCB,
PWSTR pFileToFind,
PVFATFCB * pFoundFCB)
{
assert (pFileToFind);
DPRINT ("vfatDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n",
- pDeviceExt,
+ pDeviceExt,
pDirectoryFCB,
pFileToFind);
DPRINT ("Dir Path:%S\n", pDirectoryFCB->PathName);
pFileToFind = defaultFileName;
}
- directoryIndex = 0;
+ directoryIndex = 0;
finishedScanningDirectory = FALSE;
while (!finishedScanningDirectory)
{
return status;
}
- DPRINT (" Index:%d longName:%S\n",
+ DPRINT (" Index:%d longName:%S\n",
directoryIndex,
currentLongName);
pFoundFCB);
return status;
}
- else
+ else
{
vfatGetDirEntryName (¤tDirEntry, currentEntryName);
DPRINT (" entryName:%S\n", currentEntryName);
}
NTSTATUS
-vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
- PVFATFCB *pParentFCB,
+vfatGetFCBForFile (PDEVICE_EXTENSION pVCB,
+ PVFATFCB *pParentFCB,
PVFATFCB *pFCB,
const PWSTR pFileName)
{
PWCHAR currentElement;
PVFATFCB FCB;
PVFATFCB parentFCB;
-
+
DPRINT ("vfatGetFCBForFile (%x,%x,%x,%S)\n",
- pVCB,
- pParentFCB,
- pFCB,
+ pVCB,
+ pParentFCB,
+ pFCB,
pFileName);
// Trivial case, open of the root directory on volume
parentFCB = FCB;
// Extract next directory level into dirName
- vfatWSubString (pathName,
- pFileName,
+ vfatWSubString (pathName,
+ pFileName,
vfatGetNextPathElement (currentElement) - pFileName);
DPRINT (" pathName:%S\n", pathName);
FCB = vfatGrabFCBFromTable (pVCB, pathName);
if (FCB == NULL)
{
- vfatWSubString (elementName,
- currentElement,
+ vfatWSubString (elementName,
+ currentElement,
vfatGetNextPathElement (currentElement) - currentElement);
DPRINT (" elementName:%S\n", elementName);
-/* $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
* PROJECT: ReactOS kernel
PDEVICE_OBJECT DeviceObject,
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");
- 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
-/* $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
* PROJECT: ReactOS kernel
assert (DeviceExt != NULL);
assert (DeviceExt->BytesPerCluster != 0);
assert (FileObject != NULL);
- assert (FileObject->FsContext != NULL);
+ assert (FileObject->FsContext2 != NULL);
DPRINT("VfatReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
"Length %d, ReadOffset 0x%x)\n", DeviceExt, FileObject, Buffer,
-/* $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>
ULONG FatType;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION, VCB, *PVCB;
+#define FCB_CACHE_INITIALIZED 0x0001
+#define FCB_DELETE_PENDING 0x0002
+
typedef struct _VFATFCB
{
REACTOS_COMMON_FCB_HEADER RFCB;
SECTION_OBJECT_POINTERS SectionObjectPointers;
FATDirEntry entry;
/* point on filename (250 chars max) in PathName */
- WCHAR *ObjectName;
+ WCHAR *ObjectName;
/* path+filename 260 max */
- WCHAR PathName[MAX_PATH];
+ WCHAR PathName[MAX_PATH];
LONG RefCount;
PDEVICE_EXTENSION pDevExt;
LIST_ENTRY FcbListEntry;
struct _VFATFCB* parentFcb;
- BOOL isCacheInitialized;
+ ULONG Flags;
} VFATFCB, *PVFATFCB;
typedef struct _VFATCCB
PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr);
NTSTATUS
updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
+NTSTATUS
+delEntry(PDEVICE_EXTENSION, PFILE_OBJECT);
/*
* String functions
PFAT_DIR_ENTRY pDirEntry);
BOOL vfatIsDirEntryDeleted (FATDirEntry * pFatDirEntry);
BOOL vfatIsDirEntryVolume (FATDirEntry * pFatDirEntry);
+BOOL vfatIsDirEntryEndMarker (FATDirEntry * pFatDirEntry);
void vfatGetDirEntryName (PFAT_DIR_ENTRY pDirEntry, PWSTR pEntryName);
NTSTATUS vfatGetNextDirEntry (PDEVICE_EXTENSION pDeviceExt,
PVFATFCB pDirectoryFCB,
PVFATFCB *pParentFCB,
PVFATFCB *pFCB,
const PWSTR pFileName);
+NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb,
+ PVFATFCB directoryFCB,
+ PWSTR longName,
+ PFAT_DIR_ENTRY dirEntry,
+ PVFATFCB * fileFCB);