mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 13:02:10 -05:00
sys: file: GATHER_DESCENDANTS, SCATTER_DESCENDANTS macros
This commit is contained in:
parent
b0a59e42fc
commit
8f10ba4fc9
269
src/sys/file.c
269
src/sys/file.c
@ -851,6 +851,65 @@ NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
|||||||
return IoStatus.Status;
|
return IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GATHER_DESCENDANTS(FILENAME, SUBPATHONLY, REFERENCE, ...)\
|
||||||
|
FSP_FILE_NODE *DescendantFileNode;\
|
||||||
|
FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes;\
|
||||||
|
ULONG DescendantFileNodeCount, DescendantFileNodeIndex;\
|
||||||
|
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey;\
|
||||||
|
DescendantFileNodes = DescendantFileNodeArray;\
|
||||||
|
DescendantFileNodeCount = 0;\
|
||||||
|
memset(&RestartKey, 0, sizeof RestartKey);\
|
||||||
|
for (;;) \
|
||||||
|
{ \
|
||||||
|
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,\
|
||||||
|
FILENAME, SUBPATHONLY, &RestartKey);\
|
||||||
|
if (0 == DescendantFileNode) \
|
||||||
|
break; \
|
||||||
|
ASSERT(0 == ((UINT_PTR)DescendantFileNode & 7));\
|
||||||
|
__VA_ARGS__; \
|
||||||
|
if (REFERENCE) \
|
||||||
|
FspFileNodeReference((PVOID)((UINT_PTR)DescendantFileNode & ~7));\
|
||||||
|
if (ARRAYSIZE(DescendantFileNodeArray) > DescendantFileNodeCount)\
|
||||||
|
DescendantFileNodes[DescendantFileNodeCount] = DescendantFileNode;\
|
||||||
|
DescendantFileNodeCount++; \
|
||||||
|
} \
|
||||||
|
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount ||\
|
||||||
|
DEBUGTEST_EX(0 != DescendantFileNodeCount, 10, FALSE)) \
|
||||||
|
{ \
|
||||||
|
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; \
|
||||||
|
ASSERT(0 == ((UINT_PTR)DescendantFileNode & 7));\
|
||||||
|
__VA_ARGS__; \
|
||||||
|
DescendantFileNodes[DescendantFileNodeIndex] = DescendantFileNode;\
|
||||||
|
DescendantFileNodeIndex++; \
|
||||||
|
ASSERT(DescendantFileNodeCount >= DescendantFileNodeIndex);\
|
||||||
|
} \
|
||||||
|
ASSERT(DescendantFileNodeCount == DescendantFileNodeIndex);\
|
||||||
|
} \
|
||||||
|
((VOID)0)
|
||||||
|
#define SCATTER_DESCENDANTS(REFERENCE) \
|
||||||
|
if (REFERENCE) \
|
||||||
|
{ \
|
||||||
|
for ( \
|
||||||
|
DescendantFileNodeIndex = 0;\
|
||||||
|
DescendantFileNodeCount > DescendantFileNodeIndex;\
|
||||||
|
DescendantFileNodeIndex++) \
|
||||||
|
{ \
|
||||||
|
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];\
|
||||||
|
FspFileNodeDereference((PVOID)((UINT_PTR)DescendantFileNode & ~7));\
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if (DescendantFileNodeArray != DescendantFileNodes)\
|
||||||
|
FspFree(DescendantFileNodes); \
|
||||||
|
((VOID)0)
|
||||||
|
|
||||||
NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
|
NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject,
|
PDEVICE_OBJECT FsvolDeviceObject,
|
||||||
PIRP OplockIrp,
|
PIRP OplockIrp,
|
||||||
@ -867,91 +926,30 @@ NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
|
|||||||
|
|
||||||
ASSERT(0 == FileNode->MainFileNode);
|
ASSERT(0 == FileNode->MainFileNode);
|
||||||
|
|
||||||
FSP_FILE_NODE *DescendantFileNode;
|
|
||||||
FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes;
|
|
||||||
ULONG DescendantFileNodeCount, DescendantFileNodeIndex;
|
|
||||||
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey;
|
|
||||||
USHORT FileNameLength = FileNode->FileName.Length;
|
USHORT FileNameLength = FileNode->FileName.Length;
|
||||||
BOOLEAN CaseInsensitive = !FspFsvolDeviceExtension(FsvolDeviceObject)->
|
BOOLEAN CaseInsensitive = !FspFsvolDeviceExtension(FsvolDeviceObject)->
|
||||||
VolumeParams.CaseSensitiveSearch;
|
VolumeParams.CaseSensitiveSearch;
|
||||||
ULONG IsBatchOplock, IsHandleOplock;
|
ULONG IsBatchOplock, IsHandleOplock;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
DescendantFileNodes = DescendantFileNodeArray;
|
|
||||||
DescendantFileNodeCount = 0;
|
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
/* count descendant file nodes and try to gather them in a local array if possible */
|
GATHER_DESCENDANTS(&FileNode->FileName, FALSE, TRUE,
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
|
||||||
&FileNode->FileName, FALSE, &RestartKey);
|
|
||||||
if (0 == DescendantFileNode)
|
|
||||||
break;
|
|
||||||
if (DescendantFileNode->FileName.Length > FileNameLength &&
|
if (DescendantFileNode->FileName.Length > FileNameLength &&
|
||||||
L'\\' == DescendantFileNode->FileName.Buffer[FileNameLength / sizeof(WCHAR)])
|
L'\\' == DescendantFileNode->FileName.Buffer[FileNameLength / sizeof(WCHAR)])
|
||||||
break;
|
break;
|
||||||
|
if (0 >= DescendantFileNode->HandleCount)
|
||||||
if (1 >= DescendantFileNode->HandleCount)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (0 != StreamFileName)
|
if (0 != StreamFileName)
|
||||||
{
|
{
|
||||||
if (DescendantFileNode != FileNode &&
|
if (DescendantFileNode != FileNode &&
|
||||||
0 != FspFileNameCompare(&DescendantFileNode->FileName, StreamFileName,
|
0 != FspFileNameCompare(&DescendantFileNode->FileName, StreamFileName,
|
||||||
CaseInsensitive, 0))
|
CaseInsensitive, 0))
|
||||||
continue;
|
continue;
|
||||||
}
|
});
|
||||||
|
|
||||||
ASSERT(0 == ((UINT_PTR)DescendantFileNode & 7));
|
|
||||||
|
|
||||||
/* keep a reference to the FileNode in case it goes away in later processing */
|
|
||||||
FspFileNodeReference(DescendantFileNode);
|
|
||||||
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) > DescendantFileNodeCount)
|
|
||||||
DescendantFileNodes[DescendantFileNodeCount] = DescendantFileNode;
|
|
||||||
DescendantFileNodeCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(0 != StreamFileName || DescendantFileNodeCount <= 2);
|
|
||||||
|
|
||||||
/* if the local array is out of space, gather descendant file nodes in the pool */
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount)
|
|
||||||
{
|
|
||||||
ASSERT(0 == StreamFileName);
|
|
||||||
|
|
||||||
DescendantFileNodes = FspAllocMustSucceed(DescendantFileNodeCount * sizeof(FSP_FILE_NODE *));
|
|
||||||
DescendantFileNodeIndex = 0;
|
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
|
||||||
&FileNode->FileName, FALSE, &RestartKey);
|
|
||||||
if (0 == DescendantFileNode)
|
|
||||||
break;
|
|
||||||
if (DescendantFileNode->FileName.Length > FileNameLength &&
|
|
||||||
L'\\' == DescendantFileNode->FileName.Buffer[FileNameLength / sizeof(WCHAR)])
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (1 >= DescendantFileNode->HandleCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
DescendantFileNodes[DescendantFileNodeIndex] = DescendantFileNode;
|
|
||||||
DescendantFileNodeIndex++;
|
|
||||||
ASSERT(DescendantFileNodeCount >= DescendantFileNodeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(DescendantFileNodeCount == DescendantFileNodeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
/*
|
|
||||||
* At this point all descendant FileNode's are enumerated and referenced.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* break any Batch or Handle oplocks on descendants */
|
/* break any Batch or Handle oplocks on descendants */
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
for (
|
for (
|
||||||
@ -993,6 +991,7 @@ NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* release the FileNode so that we can safely wait without deadlocks */
|
||||||
FspFileNodeReleaseF(FileNode, AcquireFlags);
|
FspFileNodeReleaseF(FileNode, AcquireFlags);
|
||||||
|
|
||||||
/* wait for oplock breaks to finish */
|
/* wait for oplock breaks to finish */
|
||||||
@ -1024,20 +1023,7 @@ NTSTATUS FspFileNodeCheckBatchOplocksOnAllStreams(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dereference all FileNode's referenced during initial enumeration */
|
SCATTER_DESCENDANTS(TRUE);
|
||||||
for (
|
|
||||||
DescendantFileNodeIndex = 0;
|
|
||||||
DescendantFileNodeCount > DescendantFileNodeIndex;
|
|
||||||
DescendantFileNodeIndex++)
|
|
||||||
{
|
|
||||||
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
|
|
||||||
DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode & ~7);
|
|
||||||
|
|
||||||
FspFileNodeDereference(DescendantFileNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DescendantFileNodeArray != DescendantFileNodes)
|
|
||||||
FspFree(DescendantFileNodes);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -1047,28 +1033,10 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/*
|
|
||||||
* Special rules for renaming open files:
|
|
||||||
* - A file cannot be renamed if it has any open handles,
|
|
||||||
* unless it is only open because of a batch opportunistic lock (oplock)
|
|
||||||
* and the batch oplock can be broken immediately.
|
|
||||||
* - A file cannot be renamed if a file with the same name exists
|
|
||||||
* and has open handles (except in the batch-oplock case described earlier).
|
|
||||||
* - A directory cannot be renamed if it or any of its subdirectories contains a file
|
|
||||||
* that has open handles (except in the batch-oplock case described earlier).
|
|
||||||
*/
|
|
||||||
|
|
||||||
FSP_FILE_NODE *DescendantFileNode;
|
|
||||||
FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes;
|
|
||||||
ULONG DescendantFileNodeCount, DescendantFileNodeIndex;
|
|
||||||
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey;
|
|
||||||
BOOLEAN CheckingOldName = 0 != FileNode;
|
BOOLEAN CheckingOldName = 0 != FileNode;
|
||||||
BOOLEAN HasOpenHandles;
|
BOOLEAN HasOpenHandles;
|
||||||
BOOLEAN Success = TRUE;
|
BOOLEAN Success = TRUE;
|
||||||
|
|
||||||
DescendantFileNodes = DescendantFileNodeArray;
|
|
||||||
DescendantFileNodeCount = 0;
|
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
/* if we are checking the existing file name, do a quick check here */
|
/* if we are checking the existing file name, do a quick check here */
|
||||||
@ -1077,32 +1045,16 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
|
|||||||
/* if file has single open handle (also means no streams open) and not a directory, exit now */
|
/* if file has single open handle (also means no streams open) and not a directory, exit now */
|
||||||
if (1 == FileNode->HandleCount && !FileNode->IsDirectory)
|
if (1 == FileNode->HandleCount && !FileNode->IsDirectory)
|
||||||
{
|
{
|
||||||
ASSERT(Success);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
goto unlock_exit;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: when CheckingOldName==TRUE, the old FileNode is not included in enumerations below */
|
/* Note: when CheckingOldName==TRUE, the old FileNode is not included in enumerations below */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count descendant file nodes and try to gather them in a local array if possible */
|
GATHER_DESCENDANTS(FileName, CheckingOldName, TRUE,
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);
|
DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode |
|
||||||
for (;;)
|
(0 < DescendantFileNode->HandleCount)));
|
||||||
{
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
|
||||||
FileName, CheckingOldName, &RestartKey);
|
|
||||||
if (0 == DescendantFileNode)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* keep a reference to the FileNode in case it goes away in later processing */
|
|
||||||
FspFileNodeReference(DescendantFileNode);
|
|
||||||
|
|
||||||
HasOpenHandles = 0 < DescendantFileNode->HandleCount;
|
|
||||||
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) > DescendantFileNodeCount)
|
|
||||||
DescendantFileNodes[DescendantFileNodeCount] =
|
|
||||||
(PVOID)((UINT_PTR)DescendantFileNode | HasOpenHandles);
|
|
||||||
DescendantFileNodeCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == DescendantFileNodeCount)
|
if (0 == DescendantFileNodeCount)
|
||||||
{
|
{
|
||||||
@ -1110,30 +1062,6 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
|
|||||||
goto unlock_exit;
|
goto unlock_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the local array is out of space, gather descendant file nodes in the pool */
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount)
|
|
||||||
{
|
|
||||||
DescendantFileNodes = FspAllocMustSucceed(DescendantFileNodeCount * sizeof(FSP_FILE_NODE *));
|
|
||||||
DescendantFileNodeIndex = 0;
|
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
|
||||||
FileName, CheckingOldName, &RestartKey);
|
|
||||||
if (0 == DescendantFileNode)
|
|
||||||
break;
|
|
||||||
|
|
||||||
HasOpenHandles = 0 < DescendantFileNode->HandleCount;
|
|
||||||
|
|
||||||
DescendantFileNodes[DescendantFileNodeIndex] =
|
|
||||||
(PVOID)((UINT_PTR)DescendantFileNode | HasOpenHandles);
|
|
||||||
DescendantFileNodeIndex++;
|
|
||||||
ASSERT(DescendantFileNodeCount >= DescendantFileNodeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(DescendantFileNodeCount == DescendantFileNodeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1197,20 +1125,7 @@ BOOLEAN FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp,
|
|||||||
unlock_exit:
|
unlock_exit:
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
/* dereference all FileNode's referenced during initial enumeration */
|
SCATTER_DESCENDANTS(TRUE);
|
||||||
for (
|
|
||||||
DescendantFileNodeIndex = 0;
|
|
||||||
DescendantFileNodeCount > DescendantFileNodeIndex;
|
|
||||||
DescendantFileNodeIndex++)
|
|
||||||
{
|
|
||||||
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
|
|
||||||
DescendantFileNode = (PVOID)((UINT_PTR)DescendantFileNode & ~1);
|
|
||||||
|
|
||||||
FspFileNodeDereference(DescendantFileNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DescendantFileNodeArray != DescendantFileNodes)
|
|
||||||
FspFree(DescendantFileNodes);
|
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
@ -1239,52 +1154,13 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
FSP_FILE_NODE *DescendantFileNode;
|
|
||||||
FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes;
|
|
||||||
ULONG DescendantFileNodeCount, DescendantFileNodeIndex;
|
|
||||||
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey;
|
|
||||||
BOOLEAN Deleted, Inserted, AcquireForeign;
|
BOOLEAN Deleted, Inserted, AcquireForeign;
|
||||||
USHORT FileNameLength;
|
USHORT FileNameLength;
|
||||||
PWSTR ExternalFileName;
|
PWSTR ExternalFileName;
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
DescendantFileNodes = DescendantFileNodeArray;
|
GATHER_DESCENDANTS(&FileNode->FileName, FALSE, FALSE, {});
|
||||||
DescendantFileNodes[0] = FileNode;
|
|
||||||
DescendantFileNodeCount = 1;
|
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
|
||||||
&FileNode->FileName, TRUE, &RestartKey);
|
|
||||||
if (0 == DescendantFileNode)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) > DescendantFileNodeCount)
|
|
||||||
DescendantFileNodes[DescendantFileNodeCount] = DescendantFileNode;
|
|
||||||
DescendantFileNodeCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount)
|
|
||||||
{
|
|
||||||
DescendantFileNodes = FspAllocMustSucceed(DescendantFileNodeCount * sizeof(FSP_FILE_NODE *));
|
|
||||||
DescendantFileNodes[0] = FileNode;
|
|
||||||
DescendantFileNodeIndex = 1;
|
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,
|
|
||||||
&FileNode->FileName, TRUE, &RestartKey);
|
|
||||||
if (0 == DescendantFileNode)
|
|
||||||
break;
|
|
||||||
|
|
||||||
DescendantFileNodes[DescendantFileNodeIndex] = DescendantFileNode;
|
|
||||||
DescendantFileNodeIndex++;
|
|
||||||
ASSERT(DescendantFileNodeCount >= DescendantFileNodeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(DescendantFileNodeCount == DescendantFileNodeIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileNameLength = FileNode->FileName.Length;
|
FileNameLength = FileNode->FileName.Length;
|
||||||
for (
|
for (
|
||||||
@ -1333,8 +1209,7 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName)
|
|||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
if (DescendantFileNodeArray != DescendantFileNodes)
|
SCATTER_DESCENDANTS(FALSE);
|
||||||
FspFree(DescendantFileNodes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user