sys,dll: Overwrite: named streams are now removed as per NTFS

This commit is contained in:
Bill Zissimopoulos 2016-12-13 14:37:44 -08:00
parent c37444b0ae
commit ff08d63a82
6 changed files with 60 additions and 0 deletions

View File

@ -48,6 +48,7 @@ FSP_API NTSTATUS FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem,
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
if ((FspFsctlTransactCreateKind == Request->Kind &&
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
FspFsctlTransactOverwriteKind == Request->Kind ||
(FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind &&
@ -86,6 +87,7 @@ FSP_API NTSTATUS FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem,
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
if ((FspFsctlTransactCreateKind == Request->Kind &&
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
FspFsctlTransactOverwriteKind == Request->Kind ||
(FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind &&

View File

@ -26,6 +26,7 @@ VOID fsp_fuse_op_enter_lock(FSP_FILE_SYSTEM *FileSystem,
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
if ((FspFsctlTransactCreateKind == Request->Kind &&
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
FspFsctlTransactOverwriteKind == Request->Kind ||
(FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind &&
@ -69,6 +70,7 @@ VOID fsp_fuse_op_leave_unlock(FSP_FILE_SYSTEM *FileSystem,
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
if ((FspFsctlTransactCreateKind == Request->Kind &&
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
FspFsctlTransactOverwriteKind == Request->Kind ||
(FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind &&

View File

@ -996,6 +996,8 @@ NTSTATUS FspFsvolCreateComplete(
}
/* file was successfully overwritten/superseded */
if (0 == FileNode->MainFileNode)
FspFileNodeOverwriteStreams(FileNode);
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo);
FspFileNodeNotifyChange(FileNode,
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE,

View File

@ -1264,6 +1264,7 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
VOID FspFileNodeOverwriteStreams(FSP_FILE_NODE *FileNode);
NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
PDEVICE_OBJECT FsvolDeviceObject,
PIRP OplockIrp,

View File

@ -42,6 +42,7 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
VOID FspFileNodeOverwriteStreams(FSP_FILE_NODE *FileNode);
NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
PDEVICE_OBJECT FsvolDeviceObject,
PIRP OplockIrp,
@ -113,6 +114,7 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
#pragma alloc_text(PAGE, FspFileNodeCleanupComplete)
#pragma alloc_text(PAGE, FspFileNodeClose)
#pragma alloc_text(PAGE, FspFileNodeFlushAndPurgeCache)
#pragma alloc_text(PAGE, FspFileNodeOverwriteStreams)
#pragma alloc_text(PAGE, FspFileNodeCheckBatchOplocksOnAllStreams)
#pragma alloc_text(PAGE, FspFileNodeRenameCheck)
#pragma alloc_text(PAGE, FspFileNodeRename)
@ -911,6 +913,45 @@ NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
FspFree(DescendantFileNodes); \
((VOID)0)
VOID FspFileNodeOverwriteStreams(FSP_FILE_NODE *FileNode)
{
/*
* Called during Create processing. The device rename resource has been acquired shared.
* No concurrent renames are allowed.
*/
PAGED_CODE();
ASSERT(0 == FileNode->MainFileNode);
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
USHORT FileNameLength = FileNode->FileName.Length;
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
GATHER_DESCENDANTS(&FileNode->FileName, FALSE,
if (DescendantFileNode->FileName.Length > FileNameLength &&
L'\\' == DescendantFileNode->FileName.Buffer[FileNameLength / sizeof(WCHAR)])
break;
if (FileNode == DescendantFileNode || 0 >= DescendantFileNode->HandleCount)
continue;
);
/* mark any open named streams as DeletePending */
for (
DescendantFileNodeIndex = 0;
DescendantFileNodeCount > DescendantFileNodeIndex;
DescendantFileNodeIndex++)
{
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
DescendantFileNode->DeletePending = TRUE;
}
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
SCATTER_DESCENDANTS(FALSE);
}
NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
PDEVICE_OBJECT FsvolDeviceObject,
PIRP OplockIrp,

View File

@ -925,6 +925,18 @@ static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem,
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
NTSTATUS Result;
#if defined(MEMFS_NAMED_STREAMS)
MEMFS_FILE_NODE_MAP_ENUM_CONTEXT Context = { FALSE };
ULONG Index;
MemfsFileNodeMapEnumerateNamedStreams(Memfs->FileNodeMap, FileNode,
MemfsFileNodeMapEnumerateFn, &Context);
for (Index = 0; Context.Count > Index; Index++)
if (1 >= Context.FileNodes[Index]->RefCount)
MemfsFileNodeMapRemove(Memfs->FileNodeMap, Context.FileNodes[Index]);
MemfsFileNodeMapEnumerateFree(&Context);
#endif
Result = SetFileSize(FileSystem, FileNode, AllocationSize, TRUE, FileInfo);
if (!NT_SUCCESS(Result))
return Result;