diff --git a/reactos/drivers/fs/vfat/close.c b/reactos/drivers/fs/vfat/close.c index d6abd099977..79defeff6c3 100644 --- a/reactos/drivers/fs/vfat/close.c +++ b/reactos/drivers/fs/vfat/close.c @@ -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 * PROJECT: ReactOS kernel @@ -18,7 +18,7 @@ /* FUNCTIONS ****************************************************************/ -NTSTATUS +NTSTATUS VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) /* * FUNCTION: Closes a file @@ -26,6 +26,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) { PVFATFCB pFcb; PVFATCCB pCcb; + NTSTATUS Status = STATUS_SUCCESS; DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n", DeviceExt, FileObject); @@ -38,12 +39,30 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT 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 @@ -59,7 +78,9 @@ VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp) 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; diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index 8b59b6ad064..d8d1475e1d0 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -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 * PROJECT: ReactOS kernel @@ -97,84 +97,116 @@ static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pN 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)) + while (TRUE) { - 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) - { - 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); + DPRINT (" long name entry found at %d\n", *pIndex); - cpos = 0; - while ((test2[Offset].id != 0x41) && (test2[Offset].id != 0x01) && - (test2[Offset].attr > 0)) + 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); + + DPRINT (" longName: [%S]\n", Name); } - - 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; + (*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 @@ -259,44 +291,68 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) 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; + ULONG DirIndex; + ULONG Offset; + ULONG FirstCluster; + ULONG Read; + BOOL isRoot; + BOOL first; -// DPRINT ("FindFile(Parent %x, FileToFind '%S')\n", Parent, FileToFind); - DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName); + 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; @@ -308,135 +364,112 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, 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++) - { - 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)) - { - 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); - } - } + 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 (StartSector) - *StartSector = StartingSector; - if (Entry) - *Entry = i; + 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 (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); + VfatCloseFile(DeviceExt, &tmpFileObject); return (STATUS_UNSUCCESSFUL); } -NTSTATUS -vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject, +NTSTATUS +vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject, PWSTR pRelativeFileName, PWSTR *pAbsoluteFilename) { @@ -450,16 +483,16 @@ vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject, 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); @@ -518,7 +551,13 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, 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); @@ -554,14 +593,14 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) 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; @@ -583,18 +622,23 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) 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)); @@ -609,22 +653,22 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) } } 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 */ @@ -638,34 +682,34 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) 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; @@ -684,7 +728,7 @@ VfatCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp) assert (DeviceObject); assert (Irp); - + if (DeviceObject->Size == sizeof (DEVICE_OBJECT)) { /* DeviceObject represents FileSystem instead of logical volume */ @@ -700,9 +744,9 @@ VfatCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp) ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE); Status = VfatCreateFile (DeviceObject, Irp); - + ExReleaseResourceLite (&DeviceExt->DirResource); - + Irp->IoStatus.Status = Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); diff --git a/reactos/drivers/fs/vfat/dir.c b/reactos/drivers/fs/vfat/dir.c index 74edb30fe0c..bfe6b5b8158 100644 --- a/reactos/drivers/fs/vfat/dir.c +++ b/reactos/drivers/fs/vfat/dir.c @@ -276,8 +276,8 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack) 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)) diff --git a/reactos/drivers/fs/vfat/dirwr.c b/reactos/drivers/fs/vfat/dirwr.c index 792d846a913..db924aa7f9e 100644 --- a/reactos/drivers/fs/vfat/dirwr.c +++ b/reactos/drivers/fs/vfat/dirwr.c @@ -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 * PROJECT: ReactOS kernel @@ -90,81 +90,58 @@ FillSlot (slot * Slot, WCHAR * FileName) } } - 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++); + 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; + } - // 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)) - { - 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); + 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) @@ -184,11 +161,9 @@ addEntry (PDEVICE_EXTENSION DeviceExt, 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; @@ -204,8 +179,17 @@ addEntry (PDEVICE_EXTENSION DeviceExt, 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); @@ -420,7 +404,9 @@ addEntry (PDEVICE_EXTENSION DeviceExt, 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; @@ -432,7 +418,18 @@ addEntry (PDEVICE_EXTENSION DeviceExt, 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); @@ -452,7 +449,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, 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 @@ -462,40 +459,25 @@ addEntry (PDEVICE_EXTENSION DeviceExt, 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) + if (!NT_SUCCESS(status)) + { + VfatCloseFile (DeviceExt, &FileObject); + if (RequestedOptions & FILE_DIRECTORY_FILE) { - Status = CcRosInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb, - BytesPerCluster); - } - else - { - 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 .. @@ -520,4 +502,72 @@ addEntry (PDEVICE_EXTENSION DeviceExt, 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 */ diff --git a/reactos/drivers/fs/vfat/fcb.c b/reactos/drivers/fs/vfat/fcb.c index b1c43cb7743..b5dfaa8fa59 100644 --- a/reactos/drivers/fs/vfat/fcb.c +++ b/reactos/drivers/fs/vfat/fcb.c @@ -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 @@ -74,7 +74,7 @@ vfatGrabFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) KIRQL oldIrql; DPRINT ("grabbing FCB at %x: %S, refCount:%d\n", - pFCB, + pFCB, pFCB->PathName, pFCB->RefCount); @@ -89,13 +89,13 @@ vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) 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); @@ -172,9 +172,9 @@ vfatFCBInitializeCache (PVCB vcb, PVFATFCB fcb) 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)) @@ -183,7 +183,7 @@ vfatFCBInitializeCache (PVCB vcb, PVFATFCB fcb) KeBugCheck (0); } ObDereferenceObject (fileObject); - fcb->isCacheInitialized = TRUE; + fcb->Flags |= FCB_CACHE_INITIALIZED; return status; } @@ -216,9 +216,9 @@ vfatRequestAndValidateRegion(PDEVICE_EXTENSION pDeviceExt, 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)) @@ -230,9 +230,9 @@ vfatRequestAndValidateRegion(PDEVICE_EXTENSION pDeviceExt, { 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)) @@ -240,9 +240,9 @@ vfatRequestAndValidateRegion(PDEVICE_EXTENSION pDeviceExt, 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)) { @@ -257,7 +257,7 @@ vfatRequestAndValidateRegion(PDEVICE_EXTENSION pDeviceExt, } else { - status = VfatRawReadCluster (pDeviceExt, + status = VfatRawReadCluster (pDeviceExt, vfatDirEntryGetFirstCluster (pDeviceExt, &pFCB->entry), *pBuffer, currentCluster); @@ -317,7 +317,7 @@ vfatOpenRootFCB(PDEVICE_EXTENSION pVCB) { FCB = vfatMakeRootFCB (pVCB); } - + return FCB; } @@ -356,15 +356,16 @@ vfatMakeFCBFromDirEntry(PVCB vcb, 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) { @@ -387,15 +388,15 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, 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)) @@ -403,7 +404,7 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, 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); @@ -412,8 +413,8 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, } NTSTATUS -vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, - PVFATFCB pDirectoryFCB, +vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, + PVFATFCB pDirectoryFCB, PWSTR pFileToFind, PVFATFCB * pFoundFCB) { @@ -430,7 +431,7 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, assert (pFileToFind); DPRINT ("vfatDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n", - pDeviceExt, + pDeviceExt, pDirectoryFCB, pFileToFind); DPRINT ("Dir Path:%S\n", pDirectoryFCB->PathName); @@ -443,7 +444,7 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, pFileToFind = defaultFileName; } - directoryIndex = 0; + directoryIndex = 0; finishedScanningDirectory = FALSE; while (!finishedScanningDirectory) { @@ -462,7 +463,7 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, return status; } - DPRINT (" Index:%d longName:%S\n", + DPRINT (" Index:%d longName:%S\n", directoryIndex, currentLongName); @@ -479,7 +480,7 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, pFoundFCB); return status; } - else + else { vfatGetDirEntryName (¤tDirEntry, currentEntryName); DPRINT (" entryName:%S\n", currentEntryName); @@ -502,8 +503,8 @@ vfatDirFindFile (PDEVICE_EXTENSION pDeviceExt, } NTSTATUS -vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, - PVFATFCB *pParentFCB, +vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, + PVFATFCB *pParentFCB, PVFATFCB *pFCB, const PWSTR pFileName) { @@ -513,11 +514,11 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, 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 @@ -573,16 +574,16 @@ vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, 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); diff --git a/reactos/drivers/fs/vfat/finfo.c b/reactos/drivers/fs/vfat/finfo.c index ae51f7e70ab..28641864eaf 100644 --- a/reactos/drivers/fs/vfat/finfo.c +++ b/reactos/drivers/fs/vfat/finfo.c @@ -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 * PROJECT: ReactOS kernel @@ -145,11 +145,65 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject, 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 diff --git a/reactos/drivers/fs/vfat/rw.c b/reactos/drivers/fs/vfat/rw.c index bbec2c37f22..352042de84c 100644 --- a/reactos/drivers/fs/vfat/rw.c +++ b/reactos/drivers/fs/vfat/rw.c @@ -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 * PROJECT: ReactOS kernel @@ -366,7 +366,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, 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, diff --git a/reactos/drivers/fs/vfat/vfat.h b/reactos/drivers/fs/vfat/vfat.h index d1b0a863c37..dd60b6a8dcf 100644 --- a/reactos/drivers/fs/vfat/vfat.h +++ b/reactos/drivers/fs/vfat/vfat.h @@ -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 @@ -115,20 +115,23 @@ typedef struct 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 @@ -253,6 +256,8 @@ addEntry(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr); NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject); +NTSTATUS +delEntry(PDEVICE_EXTENSION, PFILE_OBJECT); /* * String functions @@ -335,6 +340,7 @@ ULONG vfatDirEntryGetFirstCluster (PDEVICE_EXTENSION pDeviceExt, 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, @@ -375,6 +381,11 @@ NTSTATUS vfatGetFCBForFile (PDEVICE_EXTENSION pVCB, PVFATFCB *pParentFCB, PVFATFCB *pFCB, const PWSTR pFileName); +NTSTATUS vfatMakeFCBFromDirEntry(PVCB vcb, + PVFATFCB directoryFCB, + PWSTR longName, + PFAT_DIR_ENTRY dirEntry, + PVFATFCB * fileFCB);