mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: rename: oplocks
This commit is contained in:
parent
f49cf412a8
commit
cb6b10385b
@ -1114,9 +1114,9 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
|||||||
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
||||||
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
||||||
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
||||||
|
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
||||||
|
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName);
|
||||||
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
||||||
BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject,
|
|
||||||
PUNICODE_STRING FileName, BOOLEAN SubpathOnly);
|
|
||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
||||||
|
160
src/sys/file.c
160
src/sys/file.c
@ -41,9 +41,9 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
|||||||
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
BOOLEAN HandleCleanup); /* TRUE to decrement handle count */
|
||||||
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
||||||
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
UINT64 FlushOffset64, ULONG FlushLength, BOOLEAN FlushAndPurge);
|
||||||
|
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
||||||
|
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName);
|
||||||
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
||||||
BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject,
|
|
||||||
PUNICODE_STRING FileName, BOOLEAN SubpathOnly);
|
|
||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
||||||
@ -103,8 +103,8 @@ NTSTATUS FspMainFileClose(
|
|||||||
#pragma alloc_text(PAGE, FspFileNodeCleanupComplete)
|
#pragma alloc_text(PAGE, FspFileNodeCleanupComplete)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeClose)
|
#pragma alloc_text(PAGE, FspFileNodeClose)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeFlushAndPurgeCache)
|
#pragma alloc_text(PAGE, FspFileNodeFlushAndPurgeCache)
|
||||||
|
#pragma alloc_text(PAGE, FspFileNodeRenameCheck)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeRename)
|
#pragma alloc_text(PAGE, FspFileNodeRename)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeHasOpenHandles)
|
|
||||||
#pragma alloc_text(PAGE, FspFileNodeGetFileInfo)
|
#pragma alloc_text(PAGE, FspFileNodeGetFileInfo)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo)
|
#pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeSetFileInfo)
|
#pragma alloc_text(PAGE, FspFileNodeSetFileInfo)
|
||||||
@ -833,6 +833,137 @@ NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
|||||||
return IoStatus.Status;
|
return IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
|
||||||
|
FSP_FILE_NODE *FileNode, PUNICODE_STRING FileName)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FILE_NODE *DescendantFileNode;
|
||||||
|
FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes;
|
||||||
|
ULONG DescendantFileNodeCount, DescendantFileNodeIndex;
|
||||||
|
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey;
|
||||||
|
BOOLEAN SubpathOnly = 0 != FileNode;
|
||||||
|
BOOLEAN Success = TRUE;
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
DescendantFileNodes = DescendantFileNodeArray;
|
||||||
|
|
||||||
|
if (0 != FileNode)
|
||||||
|
{
|
||||||
|
if (1 < FileNode->HandleCount)
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
goto unlock_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FileNode->IsDirectory)
|
||||||
|
goto unlock_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
DescendantFileNodeCount = 0;
|
||||||
|
memset(&RestartKey, 0, sizeof RestartKey);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
||||||
|
FileName, SubpathOnly, &RestartKey);
|
||||||
|
if (0 == DescendantFileNode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (0 < DescendantFileNode->HandleCount)
|
||||||
|
{
|
||||||
|
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(DescendantFileNode)) ||
|
||||||
|
FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(DescendantFileNode)))
|
||||||
|
{
|
||||||
|
if (ARRAYSIZE(DescendantFileNodeArray) > DescendantFileNodeCount)
|
||||||
|
DescendantFileNodes[DescendantFileNodeCount] = DescendantFileNode;
|
||||||
|
DescendantFileNodeCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
goto unlock_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount)
|
||||||
|
{
|
||||||
|
DescendantFileNodes = FspAllocMustSucceed(DescendantFileNodeCount * sizeof(FSP_FILE_NODE *));
|
||||||
|
DescendantFileNodeIndex = 0;
|
||||||
|
memset(&RestartKey, 0, sizeof RestartKey);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
||||||
|
FileName, SubpathOnly, &RestartKey);
|
||||||
|
if (0 == DescendantFileNode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (0 < DescendantFileNode->HandleCount)
|
||||||
|
{
|
||||||
|
if (FsRtlCurrentBatchOplock(FspFileNodeAddrOfOplock(DescendantFileNode)) ||
|
||||||
|
FsRtlCurrentOplockH(FspFileNodeAddrOfOplock(DescendantFileNode)))
|
||||||
|
{
|
||||||
|
DescendantFileNodes[DescendantFileNodeIndex] = DescendantFileNode;
|
||||||
|
DescendantFileNodeIndex++;
|
||||||
|
ASSERT(DescendantFileNodeCount >= DescendantFileNodeIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
goto unlock_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(DescendantFileNodeCount == DescendantFileNodeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
for (
|
||||||
|
DescendantFileNodeIndex = 0;
|
||||||
|
DescendantFileNodeCount > DescendantFileNodeIndex;
|
||||||
|
DescendantFileNodeIndex++)
|
||||||
|
{
|
||||||
|
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
|
||||||
|
|
||||||
|
FspCheckOplock(FspFileNodeAddrOfOplock(DescendantFileNode), Irp, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
memset(&RestartKey, 0, sizeof RestartKey);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
||||||
|
FileName, SubpathOnly, &RestartKey);
|
||||||
|
if (0 == DescendantFileNode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (0 < DescendantFileNode->HandleCount)
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
goto unlock_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
if (DescendantFileNodeArray != DescendantFileNodes)
|
||||||
|
FspFree(DescendantFileNodes);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
|
||||||
|
unlock_exit:
|
||||||
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
if (DescendantFileNodeArray != DescendantFileNodes)
|
||||||
|
FspFree(DescendantFileNodes);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -953,29 +1084,6 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
|||||||
FspFree(DescendantFileNodes);
|
FspFree(DescendantFileNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject,
|
|
||||||
PUNICODE_STRING FileName, BOOLEAN SubpathOnly)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The ContextByNameTable must be already locked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FSP_FILE_NODE *FileNode;
|
|
||||||
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey = { 0 };
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
FileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject, FileName, SubpathOnly,
|
|
||||||
&RestartKey);
|
|
||||||
if (0 == FileNode)
|
|
||||||
return FALSE;
|
|
||||||
if (0 < FileNode->HandleCount)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -1280,13 +1280,9 @@ retry:
|
|||||||
* that has open handles (except in the batch-oplock case described earlier).
|
* that has open handles (except in the batch-oplock case described earlier).
|
||||||
*/
|
*/
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
if (!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, FileNode, &FileNode->FileName) &&
|
||||||
if (1 < FileNode->HandleCount ||
|
!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, 0, &NewFileName))
|
||||||
(FileNode->IsDirectory &&
|
|
||||||
FspFileNodeHasOpenHandles(FsvolDeviceObject, &FileNode->FileName, TRUE)) ||
|
|
||||||
FspFileNodeHasOpenHandles(FsvolDeviceObject, &NewFileName, FALSE))
|
|
||||||
Result = STATUS_ACCESS_DENIED;
|
Result = STATUS_ACCESS_DENIED;
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
@ -1408,6 +1404,7 @@ static NTSTATUS FspFsvolSetInformation(
|
|||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
|
|
||||||
|
retry:
|
||||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||||
|
|
||||||
if (FileAllocationInformation == FileInformationClass ||
|
if (FileAllocationInformation == FileInformationClass ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user