mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: IRP_MJ_CREATE: oplock support
This commit is contained in:
parent
7adbd7a56c
commit
fb70eccc9c
@ -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, FALSE);
|
FspFileNodeClose(FileNode, FileObject, FALSE, 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 */
|
||||||
|
148
src/sys/create.c
148
src/sys/create.c
@ -28,6 +28,13 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
BOOLEAN MainFileOpen);
|
BOOLEAN MainFileOpen);
|
||||||
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
|
||||||
|
static NTSTATUS FspFsvolCreateSharingViolation(
|
||||||
|
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, FSP_FILE_NODE *FileNode);
|
||||||
|
static NTSTATUS FspFsvolCreateSharingViolationWork(
|
||||||
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||||
|
BOOLEAN CanWait);
|
||||||
|
static VOID FspFsvolCreateSharingViolationOplockComplete(
|
||||||
|
PVOID Context, PIRP Irp);
|
||||||
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
|
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
|
||||||
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject,
|
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject,
|
||||||
BOOLEAN FlushImage);
|
BOOLEAN FlushImage);
|
||||||
@ -45,6 +52,9 @@ FSP_DRIVER_DISPATCH FspCreate;
|
|||||||
#pragma alloc_text(PAGE, FspFsvolCreatePrepare)
|
#pragma alloc_text(PAGE, FspFsvolCreatePrepare)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreateComplete)
|
#pragma alloc_text(PAGE, FspFsvolCreateComplete)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreateTryOpen)
|
#pragma alloc_text(PAGE, FspFsvolCreateTryOpen)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolCreateSharingViolation)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolCreateSharingViolationWork)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolCreateSharingViolationOplockComplete)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreatePostClose)
|
#pragma alloc_text(PAGE, FspFsvolCreatePostClose)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreateRequestFini)
|
#pragma alloc_text(PAGE, FspFsvolCreateRequestFini)
|
||||||
#pragma alloc_text(PAGE, FspFsvolCreateTryOpenRequestFini)
|
#pragma alloc_text(PAGE, FspFsvolCreateTryOpenRequestFini)
|
||||||
@ -813,11 +823,25 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
FileDesc->DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE);
|
FileDesc->DeleteOnClose = BooleanFlagOn(IrpSp->Parameters.Create.Options, FILE_DELETE_ON_CLOSE);
|
||||||
|
|
||||||
/* open the FileNode */
|
/* open the FileNode */
|
||||||
OpenedFileNode = FspFileNodeOpen(FileNode, FileObject,
|
Result = FspFileNodeOpen(FileNode, FileObject,
|
||||||
Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
|
Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
|
||||||
&Result);
|
&OpenedFileNode);
|
||||||
if (0 == OpenedFileNode)
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
|
if (STATUS_SHARING_VIOLATION == Result)
|
||||||
|
{
|
||||||
|
Result = FspFsvolCreateSharingViolation(Irp, Response, OpenedFileNode);
|
||||||
|
if (STATUS_PENDING != Result)
|
||||||
|
{
|
||||||
|
FspFileNodeClose(OpenedFileNode, FileObject, FALSE, TRUE);
|
||||||
|
FspFileNodeDereference(OpenedFileNode);
|
||||||
|
Result = STATUS_SHARING_VIOLATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
FSP_RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
/* unable to open the FileNode; post a Close request */
|
/* unable to open the FileNode; post a Close request */
|
||||||
FspFsvolCreatePostClose(FileDesc);
|
FspFsvolCreatePostClose(FileDesc);
|
||||||
|
|
||||||
@ -955,6 +979,118 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName);
|
IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvolCreateSharingViolation(
|
||||||
|
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, FSP_FILE_NODE *FileNode)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
|
|
||||||
|
FspIopSetIrpResponse(Irp, Response);
|
||||||
|
FspIopRequestContext(Request, FspIopRequestExtraContext) = FileNode;
|
||||||
|
|
||||||
|
Result = FspWqRepostIrpWorkItem(Irp,
|
||||||
|
FspFsvolCreateSharingViolationWork, FspFsvolCreateRequestFini);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspIopRequestContext(Request, FspIopRequestExtraContext) = 0;
|
||||||
|
return STATUS_SHARING_VIOLATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvolCreateSharingViolationWork(
|
||||||
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||||
|
BOOLEAN CanWait)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform oplock checks in the case that we received STATUS_SHARING_VIOLATION.
|
||||||
|
* The logic below is quite tortured, because it tries to mimic what FastFat
|
||||||
|
* does in Win7. Here is an explanation.
|
||||||
|
*
|
||||||
|
* First notice that this is run in a work thread. So it is assumed that we can
|
||||||
|
* block here. We cannot block in the completion thread, because it belongs to
|
||||||
|
* the user mode file system that may have a limited number of threads to service
|
||||||
|
* file system requests.
|
||||||
|
*
|
||||||
|
* Second we want a way to differentiate the case between an oplock break being
|
||||||
|
* underway and no oplock needed. Unfortunately this only seems possible when a
|
||||||
|
* completion routine is set in FsRtlCheckOplock and FsRtlOplockBreakH. In this
|
||||||
|
* case we get STATUS_PENDING when there is an oplock to be broken and
|
||||||
|
* STATUS_SUCCESS where there is not one.
|
||||||
|
*
|
||||||
|
* Third notice that by default we must return STATUS_SHARING_VIOLATION, because
|
||||||
|
* the share access check failed. The only case that we will completely retry is
|
||||||
|
* when FspRtlOplockBreakH returns STATUS_PENDING.
|
||||||
|
*
|
||||||
|
* So in a nutshell, this routine emulates what happens with FastFat during
|
||||||
|
* STATUS_SHARING_VIOLATION processing. However FastFat tries to break batch
|
||||||
|
* oplocks before the share access check. Unfortunately this is hard to do in
|
||||||
|
* this FSD, so we have to emulate this behavior.
|
||||||
|
*/
|
||||||
|
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
|
FSP_FSCTL_TRANSACT_RSP *Response = FspIopIrpResponse(Irp);
|
||||||
|
FSP_FILE_NODE *FileNode = FspIopRequestContext(Request, FspIopRequestExtraContext);
|
||||||
|
BOOLEAN StatusSharingViolation = TRUE, OpbatchBreakUnderway = FALSE;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
FspFileNodeAcquireShared(FileNode, Main);
|
||||||
|
|
||||||
|
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(FileNode)))
|
||||||
|
{
|
||||||
|
Result = FspCheckOplock(FspFileNodeAddrOfOplock(FileNode), Irp,
|
||||||
|
&Event, FspFsvolCreateSharingViolationOplockComplete, 0);
|
||||||
|
if (STATUS_PENDING == Result)
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 0);
|
||||||
|
if (STATUS_SUCCESS == Irp->IoStatus.Status)
|
||||||
|
OpbatchBreakUnderway = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeResetEvent(&Event);
|
||||||
|
Result = FspOplockBreakH(FspFileNodeAddrOfOplock(FileNode), Irp, 0,
|
||||||
|
&Event, FspFsvolCreateSharingViolationOplockComplete, 0);
|
||||||
|
if (STATUS_PENDING == Result)
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 0);
|
||||||
|
if (STATUS_SUCCESS == Irp->IoStatus.Status)
|
||||||
|
StatusSharingViolation = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFileNodeRelease(FileNode, Main);
|
||||||
|
|
||||||
|
FspFileNodeClose(FileNode, IrpSp->FileObject, FALSE, TRUE);
|
||||||
|
FspFileNodeDereference(FileNode);
|
||||||
|
FspIopRequestContext(Request, FspIopRequestExtraContext) = 0;
|
||||||
|
|
||||||
|
if (StatusSharingViolation)
|
||||||
|
{
|
||||||
|
Response->IoStatus.Status = (UINT32)STATUS_SHARING_VIOLATION;
|
||||||
|
Response->IoStatus.Information = OpbatchBreakUnderway ? FILE_OPBATCH_BREAK_UNDERWAY : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspIopRetryCompleteIrp(Irp, Response, &Result);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspFsvolCreateSharingViolationOplockComplete(
|
||||||
|
PVOID Context, PIRP Irp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
KeSetEvent((PKEVENT)Context, FSP_IO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
|
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
|
||||||
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject,
|
FSP_FILE_NODE *FileNode, FSP_FILE_DESC *FileDesc, PFILE_OBJECT FileObject,
|
||||||
BOOLEAN FlushImage)
|
BOOLEAN FlushImage)
|
||||||
@ -1009,7 +1145,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, TRUE);
|
FspFileNodeClose(FileNode, FileObject, TRUE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
|
return DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
|
||||||
@ -1115,7 +1251,7 @@ static VOID FspFsvolCreateTryOpenRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PV
|
|||||||
ASSERT(0 != FileObject);
|
ASSERT(0 != FileObject);
|
||||||
|
|
||||||
FspFsvolCreatePostClose(FileDesc);
|
FspFsvolCreatePostClose(FileDesc);
|
||||||
FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE);
|
FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE, TRUE);
|
||||||
FspFileNodeDereference(FileDesc->FileNode);
|
FspFileNodeDereference(FileDesc->FileNode);
|
||||||
FspFileDescDelete(FileDesc);
|
FspFileDescDelete(FileDesc);
|
||||||
}
|
}
|
||||||
@ -1142,7 +1278,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, TRUE);
|
FspFileNodeClose(FileDesc->FileNode, FileObject, TRUE, TRUE);
|
||||||
FspFileNodeDereference(FileDesc->FileNode);
|
FspFileNodeDereference(FileDesc->FileNode);
|
||||||
FspFileDescDelete(FileDesc);
|
FspFileDescDelete(FileDesc);
|
||||||
}
|
}
|
||||||
|
@ -712,6 +712,10 @@ enum
|
|||||||
FspIopCreateRequestNonPagedFlag = 0x02,
|
FspIopCreateRequestNonPagedFlag = 0x02,
|
||||||
FspIopCreateRequestWorkItemFlag = 0x04,
|
FspIopCreateRequestWorkItemFlag = 0x04,
|
||||||
};
|
};
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FspIopRequestExtraContext = 4,
|
||||||
|
};
|
||||||
typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4]);
|
typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4]);
|
||||||
typedef NTSTATUS FSP_IOP_REQUEST_WORK(
|
typedef NTSTATUS FSP_IOP_REQUEST_WORK(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||||
@ -724,7 +728,7 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FSP_IOP_REQUEST_FINI *RequestFini;
|
FSP_IOP_REQUEST_FINI *RequestFini;
|
||||||
PVOID Context[4];
|
PVOID Context[4 + 1/*FspIopRequestExtraContext*/];
|
||||||
FSP_FSCTL_TRANSACT_RSP *Response;
|
FSP_FSCTL_TRANSACT_RSP *Response;
|
||||||
FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *WorkItem;
|
FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *WorkItem;
|
||||||
__declspec(align(FSP_FSCTL_TRANSACT_REQ_ALIGNMENT)) UINT8 RequestBuf[];
|
__declspec(align(FSP_FSCTL_TRANSACT_REQ_ALIGNMENT)) UINT8 RequestBuf[];
|
||||||
@ -1098,13 +1102,13 @@ VOID FspFileNodeReleaseForeign(FSP_FILE_NODE *FileNode)
|
|||||||
FileNode = FileNode->MainFileNode;
|
FileNode = FileNode->MainFileNode;
|
||||||
ExReleaseResourceLite(FileNode->Header.Resource);
|
ExReleaseResourceLite(FileNode->Header.Resource);
|
||||||
}
|
}
|
||||||
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult);
|
UINT32 GrantedAccess, UINT32 ShareAccess, FSP_FILE_NODE **POpenedFileNode);
|
||||||
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);
|
BOOLEAN RemoveShareAccess, BOOLEAN HandleCleanup);
|
||||||
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);
|
||||||
|
@ -31,13 +31,13 @@ VOID FspFileNodeConvertExclusiveToSharedF(FSP_FILE_NODE *FileNode, ULONG Flags);
|
|||||||
VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
|
VOID FspFileNodeSetOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
|
||||||
VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags);
|
VOID FspFileNodeReleaseF(FSP_FILE_NODE *FileNode, ULONG Flags);
|
||||||
VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
|
VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner);
|
||||||
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult);
|
UINT32 GrantedAccess, UINT32 ShareAccess, FSP_FILE_NODE **POpenedFileNode);
|
||||||
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);
|
BOOLEAN RemoveShareAccess, BOOLEAN HandleCleanup);
|
||||||
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);
|
||||||
@ -447,8 +447,8 @@ VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner)
|
|||||||
FSP_FILE_NODE_CLR_FLAGS();
|
FSP_FILE_NODE_CLR_FLAGS();
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
UINT32 GrantedAccess, UINT32 ShareAccess, NTSTATUS *PResult)
|
UINT32 GrantedAccess, UINT32 ShareAccess, FSP_FILE_NODE **POpenedFileNode)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Attempt to insert our FileNode into the volume device's generic table.
|
* Attempt to insert our FileNode into the volume device's generic table.
|
||||||
@ -596,13 +596,8 @@ FSP_FILE_NODE *FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result) && STATUS_SHARING_VIOLATION != Result)
|
||||||
{
|
|
||||||
if (0 != PResult)
|
|
||||||
*PResult = Result;
|
|
||||||
|
|
||||||
OpenedFileNode = 0;
|
OpenedFileNode = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != OpenedFileNode)
|
if (0 != OpenedFileNode)
|
||||||
{
|
{
|
||||||
@ -613,7 +608,9 @@ exit:
|
|||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
return OpenedFileNode;
|
*POpenedFileNode = OpenedFileNode;
|
||||||
|
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
@ -724,7 +721,7 @@ 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)
|
BOOLEAN RemoveShareAccess, BOOLEAN HandleCleanup)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Close the FileNode. If the OpenCount becomes zero remove it
|
* Close the FileNode. If the OpenCount becomes zero remove it
|
||||||
@ -740,7 +737,7 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
if (AlsoCleanup)
|
if (RemoveShareAccess)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Sharing violations between main file and streams were determined
|
* Sharing violations between main file and streams were determined
|
||||||
@ -759,10 +756,11 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IoRemoveShareAccess(FileObject, &FileNode->ShareAccess);
|
IoRemoveShareAccess(FileObject, &FileNode->ShareAccess);
|
||||||
|
|
||||||
FileNode->HandleCount--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HandleCleanup)
|
||||||
|
FileNode->HandleCount--;
|
||||||
|
|
||||||
if (0 < FileNode->OpenCount && 0 == --FileNode->OpenCount)
|
if (0 < FileNode->OpenCount && 0 == --FileNode->OpenCount)
|
||||||
{
|
{
|
||||||
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName,
|
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName,
|
||||||
|
@ -321,7 +321,10 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference)
|
|||||||
ClearFlag(Irp->Flags, IRP_INPUT_OPERATION | IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
|
ClearFlag(Irp->Flags, IRP_INPUT_OPERATION | IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STATUS_SUCCESS != Result && STATUS_REPARSE != Result && STATUS_BUFFER_OVERFLOW != Result)
|
if (STATUS_SUCCESS != Result &&
|
||||||
|
STATUS_REPARSE != Result &&
|
||||||
|
STATUS_BUFFER_OVERFLOW != Result &&
|
||||||
|
STATUS_SHARING_VIOLATION != Result)
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Irp->IoStatus.Status = Result;
|
Irp->IoStatus.Status = Result;
|
||||||
IoCompleteRequest(Irp, FSP_IO_INCREMENT);
|
IoCompleteRequest(Irp, FSP_IO_INCREMENT);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user