Index: cleanup.c =================================================================== --- drivers/filesystems/fastfat/cleanup.c (revision 72186) +++ drivers/filesystems/fastfat/cleanup.c (working copy) @@ -24,6 +24,7 @@ PVFAT_IRP_CONTEXT IrpContext) { PVFATFCB pFcb; + PVFATCCB pCcb; PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt; PFILE_OBJECT FileObject = IrpContext->FileObject; @@ -58,6 +59,12 @@ return STATUS_PENDING; } + pCcb = FileObject->FsContext2; + if (pCcb->Flags & CCB_DELETE_ON_CLOSE) + { + pFcb->Flags |= FCB_DELETE_PENDING; + } + /* Notify about the cleanup */ FsRtlNotifyCleanup(IrpContext->DeviceExt->NotifySync, &(IrpContext->DeviceExt->NotifyList), @@ -66,7 +73,7 @@ pFcb->OpenHandleCount--; DeviceExt->OpenHandleCount--; - if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) && + if (!vfatFCBIsDirectory(pFcb) && FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) { /* remove all locks this process have on this file */ @@ -84,18 +91,26 @@ if (pFcb->Flags & FCB_DELETE_PENDING && pFcb->OpenHandleCount == 0) { - PFILE_OBJECT tmpFileObject; - tmpFileObject = pFcb->FileObject; - if (tmpFileObject != NULL) + if (vfatFCBIsDirectory(pFcb) && + !VfatIsDirectoryEmpty(pFcb)) { - pFcb->FileObject = NULL; - CcUninitializeCacheMap(tmpFileObject, NULL, NULL); - ObDereferenceObject(tmpFileObject); + pFcb->Flags &= ~FCB_DELETE_PENDING; } + else + { + PFILE_OBJECT tmpFileObject; + tmpFileObject = pFcb->FileObject; + if (tmpFileObject != NULL) + { + pFcb->FileObject = NULL; + CcUninitializeCacheMap(tmpFileObject, NULL, NULL); + ObDereferenceObject(tmpFileObject); + } - pFcb->RFCB.ValidDataLength.QuadPart = 0; - pFcb->RFCB.FileSize.QuadPart = 0; - pFcb->RFCB.AllocationSize.QuadPart = 0; + pFcb->RFCB.ValidDataLength.QuadPart = 0; + pFcb->RFCB.FileSize.QuadPart = 0; + pFcb->RFCB.AllocationSize.QuadPart = 0; + } } /* Uninitialize the cache (should be done even if caching was never initialized) */ Index: create.c =================================================================== --- drivers/filesystems/fastfat/create.c (revision 72186) +++ drivers/filesystems/fastfat/create.c (working copy) @@ -460,6 +460,23 @@ return STATUS_ACCESS_DENIED; } + if ((*Fcb->Attributes & FILE_ATTRIBUTE_READONLY) && + (RequestedOptions & FILE_DELETE_ON_CLOSE)) + { + vfatReleaseFCB(DeviceExt, Fcb); + return STATUS_CANNOT_DELETE; + } + + if ((vfatFCBIsRoot(Fcb) || + (Fcb->LongNameU.Length == sizeof(WCHAR) && Fcb->LongNameU.Buffer[0] == L'.') || + (Fcb->LongNameU.Length == 2 * sizeof(WCHAR) && Fcb->LongNameU.Buffer[0] == L'.' && Fcb->LongNameU.Buffer[1] == L'.')) && + (RequestedOptions & FILE_DELETE_ON_CLOSE)) + { + // we cannot delete a '.', '..' or the root directory + vfatReleaseFCB(DeviceExt, Fcb); + return STATUS_CANNOT_DELETE; + } + DPRINT("Attaching FCB to fileObject\n"); Status = vfatAttachFCBToFileObject(DeviceExt, Fcb, FileObject); if (!NT_SUCCESS(Status)) @@ -484,6 +501,7 @@ ULONG RequestedDisposition, RequestedOptions; PVFATFCB pFcb = NULL; PVFATFCB ParentFcb = NULL; + PVFATCCB pCcb = NULL; PWCHAR c, last; BOOLEAN PagingFileCreate; BOOLEAN Dots; @@ -552,6 +570,11 @@ return STATUS_INVALID_PARAMETER; } + if (RequestedOptions & FILE_DELETE_ON_CLOSE) + { + return STATUS_CANNOT_DELETE; + } + pFcb = DeviceExt->VolumeFcb; if (pFcb->OpenHandleCount == 0) @@ -733,6 +756,12 @@ } } + pCcb = FileObject->FsContext2; + if (RequestedOptions & FILE_DELETE_ON_CLOSE) + { + pCcb->Flags |= CCB_DELETE_ON_CLOSE; + } + pFcb->OpenHandleCount++; DeviceExt->OpenHandleCount++; } @@ -870,7 +899,8 @@ { if (Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA || RequestedDisposition == FILE_OVERWRITE || - RequestedDisposition == FILE_OVERWRITE_IF) + RequestedDisposition == FILE_OVERWRITE_IF || + (RequestedOptions & FILE_DELETE_ON_CLOSE)) { if (!MmFlushImageSection(&pFcb->SectionObjectPointers, MmFlushForWrite)) { @@ -878,7 +908,8 @@ DPRINT1("%d %d %d\n", Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA, RequestedDisposition == FILE_OVERWRITE, RequestedDisposition == FILE_OVERWRITE_IF); VfatCloseFile (DeviceExt, FileObject); - return STATUS_SHARING_VIOLATION; + return (RequestedOptions & FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE + : STATUS_SHARING_VIOLATION; } } } @@ -967,6 +998,12 @@ &pFcb->FCBShareAccess); } + pCcb = FileObject->FsContext2; + if (RequestedOptions & FILE_DELETE_ON_CLOSE) + { + pCcb->Flags |= CCB_DELETE_ON_CLOSE; + } + if (Irp->IoStatus.Information == FILE_CREATED) { FsRtlNotifyFullReportChange(DeviceExt->NotifySync, Index: vfat.h =================================================================== --- drivers/filesystems/fastfat/vfat.h (revision 72186) +++ drivers/filesystems/fastfat/vfat.h (working copy) @@ -432,6 +432,8 @@ ULONG LastOffset; } VFATFCB, *PVFATFCB; +#define CCB_DELETE_ON_CLOSE 0x0001 + typedef struct _VFATCCB { LARGE_INTEGER CurrentByteOffset; @@ -439,6 +441,7 @@ ULONG Entry; /* for DirectoryControl */ UNICODE_STRING SearchPattern; + ULONG Flags; } VFATCCB, *PVFATCCB; #define TAG_CCB 'BCCV'