mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -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 */
|
||||
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
||||
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);
|
||||
BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject,
|
||||
PUNICODE_STRING FileName, BOOLEAN SubpathOnly);
|
||||
VOID FspFileNodeGetFileInfo(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,
|
||||
|
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 */
|
||||
NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
||||
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);
|
||||
BOOLEAN FspFileNodeHasOpenHandles(PDEVICE_OBJECT FsvolDeviceObject,
|
||||
PUNICODE_STRING FileName, BOOLEAN SubpathOnly);
|
||||
VOID FspFileNodeGetFileInfo(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,
|
||||
@ -103,8 +103,8 @@ NTSTATUS FspMainFileClose(
|
||||
#pragma alloc_text(PAGE, FspFileNodeCleanupComplete)
|
||||
#pragma alloc_text(PAGE, FspFileNodeClose)
|
||||
#pragma alloc_text(PAGE, FspFileNodeFlushAndPurgeCache)
|
||||
#pragma alloc_text(PAGE, FspFileNodeRenameCheck)
|
||||
#pragma alloc_text(PAGE, FspFileNodeRename)
|
||||
#pragma alloc_text(PAGE, FspFileNodeHasOpenHandles)
|
||||
#pragma alloc_text(PAGE, FspFileNodeGetFileInfo)
|
||||
#pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo)
|
||||
#pragma alloc_text(PAGE, FspFileNodeSetFileInfo)
|
||||
@ -833,6 +833,137 @@ NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
||||
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)
|
||||
{
|
||||
/*
|
||||
@ -953,29 +1084,6 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
||||
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)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
@ -1280,13 +1280,9 @@ retry:
|
||||
* that has open handles (except in the batch-oplock case described earlier).
|
||||
*/
|
||||
Result = STATUS_SUCCESS;
|
||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||
if (1 < FileNode->HandleCount ||
|
||||
(FileNode->IsDirectory &&
|
||||
FspFileNodeHasOpenHandles(FsvolDeviceObject, &FileNode->FileName, TRUE)) ||
|
||||
FspFileNodeHasOpenHandles(FsvolDeviceObject, &NewFileName, FALSE))
|
||||
if (!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, FileNode, &FileNode->FileName) &&
|
||||
!FspFileNodeRenameCheck(FsvolDeviceObject, Irp, 0, &NewFileName))
|
||||
Result = STATUS_ACCESS_DENIED;
|
||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
@ -1408,6 +1404,7 @@ static NTSTATUS FspFsvolSetInformation(
|
||||
|
||||
ASSERT(FileNode == FileDesc->FileNode);
|
||||
|
||||
retry:
|
||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||
|
||||
if (FileAllocationInformation == FileInformationClass ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user