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.UserContext = FileNode->UserContext;
Request->Req.Close.UserContext2 = FileDesc->UserContext2; 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) */ /* delete the FileDesc and deref the FileNode; order is important (FileDesc has FileNode ref) */
FspFileDescDelete(FileDesc); /* this will also close the MainFileObject if any */ 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) if (0 == Request)
{ {
FspFsvolCreatePostClose(FileDesc); FspFsvolCreatePostClose(FileDesc);
FspFileNodeClose(FileNode, FileObject); FspFileNodeClose(FileNode, FileObject, TRUE);
} }
return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION; return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
@ -1115,7 +1115,7 @@ static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PV
ASSERT(0 != FileObject); ASSERT(0 != FileObject);
FspFsvolCreatePostClose(FileDesc); FspFsvolCreatePostClose(FileDesc);
FspFileNodeClose(FileDesc->FileNode, FileObject); FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE);
FspFileNodeDereference(FileDesc->FileNode); FspFileNodeDereference(FileDesc->FileNode);
FspFileDescDelete(FileDesc); FspFileDescDelete(FileDesc);
} }
@ -1142,7 +1142,7 @@ static VOID FspFsvolCreateOverwriteRequestFini(FSP_FSCTL_TRANSACT_REQ *Request,
else if (RequestProcessing == State) else if (RequestProcessing == State)
FspFileNodeReleaseOwner(FileDesc->FileNode, Full, Request); FspFileNodeReleaseOwner(FileDesc->FileNode, Full, Request);
FspFileNodeClose(FileDesc->FileNode, FileObject); FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE);
FspFileNodeDereference(FileDesc->FileNode); FspFileNodeDereference(FileDesc->FileNode);
FspFileDescDelete(FileDesc); 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, VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending); PBOOLEAN PDeletePending);
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); 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, NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge); UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); 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, VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending); PBOOLEAN PDeletePending);
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); 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, NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge); UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
@ -720,7 +721,8 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
FspFileNodeDereference(FileNode); 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 * 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); 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) if (0 < FileNode->OpenCount && 0 == --FileNode->OpenCount)
{ {
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName, FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName,