2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
16 * nor the names of their contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission from Kernel Drivers, LLC and Your File System, Inc.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // File: AFSGeneric.cpp
37 #include "AFSCommon.h"
40 // Function: AFSExceptionFilter
44 // This function is the exception handler
48 // A status is returned for the function
52 AFSExceptionFilter( IN CHAR *FunctionString,
54 IN PEXCEPTION_POINTERS ExceptPtrs)
57 UNREFERENCED_PARAMETER(Code);
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
74 ExceptRec->ExceptionCode,
75 ExceptRec->ExceptionAddress,
76 (void *)AFSExceptionFilter));
78 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
80 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
81 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
83 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
85 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
88 KeBugCheck( (ULONG)-2);
96 __except( EXCEPTION_EXECUTE_HANDLER)
102 return EXCEPTION_EXECUTE_HANDLER;
106 // Function: AFSLibExAllocatePoolWithTag()
108 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
109 // is configured on, then bugcheck the system if
110 // a memory allocation fails. The routine should be
111 // used for all memory allocations that are to be freed
112 // when the library is unloaded. Memory allocations that
113 // are to survive library unload and reload should be
114 // performed using AFSExAllocatePoolWithTag() which is
115 // provided by the AFS Framework.
118 // POOL_TYPE PoolType - Paged or NonPaged
119 // SIZE_T NumberOfBytes - requested allocation size
120 // ULONG Tag - Pool Allocation Tag to be applied for tracking
123 // void * - the memory allocation
127 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
128 IN SIZE_T NumberOfBytes,
132 void *pBuffer = NULL;
134 pBuffer = ExAllocatePoolWithTag( PoolType,
141 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
144 KeBugCheck( (ULONG)-2);
151 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
155 PsGetCurrentThread()));
165 // Function: AFSAcquireExcl()
167 // Purpose: Called to acquire a resource exclusive with optional wait
170 // PERESOURCE Resource - Resource to acquire
171 // BOOLEAN Wait - Whether to block
174 // BOOLEAN - Whether the mask was acquired
178 AFSAcquireExcl( IN PERESOURCE Resource,
182 BOOLEAN bStatus = FALSE;
185 // Normal kernel APCs must be disabled before calling
186 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
189 KeEnterCriticalRegion();
191 bStatus = ExAcquireResourceExclusiveLite( Resource,
197 KeLeaveCriticalRegion();
204 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
208 BOOLEAN bStatus = FALSE;
210 KeEnterCriticalRegion();
212 bStatus = ExAcquireSharedStarveExclusive( Resource,
218 KeLeaveCriticalRegion();
225 // Function: AFSAcquireShared()
227 // Purpose: Called to acquire a resource shared with optional wait
230 // PERESOURCE Resource - Resource to acquire
231 // BOOLEAN Wait - Whether to block
234 // BOOLEAN - Whether the mask was acquired
238 AFSAcquireShared( IN PERESOURCE Resource,
242 BOOLEAN bStatus = FALSE;
244 KeEnterCriticalRegion();
246 bStatus = ExAcquireResourceSharedLite( Resource,
252 KeLeaveCriticalRegion();
259 // Function: AFSReleaseResource()
261 // Purpose: Called to release a resource
264 // PERESOURCE Resource - Resource to release
271 AFSReleaseResource( IN PERESOURCE Resource)
274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
278 PsGetCurrentThread()));
280 ExReleaseResourceLite( Resource);
282 KeLeaveCriticalRegion();
288 AFSConvertToShared( IN PERESOURCE Resource)
291 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSConvertToShared Converting lock %p Thread %08lX\n",
295 PsGetCurrentThread()));
297 ExConvertExclusiveToSharedLite( Resource);
303 // Function: AFSCompleteRequest
307 // This function completes irps
311 // A status is returned for the function
315 AFSCompleteRequest( IN PIRP Irp,
319 Irp->IoStatus.Status = Status;
321 IoCompleteRequest( Irp,
328 // Function: AFSGenerateCRC
332 // Given a device and filename this function generates a CRC
336 // A status is returned for the function
340 AFSGenerateCRC( IN PUNICODE_STRING FileName,
341 IN BOOLEAN UpperCaseName)
345 NTSTATUS ntStatus = STATUS_SUCCESS;
347 ntStatus = RtlHashUnicodeString( FileName,
349 HASH_STRING_ALGORITHM_DEFAULT,
352 if( !NT_SUCCESS( ntStatus))
361 AFSLockSystemBuffer( IN PIRP Irp,
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
409 AFSDumpTraceFilesFnc();
411 IoFreeMdl( Irp->MdlAddress );
412 Irp->MdlAddress = NULL;
422 AFSLockUserBuffer( IN void *UserBuffer,
423 IN ULONG BufferLength,
427 NTSTATUS ntStatus = STATUS_SUCCESS;
428 void *pAddress = NULL;
434 pMdl = IoAllocateMdl( UserBuffer,
443 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
447 // Lock the new Mdl in memory.
453 MmProbeAndLockPages( pMdl,
457 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
460 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
463 AFSDumpTraceFilesFnc();
485 AFSMapToService( IN PIRP Irp,
489 NTSTATUS ntStatus = STATUS_SUCCESS;
490 void *pMappedBuffer = NULL;
491 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
497 if( pDevExt->Specific.Control.ServiceProcess == NULL)
500 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
503 if( Irp->MdlAddress == NULL)
506 if( AFSLockSystemBuffer( Irp,
510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
515 // Attach to the service process for mapping
518 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
519 (PRKAPC_STATE)&stApcState);
521 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
528 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
535 return pMappedBuffer;
539 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
543 NTSTATUS ntStatus = STATUS_SUCCESS;
544 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
550 if( pDevExt->Specific.Control.ServiceProcess == NULL)
553 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
560 // Attach to the service process for mapping
563 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
564 (PRKAPC_STATE)&stApcState);
566 MmUnmapLockedPages( MappedBuffer,
569 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
581 AFSInitializeLibraryDevice()
584 NTSTATUS ntStatus = STATUS_SUCCESS;
585 AFSDeviceExt *pDeviceExt = NULL;
590 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
593 // The PIOCtl file name
596 RtlInitUnicodeString( &AFSPIOCtlName,
597 AFS_PIOCTL_FILE_INTERFACE_NAME);
600 // And the global root share name
603 RtlInitUnicodeString( &AFSGlobalRootName,
604 AFS_GLOBAL_ROOT_SHARE_NAME);
612 AFSRemoveLibraryDevice()
615 NTSTATUS ntStatus = STATUS_SUCCESS;
626 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
630 UNREFERENCED_PARAMETER(DeviceObject);
631 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
633 AFSCompleteRequest( Irp,
640 AFSInitializeGlobalDirectoryEntries()
643 NTSTATUS ntStatus = STATUS_SUCCESS;
644 AFSDirectoryCB *pDirNode = NULL;
645 ULONG ulEntryLength = 0;
646 AFSObjectInfoCB *pObjectInfoCB = NULL;
647 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
654 // Initialize the global . entry
657 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
660 if( pObjectInfoCB == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
664 AFS_TRACE_LEVEL_ERROR,
665 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
672 AFS_OBJECT_REFERENCE_GLOBAL);
674 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
675 AFS_TRACE_LEVEL_VERBOSE,
676 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
680 ntStatus = STATUS_SUCCESS;
682 ulEntryLength = sizeof( AFSDirectoryCB) +
685 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
689 if( pDirNode == NULL)
692 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
693 AFS_OBJECT_REFERENCE_GLOBAL);
695 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
696 AFS_TRACE_LEVEL_VERBOSE,
697 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
704 AFSDeleteObjectInfo( &pObjectInfoCB);
707 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
708 AFS_TRACE_LEVEL_ERROR,
709 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
711 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
714 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
715 AFS_TRACE_LEVEL_VERBOSE,
716 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
719 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
720 sizeof( AFSNonPagedDirectoryCB),
721 AFS_DIR_ENTRY_NP_TAG);
723 if( pNonPagedDirEntry == NULL)
726 ExFreePool( pDirNode);
728 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
729 AFS_OBJECT_REFERENCE_GLOBAL);
731 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
732 AFS_TRACE_LEVEL_VERBOSE,
733 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
740 AFSDeleteObjectInfo( &pObjectInfoCB);
743 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
744 AFS_TRACE_LEVEL_ERROR,
745 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
747 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
750 RtlZeroMemory( pDirNode,
753 RtlZeroMemory( pNonPagedDirEntry,
754 sizeof( AFSNonPagedDirectoryCB));
756 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
758 pDirNode->NonPaged = pNonPagedDirEntry;
760 pDirNode->ObjectInformation = pObjectInfoCB;
766 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
768 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
771 // Setup the names in the entry
774 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
776 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
778 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
780 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
783 // Populate the rest of the data
786 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
788 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
790 AFSGlobalDotDirEntry = pDirNode;
796 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
799 if( pObjectInfoCB == NULL)
802 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
803 AFS_TRACE_LEVEL_ERROR,
804 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
807 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
810 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
811 AFS_OBJECT_REFERENCE_GLOBAL);
813 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
814 AFS_TRACE_LEVEL_VERBOSE,
815 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
819 ntStatus = STATUS_SUCCESS;
821 ulEntryLength = sizeof( AFSDirectoryCB) +
822 ( 2 * sizeof( WCHAR));
824 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
828 if( pDirNode == NULL)
831 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
832 AFS_TRACE_LEVEL_ERROR,
833 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
835 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
836 AFS_OBJECT_REFERENCE_GLOBAL);
838 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
839 AFS_TRACE_LEVEL_VERBOSE,
840 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
847 AFSDeleteObjectInfo( &pObjectInfoCB);
850 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
853 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
854 AFS_TRACE_LEVEL_VERBOSE,
855 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
858 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
859 sizeof( AFSNonPagedDirectoryCB),
860 AFS_DIR_ENTRY_NP_TAG);
862 if( pNonPagedDirEntry == NULL)
865 ExFreePool( pDirNode);
867 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
868 AFS_OBJECT_REFERENCE_GLOBAL);
870 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
871 AFS_TRACE_LEVEL_VERBOSE,
872 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
879 AFSDeleteObjectInfo( &pObjectInfoCB);
882 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
885 RtlZeroMemory( pDirNode,
888 RtlZeroMemory( pNonPagedDirEntry,
889 sizeof( AFSNonPagedDirectoryCB));
891 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
893 pDirNode->NonPaged = pNonPagedDirEntry;
895 pDirNode->ObjectInformation = pObjectInfoCB;
901 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
903 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
906 // Setup the names in the entry
909 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
911 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
915 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
917 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
920 // Populate the rest of the data
923 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
925 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
927 AFSGlobalDotDotDirEntry = pDirNode;
931 if( !NT_SUCCESS( ntStatus))
934 if( AFSGlobalDotDirEntry != NULL)
937 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
938 AFS_OBJECT_REFERENCE_GLOBAL);
940 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
941 AFS_TRACE_LEVEL_VERBOSE,
942 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
943 AFSGlobalDotDirEntry->ObjectInformation,
949 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
952 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
954 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
956 ExFreePool( AFSGlobalDotDirEntry);
958 AFSGlobalDotDirEntry = NULL;
961 if( AFSGlobalDotDotDirEntry != NULL)
964 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
965 AFS_OBJECT_REFERENCE_GLOBAL);
967 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
968 AFS_TRACE_LEVEL_VERBOSE,
969 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
970 AFSGlobalDotDotDirEntry->ObjectInformation,
976 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
979 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
981 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
983 ExFreePool( AFSGlobalDotDotDirEntry);
985 AFSGlobalDotDotDirEntry = NULL;
994 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
995 IN PUNICODE_STRING FileName,
996 IN PUNICODE_STRING TargetName,
997 IN AFSDirEnumEntry *DirEnumEntry,
1001 AFSDirectoryCB *pDirNode = NULL;
1002 NTSTATUS ntStatus = STATUS_SUCCESS;
1003 ULONG ulEntryLength = 0;
1004 AFSObjectInfoCB *pObjectInfoCB = NULL;
1005 ULONGLONG ullIndex = 0;
1006 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
1012 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1013 AFS_TRACE_LEVEL_VERBOSE,
1014 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
1016 ParentObjectInfo->FileId.Cell,
1017 ParentObjectInfo->FileId.Volume,
1018 ParentObjectInfo->FileId.Vnode,
1019 ParentObjectInfo->FileId.Unique));
1022 // First thing is to locate/create our object information block
1026 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1029 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1031 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1033 (AFSBTreeEntry **)&pObjectInfoCB);
1035 if( !NT_SUCCESS( ntStatus))
1039 // Allocate our object info cb
1042 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1045 if( pObjectInfoCB == NULL)
1048 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1050 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1053 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1054 AFS_TRACE_LEVEL_VERBOSE,
1055 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
1061 // If we allocated the object information cb then set the information
1064 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1066 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1068 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1070 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1072 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1073 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1076 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1079 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1082 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1085 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1090 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1095 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1096 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1100 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1101 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1102 pObjectInfoCB->TargetFileId.Unique == 0 &&
1103 (TargetName == NULL || TargetName->Length == 0))
1107 // This will ensure we perform a validation on the node
1110 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1113 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1116 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1119 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1122 if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
1125 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1127 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1129 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1131 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1133 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1135 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1137 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1139 pObjectInfoCB->Links = DirEnumEntry->Links;
1141 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1143 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1145 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1149 // This reference count is either stored into the return DirectoryCB
1150 // or released before function exit.
1153 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1154 AFS_OBJECT_REFERENCE_DIRENTRY);
1156 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1157 AFS_TRACE_LEVEL_VERBOSE,
1158 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1162 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1164 ntStatus = STATUS_SUCCESS;
1166 ulEntryLength = sizeof( AFSDirectoryCB) +
1169 if( TargetName != NULL)
1172 ulEntryLength += TargetName->Length;
1175 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1179 if( pDirNode == NULL)
1182 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1185 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1186 AFS_TRACE_LEVEL_VERBOSE,
1187 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1190 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1191 sizeof( AFSNonPagedDirectoryCB),
1192 AFS_DIR_ENTRY_NP_TAG);
1194 if( pNonPagedDirEntry == NULL)
1197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1200 RtlZeroMemory( pDirNode,
1203 RtlZeroMemory( pNonPagedDirEntry,
1204 sizeof( AFSNonPagedDirectoryCB));
1206 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1208 pDirNode->NonPaged = pNonPagedDirEntry;
1210 pDirNode->ObjectInformation = pObjectInfoCB;
1213 // Set valid entry and NOT_IN_PARENT flag
1216 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1218 pDirNode->FileIndex = FileIndex;
1221 // Setup the names in the entry
1224 if( FileName->Length > 0)
1227 pDirNode->NameInformation.FileName.Length = FileName->Length;
1229 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1231 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1233 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1235 pDirNode->NameInformation.FileName.Length);
1238 // Create a CRC for the file
1241 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1244 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1249 AFS_TRACE_LEVEL_VERBOSE,
1250 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1253 ParentObjectInfo->FileId.Cell,
1254 ParentObjectInfo->FileId.Volume,
1255 ParentObjectInfo->FileId.Vnode,
1256 ParentObjectInfo->FileId.Unique));
1258 if( TargetName != NULL &&
1259 TargetName->Length > 0)
1262 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1264 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1266 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1267 sizeof( AFSDirectoryCB) +
1268 pDirNode->NameInformation.FileName.Length);
1270 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1272 pDirNode->NameInformation.TargetName.Length);
1278 if( !NT_SUCCESS( ntStatus))
1281 if( pNonPagedDirEntry != NULL)
1284 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1286 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1289 if( pDirNode != NULL)
1292 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1293 AFS_TRACE_LEVEL_VERBOSE,
1294 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1297 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1303 // Dereference our object info block if we have one
1306 if( pObjectInfoCB != NULL)
1309 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1312 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1313 AFS_OBJECT_REFERENCE_DIRENTRY);
1315 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1316 AFS_TRACE_LEVEL_VERBOSE,
1317 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1321 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1330 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1331 IN BOOLEAN DirectoryEntry)
1334 BOOLEAN bReturn = TRUE;
1335 ACCESS_MASK stAccessMask = 0;
1338 // Get rid of anything we don't know about
1341 DesiredAccess = (DesiredAccess &
1347 ACCESS_SYSTEM_SECURITY |
1351 FILE_READ_ATTRIBUTES |
1352 FILE_WRITE_ATTRIBUTES |
1353 FILE_LIST_DIRECTORY |
1359 // Our 'read only' access mask. These are the accesses we will
1360 // allow for a read only file
1363 stAccessMask = DELETE |
1368 ACCESS_SYSTEM_SECURITY |
1372 FILE_READ_ATTRIBUTES |
1373 FILE_WRITE_ATTRIBUTES |
1375 FILE_LIST_DIRECTORY |
1379 // For a directory, add in the directory specific accesses
1385 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1390 if( FlagOn( DesiredAccess, ~stAccessMask))
1394 // A write access is set ...
1404 AFSEvaluateNode( IN GUID *AuthGroup,
1405 IN AFSDirectoryCB *DirEntry)
1408 NTSTATUS ntStatus = STATUS_SUCCESS;
1409 AFSDirEnumEntry *pDirEntry = NULL;
1410 UNICODE_STRING uniTargetName;
1415 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1420 if( !NT_SUCCESS( ntStatus))
1423 try_return( ntStatus);
1426 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1428 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1430 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1432 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1434 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1436 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1438 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1440 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1442 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1444 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1446 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1448 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1449 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1452 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1455 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1458 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1461 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1466 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1470 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1472 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1475 // If we have a target name then see if it needs updating ...
1478 if( pDirEntry->TargetNameLength > 0)
1482 // Update the target name information if needed
1485 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1487 uniTargetName.MaximumLength = uniTargetName.Length;
1489 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1491 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1494 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1495 RtlCompareUnicodeString( &uniTargetName,
1496 &DirEntry->NameInformation.TargetName,
1501 // Update the target name
1504 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1506 uniTargetName.Buffer,
1507 uniTargetName.Length);
1509 if( !NT_SUCCESS( ntStatus))
1512 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1514 try_return( ntStatus);
1518 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1523 if( pDirEntry != NULL)
1526 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1534 AFSValidateSymLink( IN GUID *AuthGroup,
1535 IN AFSDirectoryCB *DirEntry)
1538 NTSTATUS ntStatus = STATUS_SUCCESS;
1539 AFSDirEnumEntry *pDirEntry = NULL;
1540 UNICODE_STRING uniTargetName;
1545 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1550 if( !NT_SUCCESS( ntStatus))
1553 try_return( ntStatus);
1556 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1557 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1560 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1561 AFS_TRACE_LEVEL_VERBOSE_2,
1562 "AFSValidateSymLink Invalid type Status %08lX\n",
1563 STATUS_OBJECT_NAME_NOT_FOUND));
1565 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1568 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1570 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1572 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1575 // Update the target name information if needed
1578 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1580 uniTargetName.MaximumLength = uniTargetName.Length;
1582 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1584 if( uniTargetName.Length > 0)
1587 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1590 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1591 RtlCompareUnicodeString( &uniTargetName,
1592 &DirEntry->NameInformation.TargetName,
1597 // Update the target name
1600 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1602 uniTargetName.Buffer,
1603 uniTargetName.Length);
1605 if( !NT_SUCCESS( ntStatus))
1608 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1610 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1614 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1618 // If the FileType is the same then nothing to do since it IS
1622 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1625 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1627 try_return( ntStatus = STATUS_SUCCESS);
1630 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1632 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1634 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1636 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1638 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1640 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1642 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1644 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1646 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1647 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1650 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1653 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1656 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1659 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1664 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1668 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1670 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1674 if( pDirEntry != NULL)
1677 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1685 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1689 NTSTATUS ntStatus = STATUS_SUCCESS;
1690 IO_STATUS_BLOCK stIoStatus;
1692 AFSObjectInfoCB * pParentObjectInfo = NULL;
1694 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1695 AFS_TRACE_LEVEL_VERBOSE,
1696 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1697 (*ppObjectInfo)->FileType,
1698 (*ppObjectInfo)->FileId.Cell,
1699 (*ppObjectInfo)->FileId.Volume,
1700 (*ppObjectInfo)->FileId.Vnode,
1701 (*ppObjectInfo)->FileId.Unique,
1704 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1707 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1708 &(*ppObjectInfo)->ParentFileId,
1712 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1713 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1714 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1717 // We only act on the mount point itself, not the target. If the
1718 // node has been deleted then mark it as such otherwise indicate
1719 // it requires verification
1722 if( Reason == AFS_INVALIDATE_DELETED)
1724 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1729 if( Reason == AFS_INVALIDATE_FLUSHED)
1732 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1734 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1737 (*ppObjectInfo)->Expiration.QuadPart = 0;
1739 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1741 (*ppObjectInfo)->TargetFileId.Unique = 0;
1743 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1744 AFS_TRACE_LEVEL_VERBOSE,
1745 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1746 (*ppObjectInfo)->FileId.Cell,
1747 (*ppObjectInfo)->FileId.Volume,
1748 (*ppObjectInfo)->FileId.Vnode,
1749 (*ppObjectInfo)->FileId.Unique));
1751 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1754 if ( pParentObjectInfo != NULL)
1757 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1759 if( Reason == AFS_INVALIDATE_CREDS)
1761 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1764 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1765 Reason == AFS_INVALIDATE_FLUSHED)
1767 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1771 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1774 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1777 FILE_ACTION_MODIFIED);
1780 try_return( ntStatus);
1784 // Depending on the reason for invalidation then perform work on the node
1790 case AFS_INVALIDATE_DELETED:
1794 // Mark this node as invalid
1797 (*ppObjectInfo)->Links = 0;
1799 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1801 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1802 AFS_TRACE_LEVEL_VERBOSE,
1803 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1804 (*ppObjectInfo)->FileId.Cell,
1805 (*ppObjectInfo)->FileId.Volume,
1806 (*ppObjectInfo)->FileId.Vnode,
1807 (*ppObjectInfo)->FileId.Unique));
1809 if( pParentObjectInfo != NULL)
1812 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1813 AFS_TRACE_LEVEL_VERBOSE,
1814 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1815 pParentObjectInfo->FileId.Cell,
1816 pParentObjectInfo->FileId.Volume,
1817 pParentObjectInfo->FileId.Vnode,
1818 pParentObjectInfo->FileId.Unique));
1820 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1822 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1824 pParentObjectInfo->Expiration.QuadPart = 0;
1826 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1828 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1832 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1835 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1838 FILE_ACTION_REMOVED);
1841 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1844 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1850 case AFS_INVALIDATE_FLUSHED:
1853 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1854 (*ppObjectInfo)->Fcb != NULL)
1857 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1858 AFS_TRACE_LEVEL_VERBOSE,
1859 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1860 (*ppObjectInfo)->FileId.Cell,
1861 (*ppObjectInfo)->FileId.Volume,
1862 (*ppObjectInfo)->FileId.Vnode,
1863 (*ppObjectInfo)->FileId.Unique));
1865 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1871 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1876 if( !NT_SUCCESS( stIoStatus.Status))
1879 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1880 AFS_TRACE_LEVEL_ERROR,
1881 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1882 (*ppObjectInfo)->FileId.Cell,
1883 (*ppObjectInfo)->FileId.Volume,
1884 (*ppObjectInfo)->FileId.Vnode,
1885 (*ppObjectInfo)->FileId.Unique,
1887 stIoStatus.Information));
1889 ntStatus = stIoStatus.Status;
1893 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1896 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1902 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1903 AFS_TRACE_LEVEL_WARNING,
1904 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1905 (*ppObjectInfo)->FileId.Cell,
1906 (*ppObjectInfo)->FileId.Volume,
1907 (*ppObjectInfo)->FileId.Vnode,
1908 (*ppObjectInfo)->FileId.Unique));
1910 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1914 __except( EXCEPTION_EXECUTE_HANDLER)
1917 ntStatus = GetExceptionCode();
1921 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1922 (*ppObjectInfo)->FileId.Cell,
1923 (*ppObjectInfo)->FileId.Volume,
1924 (*ppObjectInfo)->FileId.Vnode,
1925 (*ppObjectInfo)->FileId.Unique,
1928 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1931 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1934 // Clear out the extents
1935 // Get rid of them (note this involves waiting
1936 // for any writes or reads to the cache to complete)
1939 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1943 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1946 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1949 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1950 AFS_TRACE_LEVEL_VERBOSE,
1951 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1952 (*ppObjectInfo)->FileId.Cell,
1953 (*ppObjectInfo)->FileId.Volume,
1954 (*ppObjectInfo)->FileId.Vnode,
1955 (*ppObjectInfo)->FileId.Unique));
1957 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1960 // Fall through to the default processing
1966 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1968 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1972 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1975 if( Reason == AFS_INVALIDATE_CREDS)
1977 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1980 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1982 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1986 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1989 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1992 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1995 FILE_ACTION_MODIFIED);
1997 else if ( pParentObjectInfo != NULL)
2000 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2003 FILE_ACTION_MODIFIED);
2007 // Indicate this node requires re-evaluation for the remaining reasons
2010 (*ppObjectInfo)->Expiration.QuadPart = 0;
2012 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2013 AFS_TRACE_LEVEL_VERBOSE,
2014 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2015 (*ppObjectInfo)->FileId.Cell,
2016 (*ppObjectInfo)->FileId.Volume,
2017 (*ppObjectInfo)->FileId.Vnode,
2018 (*ppObjectInfo)->FileId.Unique));
2020 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2022 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2023 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2024 ( Reason == AFS_INVALIDATE_CALLBACK ||
2025 Reason == AFS_INVALIDATE_EXPIRED))
2027 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2028 AFS_INVALIDATE_DATA_VERSION)))
2031 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2041 if ( pParentObjectInfo != NULL)
2044 AFSReleaseObjectInfo( &pParentObjectInfo);
2051 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2054 NTSTATUS ntStatus = STATUS_SUCCESS;
2055 AFSVolumeCB *pVolumeCB = NULL;
2056 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2057 ULONGLONG ullIndex = 0;
2058 AFSObjectInfoCB *pObjectInfo = NULL;
2064 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2065 AFS_TRACE_LEVEL_VERBOSE,
2066 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2067 InvalidateCB->FileID.Cell,
2068 InvalidateCB->FileID.Volume,
2069 InvalidateCB->FileID.Vnode,
2070 InvalidateCB->FileID.Unique,
2071 InvalidateCB->FileType,
2072 InvalidateCB->WholeVolume,
2073 InvalidateCB->Reason));
2076 // Need to locate the Fcb for the directory to purge
2079 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2080 AFS_TRACE_LEVEL_VERBOSE,
2081 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2082 &pDevExt->Specific.RDR.VolumeTreeLock,
2083 PsGetCurrentThread()));
2086 // Starve any exclusive waiters on this paticular call
2089 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2092 // Locate the volume node
2095 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2097 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2099 (AFSBTreeEntry **)&pVolumeCB);
2101 if( pVolumeCB != NULL)
2104 lCount = AFSVolumeIncrement( pVolumeCB,
2105 AFS_VOLUME_REFERENCE_INVALIDATE);
2107 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2108 AFS_TRACE_LEVEL_VERBOSE,
2109 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2114 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2116 if( !NT_SUCCESS( ntStatus) ||
2120 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2121 AFS_TRACE_LEVEL_WARNING,
2122 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2123 InvalidateCB->FileID.Cell,
2124 InvalidateCB->FileID.Volume,
2125 InvalidateCB->FileID.Vnode,
2126 InvalidateCB->FileID.Unique,
2129 try_return( ntStatus = STATUS_SUCCESS);
2133 // If this is a whole volume invalidation then go do it now
2136 if( InvalidateCB->WholeVolume)
2139 ntStatus = AFSInvalidateVolume( pVolumeCB,
2140 InvalidateCB->Reason);
2142 try_return( ntStatus);
2145 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2148 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2151 pObjectInfo = &pVolumeCB->ObjectInformation;
2156 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2158 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2160 (AFSBTreeEntry **)&pObjectInfo);
2163 if( pObjectInfo != NULL)
2167 // Reference the node so it won't be torn down
2170 lCount = AFSObjectInfoIncrement( pObjectInfo,
2171 AFS_OBJECT_REFERENCE_INVALIDATION);
2173 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2174 AFS_TRACE_LEVEL_VERBOSE,
2175 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2180 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2182 if( !NT_SUCCESS( ntStatus) ||
2183 pObjectInfo == NULL)
2186 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2187 AFS_TRACE_LEVEL_VERBOSE,
2188 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2189 InvalidateCB->FileID.Cell,
2190 InvalidateCB->FileID.Volume,
2191 InvalidateCB->FileID.Vnode,
2192 InvalidateCB->FileID.Unique,
2195 try_return( ntStatus = STATUS_SUCCESS);
2198 AFSInvalidateObject( &pObjectInfo,
2199 InvalidateCB->Reason);
2203 if( pObjectInfo != NULL)
2206 lCount = AFSObjectInfoDecrement( pObjectInfo,
2207 AFS_OBJECT_REFERENCE_INVALIDATION);
2209 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2210 AFS_TRACE_LEVEL_VERBOSE,
2211 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2216 if ( pVolumeCB != NULL)
2219 lCount = AFSVolumeDecrement( pVolumeCB,
2220 AFS_VOLUME_REFERENCE_INVALIDATE);
2222 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2223 AFS_TRACE_LEVEL_VERBOSE,
2224 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2234 AFSIsChildOfParent( IN AFSFcb *Dcb,
2238 BOOLEAN bIsChild = FALSE;
2239 AFSFcb *pCurrentFcb = Fcb;
2240 AFSObjectInfoCB * pParentObjectInfo = NULL;
2242 while( pCurrentFcb != NULL)
2245 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2246 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2254 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2255 &pCurrentFcb->ObjectInformation->ParentFileId,
2258 if ( pParentObjectInfo != NULL)
2261 pCurrentFcb = pParentObjectInfo->Fcb;
2263 AFSReleaseObjectInfo( &pParentObjectInfo);
2277 AFSCreateHighIndex( IN AFSFileID *FileID)
2280 ULONGLONG ullIndex = 0;
2282 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2289 AFSCreateLowIndex( IN AFSFileID *FileID)
2292 ULONGLONG ullIndex = 0;
2294 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2300 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2301 IN ACCESS_MASK GrantedAccess,
2302 IN BOOLEAN DirectoryEntry)
2305 BOOLEAN bAccessGranted = TRUE;
2308 // Check if we are asking for read/write and granted only read only
2309 // NOTE: There will be more checks here
2312 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2314 AFSCheckForReadOnlyAccess( GrantedAccess,
2318 bAccessGranted = FALSE;
2321 return bAccessGranted;
2325 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2328 NTSTATUS ntStatus = STATUS_SUCCESS;
2329 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2335 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2337 if( AFSGlobalRoot == NULL)
2344 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2347 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2354 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2361 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2362 IN UNICODE_STRING *SubstituteName,
2363 IN ULONG StringIndex)
2366 NTSTATUS ntStatus = STATUS_SUCCESS;
2367 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2368 AFSSysNameCB *pSysName = NULL;
2369 ERESOURCE *pSysNameLock = NULL;
2372 UNICODE_STRING uniSysName;
2379 if( IoIs32bitProcess( NULL))
2382 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2384 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2389 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2391 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2395 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2397 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2401 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2402 AFS_TRACE_LEVEL_VERBOSE,
2403 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2405 PsGetCurrentThread()));
2407 AFSAcquireShared( pSysNameLock,
2411 // Find where we are in the list
2414 while( pSysName != NULL &&
2415 ulIndex < StringIndex)
2418 pSysName = pSysName->fLink;
2423 if( pSysName == NULL)
2426 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2427 AFS_TRACE_LEVEL_VERBOSE_2,
2428 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2430 STATUS_OBJECT_NAME_NOT_FOUND));
2432 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2435 RtlInitUnicodeString( &uniSysName,
2438 // If it is a full component of @SYS then just substitue the
2442 if( RtlCompareUnicodeString( &uniSysName,
2447 SubstituteName->Length = pSysName->SysName.Length;
2448 SubstituteName->MaximumLength = SubstituteName->Length;
2450 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2451 SubstituteName->Length,
2452 AFS_SUBST_BUFFER_TAG);
2454 if( SubstituteName->Buffer == NULL)
2457 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2460 RtlCopyMemory( SubstituteName->Buffer,
2461 pSysName->SysName.Buffer,
2462 pSysName->SysName.Length);
2469 while( ComponentName->Buffer[ usIndex] != L'@')
2475 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2476 SubstituteName->MaximumLength = SubstituteName->Length;
2478 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2479 SubstituteName->Length,
2480 AFS_SUBST_BUFFER_TAG);
2482 if( SubstituteName->Buffer == NULL)
2485 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2488 RtlCopyMemory( SubstituteName->Buffer,
2489 ComponentName->Buffer,
2490 usIndex * sizeof( WCHAR));
2492 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2493 pSysName->SysName.Buffer,
2494 pSysName->SysName.Length);
2499 AFSReleaseResource( pSysNameLock);
2506 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2507 IN OUT UNICODE_STRING *ComponentName,
2508 IN UNICODE_STRING *SubstituteName,
2509 IN OUT UNICODE_STRING *RemainingPath,
2510 IN BOOLEAN FreePathName)
2513 NTSTATUS ntStatus = STATUS_SUCCESS;
2514 UNICODE_STRING uniPathName;
2515 USHORT usPrefixNameLen = 0;
2516 SHORT sNameLenDelta = 0;
2522 // If the passed in name can handle the additional length
2523 // then just moves things around
2526 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2528 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2530 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2533 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2536 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2537 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2538 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2541 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2542 SubstituteName->Buffer,
2543 SubstituteName->Length);
2545 FullPathName->Length += sNameLenDelta;
2547 ComponentName->Length += sNameLenDelta;
2549 ComponentName->MaximumLength = ComponentName->Length;
2551 if ( RemainingPath->Buffer)
2554 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2557 try_return( ntStatus);
2561 // Need to re-allocate the buffer
2564 uniPathName.Length = FullPathName->Length -
2565 ComponentName->Length +
2566 SubstituteName->Length;
2568 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2570 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2571 uniPathName.MaximumLength,
2572 AFS_NAME_BUFFER_FOUR_TAG);
2574 if( uniPathName.Buffer == NULL)
2577 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2580 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2582 usPrefixNameLen *= sizeof( WCHAR);
2584 RtlZeroMemory( uniPathName.Buffer,
2585 uniPathName.MaximumLength);
2587 RtlCopyMemory( uniPathName.Buffer,
2588 FullPathName->Buffer,
2591 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2592 SubstituteName->Buffer,
2593 SubstituteName->Length);
2595 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2598 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2599 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2600 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2603 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2605 ComponentName->Length += sNameLenDelta;
2607 ComponentName->MaximumLength = ComponentName->Length;
2609 if ( RemainingPath->Buffer)
2612 RemainingPath->Buffer = uniPathName.Buffer
2613 + (RemainingPath->Buffer - FullPathName->Buffer)
2614 + sNameLenDelta/sizeof( WCHAR);
2619 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2622 *FullPathName = uniPathName;
2633 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2637 NTSTATUS ntStatus = STATUS_SUCCESS;
2638 AFSObjectInfoCB *pCurrentObject = NULL;
2639 AFSObjectInfoCB *pNextObject = NULL;
2645 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2646 AFS_TRACE_LEVEL_VERBOSE,
2647 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2648 VolumeCB->ObjectInformation.FileId.Cell,
2649 VolumeCB->ObjectInformation.FileId.Volume,
2650 VolumeCB->ObjectInformation.FileId.Vnode,
2651 VolumeCB->ObjectInformation.FileId.Unique,
2655 // Depending on the reason for invalidation then perform work on the node
2661 case AFS_INVALIDATE_DELETED:
2665 // Mark this volume as invalid
2668 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2670 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2677 // Invalidate the volume root directory
2680 pCurrentObject = &VolumeCB->ObjectInformation;
2682 if ( pCurrentObject )
2685 lCount = AFSObjectInfoIncrement( pCurrentObject,
2686 AFS_OBJECT_REFERENCE_INVALIDATION);
2688 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2689 AFS_TRACE_LEVEL_VERBOSE,
2690 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2694 AFSInvalidateObject( &pCurrentObject,
2697 if ( pCurrentObject)
2700 lCount = AFSObjectInfoDecrement( pCurrentObject,
2701 AFS_OBJECT_REFERENCE_INVALIDATION);
2703 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2704 AFS_TRACE_LEVEL_VERBOSE,
2705 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2712 // Apply invalidation to all other volume objects
2715 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2718 pCurrentObject = VolumeCB->ObjectInfoListHead;
2720 if ( pCurrentObject)
2724 // Reference the node so it won't be torn down
2727 lCount = AFSObjectInfoIncrement( pCurrentObject,
2728 AFS_OBJECT_REFERENCE_INVALIDATION);
2730 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2731 AFS_TRACE_LEVEL_VERBOSE,
2732 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2737 while( pCurrentObject != NULL)
2740 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2746 // Reference the node so it won't be torn down
2749 lCount = AFSObjectInfoIncrement( pNextObject,
2750 AFS_OBJECT_REFERENCE_INVALIDATION);
2752 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2753 AFS_TRACE_LEVEL_VERBOSE,
2754 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2759 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2761 AFSInvalidateObject( &pCurrentObject,
2764 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2767 if ( pCurrentObject )
2770 lCount = AFSObjectInfoDecrement( pCurrentObject,
2771 AFS_OBJECT_REFERENCE_INVALIDATION);
2773 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2774 AFS_TRACE_LEVEL_VERBOSE,
2775 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2780 pCurrentObject = pNextObject;
2783 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2790 AFSInvalidateAllVolumes( VOID)
2792 AFSVolumeCB *pVolumeCB = NULL;
2793 AFSVolumeCB *pNextVolumeCB = NULL;
2794 AFSDeviceExt *pRDRDeviceExt = NULL;
2797 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2799 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2800 AFS_TRACE_LEVEL_VERBOSE,
2801 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2802 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2803 PsGetCurrentThread()));
2805 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2808 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2813 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2814 AFS_TRACE_LEVEL_VERBOSE,
2815 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2816 pVolumeCB->ObjectInfoTree.TreeLock,
2817 PsGetCurrentThread()));
2819 lCount = AFSVolumeIncrement( pVolumeCB,
2820 AFS_VOLUME_REFERENCE_INVALIDATE);
2822 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2823 AFS_TRACE_LEVEL_VERBOSE,
2824 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2829 while( pVolumeCB != NULL)
2832 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2837 lCount = AFSVolumeIncrement( pNextVolumeCB,
2838 AFS_VOLUME_REFERENCE_INVALIDATE);
2840 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2841 AFS_TRACE_LEVEL_VERBOSE,
2842 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2847 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2849 // do I need to hold the volume lock here?
2851 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2853 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2856 lCount = AFSVolumeDecrement( pVolumeCB,
2857 AFS_VOLUME_REFERENCE_INVALIDATE);
2859 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2860 AFS_TRACE_LEVEL_VERBOSE,
2861 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2865 pVolumeCB = pNextVolumeCB;
2868 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2872 AFSVerifyEntry( IN GUID *AuthGroup,
2873 IN AFSDirectoryCB *DirEntry)
2876 NTSTATUS ntStatus = STATUS_SUCCESS;
2877 AFSDirEnumEntry *pDirEnumEntry = NULL;
2878 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2879 IO_STATUS_BLOCK stIoStatus;
2884 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2885 AFS_TRACE_LEVEL_VERBOSE_2,
2886 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2887 &DirEntry->NameInformation.FileName,
2888 pObjectInfo->FileId.Cell,
2889 pObjectInfo->FileId.Volume,
2890 pObjectInfo->FileId.Vnode,
2891 pObjectInfo->FileId.Unique));
2893 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2898 if( !NT_SUCCESS( ntStatus))
2901 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2902 AFS_TRACE_LEVEL_ERROR,
2903 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2904 &DirEntry->NameInformation.FileName,
2905 pObjectInfo->FileId.Cell,
2906 pObjectInfo->FileId.Volume,
2907 pObjectInfo->FileId.Vnode,
2908 pObjectInfo->FileId.Unique,
2911 try_return( ntStatus);
2915 // Check the data version of the file
2918 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2920 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2923 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2924 AFS_TRACE_LEVEL_VERBOSE,
2925 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2926 pObjectInfo->DataVersion.QuadPart,
2927 &DirEntry->NameInformation.FileName,
2928 pObjectInfo->FileId.Cell,
2929 pObjectInfo->FileId.Volume,
2930 pObjectInfo->FileId.Vnode,
2931 pObjectInfo->FileId.Unique));
2934 // We are ok, just get out
2937 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2939 try_return( ntStatus = STATUS_SUCCESS);
2944 // New data version so we will need to process the node based on the type
2947 switch( pDirEnumEntry->FileType)
2950 case AFS_FILE_TYPE_MOUNTPOINT:
2954 // For a mount point we need to ensure the target is the same
2957 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2958 &pDirEnumEntry->TargetFileId))
2964 // Update the metadata for the entry
2967 ntStatus = AFSUpdateMetaData( DirEntry,
2970 if( NT_SUCCESS( ntStatus))
2973 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2979 case AFS_FILE_TYPE_SYMLINK:
2983 // Update the metadata for the entry
2986 ntStatus = AFSUpdateMetaData( DirEntry,
2989 if( NT_SUCCESS( ntStatus))
2992 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2998 case AFS_FILE_TYPE_FILE:
3000 FILE_OBJECT * pCCFileObject = NULL;
3001 BOOLEAN bPurgeExtents = FALSE;
3003 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3006 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3007 AFS_TRACE_LEVEL_VERBOSE,
3008 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3009 &DirEntry->NameInformation.FileName,
3010 pObjectInfo->FileId.Cell,
3011 pObjectInfo->FileId.Volume,
3012 pObjectInfo->FileId.Vnode,
3013 pObjectInfo->FileId.Unique,
3014 pObjectInfo->DataVersion.LowPart,
3015 pDirEnumEntry->DataVersion.LowPart));
3017 bPurgeExtents = TRUE;
3020 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3023 bPurgeExtents = TRUE;
3025 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3026 AFS_TRACE_LEVEL_VERBOSE,
3027 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3028 &DirEntry->NameInformation.FileName,
3029 pObjectInfo->FileId.Cell,
3030 pObjectInfo->FileId.Volume,
3031 pObjectInfo->FileId.Vnode,
3032 pObjectInfo->FileId.Unique));
3034 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3037 if( pObjectInfo->Fcb != NULL)
3040 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3041 AFS_TRACE_LEVEL_VERBOSE,
3042 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3043 &DirEntry->NameInformation.FileName,
3044 pObjectInfo->FileId.Cell,
3045 pObjectInfo->FileId.Volume,
3046 pObjectInfo->FileId.Vnode,
3047 pObjectInfo->FileId.Unique));
3049 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3055 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3060 if( !NT_SUCCESS( stIoStatus.Status))
3063 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3064 AFS_TRACE_LEVEL_ERROR,
3065 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3066 &DirEntry->NameInformation.FileName,
3067 pObjectInfo->FileId.Cell,
3068 pObjectInfo->FileId.Volume,
3069 pObjectInfo->FileId.Vnode,
3070 pObjectInfo->FileId.Unique,
3072 stIoStatus.Information));
3074 ntStatus = stIoStatus.Status;
3077 if ( bPurgeExtents &&
3078 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3081 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3087 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3088 AFS_TRACE_LEVEL_WARNING,
3089 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3090 &DirEntry->NameInformation.FileName,
3091 pObjectInfo->FileId.Cell,
3092 pObjectInfo->FileId.Volume,
3093 pObjectInfo->FileId.Vnode,
3094 pObjectInfo->FileId.Unique));
3096 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3100 __except( EXCEPTION_EXECUTE_HANDLER)
3102 ntStatus = GetExceptionCode();
3106 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3107 &DirEntry->NameInformation.FileName,
3108 pObjectInfo->FileId.Cell,
3109 pObjectInfo->FileId.Volume,
3110 pObjectInfo->FileId.Vnode,
3111 pObjectInfo->FileId.Unique,
3114 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3117 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3121 AFSFlushExtents( pObjectInfo->Fcb,
3126 // Reacquire the Fcb to purge the cache
3129 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3130 AFS_TRACE_LEVEL_VERBOSE,
3131 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3132 &pObjectInfo->Fcb->NPFcb->Resource,
3133 PsGetCurrentThread()));
3135 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3139 // Update the metadata for the entry
3142 ntStatus = AFSUpdateMetaData( DirEntry,
3145 if( !NT_SUCCESS( ntStatus))
3148 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3149 AFS_TRACE_LEVEL_ERROR,
3150 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3151 &DirEntry->NameInformation.FileName,
3152 pObjectInfo->FileId.Cell,
3153 pObjectInfo->FileId.Volume,
3154 pObjectInfo->FileId.Vnode,
3155 pObjectInfo->FileId.Unique,
3162 // Update file sizes
3165 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3166 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3167 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3169 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3170 AFS_TRACE_LEVEL_VERBOSE,
3171 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3172 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3173 PsGetCurrentThread()));
3175 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3178 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3180 if ( pCCFileObject != NULL)
3182 CcSetFileSizes( pCCFileObject,
3183 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3186 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3187 AFS_TRACE_LEVEL_VERBOSE,
3188 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3189 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3190 PsGetCurrentThread()));
3192 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3194 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3200 // Update the metadata for the entry
3203 ntStatus = AFSUpdateMetaData( DirEntry,
3206 if( !NT_SUCCESS( ntStatus))
3209 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3210 AFS_TRACE_LEVEL_ERROR,
3211 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3212 &DirEntry->NameInformation.FileName,
3213 pObjectInfo->FileId.Cell,
3214 pObjectInfo->FileId.Volume,
3215 pObjectInfo->FileId.Vnode,
3216 pObjectInfo->FileId.Unique,
3222 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3223 AFS_TRACE_LEVEL_WARNING,
3224 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3225 &DirEntry->NameInformation.FileName,
3226 pObjectInfo->FileId.Cell,
3227 pObjectInfo->FileId.Volume,
3228 pObjectInfo->FileId.Vnode,
3229 pObjectInfo->FileId.Unique));
3232 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3237 case AFS_FILE_TYPE_DIRECTORY:
3241 // For a directory or root entry flush the content of
3242 // the directory enumeration.
3245 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3249 AFS_TRACE_LEVEL_VERBOSE_2,
3250 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3251 &DirEntry->NameInformation.FileName,
3252 pObjectInfo->FileId.Cell,
3253 pObjectInfo->FileId.Volume,
3254 pObjectInfo->FileId.Vnode,
3255 pObjectInfo->FileId.Unique));
3257 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3260 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3263 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3265 if ( !NT_SUCCESS( ntStatus))
3268 try_return( ntStatus);
3273 // Update the metadata for the entry
3276 ntStatus = AFSUpdateMetaData( DirEntry,
3279 if( NT_SUCCESS( ntStatus))
3282 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3288 case AFS_FILE_TYPE_DFSLINK:
3291 UNICODE_STRING uniTargetName;
3294 // For a DFS link need to check the target name has not changed
3297 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3299 uniTargetName.MaximumLength = uniTargetName.Length;
3301 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3303 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3306 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3307 RtlCompareUnicodeString( &uniTargetName,
3308 &DirEntry->NameInformation.TargetName,
3313 // Update the target name
3316 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3318 uniTargetName.Buffer,
3319 uniTargetName.Length);
3321 if( !NT_SUCCESS( ntStatus))
3324 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3330 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3333 // Update the metadata for the entry
3336 ntStatus = AFSUpdateMetaData( DirEntry,
3339 if( NT_SUCCESS( ntStatus))
3342 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3350 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3351 AFS_TRACE_LEVEL_WARNING,
3352 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3353 pObjectInfo->FileType,
3354 &DirEntry->NameInformation.FileName,
3355 pObjectInfo->FileId.Cell,
3356 pObjectInfo->FileId.Volume,
3357 pObjectInfo->FileId.Vnode,
3358 pObjectInfo->FileId.Unique));
3365 if( pDirEnumEntry != NULL)
3368 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3376 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3379 NTSTATUS ntStatus = STATUS_SUCCESS;
3380 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3381 ULONGLONG ullIndex = 0;
3382 AFSVolumeCB *pVolumeCB = NULL;
3388 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3389 AFS_TRACE_LEVEL_VERBOSE,
3390 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3391 VolumeStatus->Online,
3392 VolumeStatus->FileID.Cell,
3393 VolumeStatus->FileID.Volume));
3396 // Need to locate the Fcb for the directory to purge
3399 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3400 AFS_TRACE_LEVEL_VERBOSE,
3401 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3402 &pDevExt->Specific.RDR.VolumeTreeLock,
3403 PsGetCurrentThread()));
3405 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3408 // Locate the volume node
3411 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3413 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3415 (AFSBTreeEntry **)&pVolumeCB);
3417 if( pVolumeCB != NULL)
3420 lCount = AFSVolumeIncrement( pVolumeCB,
3421 AFS_VOLUME_REFERENCE_INVALIDATE);
3423 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3424 AFS_TRACE_LEVEL_VERBOSE,
3425 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3429 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3432 // Set the volume state accordingly
3435 if( VolumeStatus->Online)
3438 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3443 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3452 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3455 NTSTATUS ntStatus = STATUS_SUCCESS;
3460 if( AFSGlobalRoot == NULL)
3463 try_return( ntStatus);
3466 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3470 // Set the network state according to the information
3473 if( NetworkStatus->Online)
3476 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3481 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3484 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3495 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3499 NTSTATUS ntStatus = STATUS_SUCCESS;
3500 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3501 BOOLEAN bAcquiredLock = FALSE;
3502 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3507 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3508 AFS_TRACE_LEVEL_VERBOSE,
3509 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3510 ObjectInfo->FileId.Cell,
3511 ObjectInfo->FileId.Volume,
3512 ObjectInfo->FileId.Vnode,
3513 ObjectInfo->FileId.Unique));
3515 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3518 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3519 AFS_TRACE_LEVEL_VERBOSE,
3520 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3521 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3522 PsGetCurrentThread()));
3524 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3527 bAcquiredLock = TRUE;
3531 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3534 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3535 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3538 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3539 AFS_TRACE_LEVEL_ERROR,
3540 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3541 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3542 ObjectInfo->FileId.Cell,
3543 ObjectInfo->FileId.Volume,
3544 ObjectInfo->FileId.Vnode,
3545 ObjectInfo->FileId.Unique));
3549 // Reset the directory list information by clearing all valid entries
3552 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3554 while( pCurrentDirEntry != NULL)
3557 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3559 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3563 // If this entry has been deleted then process it here
3566 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3567 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3568 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3571 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3572 AFS_TRACE_LEVEL_VERBOSE,
3573 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3575 &pCurrentDirEntry->NameInformation.FileName));
3577 AFSDeleteDirEntry( ObjectInfo,
3583 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3585 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3586 AFS_TRACE_LEVEL_VERBOSE,
3587 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3589 pCurrentDirEntry->DirOpenReferenceCount));
3592 // We pull the short name from the parent tree since it could change below
3595 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3598 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3599 AFS_TRACE_LEVEL_VERBOSE,
3600 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3602 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3603 &pCurrentDirEntry->NameInformation.FileName));
3605 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3608 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3613 pCurrentDirEntry = pNextDirEntry;
3617 // Reget the directory contents
3620 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3623 if ( !NT_SUCCESS( ntStatus))
3625 try_return( ntStatus);
3629 // Now start again and tear down any entries not valid
3632 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3634 while( pCurrentDirEntry != NULL)
3637 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3639 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3642 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3643 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3644 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3647 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3650 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3652 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3653 AFS_TRACE_LEVEL_VERBOSE,
3654 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3656 &pCurrentDirEntry->NameInformation.FileName));
3658 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3663 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3666 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3667 AFS_TRACE_LEVEL_VERBOSE,
3668 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3670 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3671 &pCurrentDirEntry->NameInformation.FileName));
3675 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3677 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3678 AFS_TRACE_LEVEL_VERBOSE,
3679 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3681 &pCurrentDirEntry->NameInformation.FileName));
3686 pCurrentDirEntry = pNextDirEntry;
3691 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3692 AFS_TRACE_LEVEL_VERBOSE,
3693 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3695 pCurrentDirEntry->DirOpenReferenceCount));
3697 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3698 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3701 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3702 AFS_TRACE_LEVEL_VERBOSE,
3703 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3704 &pCurrentDirEntry->NameInformation.FileName,
3705 ObjectInfo->FileId.Cell,
3706 ObjectInfo->FileId.Volume,
3707 ObjectInfo->FileId.Vnode,
3708 ObjectInfo->FileId.Unique));
3710 AFSDeleteDirEntry( ObjectInfo,
3716 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3717 AFS_TRACE_LEVEL_VERBOSE,
3718 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3720 &pCurrentDirEntry->NameInformation.FileName,
3721 ObjectInfo->FileId.Cell,
3722 ObjectInfo->FileId.Volume,
3723 ObjectInfo->FileId.Vnode,
3724 ObjectInfo->FileId.Unique));
3726 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3728 AFSRemoveNameEntry( ObjectInfo,
3732 pCurrentDirEntry = pNextDirEntry;
3736 if( !AFSValidateDirList( ObjectInfo))
3739 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3748 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3756 AFSIsVolumeFID( IN AFSFileID *FileID)
3759 BOOLEAN bIsVolume = FALSE;
3761 if( FileID->Vnode == 1 &&
3762 FileID->Unique == 1)
3772 AFSIsFinalNode( IN AFSFcb *Fcb)
3775 BOOLEAN bIsFinalNode = FALSE;
3777 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3778 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3779 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3780 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3781 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3784 bIsFinalNode = TRUE;
3789 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3790 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3793 return bIsFinalNode;
3797 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3798 IN AFSDirEnumEntry *DirEnumEntry)
3801 NTSTATUS ntStatus = STATUS_SUCCESS;
3802 UNICODE_STRING uniTargetName;
3803 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3808 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3810 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3812 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3814 pObjectInfo->FileType = DirEnumEntry->FileType;
3816 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3818 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3820 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3822 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3824 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3826 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3828 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3830 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3831 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3834 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3837 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3840 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3843 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3848 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3852 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3854 pObjectInfo->Links = DirEnumEntry->Links;
3856 if( DirEnumEntry->TargetNameLength > 0 &&
3857 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3858 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3862 // Update the target name information if needed
3865 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3867 uniTargetName.MaximumLength = uniTargetName.Length;
3869 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3871 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3874 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3875 RtlCompareUnicodeString( &uniTargetName,
3876 &DirEntry->NameInformation.TargetName,
3881 // Update the target name
3884 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3886 uniTargetName.Buffer,
3887 uniTargetName.Length);
3889 if( !NT_SUCCESS( ntStatus))
3892 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3894 try_return( ntStatus);
3898 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3900 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3901 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3904 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3907 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3908 DirEntry->NameInformation.TargetName.Buffer != NULL)
3910 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3913 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3915 DirEntry->NameInformation.TargetName.Length = 0;
3916 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3917 DirEntry->NameInformation.TargetName.Buffer = NULL;
3919 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3931 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3933 IN BOOLEAN FastCall,
3934 IN BOOLEAN bSafeToPurge)
3937 NTSTATUS ntStatus = STATUS_SUCCESS;
3938 LARGE_INTEGER liSystemTime;
3939 AFSDirEnumEntry *pDirEnumEntry = NULL;
3940 AFSFcb *pCurrentFcb = NULL;
3941 BOOLEAN bReleaseFcb = FALSE;
3942 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3948 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3952 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3953 AFS_TRACE_LEVEL_VERBOSE_2,
3954 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3955 &DirEntry->NameInformation.FileName,
3956 pObjectInfo->FileId.Cell,
3957 pObjectInfo->FileId.Volume,
3958 pObjectInfo->FileId.Vnode,
3959 pObjectInfo->FileId.Unique,
3963 // If this is a fake node then bail since the service knows nothing about it
3966 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3969 try_return( ntStatus);
3973 // This routine ensures that the current entry is valid by:
3975 // 1) Checking that the expiration time is non-zero and after where we
3979 KeQuerySystemTime( &liSystemTime);
3981 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3982 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3983 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3984 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3987 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3988 AFS_TRACE_LEVEL_VERBOSE_2,
3989 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3990 &DirEntry->NameInformation.FileName,
3991 pObjectInfo->FileId.Cell,
3992 pObjectInfo->FileId.Volume,
3993 pObjectInfo->FileId.Vnode,
3994 pObjectInfo->FileId.Unique));
3996 try_return( ntStatus);
4000 // This node requires updating
4003 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4008 if( !NT_SUCCESS( ntStatus))
4011 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4012 AFS_TRACE_LEVEL_ERROR,
4013 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4015 &DirEntry->NameInformation.FileName,
4016 pObjectInfo->FileId.Cell,
4017 pObjectInfo->FileId.Volume,
4018 pObjectInfo->FileId.Vnode,
4019 pObjectInfo->FileId.Unique,
4023 // Failed validation of node so return access-denied
4026 try_return( ntStatus);
4029 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4030 AFS_TRACE_LEVEL_VERBOSE,
4031 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4033 &DirEntry->NameInformation.FileName,
4034 pObjectInfo->FileId.Cell,
4035 pObjectInfo->FileId.Volume,
4036 pObjectInfo->FileId.Vnode,
4037 pObjectInfo->FileId.Unique,
4038 pObjectInfo->DataVersion.QuadPart,
4039 pDirEnumEntry->DataVersion.QuadPart,
4040 pDirEnumEntry->FileType));
4044 // Based on the file type, process the node
4047 switch( pDirEnumEntry->FileType)
4050 case AFS_FILE_TYPE_MOUNTPOINT:
4054 // Update the metadata for the entry
4057 ntStatus = AFSUpdateMetaData( DirEntry,
4060 if( NT_SUCCESS( ntStatus))
4063 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4069 case AFS_FILE_TYPE_SYMLINK:
4070 case AFS_FILE_TYPE_DFSLINK:
4074 // Update the metadata for the entry
4077 ntStatus = AFSUpdateMetaData( DirEntry,
4080 if( NT_SUCCESS( ntStatus))
4083 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4089 case AFS_FILE_TYPE_FILE:
4092 BOOLEAN bPurgeExtents = FALSE;
4095 // For a file where the data version has become invalid we need to
4096 // fail any current extent requests and purge the cache for the file
4097 // Can't hold the Fcb resource while doing this
4100 if( pObjectInfo->Fcb != NULL &&
4101 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4102 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4105 pCurrentFcb = pObjectInfo->Fcb;
4107 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4110 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4111 AFS_TRACE_LEVEL_VERBOSE,
4112 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4113 &pCurrentFcb->NPFcb->Resource,
4114 PsGetCurrentThread()));
4116 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4122 if( pCurrentFcb != NULL)
4125 IO_STATUS_BLOCK stIoStatus;
4127 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4128 AFS_TRACE_LEVEL_VERBOSE_2,
4129 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4130 &DirEntry->NameInformation.FileName,
4131 pObjectInfo->FileId.Cell,
4132 pObjectInfo->FileId.Volume,
4133 pObjectInfo->FileId.Vnode,
4134 pObjectInfo->FileId.Unique));
4136 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4139 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4140 AFS_TRACE_LEVEL_VERBOSE,
4141 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4142 &DirEntry->NameInformation.FileName,
4143 pObjectInfo->FileId.Cell,
4144 pObjectInfo->FileId.Volume,
4145 pObjectInfo->FileId.Vnode,
4146 pObjectInfo->FileId.Unique,
4147 pObjectInfo->DataVersion.LowPart,
4148 pDirEnumEntry->DataVersion.LowPart));
4150 bPurgeExtents = TRUE;
4156 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4158 bPurgeExtents = TRUE;
4160 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4161 AFS_TRACE_LEVEL_VERBOSE,
4162 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4163 &DirEntry->NameInformation.FileName,
4164 pObjectInfo->FileId.Cell,
4165 pObjectInfo->FileId.Volume,
4166 pObjectInfo->FileId.Vnode,
4167 pObjectInfo->FileId.Unique));
4169 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4172 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4173 AFS_TRACE_LEVEL_VERBOSE,
4174 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4175 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4176 PsGetCurrentThread()));
4178 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4182 // Release Fcb->Resource to avoid Trend Micro deadlock
4185 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4190 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4195 if( !NT_SUCCESS( stIoStatus.Status))
4198 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4199 AFS_TRACE_LEVEL_ERROR,
4200 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4201 &DirEntry->NameInformation.FileName,
4202 pObjectInfo->FileId.Cell,
4203 pObjectInfo->FileId.Volume,
4204 pObjectInfo->FileId.Vnode,
4205 pObjectInfo->FileId.Unique,
4207 stIoStatus.Information));
4209 ntStatus = stIoStatus.Status;
4212 if ( bPurgeExtents &&
4213 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4216 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4222 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4223 AFS_TRACE_LEVEL_WARNING,
4224 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4225 &DirEntry->NameInformation.FileName,
4226 pObjectInfo->FileId.Cell,
4227 pObjectInfo->FileId.Volume,
4228 pObjectInfo->FileId.Vnode,
4229 pObjectInfo->FileId.Unique));
4231 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4235 __except( EXCEPTION_EXECUTE_HANDLER)
4237 ntStatus = GetExceptionCode();
4241 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4242 &DirEntry->NameInformation.FileName,
4243 pObjectInfo->FileId.Cell,
4244 pObjectInfo->FileId.Volume,
4245 pObjectInfo->FileId.Vnode,
4246 pObjectInfo->FileId.Unique,
4249 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4252 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4253 AFS_TRACE_LEVEL_VERBOSE,
4254 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4255 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4256 PsGetCurrentThread()));
4258 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4260 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4269 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4274 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4276 bReleaseFcb = FALSE;
4278 if ( bPurgeExtents &&
4281 AFSFlushExtents( pCurrentFcb,
4288 // Update the metadata for the entry but only if it is safe to do so.
4289 // If it was determined that a data version change has occurred or
4290 // that a pending data verification was required, do not update the
4291 // ObjectInfo meta data or the FileObject size information. That
4292 // way it is consistent for the next time that the data is verified
4296 if ( !(bPurgeExtents && bSafeToPurge))
4299 ntStatus = AFSUpdateMetaData( DirEntry,
4302 if( !NT_SUCCESS( ntStatus))
4305 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4306 AFS_TRACE_LEVEL_ERROR,
4307 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4308 &DirEntry->NameInformation.FileName,
4309 pObjectInfo->FileId.Cell,
4310 pObjectInfo->FileId.Volume,
4311 pObjectInfo->FileId.Vnode,
4312 pObjectInfo->FileId.Unique,
4318 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4321 // Update file sizes
4324 if( pObjectInfo->Fcb != NULL)
4326 FILE_OBJECT *pCCFileObject;
4328 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4329 AFS_TRACE_LEVEL_VERBOSE,
4330 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4331 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4332 PsGetCurrentThread()));
4334 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4337 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4339 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4340 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4341 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4343 if ( pCCFileObject != NULL)
4345 CcSetFileSizes( pCCFileObject,
4346 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4349 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4350 AFS_TRACE_LEVEL_VERBOSE,
4351 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4352 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4353 PsGetCurrentThread()));
4355 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4361 case AFS_FILE_TYPE_DIRECTORY:
4364 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4368 // For a directory or root entry flush the content of
4369 // the directory enumeration.
4372 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4373 AFS_TRACE_LEVEL_VERBOSE,
4374 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4375 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4376 PsGetCurrentThread()));
4378 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4381 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4382 AFS_TRACE_LEVEL_VERBOSE_2,
4383 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4384 &DirEntry->NameInformation.FileName,
4385 pObjectInfo->FileId.Cell,
4386 pObjectInfo->FileId.Volume,
4387 pObjectInfo->FileId.Vnode,
4388 pObjectInfo->FileId.Unique));
4390 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4393 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4396 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4399 if( !NT_SUCCESS( ntStatus))
4402 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4403 AFS_TRACE_LEVEL_ERROR,
4404 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4405 &DirEntry->NameInformation.FileName,
4406 pObjectInfo->FileId.Cell,
4407 pObjectInfo->FileId.Volume,
4408 pObjectInfo->FileId.Vnode,
4409 pObjectInfo->FileId.Unique,
4417 // Update the metadata for the entry
4420 ntStatus = AFSUpdateMetaData( DirEntry,
4423 if( NT_SUCCESS( ntStatus))
4426 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4434 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4435 AFS_TRACE_LEVEL_WARNING,
4436 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4437 pObjectInfo->FileType,
4439 &DirEntry->NameInformation.FileName,
4440 pObjectInfo->FileId.Cell,
4441 pObjectInfo->FileId.Volume,
4442 pObjectInfo->FileId.Vnode,
4443 pObjectInfo->FileId.Unique));
4453 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4456 if( pDirEnumEntry != NULL)
4459 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4467 AFSInitializeSpecialShareNameList()
4470 NTSTATUS ntStatus = STATUS_SUCCESS;
4471 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4472 AFSObjectInfoCB *pObjectInfoCB = NULL;
4473 UNICODE_STRING uniShareName;
4474 ULONG ulEntryLength = 0;
4475 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4481 RtlInitUnicodeString( &uniShareName,
4484 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4487 if( pObjectInfoCB == NULL)
4490 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4493 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4494 AFS_OBJECT_REFERENCE_GLOBAL);
4496 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4497 AFS_TRACE_LEVEL_VERBOSE,
4498 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4502 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4504 ulEntryLength = sizeof( AFSDirectoryCB) +
4505 uniShareName.Length;
4507 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4511 if( pDirNode == NULL)
4514 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4515 AFS_OBJECT_REFERENCE_GLOBAL);
4517 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4518 AFS_TRACE_LEVEL_VERBOSE,
4519 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4526 AFSDeleteObjectInfo( &pObjectInfoCB);
4529 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4532 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4533 AFS_TRACE_LEVEL_VERBOSE,
4534 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4537 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4538 sizeof( AFSNonPagedDirectoryCB),
4539 AFS_DIR_ENTRY_NP_TAG);
4541 if( pNonPagedDirEntry == NULL)
4544 ExFreePool( pDirNode);
4546 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4547 AFS_OBJECT_REFERENCE_GLOBAL);
4549 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4550 AFS_TRACE_LEVEL_VERBOSE,
4551 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4558 AFSDeleteObjectInfo( &pObjectInfoCB);
4561 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4564 RtlZeroMemory( pDirNode,
4567 RtlZeroMemory( pNonPagedDirEntry,
4568 sizeof( AFSNonPagedDirectoryCB));
4570 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4572 pDirNode->NonPaged = pNonPagedDirEntry;
4574 pDirNode->ObjectInformation = pObjectInfoCB;
4580 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4582 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4584 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4586 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4588 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4589 uniShareName.Buffer,
4590 pDirNode->NameInformation.FileName.Length);
4592 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4595 AFSSpecialShareNames = pDirNode;
4597 pLastDirNode = pDirNode;
4600 RtlInitUnicodeString( &uniShareName,
4603 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4606 if( pObjectInfoCB == NULL)
4609 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4612 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4613 AFS_OBJECT_REFERENCE_GLOBAL);
4615 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4616 AFS_TRACE_LEVEL_VERBOSE,
4617 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4621 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4623 ulEntryLength = sizeof( AFSDirectoryCB) +
4624 uniShareName.Length;
4626 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4630 if( pDirNode == NULL)
4633 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4634 AFS_OBJECT_REFERENCE_GLOBAL);
4636 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4637 AFS_TRACE_LEVEL_VERBOSE,
4638 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4645 AFSDeleteObjectInfo( &pObjectInfoCB);
4648 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4651 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4652 AFS_TRACE_LEVEL_VERBOSE,
4653 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4656 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4657 sizeof( AFSNonPagedDirectoryCB),
4658 AFS_DIR_ENTRY_NP_TAG);
4660 if( pNonPagedDirEntry == NULL)
4663 ExFreePool( pDirNode);
4665 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4666 AFS_OBJECT_REFERENCE_GLOBAL);
4668 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4669 AFS_TRACE_LEVEL_VERBOSE,
4670 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4677 AFSDeleteObjectInfo( &pObjectInfoCB);
4680 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4683 RtlZeroMemory( pDirNode,
4686 RtlZeroMemory( pNonPagedDirEntry,
4687 sizeof( AFSNonPagedDirectoryCB));
4689 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4691 pDirNode->NonPaged = pNonPagedDirEntry;
4693 pDirNode->ObjectInformation = pObjectInfoCB;
4699 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4701 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4703 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4705 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4707 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4708 uniShareName.Buffer,
4709 pDirNode->NameInformation.FileName.Length);
4711 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4714 pLastDirNode->ListEntry.fLink = pDirNode;
4716 pDirNode->ListEntry.bLink = pLastDirNode;
4720 if( !NT_SUCCESS( ntStatus))
4723 if( AFSSpecialShareNames != NULL)
4726 pDirNode = AFSSpecialShareNames;
4728 while( pDirNode != NULL)
4731 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4733 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4734 AFS_OBJECT_REFERENCE_GLOBAL);
4736 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4737 AFS_TRACE_LEVEL_VERBOSE,
4738 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4739 pDirNode->ObjectInformation,
4745 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4748 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4750 ExFreePool( pDirNode->NonPaged);
4752 ExFreePool( pDirNode);
4754 pDirNode = pLastDirNode;
4757 AFSSpecialShareNames = NULL;
4766 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4767 IN UNICODE_STRING *SecondaryName)
4770 AFSDirectoryCB *pDirectoryCB = NULL;
4771 ULONGLONG ullHash = 0;
4772 UNICODE_STRING uniFullShareName;
4778 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4779 AFS_TRACE_LEVEL_VERBOSE_2,
4780 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4784 uniFullShareName = *ShareName;
4787 // Generate our hash value
4790 ullHash = AFSGenerateCRC( &uniFullShareName,
4794 // Loop through our special share names to see if this is one of them
4797 pDirectoryCB = AFSSpecialShareNames;
4799 while( pDirectoryCB != NULL)
4802 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4808 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4812 return pDirectoryCB;
4816 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4820 // Block on the queue flush event
4823 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4833 AFSWaitOnQueuedReleases()
4836 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4839 // Block on the queue flush event
4842 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4852 AFSIsEqualFID( IN AFSFileID *FileId1,
4853 IN AFSFileID *FileId2)
4856 BOOLEAN bIsEqual = FALSE;
4858 if( FileId1->Hash == FileId2->Hash &&
4859 FileId1->Unique == FileId2->Unique &&
4860 FileId1->Vnode == FileId2->Vnode &&
4861 FileId1->Volume == FileId2->Volume &&
4862 FileId1->Cell == FileId2->Cell)
4872 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4875 NTSTATUS ntStatus = STATUS_SUCCESS;
4876 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4881 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4884 // Reset the directory list information
4887 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4889 while( pCurrentDirEntry != NULL)
4892 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4894 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4895 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4898 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4899 AFS_TRACE_LEVEL_VERBOSE,
4900 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4902 &pCurrentDirEntry->NameInformation.FileName));
4904 AFSDeleteDirEntry( ObjectInfoCB,
4910 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4911 AFS_TRACE_LEVEL_VERBOSE,
4912 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4914 &pCurrentDirEntry->NameInformation.FileName));
4916 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4918 AFSRemoveNameEntry( ObjectInfoCB,
4922 pCurrentDirEntry = pNextDirEntry;
4925 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4927 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4929 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4931 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4933 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4935 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4937 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4938 AFS_TRACE_LEVEL_VERBOSE,
4939 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4940 ObjectInfoCB->FileId.Cell,
4941 ObjectInfoCB->FileId.Volume,
4942 ObjectInfoCB->FileId.Vnode,
4943 ObjectInfoCB->FileId.Unique));
4950 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4953 NTSTATUS ntStatus = STATUS_SUCCESS;
4954 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4955 UNICODE_STRING uniFullName;
4960 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4961 AFS_TRACE_LEVEL_VERBOSE,
4962 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4963 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4964 PsGetCurrentThread()));
4966 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4969 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4972 try_return( ntStatus);
4976 // Initialize the root information
4979 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4982 // Enumerate the shares in the volume
4985 ntStatus = AFSEnumerateDirectory( AuthGroup,
4986 &AFSGlobalRoot->ObjectInformation,
4989 if( !NT_SUCCESS( ntStatus))
4992 try_return( ntStatus);
4995 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4997 uniFullName.MaximumLength = PAGE_SIZE;
4998 uniFullName.Length = 0;
5000 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5001 uniFullName.MaximumLength,
5002 AFS_GENERIC_MEMORY_12_TAG);
5004 if( uniFullName.Buffer == NULL)
5008 // Reset the directory content
5011 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5013 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5015 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5019 // Populate our list of entries in the NP enumeration list
5022 while( pDirGlobalDirNode != NULL)
5025 uniFullName.Buffer[ 0] = L'\\';
5026 uniFullName.Buffer[ 1] = L'\\';
5028 uniFullName.Length = 2 * sizeof( WCHAR);
5030 RtlCopyMemory( &uniFullName.Buffer[ 2],
5031 AFSServerName.Buffer,
5032 AFSServerName.Length);
5034 uniFullName.Length += AFSServerName.Length;
5036 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5038 uniFullName.Length += sizeof( WCHAR);
5040 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5041 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5042 pDirGlobalDirNode->NameInformation.FileName.Length);
5044 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5046 AFSAddConnectionEx( &uniFullName,
5047 RESOURCEDISPLAYTYPE_SHARE,
5050 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5053 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
5057 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5064 AFSIsRelativeName( IN UNICODE_STRING *Name)
5067 BOOLEAN bIsRelative = FALSE;
5069 if( Name->Length > 0 &&
5070 Name->Buffer[ 0] != L'\\')
5080 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5082 UNICODE_STRING uniTempName;
5083 BOOLEAN bIsAbsolute = FALSE;
5086 // An absolute AFS path must begin with \afs\... or equivalent
5089 if ( Name->Length == 0 ||
5090 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5091 Name->Buffer[ 0] != L'\\' ||
5092 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5098 uniTempName.Length = AFSMountRootName.Length;
5099 uniTempName.MaximumLength = AFSMountRootName.Length;
5101 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5102 uniTempName.MaximumLength,
5103 AFS_NAME_BUFFER_TWO_TAG);
5105 if( uniTempName.Buffer == NULL)
5111 RtlCopyMemory( uniTempName.Buffer,
5113 AFSMountRootName.Length);
5115 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5119 AFSExFreePoolWithTag( uniTempName.Buffer,
5120 AFS_NAME_BUFFER_TWO_TAG);
5127 AFSUpdateName( IN UNICODE_STRING *Name)
5132 while( usIndex < Name->Length/sizeof( WCHAR))
5135 if( Name->Buffer[ usIndex] == L'/')
5138 Name->Buffer[ usIndex] = L'\\';
5148 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5149 IN OUT ULONG *Flags,
5150 IN WCHAR *NameBuffer,
5151 IN USHORT NameLength)
5154 NTSTATUS ntStatus = STATUS_SUCCESS;
5155 WCHAR *pTmpBuffer = NULL;
5161 // If we have enough space then just move in the name otherwise
5162 // allocate a new buffer
5165 if( TargetName->Length < NameLength)
5168 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5170 AFS_NAME_BUFFER_FIVE_TAG);
5172 if( pTmpBuffer == NULL)
5175 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5178 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5181 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5184 TargetName->MaximumLength = NameLength;
5186 TargetName->Buffer = pTmpBuffer;
5188 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5191 TargetName->Length = NameLength;
5193 RtlCopyMemory( TargetName->Buffer,
5195 TargetName->Length);
5198 // Update the name in the buffer
5201 AFSUpdateName( TargetName);
5212 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5217 // Depending on the type of node, set the event
5220 switch( Fcb->Header.NodeTypeCode)
5223 case AFS_DIRECTORY_FCB:
5228 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5238 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5244 // Depending on the type of node, set the event
5247 switch( Fcb->Header.NodeTypeCode)
5250 case AFS_DIRECTORY_FCB:
5255 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5257 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5267 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5270 BOOLEAN bIsInProcess = FALSE;
5275 if( ObjectInfo->Fcb == NULL)
5278 try_return( bIsInProcess);
5281 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5284 case AFS_DIRECTORY_FCB:
5289 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5292 bIsInProcess = TRUE;
5304 return bIsInProcess;
5308 AFSVerifyVolume( IN ULONGLONG ProcessId,
5309 IN AFSVolumeCB *VolumeCB)
5312 UNREFERENCED_PARAMETER(ProcessId);
5313 UNREFERENCED_PARAMETER(VolumeCB);
5314 NTSTATUS ntStatus = STATUS_SUCCESS;
5321 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5324 NTSTATUS ntStatus = STATUS_SUCCESS;
5325 AFSObjectInfoCB *pObjectInfoCB = NULL;
5326 AFSDirectoryCB *pDirNode = NULL;
5327 ULONG ulEntryLength = 0;
5328 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5334 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5337 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5340 if( pObjectInfoCB == NULL)
5343 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5345 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5348 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5349 AFS_OBJECT_REFERENCE_PIOCTL);
5351 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5352 AFS_TRACE_LEVEL_VERBOSE,
5353 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5357 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5359 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5361 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5363 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5365 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5369 if( pDirNode == NULL)
5372 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5375 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5376 AFS_TRACE_LEVEL_VERBOSE,
5377 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5380 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5381 sizeof( AFSNonPagedDirectoryCB),
5382 AFS_DIR_ENTRY_NP_TAG);
5384 if( pNonPagedDirEntry == NULL)
5387 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5390 RtlZeroMemory( pDirNode,
5393 RtlZeroMemory( pNonPagedDirEntry,
5394 sizeof( AFSNonPagedDirectoryCB));
5396 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5398 pDirNode->NonPaged = pNonPagedDirEntry;
5400 pDirNode->ObjectInformation = pObjectInfoCB;
5402 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5408 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5410 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5412 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5414 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5416 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5417 AFSPIOCtlName.Buffer,
5418 pDirNode->NameInformation.FileName.Length);
5420 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5423 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5426 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5427 AFS_TRACE_LEVEL_WARNING,
5428 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5429 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5432 try_return( ntStatus = STATUS_REPARSE);
5437 if ( ntStatus != STATUS_SUCCESS)
5440 if ( pDirNode != NULL)
5443 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5444 AFS_TRACE_LEVEL_VERBOSE,
5445 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5448 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5451 if( pNonPagedDirEntry != NULL)
5454 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5456 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5459 if ( pObjectInfoCB != NULL)
5462 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5463 AFS_OBJECT_REFERENCE_PIOCTL);
5465 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5466 AFS_TRACE_LEVEL_VERBOSE,
5467 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5474 AFSDeleteObjectInfo( &pObjectInfoCB);
5484 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5485 IN AFSDirectoryCB *DirectoryCB,
5486 IN UNICODE_STRING *ParentPathName,
5487 IN AFSNameArrayHdr *RelatedNameArray,
5489 OUT AFSFileInfoCB *FileInfo)
5492 NTSTATUS ntStatus = STATUS_SUCCESS;
5493 AFSDirEnumEntry *pDirEntry = NULL;
5494 UNICODE_STRING uniFullPathName = {0};
5495 AFSNameArrayHdr *pNameArray = NULL;
5496 AFSVolumeCB *pVolumeCB = NULL;
5497 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5498 AFSVolumeCB *pNewVolumeCB = NULL;
5499 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5500 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5501 AFSDirectoryCB *pNewParentDirEntry = NULL;
5502 WCHAR *pwchBuffer = NULL;
5503 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5504 ULONG ulNameDifference = 0;
5511 // Retrieve a target name for the entry
5514 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5517 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5520 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5522 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5527 if( !NT_SUCCESS( ntStatus) ||
5528 pDirEntry->TargetNameLength == 0)
5531 if( pDirEntry != NULL)
5534 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5537 try_return( ntStatus);
5540 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5543 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5547 // Update the target name
5550 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5551 &DirectoryCB->Flags,
5552 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5553 (USHORT)pDirEntry->TargetNameLength);
5555 if( !NT_SUCCESS( ntStatus))
5558 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5560 try_return( ntStatus);
5564 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5568 // Need to pass the full path in for parsing.
5571 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5574 uniFullPathName.Length = 0;
5575 uniFullPathName.MaximumLength = ParentPathName->Length +
5577 DirectoryCB->NameInformation.TargetName.Length;
5579 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5580 uniFullPathName.MaximumLength,
5581 AFS_NAME_BUFFER_SIX_TAG);
5583 if( uniFullPathName.Buffer == NULL)
5586 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5588 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5591 pwchBuffer = uniFullPathName.Buffer;
5593 RtlZeroMemory( uniFullPathName.Buffer,
5594 uniFullPathName.MaximumLength);
5596 RtlCopyMemory( uniFullPathName.Buffer,
5597 ParentPathName->Buffer,
5598 ParentPathName->Length);
5600 uniFullPathName.Length = ParentPathName->Length;
5602 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5603 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5606 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5608 uniFullPathName.Length += sizeof( WCHAR);
5611 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5612 DirectoryCB->NameInformation.TargetName.Buffer,
5613 DirectoryCB->NameInformation.TargetName.Length);
5615 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5617 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5618 uniParsedName.MaximumLength = uniParsedName.Length;
5620 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5622 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5625 // We populate up to the current parent
5628 if( RelatedNameArray != NULL)
5631 pNameArray = AFSInitNameArray( NULL,
5632 RelatedNameArray->MaxElementCount);
5634 if( pNameArray == NULL)
5637 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5640 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5647 pNameArray = AFSInitNameArray( NULL,
5650 if( pNameArray == NULL)
5653 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5656 ntStatus = AFSPopulateNameArray( pNameArray,
5661 if( !NT_SUCCESS( ntStatus))
5664 try_return( ntStatus);
5667 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5669 pParentDirEntry = ParentDirectoryCB;
5674 uniFullPathName.Length = 0;
5675 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5677 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5678 uniFullPathName.MaximumLength,
5679 AFS_NAME_BUFFER_SEVEN_TAG);
5681 if( uniFullPathName.Buffer == NULL)
5684 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5686 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5689 pwchBuffer = uniFullPathName.Buffer;
5691 RtlZeroMemory( uniFullPathName.Buffer,
5692 uniFullPathName.MaximumLength);
5694 RtlCopyMemory( uniFullPathName.Buffer,
5695 DirectoryCB->NameInformation.TargetName.Buffer,
5696 DirectoryCB->NameInformation.TargetName.Length);
5698 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5701 // This name should begin with the \afs server so parse it off and check it
5704 FsRtlDissectName( uniFullPathName,
5708 if( RtlCompareUnicodeString( &uniComponentName,
5713 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5715 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5716 AFS_TRACE_LEVEL_ERROR,
5717 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5720 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5723 uniFullPathName = uniRemainingPath;
5725 uniParsedName = uniFullPathName;
5727 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5729 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5735 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5738 if( pNameArray == NULL)
5741 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5744 pVolumeCB = AFSGlobalRoot;
5746 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5750 // Increment the ref count on the volume and dir entry for correct processing below
5753 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5755 lCount = AFSVolumeIncrement( pVolumeCB,
5756 VolumeReferenceReason);
5758 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5759 AFS_TRACE_LEVEL_VERBOSE,
5760 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5762 VolumeReferenceReason,
5765 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5767 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5768 AFS_TRACE_LEVEL_VERBOSE,
5769 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5770 &pParentDirEntry->NameInformation.FileName,
5775 ntStatus = AFSLocateNameEntry( NULL,
5780 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5784 &NewVolumeReferenceReason,
5785 &pNewParentDirEntry,
5789 if ( pNewVolumeCB != NULL)
5792 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5793 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5794 // the reference on pVolumeCB that was held prior to the call.
5795 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5796 // will be released second.
5799 lCount = AFSVolumeDecrement( pVolumeCB,
5800 VolumeReferenceReason);
5802 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5803 AFS_TRACE_LEVEL_VERBOSE,
5804 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5806 VolumeReferenceReason,
5809 pVolumeCB = pNewVolumeCB;
5811 pNewVolumeCB = NULL;
5813 VolumeReferenceReason = NewVolumeReferenceReason;
5815 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5819 // AFSLocateNameEntry does not alter the reference count of
5820 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5821 // a reference held.
5824 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5826 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5827 AFS_TRACE_LEVEL_VERBOSE,
5828 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5829 &pParentDirEntry->NameInformation.FileName,
5833 pParentDirEntry = pNewParentDirEntry;
5835 pNewParentDirEntry = NULL;
5837 if( !NT_SUCCESS( ntStatus) ||
5838 ntStatus == STATUS_REPARSE)
5841 try_return( ntStatus);
5845 // Store off the information
5848 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5851 // Check for the mount point being returned
5854 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5855 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5858 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5860 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5863 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5866 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5871 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5875 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5877 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5879 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5881 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5883 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5885 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5889 if( pDirEntry != NULL)
5892 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5895 if( pDirectoryEntry != NULL)
5898 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
5900 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5901 AFS_TRACE_LEVEL_VERBOSE,
5902 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5903 &pDirectoryEntry->NameInformation.FileName,
5908 ASSERT( lCount >= 0);
5911 if ( pParentDirEntry != NULL)
5914 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5916 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5917 AFS_TRACE_LEVEL_VERBOSE,
5918 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5919 &pParentDirEntry->NameInformation.FileName,
5924 ASSERT( lCount >= 0);
5927 if( pVolumeCB != NULL)
5930 lCount = AFSVolumeDecrement( pVolumeCB,
5931 VolumeReferenceReason);
5933 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5934 AFS_TRACE_LEVEL_VERBOSE,
5935 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
5937 VolumeReferenceReason,
5941 if( pNameArray != NULL)
5944 AFSFreeNameArray( pNameArray);
5947 if( pwchBuffer != NULL)
5951 // Always free the buffer that we allocated as AFSLocateNameEntry
5952 // will not free it. If uniFullPathName.Buffer was allocated by
5953 // AFSLocateNameEntry, then we must free that as well.
5954 // Check that the uniFullPathName.Buffer in the string is not the same
5955 // offset by the length of the server name
5958 if( uniFullPathName.Length > 0 &&
5959 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
5962 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
5965 AFSExFreePoolWithTag( pwchBuffer, 0);
5973 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
5974 IN ULONGLONG HashIndex)
5977 NTSTATUS ntStatus = STATUS_SUCCESS;
5978 AFSObjectInfoCB *pObjectInfo = NULL;
5984 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
5985 sizeof( AFSObjectInfoCB),
5986 AFS_OBJECT_INFO_TAG);
5988 if( pObjectInfo == NULL)
5991 try_return( pObjectInfo);
5994 RtlZeroMemory( pObjectInfo,
5995 sizeof( AFSObjectInfoCB));
5997 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5998 sizeof( AFSNonPagedObjectInfoCB),
5999 AFS_NP_OBJECT_INFO_TAG);
6001 if( pObjectInfo->NonPagedInfo == NULL)
6004 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6006 try_return( pObjectInfo = NULL);
6009 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6011 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6013 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6015 if( ParentObjectInfo != NULL)
6018 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6020 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6022 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6024 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6025 AFS_OBJECT_REFERENCE_CHILD);
6027 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6028 AFS_TRACE_LEVEL_VERBOSE,
6029 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6035 // Initialize the access time
6038 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6043 ASSERT( ParentObjectInfo);
6046 // Insert the entry into the object tree and list
6049 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6051 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6054 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6059 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6060 &pObjectInfo->TreeEntry);
6062 ASSERT( NT_SUCCESS( ntStatus));
6066 // And the object list in the volume
6069 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6072 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6077 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6079 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6082 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6085 // Indicate the object is in the hash tree and linked list in the volume
6088 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6100 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6106 if ( ObjectInfo->ObjectReferenceCount == 0)
6109 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6112 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6117 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6120 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6125 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6127 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6132 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6134 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6140 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6144 LONG lCount, lCount2;
6146 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6149 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6154 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6156 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6158 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6161 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6164 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6166 ASSERT( lCount2 >= 0);
6168 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6174 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6175 IN AFSFileID *FileId,
6176 IN BOOLEAN bUpdateLastUse)
6178 DWORD ntStatus = STATUS_SUCCESS;
6180 AFSObjectInfoCB *pObjectInfo = NULL;
6183 ullIndex = AFSCreateLowIndex( FileId);
6185 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6188 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6191 pObjectInfo = &VolumeCB->ObjectInformation;
6196 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6198 (AFSBTreeEntry **)&pObjectInfo);
6201 if ( NT_SUCCESS( ntStatus)) {
6203 lCount = AFSObjectInfoIncrement( pObjectInfo,
6204 AFS_OBJECT_REFERENCE_FIND);
6206 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6207 AFS_TRACE_LEVEL_VERBOSE,
6208 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6212 if ( bUpdateLastUse)
6215 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6219 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6225 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6229 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6230 AFS_OBJECT_REFERENCE_FIND);
6232 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6233 AFS_TRACE_LEVEL_VERBOSE,
6234 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6238 *ppObjectInfo = NULL;
6242 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6244 BOOLEAN bAcquiredTreeLock = FALSE;
6245 AFSObjectInfoCB *pObjectInfo = NULL;
6246 AFSVolumeCB * pVolume = NULL;
6247 BOOLEAN bHeldInService;
6248 AFSObjectInfoCB * pParentObjectInfo = NULL;
6254 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6258 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6259 // embedded in the VolumeCB.
6267 pVolume = (*ppObjectInfo)->VolumeCB;
6269 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6272 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6274 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6277 bAcquiredTreeLock = TRUE;
6280 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6283 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6286 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6288 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6292 if ( pObjectInfo == NULL)
6295 try_return( NOTHING);
6298 ASSERT( *ppObjectInfo == NULL);
6300 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6303 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6304 &pObjectInfo->ParentFileId,
6307 if( pParentObjectInfo != NULL)
6310 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6312 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6313 AFS_OBJECT_REFERENCE_CHILD);
6315 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6316 AFS_TRACE_LEVEL_VERBOSE,
6317 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6321 AFSReleaseObjectInfo( &pParentObjectInfo);
6326 // Remove it from the tree and list if it was inserted
6329 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6332 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6333 &pObjectInfo->TreeEntry);
6336 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6339 if( pObjectInfo->ListEntry.fLink == NULL)
6342 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6344 if( pVolume->ObjectInfoListTail != NULL)
6347 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6353 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6356 if( pObjectInfo->ListEntry.bLink == NULL)
6359 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6361 if( pVolume->ObjectInfoListHead != NULL)
6364 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6370 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6374 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6379 FileId = pObjectInfo->FileId;
6382 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6384 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6386 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6388 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6390 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6394 if( bAcquiredTreeLock)
6397 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6401 // Release the fid in the service
6407 AFSReleaseFid( &FileId);
6415 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6416 OUT AFSDirectoryCB **TargetDirEntry)
6419 NTSTATUS ntStatus = STATUS_SUCCESS;
6420 AFSDirEnumEntry *pDirEntry = NULL;
6421 UNICODE_STRING uniFullPathName = {0};
6422 AFSNameArrayHdr *pNameArray = NULL;
6423 AFSVolumeCB *pVolumeCB = NULL;
6424 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6425 AFSVolumeCB *pNewVolumeCB = NULL;
6426 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6427 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6428 AFSDirectoryCB *pNewParentDirEntry = NULL;
6429 WCHAR *pwchBuffer = NULL;
6430 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6431 ULONG ulNameDifference = 0;
6438 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6439 DirectoryCB->ObjectInformation,
6443 if( !NT_SUCCESS( ntStatus))
6445 try_return( ntStatus);
6449 // Retrieve a target name for the entry
6452 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6455 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6458 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6460 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6465 if( !NT_SUCCESS( ntStatus) ||
6466 pDirEntry->TargetNameLength == 0)
6469 if( pDirEntry != NULL)
6472 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6475 try_return( ntStatus);
6478 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6481 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6485 // Update the target name
6488 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6489 &DirectoryCB->Flags,
6490 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6491 (USHORT)pDirEntry->TargetNameLength);
6493 if( !NT_SUCCESS( ntStatus))
6496 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6498 try_return( ntStatus);
6502 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6506 // Need to pass the full path in for parsing.
6509 uniFullPathName.Length = 0;
6510 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6512 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6513 uniFullPathName.MaximumLength,
6514 AFS_NAME_BUFFER_EIGHT_TAG);
6516 if( uniFullPathName.Buffer == NULL)
6519 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6521 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6524 pwchBuffer = uniFullPathName.Buffer;
6526 RtlZeroMemory( uniFullPathName.Buffer,
6527 uniFullPathName.MaximumLength);
6529 RtlCopyMemory( uniFullPathName.Buffer,
6530 DirectoryCB->NameInformation.TargetName.Buffer,
6531 DirectoryCB->NameInformation.TargetName.Length);
6533 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6536 // This name should begin with the \afs server so parse it off and chech it
6539 FsRtlDissectName( uniFullPathName,
6543 if( RtlCompareUnicodeString( &uniComponentName,
6549 // Try evaluating the full path
6552 uniFullPathName.Buffer = pwchBuffer;
6554 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6556 uniFullPathName.MaximumLength = uniFullPathName.Length;
6561 uniFullPathName = uniRemainingPath;
6564 uniParsedName = uniFullPathName;
6566 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6568 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6574 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6577 if( pNameArray == NULL)
6580 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6583 pVolumeCB = AFSGlobalRoot;
6585 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6587 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6589 lCount = AFSVolumeIncrement( pVolumeCB,
6590 VolumeReferenceReason);
6592 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6593 AFS_TRACE_LEVEL_VERBOSE,
6594 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6596 VolumeReferenceReason,
6599 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6601 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6602 AFS_TRACE_LEVEL_VERBOSE,
6603 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6604 &pParentDirEntry->NameInformation.FileName,
6609 ntStatus = AFSLocateNameEntry( NULL,
6618 &VolumeReferenceReason,
6619 &pNewParentDirEntry,
6623 if ( pNewVolumeCB != NULL)
6626 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6627 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6628 // the reference on pVolumeCB that was held prior to the call.
6629 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6630 // will be released second.
6633 lCount = AFSVolumeDecrement( pVolumeCB,
6634 VolumeReferenceReason);
6636 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6637 AFS_TRACE_LEVEL_VERBOSE,
6638 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6640 VolumeReferenceReason,
6643 pVolumeCB = pNewVolumeCB;
6645 pNewVolumeCB = NULL;
6647 VolumeReferenceReason = NewVolumeReferenceReason;
6649 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6653 // AFSLocateNameEntry does not alter the reference count of
6654 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6655 // a reference held.
6658 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6660 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6661 AFS_TRACE_LEVEL_VERBOSE,
6662 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6663 &pParentDirEntry->NameInformation.FileName,
6667 pParentDirEntry = pNewParentDirEntry;
6669 pNewParentDirEntry = NULL;
6671 if( !NT_SUCCESS( ntStatus) ||
6672 ntStatus == STATUS_REPARSE)
6677 try_return( ntStatus);
6681 // Pass back the target dir entry for this request
6682 // The caller must release the DirOpenReferenceCount
6685 *TargetDirEntry = pDirectoryEntry;
6687 pDirectoryEntry = NULL;
6691 if( pDirectoryEntry != NULL)
6694 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6696 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6697 AFS_TRACE_LEVEL_VERBOSE,
6698 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6699 &pDirectoryEntry->NameInformation.FileName,
6704 ASSERT( lCount >= 0);
6707 if ( pParentDirEntry != NULL)
6710 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6712 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6713 AFS_TRACE_LEVEL_VERBOSE,
6714 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6715 &pParentDirEntry->NameInformation.FileName,
6720 ASSERT( lCount >= 0);
6723 if( pDirEntry != NULL)
6726 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6729 if( pVolumeCB != NULL)
6732 lCount = AFSVolumeDecrement( pVolumeCB,
6733 VolumeReferenceReason);
6735 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6736 AFS_TRACE_LEVEL_VERBOSE,
6737 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6739 VolumeReferenceReason,
6743 if( pNameArray != NULL)
6746 AFSFreeNameArray( pNameArray);
6749 if( pwchBuffer != NULL)
6753 // Always free the buffer that we allocated as AFSLocateNameEntry
6754 // will not free it. If uniFullPathName.Buffer was allocated by
6755 // AFSLocateNameEntry, then we must free that as well.
6756 // Check that the uniFullPathName.Buffer in the string is not the same
6757 // offset by the length of the server name
6760 if( uniFullPathName.Length > 0 &&
6761 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6764 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6767 AFSExFreePoolWithTag( pwchBuffer, 0);
6775 AFSCleanupFcb( IN AFSFcb *Fcb,
6776 IN BOOLEAN ForceFlush)
6779 NTSTATUS ntStatus = STATUS_SUCCESS;
6780 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6781 LARGE_INTEGER liTime;
6782 IO_STATUS_BLOCK stIoStatus;
6787 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6789 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6791 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6794 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6795 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6798 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6799 AFS_TRACE_LEVEL_VERBOSE,
6800 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
6801 &Fcb->NPFcb->Resource,
6802 PsGetCurrentThread()));
6804 AFSAcquireShared( &Fcb->NPFcb->Resource,
6807 if( Fcb->OpenReferenceCount > 0)
6810 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6811 AFS_TRACE_LEVEL_VERBOSE,
6812 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6813 &Fcb->NPFcb->SectionObjectResource,
6814 PsGetCurrentThread()));
6816 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6822 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6827 if( !NT_SUCCESS( stIoStatus.Status))
6830 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6831 AFS_TRACE_LEVEL_ERROR,
6832 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6833 Fcb->ObjectInformation->FileId.Cell,
6834 Fcb->ObjectInformation->FileId.Volume,
6835 Fcb->ObjectInformation->FileId.Vnode,
6836 Fcb->ObjectInformation->FileId.Unique,
6838 stIoStatus.Information));
6840 ntStatus = stIoStatus.Status;
6843 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6846 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6852 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6853 AFS_TRACE_LEVEL_WARNING,
6854 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6855 Fcb->ObjectInformation->FileId.Cell,
6856 Fcb->ObjectInformation->FileId.Volume,
6857 Fcb->ObjectInformation->FileId.Vnode,
6858 Fcb->ObjectInformation->FileId.Unique));
6860 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6864 __except( EXCEPTION_EXECUTE_HANDLER)
6867 ntStatus = GetExceptionCode();
6871 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6872 Fcb->ObjectInformation->FileId.Cell,
6873 Fcb->ObjectInformation->FileId.Volume,
6874 Fcb->ObjectInformation->FileId.Vnode,
6875 Fcb->ObjectInformation->FileId.Unique,
6878 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6881 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6882 AFS_TRACE_LEVEL_VERBOSE,
6883 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6884 &Fcb->NPFcb->SectionObjectResource,
6885 PsGetCurrentThread()));
6887 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6890 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6891 AFS_TRACE_LEVEL_VERBOSE,
6892 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
6893 &Fcb->NPFcb->Resource,
6894 PsGetCurrentThread()));
6896 AFSReleaseResource( &Fcb->NPFcb->Resource);
6899 // Wait for any currently running flush or release requests to complete
6902 AFSWaitOnQueuedFlushes( Fcb);
6905 // Now perform another flush on the file
6908 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6912 AFSReleaseExtentsWithFlush( Fcb,
6918 if( Fcb->OpenReferenceCount == 0 ||
6919 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6920 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6923 AFSTearDownFcbExtents( Fcb,
6927 try_return( ntStatus);
6930 KeQueryTickCount( &liTime);
6933 // First up are there dirty extents in the cache to flush?
6936 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6937 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6941 // The file has been marked as invalid. Dump it
6944 AFSTearDownFcbExtents( Fcb,
6947 else if( ForceFlush ||
6948 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
6949 Fcb->Specific.File.ExtentCount) &&
6950 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6951 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6953 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6955 Fcb->OpenReferenceCount == 0)
6958 AFSReleaseExtentsWithFlush( Fcb,
6965 // If there are extents and they haven't been used recently *and*
6966 // are not being used
6970 ( 0 != Fcb->Specific.File.ExtentCount &&
6971 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6972 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6973 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
6976 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6977 AFS_TRACE_LEVEL_VERBOSE,
6978 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6979 &Fcb->NPFcb->SectionObjectResource,
6980 PsGetCurrentThread()));
6982 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
6988 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6993 if( !NT_SUCCESS( stIoStatus.Status))
6996 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6997 AFS_TRACE_LEVEL_ERROR,
6998 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6999 Fcb->ObjectInformation->FileId.Cell,
7000 Fcb->ObjectInformation->FileId.Volume,
7001 Fcb->ObjectInformation->FileId.Vnode,
7002 Fcb->ObjectInformation->FileId.Unique,
7004 stIoStatus.Information));
7006 ntStatus = stIoStatus.Status;
7010 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7013 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7019 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7020 AFS_TRACE_LEVEL_WARNING,
7021 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7022 Fcb->ObjectInformation->FileId.Cell,
7023 Fcb->ObjectInformation->FileId.Volume,
7024 Fcb->ObjectInformation->FileId.Vnode,
7025 Fcb->ObjectInformation->FileId.Unique));
7027 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7031 __except( EXCEPTION_EXECUTE_HANDLER)
7034 ntStatus = GetExceptionCode();
7038 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7039 Fcb->ObjectInformation->FileId.Cell,
7040 Fcb->ObjectInformation->FileId.Volume,
7041 Fcb->ObjectInformation->FileId.Vnode,
7042 Fcb->ObjectInformation->FileId.Unique,
7046 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7047 AFS_TRACE_LEVEL_VERBOSE,
7048 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7049 &Fcb->NPFcb->SectionObjectResource,
7050 PsGetCurrentThread()));
7052 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7054 if( Fcb->OpenReferenceCount <= 0)
7058 // Tear em down we'll not be needing them again
7061 AFSTearDownFcbExtents( Fcb,
7068 ntStatus = STATUS_RETRY;
7081 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7082 IN UNICODE_STRING *NewFileName)
7085 NTSTATUS ntStatus = STATUS_SUCCESS;
7086 WCHAR *pTmpBuffer = NULL;
7091 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7094 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7097 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7099 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7101 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7105 // OK, we need to allocate a new name buffer
7108 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7109 NewFileName->Length,
7110 AFS_NAME_BUFFER_NINE_TAG);
7112 if( pTmpBuffer == NULL)
7115 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7118 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7120 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7122 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7125 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7127 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7128 NewFileName->Buffer,
7129 NewFileName->Length);
7140 AFSReadCacheFile( IN void *ReadBuffer,
7141 IN LARGE_INTEGER *ReadOffset,
7142 IN ULONG RequestedDataLength,
7143 IN OUT PULONG BytesRead)
7146 NTSTATUS ntStatus = STATUS_SUCCESS;
7149 PIO_STACK_LOCATION pIoStackLocation = NULL;
7150 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7151 FILE_OBJECT *pCacheFileObject = NULL;
7156 pCacheFileObject = AFSReferenceCacheFileObject();
7158 if( pCacheFileObject == NULL)
7160 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7163 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7166 // Initialize the event
7169 KeInitializeEvent( &kEvent,
7170 SynchronizationEvent,
7174 // Allocate an irp for this request. This could also come from a
7175 // private pool, for instance.
7178 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7184 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7188 // Build the IRP's main body
7191 pIrp->UserBuffer = ReadBuffer;
7193 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7194 pIrp->RequestorMode = KernelMode;
7195 pIrp->Flags |= IRP_READ_OPERATION;
7198 // Set up the I/O stack location.
7201 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7202 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7203 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7204 pIoStackLocation->FileObject = pCacheFileObject;
7205 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7207 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7210 // Set the completion routine.
7213 IoSetCompletionRoutine( pIrp,
7221 // Send it to the FSD
7224 ntStatus = IoCallDriver( pTargetDeviceObject,
7227 if( NT_SUCCESS( ntStatus))
7234 ntStatus = KeWaitForSingleObject( &kEvent,
7240 if( NT_SUCCESS( ntStatus))
7243 ntStatus = pIrp->IoStatus.Status;
7245 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7251 if( pCacheFileObject != NULL)
7253 AFSReleaseCacheFileObject( pCacheFileObject);
7259 if( pIrp->MdlAddress != NULL)
7262 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7265 MmUnlockPages( pIrp->MdlAddress);
7268 IoFreeMdl( pIrp->MdlAddress);
7271 pIrp->MdlAddress = NULL;
7285 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7290 UNREFERENCED_PARAMETER(Irp);
7291 UNREFERENCED_PARAMETER(DeviceObject);
7292 KEVENT *pEvent = (KEVENT *)Context;
7298 return STATUS_MORE_PROCESSING_REQUIRED;
7302 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7305 BOOLEAN bIsEmpty = FALSE;
7306 AFSDirectoryCB *pDirEntry = NULL;
7311 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7313 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7318 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7321 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7323 while( pDirEntry != NULL)
7326 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7327 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7335 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7340 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7347 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7348 IN AFSDirectoryCB *DirEntry)
7351 NTSTATUS ntStatus = STATUS_SUCCESS;
7356 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7359 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7360 AFS_TRACE_LEVEL_VERBOSE,
7361 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7363 &DirEntry->NameInformation.FileName));
7365 try_return( ntStatus);
7368 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7371 // Remove the entry from the parent tree
7374 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7375 AFS_TRACE_LEVEL_VERBOSE,
7376 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7378 &DirEntry->NameInformation.FileName));
7380 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7383 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7384 AFS_TRACE_LEVEL_VERBOSE,
7385 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7387 &DirEntry->NameInformation.FileName));
7389 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7392 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7396 // From the short name tree
7399 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7400 AFS_TRACE_LEVEL_VERBOSE,
7401 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7403 &DirEntry->NameInformation.FileName));
7405 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7408 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7411 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7412 AFS_TRACE_LEVEL_VERBOSE,
7413 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7415 &DirEntry->NameInformation.FileName));
7417 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7419 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7430 AFSGetAuthenticationId()
7433 LARGE_INTEGER liAuthId = {0,0};
7434 NTSTATUS ntStatus = STATUS_SUCCESS;
7435 PACCESS_TOKEN hToken = NULL;
7436 PTOKEN_STATISTICS pTokenInfo = NULL;
7437 BOOLEAN bCopyOnOpen = FALSE;
7438 BOOLEAN bEffectiveOnly = FALSE;
7439 BOOLEAN bPrimaryToken = FALSE;
7440 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7445 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7448 &stImpersonationLevel);
7453 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7458 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7459 AFS_TRACE_LEVEL_ERROR,
7460 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7462 try_return( ntStatus);
7465 bPrimaryToken = TRUE;
7468 ntStatus = SeQueryInformationToken( hToken,
7470 (PVOID *)&pTokenInfo);
7472 if( !NT_SUCCESS( ntStatus))
7475 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7476 AFS_TRACE_LEVEL_ERROR,
7477 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7480 try_return( ntStatus);
7483 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7484 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7486 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7487 AFS_TRACE_LEVEL_VERBOSE,
7488 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7489 liAuthId.QuadPart));
7499 PsDereferenceImpersonationToken( hToken);
7504 PsDereferencePrimaryToken( hToken);
7508 if( pTokenInfo != NULL)
7511 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7519 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7523 UNREFERENCED_PARAMETER(Fcb);
7524 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7526 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7529 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7531 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7534 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7536 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7539 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7541 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7544 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7546 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7553 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7556 BOOLEAN bIsValid = TRUE;
7558 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7560 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7562 while( pCurrentDirEntry != NULL)
7565 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7569 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7574 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7575 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7578 if( pDirEntry == NULL)
7585 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7588 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7591 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7593 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7595 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7604 AFSReferenceCacheFileObject()
7607 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7608 FILE_OBJECT *pCacheFileObject = NULL;
7610 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7613 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7615 if( pCacheFileObject != NULL)
7617 ObReferenceObject( pCacheFileObject);
7620 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7622 return pCacheFileObject;
7626 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7629 ASSERT( CacheFileObject != NULL);
7631 ObDereferenceObject( CacheFileObject);
7637 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7640 NTSTATUS ntStatus = STATUS_SUCCESS;
7641 AFSDeviceExt *pControlDevExt = NULL;
7642 ULONG ulTimeIncrement = 0;
7648 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7650 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7652 AFSServerName = LibraryInit->AFSServerName;
7654 AFSMountRootName = LibraryInit->AFSMountRootName;
7656 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7659 // Callbacks in the framework
7662 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7664 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7666 AFSDebugTraceFnc = AFSDbgLogMsg;
7668 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7670 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7672 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7674 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7676 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7678 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7680 if( LibraryInit->AFSCacheBaseAddress != NULL)
7683 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7685 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7687 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7691 // Initialize some flush parameters
7694 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7696 ulTimeIncrement = KeQueryTimeIncrement();
7698 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7699 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7700 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7701 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7702 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7705 // Initialize the global root entry
7708 ntStatus = AFSInitVolume( NULL,
7709 &LibraryInit->GlobalRootFid,
7710 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7713 if( !NT_SUCCESS( ntStatus))
7716 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7717 AFS_TRACE_LEVEL_ERROR,
7718 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7721 try_return( ntStatus);
7724 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7727 if( !NT_SUCCESS( ntStatus))
7730 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7731 AFS_TRACE_LEVEL_ERROR,
7732 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7735 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7736 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7738 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7739 AFS_TRACE_LEVEL_VERBOSE,
7740 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7744 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7746 try_return( ntStatus);
7750 // Update the node type code to AFS_ROOT_ALL
7753 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7755 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7758 // Invalidate all known volumes since contact with the service and therefore
7759 // the file server was lost.
7762 AFSInvalidateAllVolumes();
7765 // Drop the locks acquired above
7768 AFSInitVolumeWorker( AFSGlobalRoot);
7770 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7771 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7773 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7774 AFS_TRACE_LEVEL_VERBOSE,
7775 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7779 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7781 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7795 NTSTATUS ntStatus = STATUS_SUCCESS;
7796 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7802 if( AFSGlobalDotDirEntry != NULL)
7805 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7806 AFS_OBJECT_REFERENCE_GLOBAL);
7808 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7809 AFS_TRACE_LEVEL_VERBOSE,
7810 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7811 AFSGlobalDotDirEntry->ObjectInformation,
7817 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7820 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7822 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7824 ExFreePool( AFSGlobalDotDirEntry);
7826 AFSGlobalDotDirEntry = NULL;
7829 if( AFSGlobalDotDotDirEntry != NULL)
7832 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
7833 AFS_OBJECT_REFERENCE_GLOBAL);
7835 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7836 AFS_TRACE_LEVEL_VERBOSE,
7837 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7838 AFSGlobalDotDotDirEntry->ObjectInformation,
7844 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
7847 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7849 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7851 ExFreePool( AFSGlobalDotDotDirEntry);
7853 AFSGlobalDotDotDirEntry = NULL;
7856 if( AFSSpecialShareNames != NULL)
7859 pDirNode = AFSSpecialShareNames;
7861 while( pDirNode != NULL)
7864 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7866 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
7867 AFS_OBJECT_REFERENCE_GLOBAL);
7869 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7870 AFS_TRACE_LEVEL_VERBOSE,
7871 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7872 pDirNode->ObjectInformation,
7878 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
7881 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7883 ExFreePool( pDirNode->NonPaged);
7885 ExFreePool( pDirNode);
7887 pDirNode = pLastDirNode;
7890 AFSSpecialShareNames = NULL;
7898 AFSDefaultLogMsg( IN ULONG Subsystem,
7904 UNREFERENCED_PARAMETER(Subsystem);
7905 UNREFERENCED_PARAMETER(Level);
7906 NTSTATUS ntStatus = STATUS_SUCCESS;
7908 char chDebugBuffer[ 256];
7913 va_start( va_args, Format);
7915 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7920 if( NT_SUCCESS( ntStatus))
7922 DbgPrint( chDebugBuffer);
7932 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7933 IN ULONG InputBufferLength,
7934 IN AFSStatusInfoCB *StatusInfo,
7935 OUT ULONG *ReturnLength)
7938 NTSTATUS ntStatus = STATUS_SUCCESS;
7939 AFSVolumeCB *pVolumeCB = NULL;
7940 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7941 AFSVolumeCB *pNewVolumeCB = NULL;
7942 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7943 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7944 AFSObjectInfoCB *pObjectInfo = NULL;
7945 ULONGLONG ullIndex = 0;
7946 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7947 AFSNameArrayHdr *pNameArray = NULL;
7948 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7949 AFSDirectoryCB *pNewParentDirEntry = NULL;
7956 // If we are given a FID then look up the entry by that, otherwise
7960 if( GetStatusInfo->FileID.Cell != 0 &&
7961 GetStatusInfo->FileID.Volume != 0 &&
7962 GetStatusInfo->FileID.Vnode != 0 &&
7963 GetStatusInfo->FileID.Unique != 0)
7966 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7969 // Locate the volume node
7972 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7974 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7976 (AFSBTreeEntry **)&pVolumeCB);
7978 if( pVolumeCB != NULL)
7981 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
7983 lCount = AFSVolumeIncrement( pVolumeCB,
7984 VolumeReferenceReason);
7986 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7987 AFS_TRACE_LEVEL_VERBOSE,
7988 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
7990 VolumeReferenceReason,
7994 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7996 if( !NT_SUCCESS( ntStatus) ||
7999 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8002 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8005 pObjectInfo = &pVolumeCB->ObjectInformation;
8007 lCount = AFSObjectInfoIncrement( pObjectInfo,
8008 AFS_OBJECT_REFERENCE_STATUS);
8010 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8011 AFS_TRACE_LEVEL_VERBOSE,
8012 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8019 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8022 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8024 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8026 (AFSBTreeEntry **)&pObjectInfo);
8028 if( pObjectInfo != NULL)
8032 // Reference the node so it won't be torn down
8035 lCount = AFSObjectInfoIncrement( pObjectInfo,
8036 AFS_OBJECT_REFERENCE_STATUS);
8038 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8039 AFS_TRACE_LEVEL_VERBOSE,
8040 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8045 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8047 if( !NT_SUCCESS( ntStatus) ||
8048 pObjectInfo == NULL)
8050 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8057 if( GetStatusInfo->FileNameLength == 0 ||
8058 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8060 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8063 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8064 uniFullPathName.MaximumLength = uniFullPathName.Length;
8066 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8069 // This name should begin with the \afs server so parse it off and check it
8072 FsRtlDissectName( uniFullPathName,
8076 if( RtlCompareUnicodeString( &uniComponentName,
8080 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8081 AFS_TRACE_LEVEL_ERROR,
8082 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8085 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8088 uniFullPathName = uniRemainingPath;
8090 uniParsedName = uniFullPathName;
8096 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8099 if( pNameArray == NULL)
8101 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8104 pVolumeCB = AFSGlobalRoot;
8106 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8109 // Increment the ref count on the volume and dir entry for correct processing below
8112 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8114 lCount = AFSVolumeIncrement( pVolumeCB,
8115 VolumeReferenceReason);
8117 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8118 AFS_TRACE_LEVEL_VERBOSE,
8119 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8121 VolumeReferenceReason,
8124 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8126 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8127 AFS_TRACE_LEVEL_VERBOSE,
8128 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8129 &pParentDirEntry->NameInformation.FileName,
8134 ntStatus = AFSLocateNameEntry( NULL,
8139 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8140 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8144 &NewVolumeReferenceReason,
8145 &pNewParentDirEntry,
8149 if ( pNewVolumeCB != NULL)
8153 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8154 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8155 // the reference on pVolumeCB that was held prior to the call.
8156 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8157 // will be released second.
8160 lCount = AFSVolumeDecrement( pVolumeCB,
8161 VolumeReferenceReason);
8163 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8164 AFS_TRACE_LEVEL_VERBOSE,
8165 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8167 VolumeReferenceReason,
8170 pVolumeCB = pNewVolumeCB;
8172 pNewVolumeCB = NULL;
8174 VolumeReferenceReason = NewVolumeReferenceReason;
8176 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8180 // AFSLocateNameEntry does not alter the reference count of
8181 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8182 // a reference held.
8185 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8187 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8188 AFS_TRACE_LEVEL_VERBOSE,
8189 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8190 &pParentDirEntry->NameInformation.FileName,
8194 pParentDirEntry = pNewParentDirEntry;
8196 pNewParentDirEntry = NULL;
8198 if( !NT_SUCCESS( ntStatus) ||
8199 ntStatus == STATUS_REPARSE)
8204 try_return( ntStatus);
8207 pObjectInfo = pDirectoryEntry->ObjectInformation;
8209 lCount = AFSObjectInfoIncrement( pObjectInfo,
8210 AFS_OBJECT_REFERENCE_STATUS);
8212 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8213 AFS_TRACE_LEVEL_VERBOSE,
8214 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8220 // At this point we have an object info block, return the information
8223 StatusInfo->FileId = pObjectInfo->FileId;
8225 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8227 StatusInfo->Expiration = pObjectInfo->Expiration;
8229 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8231 StatusInfo->FileType = pObjectInfo->FileType;
8233 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8235 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8237 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8239 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8241 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8243 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8245 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8247 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8249 StatusInfo->EaSize = pObjectInfo->EaSize;
8251 StatusInfo->Links = pObjectInfo->Links;
8254 // Return the information length
8257 *ReturnLength = sizeof( AFSStatusInfoCB);
8261 if( pDirectoryEntry != NULL)
8264 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8266 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8267 AFS_TRACE_LEVEL_VERBOSE,
8268 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8269 &pDirectoryEntry->NameInformation.FileName,
8274 ASSERT( lCount >= 0);
8277 if ( pParentDirEntry != NULL)
8280 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8282 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8283 AFS_TRACE_LEVEL_VERBOSE,
8284 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8285 &pParentDirEntry->NameInformation.FileName,
8290 ASSERT( lCount >= 0);
8293 if( pObjectInfo != NULL)
8296 lCount = AFSObjectInfoDecrement( pObjectInfo,
8297 AFS_OBJECT_REFERENCE_STATUS);
8299 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8300 AFS_TRACE_LEVEL_VERBOSE,
8301 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8306 if( pVolumeCB != NULL)
8309 lCount = AFSVolumeDecrement( pVolumeCB,
8310 VolumeReferenceReason);
8312 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8313 AFS_TRACE_LEVEL_VERBOSE,
8314 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8316 VolumeReferenceReason,
8320 if( pNameArray != NULL)
8323 AFSFreeNameArray( pNameArray);
8331 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8332 IN UNICODE_STRING *ComponentName)
8335 NTSTATUS ntStatus = STATUS_SUCCESS;
8336 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8337 AFSDirectoryCB *pDirEntry = NULL;
8345 // Search for the entry in the parent
8348 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8349 AFS_TRACE_LEVEL_VERBOSE_2,
8350 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8353 ulCRC = AFSGenerateCRC( ComponentName,
8356 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8359 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8363 if( pDirEntry == NULL)
8367 // Missed so perform a case insensitive lookup
8370 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8371 AFS_TRACE_LEVEL_VERBOSE_2,
8372 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8375 ulCRC = AFSGenerateCRC( ComponentName,
8378 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8382 if( pDirEntry == NULL)
8386 // OK, if this component is a valid short name then try
8387 // a lookup in the short name tree
8390 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8391 RtlIsNameLegalDOS8Dot3( ComponentName,
8396 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8397 AFS_TRACE_LEVEL_VERBOSE_2,
8398 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8401 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8408 if( pDirEntry != NULL)
8410 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8412 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8413 AFS_TRACE_LEVEL_VERBOSE,
8414 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8415 &pDirEntry->NameInformation.FileName,
8420 ASSERT( lCount >= 0);
8423 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8425 if( pDirEntry == NULL)
8428 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8429 AFS_TRACE_LEVEL_VERBOSE_2,
8430 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8432 STATUS_OBJECT_NAME_NOT_FOUND));
8434 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8438 // We have the symlink object but previously failed to process it so return access
8442 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8443 AFS_TRACE_LEVEL_VERBOSE_2,
8444 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8447 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8449 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8451 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8452 AFS_TRACE_LEVEL_VERBOSE,
8453 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8454 &pDirEntry->NameInformation.FileName,
8459 ASSERT( lCount >= 0);
8470 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8471 OUT UNICODE_STRING *ComponentName)
8474 NTSTATUS ntStatus = STATUS_SUCCESS;
8475 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8477 uniFullPathName = *FullPathName;
8482 FsRtlDissectName( uniFullPathName,
8486 if( uniRemainingPath.Length == 0)
8491 uniFullPathName = uniRemainingPath;
8494 if( uniComponentName.Length > 0)
8496 *ComponentName = uniComponentName;
8503 AFSDumpTraceFiles_Default()
8509 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8512 BOOLEAN bIsValidName = TRUE;
8518 while( usIndex < FileName->Length/sizeof( WCHAR))
8521 if( FileName->Buffer[ usIndex] == L':' ||
8522 FileName->Buffer[ usIndex] == L'*' ||
8523 FileName->Buffer[ usIndex] == L'?' ||
8524 FileName->Buffer[ usIndex] == L'"' ||
8525 FileName->Buffer[ usIndex] == L'<' ||
8526 FileName->Buffer[ usIndex] == L'>')
8528 bIsValidName = FALSE;
8536 return bIsValidName;
8540 AFSCreateDefaultSecurityDescriptor()
8543 NTSTATUS ntStatus = STATUS_SUCCESS;
8545 ULONG ulSACLSize = 0;
8546 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8547 ULONG ulACESize = 0;
8548 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8549 ULONG ulSDLength = 0;
8550 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8551 PSID pWorldSID = NULL;
8552 ULONG *pulSubAuthority = NULL;
8553 ULONG ulWorldSIDLEngth = 0;
8558 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8560 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8562 AFS_GENERIC_MEMORY_29_TAG);
8564 if( pWorldSID == NULL)
8566 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8568 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8571 RtlZeroMemory( pWorldSID,
8574 RtlInitializeSid( pWorldSID,
8575 &SeWorldSidAuthority,
8578 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8579 *pulSubAuthority = SECURITY_WORLD_RID;
8581 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8584 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8589 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8591 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8593 AFS_GENERIC_MEMORY_29_TAG);
8598 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8600 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8603 RtlZeroMemory( pACE,
8606 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8607 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8608 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8609 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8611 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8613 SeExports->SeLowMandatorySid);
8615 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8616 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8618 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8620 AFS_GENERIC_MEMORY_29_TAG);
8625 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8627 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8630 ntStatus = RtlCreateAcl( pSACL,
8634 if( !NT_SUCCESS( ntStatus))
8637 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8640 try_return( ntStatus);
8643 ntStatus = RtlAddAce( pSACL,
8647 pACE->Header.AceSize);
8649 if( !NT_SUCCESS( ntStatus))
8652 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8655 try_return( ntStatus);
8659 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8660 sizeof( SECURITY_DESCRIPTOR),
8661 AFS_GENERIC_MEMORY_27_TAG);
8663 if( pSecurityDescr == NULL)
8666 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8671 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8672 SECURITY_DESCRIPTOR_REVISION);
8674 if( !NT_SUCCESS( ntStatus))
8677 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8680 try_return( ntStatus);
8683 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8685 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8690 if( !NT_SUCCESS( ntStatus))
8693 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8696 try_return( ntStatus);
8701 // Add in the group and owner to the SD
8704 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8706 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8710 if( !NT_SUCCESS( ntStatus))
8713 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8716 try_return( ntStatus);
8720 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8724 if( !NT_SUCCESS( ntStatus))
8727 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8730 try_return( ntStatus);
8733 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8736 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8738 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8741 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8743 AFS_GENERIC_MEMORY_27_TAG);
8745 if( pRelativeSecurityDescr == NULL)
8748 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8750 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8753 ulSDLength = PAGE_SIZE;
8755 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8756 pRelativeSecurityDescr,
8759 if( !NT_SUCCESS( ntStatus))
8762 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8765 try_return( ntStatus);
8768 AFSDefaultSD = pRelativeSecurityDescr;
8772 if( !NT_SUCCESS( ntStatus))
8775 if( pRelativeSecurityDescr != NULL)
8777 ExFreePool( pRelativeSecurityDescr);
8781 if( pSecurityDescr != NULL)
8783 ExFreePool( pSecurityDescr);
8796 if( pWorldSID != NULL)
8798 ExFreePool( pWorldSID);
8806 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8807 OUT UNICODE_STRING *ParentPath)
8810 *ParentPath = *FullFileName;
8813 // If the final character is a \, jump over it
8816 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8818 ParentPath->Length -= sizeof( WCHAR);
8821 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8823 ParentPath->Length -= sizeof( WCHAR);
8827 // And the separator
8830 ParentPath->Length -= sizeof( WCHAR);
8836 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8837 IN AFSObjectInfoCB *ObjectInfo,
8838 IN BOOLEAN WriteAccess,
8839 OUT GUID *AuthGroup)
8842 NTSTATUS ntStatus = STATUS_SUCCESS;
8843 GUID stAuthGroup, stZeroAuthGroup;
8844 BOOLEAN bFoundAuthGroup = FALSE;
8845 AFSCcb *pCcb = NULL;
8851 RtlZeroMemory( &stAuthGroup,
8854 RtlZeroMemory( &stZeroAuthGroup,
8860 if( ObjectInfo != NULL &&
8861 ObjectInfo->Fcb != NULL)
8863 pFcb = ObjectInfo->Fcb;
8870 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8873 pCcb = Fcb->CcbListHead;
8875 while( pCcb != NULL)
8879 pCcb->GrantedAccess & FILE_WRITE_DATA)
8881 RtlCopyMemory( &stAuthGroup,
8885 bFoundAuthGroup = TRUE;
8889 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8892 // At least get the read-only access
8895 RtlCopyMemory( &stAuthGroup,
8899 bFoundAuthGroup = TRUE;
8902 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8905 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8908 if( !bFoundAuthGroup)
8911 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8912 (ULONGLONG)PsGetCurrentThreadId(),
8915 if( RtlCompareMemory( &stZeroAuthGroup,
8917 sizeof( GUID)) == sizeof( GUID))
8920 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8922 try_return( ntStatus = STATUS_ACCESS_DENIED);
8926 RtlCopyMemory( AuthGroup,
8939 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8940 IN ULONG InvalidateReason)
8943 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8944 NTSTATUS ntStatus = STATUS_SUCCESS;
8947 ULONG ulProcessCount = 0;
8954 switch( InvalidateReason)
8957 case AFS_INVALIDATE_DELETED:
8960 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8961 ObjectInfo->Fcb != NULL)
8964 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8967 ObjectInfo->Links = 0;
8969 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
8971 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
8976 // Clear out the extents
8977 // And get rid of them (note this involves waiting
8978 // for any writes or reads to the cache to complete)
8981 AFSTearDownFcbExtents( ObjectInfo->Fcb,
8984 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
8990 case AFS_INVALIDATE_DATA_VERSION:
8993 LARGE_INTEGER liCurrentOffset = {0,0};
8994 LARGE_INTEGER liFlushLength = {0,0};
8995 ULONG ulFlushLength = 0;
8996 BOOLEAN bLocked = FALSE;
8997 BOOLEAN bExtentsLocked = FALSE;
8998 BOOLEAN bCleanExtents = FALSE;
9000 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9001 ObjectInfo->Fcb != NULL)
9004 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9009 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9012 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9013 AFS_TRACE_LEVEL_VERBOSE,
9014 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9015 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9016 PsGetCurrentThread()));
9018 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9021 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9028 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9029 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9035 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9036 AFS_TRACE_LEVEL_WARNING,
9037 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9038 ObjectInfo->FileId.Cell,
9039 ObjectInfo->FileId.Volume,
9040 ObjectInfo->FileId.Vnode,
9041 ObjectInfo->FileId.Unique));
9043 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9048 bCleanExtents = TRUE;
9051 __except( EXCEPTION_EXECUTE_HANDLER)
9054 ntStatus = GetExceptionCode();
9058 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9059 ObjectInfo->FileId.Cell,
9060 ObjectInfo->FileId.Volume,
9061 ObjectInfo->FileId.Vnode,
9062 ObjectInfo->FileId.Unique,
9065 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9068 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9069 AFS_TRACE_LEVEL_VERBOSE,
9070 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9071 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9072 PsGetCurrentThread()));
9074 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9079 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9080 AFS_TRACE_LEVEL_VERBOSE,
9081 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9082 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9083 PsGetCurrentThread()));
9085 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9088 bExtentsLocked = TRUE;
9091 // There are several possibilities here:
9093 // 0. If there are no extents or all of the extents are dirty, do nothing.
9095 // 1. There could be nothing dirty and an open reference count of zero
9096 // in which case we can just tear down all of the extents without
9097 // holding any resources.
9099 // 2. There could be nothing dirty and a non-zero open reference count
9100 // in which case we can issue a CcPurge against the entire file
9101 // while holding just the Fcb Resource.
9103 // 3. There can be dirty extents in which case we need to identify
9104 // the non-dirty ranges and then perform a CcPurge on just the
9105 // non-dirty ranges while holding just the Fcb Resource.
9108 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9111 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9114 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9116 bExtentsLocked = FALSE;
9118 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9121 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9125 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9131 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9132 AFS_TRACE_LEVEL_VERBOSE,
9133 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9134 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9135 PsGetCurrentThread()));
9137 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9140 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9147 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9148 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9154 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9155 AFS_TRACE_LEVEL_WARNING,
9156 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9157 ObjectInfo->FileId.Cell,
9158 ObjectInfo->FileId.Volume,
9159 ObjectInfo->FileId.Vnode,
9160 ObjectInfo->FileId.Unique));
9162 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9167 bCleanExtents = TRUE;
9170 __except( EXCEPTION_EXECUTE_HANDLER)
9173 ntStatus = GetExceptionCode();
9177 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9178 ObjectInfo->FileId.Cell,
9179 ObjectInfo->FileId.Volume,
9180 ObjectInfo->FileId.Vnode,
9181 ObjectInfo->FileId.Unique,
9184 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9187 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9188 AFS_TRACE_LEVEL_VERBOSE,
9189 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9190 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9191 PsGetCurrentThread()));
9193 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9199 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9201 bExtentsLocked = FALSE;
9203 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9204 AFS_TRACE_LEVEL_VERBOSE,
9205 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9206 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9207 PsGetCurrentThread()));
9209 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9212 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9217 // Must build a list of non-dirty ranges from the beginning of the file
9218 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9219 // ranges. In all but the most extreme random data write scenario there will
9220 // be significantly fewer.
9222 // For each range we need offset and size.
9225 AFSByteRange * ByteRangeList = NULL;
9226 ULONG ulByteRangeCount = 0;
9228 BOOLEAN bPurgeOnClose = FALSE;
9233 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9236 if ( ByteRangeList != NULL ||
9237 ulByteRangeCount == 0)
9240 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9247 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9249 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9250 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9251 &ByteRangeList[ulIndex].FileOffset,
9256 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9257 AFS_TRACE_LEVEL_WARNING,
9258 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9259 ObjectInfo->FileId.Cell,
9260 ObjectInfo->FileId.Volume,
9261 ObjectInfo->FileId.Vnode,
9262 ObjectInfo->FileId.Unique));
9264 bPurgeOnClose = TRUE;
9269 bCleanExtents = TRUE;
9272 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9274 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9276 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9283 // We couldn't allocate the memory to build the purge list
9284 // so just walk the extent list while holding the ExtentsList Resource.
9285 // This could deadlock but we do not have much choice.
9288 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9290 bExtentsLocked = TRUE;
9292 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9296 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9300 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9302 while( ulProcessCount < ulCount)
9304 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9306 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9308 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9309 &pEntry->FileOffset,
9314 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9315 AFS_TRACE_LEVEL_WARNING,
9316 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9317 ObjectInfo->FileId.Cell,
9318 ObjectInfo->FileId.Volume,
9319 ObjectInfo->FileId.Vnode,
9320 ObjectInfo->FileId.Unique));
9322 bPurgeOnClose = TRUE;
9327 bCleanExtents = TRUE;
9331 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9334 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9336 while( liFlushLength.QuadPart > 0)
9339 if( liFlushLength.QuadPart > 512 * 1024000)
9341 ulFlushLength = 512 * 1024000;
9345 ulFlushLength = liFlushLength.LowPart;
9348 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9354 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9355 AFS_TRACE_LEVEL_WARNING,
9356 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9357 ObjectInfo->FileId.Cell,
9358 ObjectInfo->FileId.Volume,
9359 ObjectInfo->FileId.Vnode,
9360 ObjectInfo->FileId.Unique));
9362 bPurgeOnClose = TRUE;
9367 bCleanExtents = TRUE;
9370 liFlushLength.QuadPart -= ulFlushLength;
9374 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9382 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9388 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9389 AFS_TRACE_LEVEL_WARNING,
9390 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9391 ObjectInfo->FileId.Cell,
9392 ObjectInfo->FileId.Volume,
9393 ObjectInfo->FileId.Vnode,
9394 ObjectInfo->FileId.Unique));
9396 bPurgeOnClose = TRUE;
9401 bCleanExtents = TRUE;
9408 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9412 __except( EXCEPTION_EXECUTE_HANDLER)
9415 ntStatus = GetExceptionCode();
9419 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9420 ObjectInfo->FileId.Cell,
9421 ObjectInfo->FileId.Volume,
9422 ObjectInfo->FileId.Vnode,
9423 ObjectInfo->FileId.Unique,
9427 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9428 AFS_TRACE_LEVEL_VERBOSE,
9429 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9430 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9431 PsGetCurrentThread()));
9433 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9437 if ( bExtentsLocked)
9440 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9447 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9453 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9463 // Destroy the reference passed in by the caller to AFSInvalidateObject
9464 // or AFSQueueInvalidateObject
9467 lCount = AFSObjectInfoDecrement( ObjectInfo,
9468 AFS_OBJECT_REFERENCE_INVALIDATION);
9470 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9471 AFS_TRACE_LEVEL_VERBOSE,
9472 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",