sys: FspFileNodeClose: ensure that cleanup also happens when Create fails

This commit is contained in:
Bill Zissimopoulos 2016-11-09 12:49:29 -08:00
parent a0cb134bd3
commit c10c7cc672
4 changed files with 33 additions and 7 deletions

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);

View File

@ -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,