From c10c7cc672d50dc12d5e59efc56f1b40eb435b16 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 9 Nov 2016 12:49:29 -0800 Subject: [PATCH] sys: FspFileNodeClose: ensure that cleanup also happens when Create fails --- src/sys/close.c | 2 +- src/sys/create.c | 6 +++--- src/sys/driver.h | 3 ++- src/sys/file.c | 29 +++++++++++++++++++++++++++-- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/sys/close.c b/src/sys/close.c index 0382c168..596999bc 100644 --- a/src/sys/close.c +++ b/src/sys/close.c @@ -74,7 +74,7 @@ static NTSTATUS FspFsvolClose( Request->Req.Close.UserContext = FileNode->UserContext; Request->Req.Close.UserContext2 = FileDesc->UserContext2; - FspFileNodeClose(FileNode, FileObject); + FspFileNodeClose(FileNode, FileObject, FALSE); /* delete the FileDesc and deref the FileNode; order is important (FileDesc has FileNode ref) */ FspFileDescDelete(FileDesc); /* this will also close the MainFileObject if any */ diff --git a/src/sys/create.c b/src/sys/create.c index 71843c5b..e5abeea4 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -1009,7 +1009,7 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re if (0 == Request) { FspFsvolCreatePostClose(FileDesc); - FspFileNodeClose(FileNode, FileObject); + FspFileNodeClose(FileNode, FileObject, TRUE); } return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION; @@ -1115,7 +1115,7 @@ static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PV ASSERT(0 != FileObject); FspFsvolCreatePostClose(FileDesc); - FspFileNodeClose(FileDesc->FileNode, FileObject); + FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE); FspFileNodeDereference(FileDesc->FileNode); FspFileDescDelete(FileDesc); } @@ -1142,7 +1142,7 @@ static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, else if (RequestProcessing == State) FspFileNodeReleaseOwner(FileDesc->FileNode, Full, Request); - FspFileNodeClose(FileDesc->FileNode, FileObject); + FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE); FspFileNodeDereference(FileDesc->FileNode); FspFileDescDelete(FileDesc); } diff --git a/src/sys/driver.h b/src/sys/driver.h index 3608e22b..d86f51c7 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1069,7 +1069,8 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PBOOLEAN PDeletePending); VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); -VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); +VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, + BOOLEAN AlsoCleanup); NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode, UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge); VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); diff --git a/src/sys/file.c b/src/sys/file.c index 5ee787fb..4b252b42 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -36,7 +36,8 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PBOOLEAN PDeletePending); VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); -VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); +VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, + BOOLEAN AlsoCleanup); NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode, UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge); VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); @@ -720,7 +721,8 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject FspFileNodeDereference(FileNode); } -VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject) +VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, + BOOLEAN AlsoCleanup) { /* * Close the FileNode. If the OpenCount becomes zero remove it @@ -736,6 +738,29 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject) FspFsvolDeviceLockContextTable(FsvolDeviceObject); + if (AlsoCleanup) + { + /* + * Sharing violations between main file and streams were determined + * through experimentation with NTFS. They may be wrong! + */ + if (0 == FileNode->MainFileNode) + { + if (FileObject->DeleteAccess) + FileNode->MainFileDenyDeleteCount--; + } + else + { + if ((FileObject->ReadAccess || FileObject->WriteAccess || FileObject->DeleteAccess) && + !FileObject->SharedDelete) + FileNode->MainFileNode->StreamDenyDeleteCount--; + } + + IoRemoveShareAccess(FileObject, &FileNode->ShareAccess); + + FileNode->HandleCount--; + } + if (0 < FileNode->OpenCount && 0 == --FileNode->OpenCount) { FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName,